diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..511b8b1 --- /dev/null +++ b/.classpath @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..61793db --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +# +# https://help.github.com/articles/dealing-with-line-endings/ +# +# These are explicitly windows files and should use crlf +*.bat text eol=crlf + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..363e476 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.gradle +.settings +build +bin +eaglercraftbungee/bin +eaglercraftbungee/rundir +epkcompiler/bin +spigot-server/world* +eaglercraftbungee/rundir \ No newline at end of file diff --git a/.project b/.project new file mode 100644 index 0000000..1e7ca72 --- /dev/null +++ b/.project @@ -0,0 +1,30 @@ + + + eaglercraft-unified + Project eaglercraft-unified created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + + + src_minecraft + 2 + S:/Misc Minecraft/minecraft html5/minecrafthtml5mcp/src_minecraft + + + diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..5b0a1bd --- /dev/null +++ b/build.gradle @@ -0,0 +1,81 @@ + +buildscript { + repositories { + jcenter() + } + + dependencies { + classpath 'io.github.zebalu:teavm-gradle-plugin:1.0.0' + } +} + +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'io.github.zebalu.teavm-gradle-plugin' + +sourceCompatibility = 1.7 +targetCompatibility = 1.8 + +sourceSets { + main { + java { + srcDir '../minecrafthtml5mcp/src_minecraft' + } + } +} + +repositories { + jcenter() +} +dependencies { + implementation 'org.teavm:teavm-platform:0.6.1' + implementation 'org.teavm:teavm-classlib:0.6.1' +} + +teavm { + + compileScopes = null; + minifying = false; + maxTopLevelNames = 10000; + properties = null; + debugInformationGenerated = false; + sourceMapsGenerated = false; + sourceFilesCopied = false; + incremental = false; + transformers = null; + + /** Where to save the result */ + targetDirectory = file("javascript"); + + /** The directory to monitor to decide if compile is up-to-date or not */ + //sourceDirectory = [file("src/main/java"),file("../minecrafthtml5mcp/src")]; + + /** How to name the result file. */ + targetFileName = "classes.js"; + + /** Which class holds your public static void main(Strin[] args) method */ + mainClass = 'net.lax1dude.eaglercraft.Client'; + + /** This will be the name of your main method after compilation. */ + entryPointName = 'main'; + + classesToPreserve = null; + stopOnErrors = false; + optimizationLevel = "FULL"; //org.teavm.vm.TeaVMOptimizationLevel.SIMPLE; + fastGlobalAnalysis = false; + targetType = "JAVASCRIPT"; //org.teavm.tooling.TeaVMTargetType.JAVASCRIPT; + cacheDirectory = null; + wasmVersion = "V_0x1"; //org.teavm.backend.wasm.render.WasmBinaryVersion.V_0x1; + minHeapSize = 4; + maxHeapSize = 128; + outOfProcess = false; + processMemory = 512; + longjmpSupported = true; + heapDump = false; + + /** Add name of configurations here where to look for jarfiles. */ + includeJarsFrom = []; + + /** By default teavmc taskd epends on javaCompile task, unless this varaibale is true. */ + skipJavaCompile = false; +} diff --git a/eaglercraftbungee/.classpath b/eaglercraftbungee/.classpath new file mode 100644 index 0000000..8cdc8a4 --- /dev/null +++ b/eaglercraftbungee/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/eaglercraftbungee/.project b/eaglercraftbungee/.project new file mode 100644 index 0000000..29e667a --- /dev/null +++ b/eaglercraftbungee/.project @@ -0,0 +1,17 @@ + + + minecrafthtml5bungee + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/eaglercraftbungee/Java-WebSocket-1.5.1-with-dependencies.jar b/eaglercraftbungee/Java-WebSocket-1.5.1-with-dependencies.jar new file mode 100644 index 0000000..8fb33ad Binary files /dev/null and b/eaglercraftbungee/Java-WebSocket-1.5.1-with-dependencies.jar differ diff --git a/eaglercraftbungee/bungee-deps.jar b/eaglercraftbungee/bungee-deps.jar new file mode 100644 index 0000000..36b6759 Binary files /dev/null and b/eaglercraftbungee/bungee-deps.jar differ diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/BungeeCord.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/BungeeCord.java new file mode 100644 index 0000000..f22b75f --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/BungeeCord.java @@ -0,0 +1,472 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee; + +import net.md_5.bungee.tab.Custom; +import net.md_5.bungee.api.tab.CustomTabList; +import net.md_5.bungee.protocol.packet.Packet3Chat; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; + +import net.md_5.bungee.protocol.packet.PacketFAPluginMessage; +import java.util.Collections; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import java.util.MissingResourceException; +import net.md_5.bungee.protocol.packet.DefinedPacket; +import io.netty.channel.ChannelException; +import java.util.Iterator; +import io.netty.util.concurrent.GenericFutureListener; +import java.net.SocketAddress; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.ChannelHandler; +import io.netty.util.AttributeKey; +import net.md_5.bungee.netty.PipelineUtils; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.util.concurrent.Future; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import net.md_5.bungee.api.config.ListenerInfo; +import java.util.TimerTask; +import net.md_5.bungee.reconnect.SQLReconnectHandler; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.command.ConsoleCommandSender; +import java.util.concurrent.TimeUnit; +import java.util.Calendar; +import java.io.IOException; +import jline.UnsupportedTerminal; +import java.io.OutputStream; +import net.md_5.bungee.log.LoggingOutputStream; +import java.util.logging.Level; +import net.md_5.bungee.log.BungeeLogger; +import org.fusesource.jansi.AnsiConsole; +import jline.internal.Log; +import java.io.PrintStream; +import com.google.common.io.ByteStreams; +import net.md_5.bungee.command.CommandFind; +import net.md_5.bungee.command.CommandSend; +import net.md_5.bungee.command.CommandPerms; +import net.md_5.bungee.command.CommandBungee; +import net.md_5.bungee.command.CommandAlert; +import net.md_5.bungee.command.CommandIP; +import net.md_5.bungee.command.CommandServer; +import net.md_5.bungee.command.CommandList; +import net.md_5.bungee.command.CommandEnd; +import net.md_5.bungee.api.plugin.Command; +import net.md_5.bungee.api.plugin.Plugin; +import net.md_5.bungee.command.CommandReload; +import java.util.concurrent.ExecutorService; +import net.md_5.bungee.scheduler.BungeeScheduler; +import net.md_5.bungee.config.YamlConfig; +import net.md_5.bungee.eaglercraft.PluginEaglerAuth; +import net.md_5.bungee.eaglercraft.PluginEaglerSkins; +import net.md_5.bungee.eaglercraft.WebSocketListener; + +import java.util.concurrent.locks.ReentrantReadWriteLock; +import net.md_5.bungee.util.CaseInsensitiveMap; +import java.util.HashSet; +import io.netty.channel.nio.NioEventLoopGroup; +import net.md_5.bungee.scheduler.BungeeThreadPool; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import java.util.logging.Logger; +import jline.console.ConsoleReader; +import net.md_5.bungee.api.scheduler.TaskScheduler; +import java.io.File; +import net.md_5.bungee.api.config.ConfigurationAdapter; +import net.md_5.bungee.api.ReconnectHandler; +import net.md_5.bungee.api.plugin.PluginManager; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.Map; +import io.netty.channel.Channel; +import java.util.Collection; +import java.util.Timer; +import io.netty.channel.MultithreadEventLoopGroup; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.ResourceBundle; +import net.md_5.bungee.config.Configuration; +import net.md_5.bungee.api.ProxyServer; + +public class BungeeCord extends ProxyServer { + public volatile boolean isRunning; + public final Configuration config; + public final ResourceBundle bundle; + public final ScheduledThreadPoolExecutor executors; + public final MultithreadEventLoopGroup eventLoops; + private final Timer saveThread; + private Collection listeners; + private Collection wsListeners; + private final Map connections; + private final ReadWriteLock connectionLock; + public final PluginManager pluginManager; + private ReconnectHandler reconnectHandler; + private ConfigurationAdapter configurationAdapter; + private final Collection pluginChannels; + private final File pluginsFolder; + private final TaskScheduler scheduler; + private ConsoleReader consoleReader; + private final Logger logger; + + public static BungeeCord getInstance() { + return (BungeeCord) ProxyServer.getInstance(); + } + + public BungeeCord() throws IOException { + this.config = new Configuration(); + this.bundle = ResourceBundle.getBundle("messages_en"); + this.executors = new BungeeThreadPool(new ThreadFactoryBuilder().setNameFormat("Bungee Pool Thread #%1$d").build()); + this.eventLoops = (MultithreadEventLoopGroup) new NioEventLoopGroup(Runtime.getRuntime().availableProcessors(), new ThreadFactoryBuilder().setNameFormat("Netty IO Thread #%1$d").build()); + this.saveThread = new Timer("Reconnect Saver"); + this.listeners = new HashSet(); + this.wsListeners = new HashSet(); + this.connections = (Map) new CaseInsensitiveMap(); + this.connectionLock = new ReentrantReadWriteLock(); + this.pluginManager = new PluginManager(this); + this.configurationAdapter = new YamlConfig(); + this.pluginChannels = new HashSet(); + this.pluginsFolder = new File("plugins"); + this.scheduler = new BungeeScheduler(); + this.getPluginManager().registerCommand(null, new CommandReload()); + this.getPluginManager().registerCommand(null, new CommandEnd()); + this.getPluginManager().registerCommand(null, new CommandList()); + this.getPluginManager().registerCommand(null, new CommandServer()); + this.getPluginManager().registerCommand(null, new CommandIP()); + this.getPluginManager().registerCommand(null, new CommandAlert()); + this.getPluginManager().registerCommand(null, new CommandBungee()); + this.getPluginManager().registerCommand(null, new CommandPerms()); + this.getPluginManager().registerCommand(null, new CommandSend()); + this.getPluginManager().registerCommand(null, new CommandFind()); + this.registerChannel("BungeeCord"); + Log.setOutput(new PrintStream(ByteStreams.nullOutputStream())); + AnsiConsole.systemInstall(); + this.consoleReader = new ConsoleReader(); + this.logger = new BungeeLogger(this); + System.setErr(new PrintStream(new LoggingOutputStream(this.logger, Level.SEVERE), true)); + System.setOut(new PrintStream(new LoggingOutputStream(this.logger, Level.INFO), true)); + if (this.consoleReader.getTerminal() instanceof UnsupportedTerminal) { + this.logger.info("Unable to initialize fancy terminal. To fix this on Windows, install the correct Microsoft Visual C++ 2008 Runtime"); + this.logger.info("NOTE: This error is non crucial, and BungeeCord will still function correctly! Do not bug the author about it unless you are still unable to get it working"); + } + } + + public static void main(final String[] args) throws Exception { + final BungeeCord bungee = new BungeeCord(); + ProxyServer.setInstance(bungee); + bungee.getLogger().info("Enabled BungeeCord version " + bungee.getVersion()); + bungee.start(); + while (bungee.isRunning) { + final String line = bungee.getConsoleReader().readLine(">"); + if (line != null && !bungee.getPluginManager().dispatchCommand(ConsoleCommandSender.getInstance(), line)) { + bungee.getConsole().sendMessage(ChatColor.RED + "Command not found"); + } + } + } + + @Override + public void start() throws Exception { + this.pluginsFolder.mkdir(); + this.config.load(); + this.pluginManager.detectPlugins(this.pluginsFolder); + this.pluginManager.addInternalPlugin(new PluginEaglerSkins()); + if(this.config.getAuthInfo().isEnabled()) this.pluginManager.addInternalPlugin(new PluginEaglerAuth()); + if (this.reconnectHandler == null) { + this.reconnectHandler = new SQLReconnectHandler(); + } + this.isRunning = true; + this.pluginManager.loadAndEnablePlugins(); + this.startListeners(); + this.saveThread.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + BungeeCord.this.getReconnectHandler().save(); + } + }, 0L, TimeUnit.MINUTES.toMillis(5L)); + } + + public void startListeners() { + for (final ListenerInfo info : this.config.getListeners()) { + InetSocketAddress sock = info.getHost(); + if(info.isWebsocket()) { + int port = 0; + try { + ServerSocket s = new ServerSocket(0, 0, InetAddress.getByName("127.11.0.1")); + sock = new InetSocketAddress("127.11.0.1", s.getLocalPort()); + s.close(); + } catch(IOException e) { + port = (int) (System.nanoTime() % 64000L + 1025L); + } + try { + this.wsListeners.add(new WebSocketListener(info, sock, this)); + BungeeCord.this.getLogger().info("Listening websockets on " + info.getHost()); + }catch(Throwable t) { + BungeeCord.this.getLogger().log(Level.WARNING, "Could not bind websocket listener to host " + info.getHost(), t); + } + } + final InetSocketAddress sock2 = sock; + final ChannelFutureListener listener = (ChannelFutureListener) new ChannelFutureListener() { + public void operationComplete(final ChannelFuture future) throws Exception { + if (future.isSuccess()) { + BungeeCord.this.listeners.add(future.channel()); + BungeeCord.this.getLogger().info("Listening on " + sock2); + } else { + BungeeCord.this.getLogger().log(Level.WARNING, "Could not bind to host " + sock2, future.cause()); + } + } + }; + ((ServerBootstrap) ((ServerBootstrap) new ServerBootstrap().channel((Class) NioServerSocketChannel.class)).childAttr((AttributeKey) PipelineUtils.LISTENER, (Object) info).childHandler((ChannelHandler) PipelineUtils.SERVER_CHILD) + .group((EventLoopGroup) this.eventLoops).localAddress((SocketAddress) sock)).bind().addListener((GenericFutureListener) listener); + } + } + + public void stopListeners() { + for (final Channel listener : this.listeners) { + this.getLogger().log(Level.INFO, "Closing listener {0}", listener); + try { + listener.close().syncUninterruptibly(); + } catch (ChannelException ex) { + this.getLogger().severe("Could not close listen thread"); + } + } + for (final WebSocketListener listener : this.wsListeners) { + this.getLogger().log(Level.INFO, "Closing websocket listener {0}", listener.getAddress()); + try { + listener.stop(); + }catch (IOException e) { + this.getLogger().severe("Could not close listen thread"); + e.printStackTrace(); + } catch (InterruptedException e) { + this.getLogger().severe("Could not close listen thread"); + e.printStackTrace(); + } + } + this.listeners.clear(); + } + + @Override + public void stop() { + new Thread("Shutdown Thread") { + @Override + public void run() { + BungeeCord.this.isRunning = false; + BungeeCord.this.executors.shutdown(); + BungeeCord.this.stopListeners(); + BungeeCord.this.getLogger().info("Closing pending connections"); + BungeeCord.this.connectionLock.readLock().lock(); + try { + BungeeCord.this.getLogger().info("Disconnecting " + BungeeCord.this.connections.size() + " connections"); + for (final UserConnection user : BungeeCord.this.connections.values()) { + user.disconnect(BungeeCord.this.getTranslation("restart")); + } + } finally { + BungeeCord.this.connectionLock.readLock().unlock(); + } + BungeeCord.this.getLogger().info("Closing IO threads"); + BungeeCord.this.eventLoops.shutdownGracefully(); + try { + BungeeCord.this.eventLoops.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + } catch (InterruptedException ex) { + } + BungeeCord.this.getLogger().info("Saving reconnect locations"); + BungeeCord.this.reconnectHandler.save(); + BungeeCord.this.reconnectHandler.close(); + BungeeCord.this.saveThread.cancel(); + BungeeCord.this.getLogger().info("Disabling plugins"); + for (final Plugin plugin : BungeeCord.this.pluginManager.getPlugins()) { + plugin.onDisable(); + BungeeCord.this.getScheduler().cancel(plugin); + } + BungeeCord.this.getLogger().info("Thankyou and goodbye"); + System.exit(0); + } + }.start(); + } + + public void broadcast(final DefinedPacket packet) { + this.connectionLock.readLock().lock(); + try { + for (final UserConnection con : this.connections.values()) { + con.unsafe().sendPacket(packet); + } + } finally { + this.connectionLock.readLock().unlock(); + } + } + + @Override + public String getName() { + return "BungeeCord"; + } + + @Override + public String getVersion() { + return (BungeeCord.class.getPackage().getImplementationVersion() == null) ? "unknown" : BungeeCord.class.getPackage().getImplementationVersion(); + } + + @Override + public String getTranslation(final String name) { + String translation = ""; + try { + translation = this.bundle.getString(name); + } catch (MissingResourceException ex) { + } + return translation; + } + + @Override + public Collection getPlayers() { + this.connectionLock.readLock().lock(); + try { + return new HashSet(this.connections.values()); + } finally { + this.connectionLock.readLock().unlock(); + } + } + + @Override + public int getOnlineCount() { + return this.connections.size(); + } + + @Override + public ProxiedPlayer getPlayer(final String name) { + this.connectionLock.readLock().lock(); + try { + return this.connections.get(name); + } finally { + this.connectionLock.readLock().unlock(); + } + } + + @Override + public Map getServers() { + return (Map) this.config.getServers(); + } + + @Override + public ServerInfo getServerInfo(final String name) { + return this.getServers().get(name); + } + + @Override + public void registerChannel(final String channel) { + synchronized (this.pluginChannels) { + this.pluginChannels.add(channel); + } + } + + @Override + public void unregisterChannel(final String channel) { + synchronized (this.pluginChannels) { + this.pluginChannels.remove(channel); + } + } + + @Override + public Collection getChannels() { + synchronized (this.pluginChannels) { + return Collections.unmodifiableCollection((Collection) this.pluginChannels); + } + } + + public PacketFAPluginMessage registerChannels() { + return new PacketFAPluginMessage("REGISTER", Util.format(this.pluginChannels, "\u0000").getBytes()); + } + + @Override + public byte getProtocolVersion() { + return 61; + } + + @Override + public String getGameVersion() { + return "1.5.2"; + } + + @Override + public ServerInfo constructServerInfo(final String name, final InetSocketAddress address, final boolean restricted) { + return new BungeeServerInfo(name, address, restricted); + } + + @Override + public CommandSender getConsole() { + return ConsoleCommandSender.getInstance(); + } + + @Override + public void broadcast(final String message) { + this.getConsole().sendMessage(message); + this.broadcast(new Packet3Chat(message)); + } + + public void addConnection(final UserConnection con) { + this.connectionLock.writeLock().lock(); + try { + this.connections.put(con.getName(), con); + } finally { + this.connectionLock.writeLock().unlock(); + } + } + + public void removeConnection(final UserConnection con) { + this.connectionLock.writeLock().lock(); + try { + this.connections.remove(con.getName()); + } finally { + this.connectionLock.writeLock().unlock(); + } + } + + @Override + public CustomTabList customTabList(final ProxiedPlayer player) { + return new Custom(player); + } + + @Override + public PluginManager getPluginManager() { + return this.pluginManager; + } + + @Override + public ReconnectHandler getReconnectHandler() { + return this.reconnectHandler; + } + + @Override + public void setReconnectHandler(final ReconnectHandler reconnectHandler) { + this.reconnectHandler = reconnectHandler; + } + + @Override + public ConfigurationAdapter getConfigurationAdapter() { + return this.configurationAdapter; + } + + @Override + public void setConfigurationAdapter(final ConfigurationAdapter configurationAdapter) { + this.configurationAdapter = configurationAdapter; + } + + @Override + public File getPluginsFolder() { + return this.pluginsFolder; + } + + @Override + public TaskScheduler getScheduler() { + return this.scheduler; + } + + public ConsoleReader getConsoleReader() { + return this.consoleReader; + } + + @Override + public Logger getLogger() { + return this.logger; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/BungeeServerInfo.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/BungeeServerInfo.java new file mode 100644 index 0000000..84ee4b9 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/BungeeServerInfo.java @@ -0,0 +1,137 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee; + +import java.beans.ConstructorProperties; +import java.util.LinkedList; +import java.util.ArrayList; +import io.netty.util.concurrent.GenericFutureListener; +import java.net.SocketAddress; +import io.netty.channel.ChannelOption; +import io.netty.channel.ChannelHandler; +import net.md_5.bungee.netty.PipelineUtils; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.bootstrap.Bootstrap; +import io.netty.util.concurrent.Future; +import net.md_5.bungee.netty.PacketHandler; +import net.md_5.bungee.connection.PingHandler; +import net.md_5.bungee.netty.HandlerBoss; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import net.md_5.bungee.api.ServerPing; +import net.md_5.bungee.api.Callback; +import net.md_5.bungee.api.connection.Server; +import net.md_5.bungee.protocol.packet.PacketFAPluginMessage; +import java.util.Objects; +import com.google.common.base.Preconditions; +import net.md_5.bungee.api.CommandSender; +import java.util.Collections; +import net.md_5.bungee.protocol.packet.DefinedPacket; +import java.util.Queue; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import java.util.Collection; +import java.net.InetSocketAddress; +import net.md_5.bungee.api.config.ServerInfo; + +public class BungeeServerInfo implements ServerInfo { + private final String name; + private final InetSocketAddress address; + private final Collection players; + private final boolean restricted; + private final Queue packetQueue; + + public void addPlayer(final ProxiedPlayer player) { + synchronized (this.players) { + this.players.add(player); + } + } + + public void removePlayer(final ProxiedPlayer player) { + synchronized (this.players) { + this.players.remove(player); + } + } + + @Override + public Collection getPlayers() { + synchronized (this.players) { + return Collections.unmodifiableCollection((Collection) this.players); + } + } + + @Override + public boolean canAccess(final CommandSender player) { + Preconditions.checkNotNull((Object) player, (Object) "player"); + return !this.restricted || player.hasPermission("bungeecord.server." + this.name); + } + + @Override + public boolean equals(final Object obj) { + return obj instanceof ServerInfo && Objects.equals(this.getAddress(), ((ServerInfo) obj).getAddress()); + } + + @Override + public int hashCode() { + return this.address.hashCode(); + } + + @Override + public void sendData(final String channel, final byte[] data) { + Preconditions.checkNotNull((Object) channel, (Object) "channel"); + Preconditions.checkNotNull((Object) data, (Object) "data"); + final Server server = this.players.isEmpty() ? null : this.players.iterator().next().getServer(); + if (server != null) { + server.sendData(channel, data); + } else { + synchronized (this.packetQueue) { + this.packetQueue.add(new PacketFAPluginMessage(channel, data)); + } + } + } + + @Override + public void ping(final Callback callback) { + Preconditions.checkNotNull((Object) callback, (Object) "callback"); + final ChannelFutureListener listener = (ChannelFutureListener) new ChannelFutureListener() { + public void operationComplete(final ChannelFuture future) throws Exception { + if (future.isSuccess()) { + ((HandlerBoss) future.channel().pipeline().get((Class) HandlerBoss.class)).setHandler(new PingHandler(BungeeServerInfo.this, callback)); + } else { + callback.done(null, future.cause()); + } + } + }; + ((Bootstrap) ((Bootstrap) ((Bootstrap) ((Bootstrap) new Bootstrap().channel((Class) NioSocketChannel.class)).group((EventLoopGroup) BungeeCord.getInstance().eventLoops)).handler((ChannelHandler) PipelineUtils.BASE)) + .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Integer.valueOf(5000))).remoteAddress((SocketAddress) this.getAddress()).connect().addListener((GenericFutureListener) listener); + } + + @ConstructorProperties({ "name", "address", "restricted" }) + public BungeeServerInfo(final String name, final InetSocketAddress address, final boolean restricted) { + this.players = new ArrayList(); + this.packetQueue = new LinkedList(); + this.name = name; + this.address = address; + this.restricted = restricted; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public InetSocketAddress getAddress() { + return this.address; + } + + public boolean isRestricted() { + return this.restricted; + } + + public Queue getPacketQueue() { + return this.packetQueue; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/EncryptionUtil.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/EncryptionUtil.java new file mode 100644 index 0000000..3f0ade9 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/EncryptionUtil.java @@ -0,0 +1,79 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee; + +import java.security.NoSuchAlgorithmException; +import java.security.KeyPairGenerator; +import java.security.spec.X509EncodedKeySpec; +import java.security.KeyFactory; +import java.security.PublicKey; +import javax.crypto.spec.IvParameterSpec; +import java.security.GeneralSecurityException; +import javax.crypto.spec.SecretKeySpec; +import java.util.Arrays; +import java.security.Key; +import javax.crypto.Cipher; +import net.md_5.bungee.protocol.packet.PacketFCEncryptionResponse; +import net.md_5.bungee.protocol.packet.PacketFDEncryptionRequest; +import javax.crypto.SecretKey; +import java.security.KeyPair; +import java.util.Random; + +public class EncryptionUtil +{ + private static final Random random; + public static KeyPair keys; + private static SecretKey secret; + + public static PacketFDEncryptionRequest encryptRequest() { + final String hash = BungeeCord.getInstance().config.isOnlineMode() ? Long.toString(EncryptionUtil.random.nextLong(), 16) : "-"; + final byte[] pubKey = EncryptionUtil.keys.getPublic().getEncoded(); + final byte[] verify = new byte[4]; + EncryptionUtil.random.nextBytes(verify); + return new PacketFDEncryptionRequest(hash, pubKey, verify); + } + + public static SecretKey getSecret(final PacketFCEncryptionResponse resp, final PacketFDEncryptionRequest request) throws GeneralSecurityException { + final Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(2, EncryptionUtil.keys.getPrivate()); + final byte[] decrypted = cipher.doFinal(resp.getVerifyToken()); + if (!Arrays.equals(request.getVerifyToken(), decrypted)) { + throw new IllegalStateException("Key pairs do not match!"); + } + cipher.init(2, EncryptionUtil.keys.getPrivate()); + return new SecretKeySpec(cipher.doFinal(resp.getSharedSecret()), "AES"); + } + + public static Cipher getCipher(final int opMode, final Key shared) throws GeneralSecurityException { + final Cipher cip = Cipher.getInstance("AES/CFB8/NoPadding"); + cip.init(opMode, shared, new IvParameterSpec(shared.getEncoded())); + return cip; + } + + public static PublicKey getPubkey(final PacketFDEncryptionRequest request) throws GeneralSecurityException { + return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(request.getPublicKey())); + } + + public static byte[] encrypt(final Key key, final byte[] b) throws GeneralSecurityException { + final Cipher hasher = Cipher.getInstance("RSA"); + hasher.init(1, key); + return hasher.doFinal(b); + } + + public static SecretKey getSecret() { + return EncryptionUtil.secret; + } + + static { + random = new Random(); + EncryptionUtil.secret = new SecretKeySpec(new byte[16], "AES"); + try { + EncryptionUtil.keys = KeyPairGenerator.getInstance("RSA").generateKeyPair(); + } + catch (NoSuchAlgorithmException ex) { + throw new ExceptionInInitializerError(ex); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/EntityMap.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/EntityMap.java new file mode 100644 index 0000000..45c0682 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/EntityMap.java @@ -0,0 +1,83 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee; + +public class EntityMap { + public static final int[][] entityIds; + + public static void rewrite(final byte[] packet, final int oldId, final int newId) { + final int packetId = packet[0] & 0xFF; + if (packetId == 29) { + for (int pos = 2; pos < packet.length; pos += 4) { + final int readId = readInt(packet, pos); + if (readId == oldId) { + setInt(packet, pos, newId); + } else if (readId == newId) { + setInt(packet, pos, oldId); + } + } + } else { + final int[] idArray = EntityMap.entityIds[packetId]; + if (idArray != null) { + for (final int pos2 : idArray) { + final int readId2 = readInt(packet, pos2); + if (readId2 == oldId) { + setInt(packet, pos2, newId); + } else if (readId2 == newId) { + setInt(packet, pos2, oldId); + } + } + } + } + if (packetId == 23) { + final int type = packet[5] & 0xFF; + if (type == 60 || type == 90) { + final int index20 = readInt(packet, 20); + if (packet.length > 24 && index20 == oldId) { + setInt(packet, 20, newId); + } + } + } + } + + private static void setInt(final byte[] buf, final int pos, final int i) { + buf[pos] = (byte) (i >> 24); + buf[pos + 1] = (byte) (i >> 16); + buf[pos + 2] = (byte) (i >> 8); + buf[pos + 3] = (byte) i; + } + + private static int readInt(final byte[] buf, final int pos) { + return (buf[pos] & 0xFF) << 24 | (buf[pos + 1] & 0xFF) << 16 | (buf[pos + 2] & 0xFF) << 8 | (buf[pos + 3] & 0xFF); + } + + static { + (entityIds = new int[256][])[5] = new int[] { 1 }; + EntityMap.entityIds[7] = new int[] { 1, 5 }; + EntityMap.entityIds[17] = new int[] { 1 }; + EntityMap.entityIds[18] = new int[] { 1 }; + EntityMap.entityIds[19] = new int[] { 1 }; + EntityMap.entityIds[20] = new int[] { 1 }; + EntityMap.entityIds[22] = new int[] { 1, 5 }; + EntityMap.entityIds[23] = new int[] { 1 }; + EntityMap.entityIds[24] = new int[] { 1 }; + EntityMap.entityIds[25] = new int[] { 1 }; + EntityMap.entityIds[26] = new int[] { 1 }; + EntityMap.entityIds[28] = new int[] { 1 }; + EntityMap.entityIds[30] = new int[] { 1 }; + EntityMap.entityIds[31] = new int[] { 1 }; + EntityMap.entityIds[32] = new int[] { 1 }; + EntityMap.entityIds[33] = new int[] { 1 }; + EntityMap.entityIds[34] = new int[] { 1 }; + EntityMap.entityIds[35] = new int[] { 1 }; + EntityMap.entityIds[38] = new int[] { 1 }; + EntityMap.entityIds[39] = new int[] { 1, 5 }; + EntityMap.entityIds[40] = new int[] { 1 }; + EntityMap.entityIds[41] = new int[] { 1 }; + EntityMap.entityIds[42] = new int[] { 1 }; + EntityMap.entityIds[55] = new int[] { 1 }; + EntityMap.entityIds[71] = new int[] { 1 }; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/PacketConstants.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/PacketConstants.java new file mode 100644 index 0000000..1bfe72f --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/PacketConstants.java @@ -0,0 +1,25 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee; + +import net.md_5.bungee.protocol.packet.PacketFAPluginMessage; +import net.md_5.bungee.protocol.packet.PacketCDClientStatus; +import net.md_5.bungee.protocol.packet.Packet9Respawn; + +public class PacketConstants { + public static final Packet9Respawn DIM1_SWITCH; + public static final Packet9Respawn DIM2_SWITCH; + public static final PacketCDClientStatus CLIENT_LOGIN; + public static final PacketFAPluginMessage FORGE_MOD_REQUEST; + public static final PacketFAPluginMessage I_AM_BUNGEE; + + static { + DIM1_SWITCH = new Packet9Respawn(1, (byte) 0, (byte) 0, (short) 256, "DEFAULT"); + DIM2_SWITCH = new Packet9Respawn(-1, (byte) 0, (byte) 0, (short) 256, "DEFAULT"); + CLIENT_LOGIN = new PacketCDClientStatus((byte) 0); + FORGE_MOD_REQUEST = new PacketFAPluginMessage("FML", new byte[] { 0, 0, 0, 0, 0, 2 }); + I_AM_BUNGEE = new PacketFAPluginMessage("BungeeCord", new byte[0]); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/ServerConnection.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/ServerConnection.java new file mode 100644 index 0000000..9a8f52b --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/ServerConnection.java @@ -0,0 +1,79 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee; + +import java.beans.ConstructorProperties; +import java.net.InetSocketAddress; +import java.util.concurrent.TimeUnit; +import net.md_5.bungee.protocol.packet.PacketFFKick; +import net.md_5.bungee.protocol.packet.DefinedPacket; +import net.md_5.bungee.protocol.packet.PacketFAPluginMessage; +import net.md_5.bungee.api.connection.Connection; +import net.md_5.bungee.netty.ChannelWrapper; +import net.md_5.bungee.api.connection.Server; + +public class ServerConnection implements Server { + private final ChannelWrapper ch; + private final BungeeServerInfo info; + private boolean isObsolete; + private final Connection.Unsafe unsafe; + + @Override + public void sendData(final String channel, final byte[] data) { + this.unsafe().sendPacket(new PacketFAPluginMessage(channel, data)); + } + + @Override + public synchronized void disconnect(final String reason) { + if (!this.ch.isClosed()) { + this.unsafe().sendPacket(new PacketFFKick(reason)); + this.ch.getHandle().eventLoop().schedule((Runnable) new Runnable() { + @Override + public void run() { + ServerConnection.this.ch.getHandle().close(); + } + }, 100L, TimeUnit.MILLISECONDS); + } + } + + @Override + public InetSocketAddress getAddress() { + return this.getInfo().getAddress(); + } + + @Override + public Connection.Unsafe unsafe() { + return this.unsafe; + } + + @ConstructorProperties({ "ch", "info" }) + public ServerConnection(final ChannelWrapper ch, final BungeeServerInfo info) { + this.unsafe = new Connection.Unsafe() { + @Override + public void sendPacket(final DefinedPacket packet) { + ServerConnection.this.ch.write(packet); + } + }; + this.ch = ch; + this.info = info; + } + + public ChannelWrapper getCh() { + return this.ch; + } + + @Override + public BungeeServerInfo getInfo() { + return this.info; + } + + public boolean isObsolete() { + return this.isObsolete; + } + + public void setObsolete(final boolean isObsolete) { + this.isObsolete = isObsolete; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/ServerConnector.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/ServerConnector.java new file mode 100644 index 0000000..88f5f15 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/ServerConnector.java @@ -0,0 +1,253 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee; + +import java.beans.ConstructorProperties; +import com.google.common.io.ByteArrayDataInput; +import net.md_5.bungee.protocol.Protocol; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.event.ServerKickEvent; +import java.util.Objects; +import net.md_5.bungee.protocol.packet.PacketFFKick; +import net.md_5.bungee.netty.CipherDecoder; +import javax.crypto.Cipher; +import java.security.PublicKey; +import io.netty.channel.ChannelHandler; +import net.md_5.bungee.netty.CipherEncoder; +import net.md_5.bungee.netty.PipelineUtils; +import net.md_5.bungee.protocol.packet.PacketFCEncryptionResponse; +import java.security.Key; +import net.md_5.bungee.protocol.packet.PacketFDEncryptionRequest; +import net.md_5.bungee.api.score.Scoreboard; +import java.util.Iterator; +import java.util.Queue; +import net.md_5.bungee.connection.CancelSendSignal; +import net.md_5.bungee.api.event.ServerSwitchEvent; +import net.md_5.bungee.connection.DownstreamBridge; +import net.md_5.bungee.netty.HandlerBoss; +import net.md_5.bungee.protocol.packet.Packet9Respawn; +import net.md_5.bungee.protocol.packet.PacketD1Team; +import net.md_5.bungee.api.score.Team; +import net.md_5.bungee.protocol.packet.PacketCEScoreboardObjective; +import net.md_5.bungee.api.score.Objective; +import net.md_5.bungee.protocol.packet.DefinedPacket; +import net.md_5.bungee.protocol.packet.forge.Forge1Login; +import net.md_5.bungee.protocol.Forge; +import net.md_5.bungee.netty.PacketDecoder; +import net.md_5.bungee.api.connection.Server; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.ServerConnectedEvent; +import com.google.common.base.Preconditions; +import net.md_5.bungee.protocol.packet.Packet1Login; +import com.google.common.io.ByteArrayDataOutput; +import net.md_5.bungee.protocol.packet.PacketFAPluginMessage; +import com.google.common.io.ByteStreams; +import net.md_5.bungee.api.ChatColor; +import javax.crypto.SecretKey; +import net.md_5.bungee.netty.ChannelWrapper; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.netty.PacketHandler; + +public class ServerConnector extends PacketHandler +{ + private final ProxyServer bungee; + private ChannelWrapper ch; + private final UserConnection user; + private final BungeeServerInfo target; + private State thisState; + private SecretKey secretkey; + private boolean sentMessages; + + @Override + public void exception(final Throwable t) throws Exception { + final String message = "Exception Connecting:" + Util.exception(t); + if (this.user.getServer() == null) { + this.user.disconnect(message); + } + else { + this.user.sendMessage(ChatColor.RED + message); + } + } + + @Override + public void connected(final ChannelWrapper channel) throws Exception { + this.ch = channel; + final ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("Login"); + out.writeUTF(this.user.getAddress().getHostString()); + out.writeInt(this.user.getAddress().getPort()); + channel.write(new PacketFAPluginMessage("BungeeCord", out.toByteArray())); + channel.write(this.user.getPendingConnection().getHandshake()); + if (this.user.getPendingConnection().getForgeLogin() == null) { + channel.write(PacketConstants.CLIENT_LOGIN); + } + } + + @Override + public void disconnected(final ChannelWrapper channel) throws Exception { + this.user.getPendingConnects().remove(this.target); + } + + @Override + public void handle(final Packet1Login login) throws Exception { + Preconditions.checkState(this.thisState == State.LOGIN, (Object)"Not exepcting LOGIN"); + final ServerConnection server = new ServerConnection(this.ch, this.target); + final ServerConnectedEvent event = new ServerConnectedEvent(this.user, server); + this.bungee.getPluginManager().callEvent(event); + this.ch.write(BungeeCord.getInstance().registerChannels()); + final Queue packetQueue = this.target.getPacketQueue(); + synchronized (packetQueue) { + while (!packetQueue.isEmpty()) { + this.ch.write(packetQueue.poll()); + } + } + for (final PacketFAPluginMessage message : this.user.getPendingConnection().getRegisterMessages()) { + this.ch.write(message); + } + if (!this.sentMessages) { + for (final PacketFAPluginMessage message : this.user.getPendingConnection().getLoginMessages()) { + this.ch.write(message); + } + } + if (this.user.getSettings() != null) { + this.ch.write(this.user.getSettings()); + } + synchronized (this.user.getSwitchMutex()) { + if (this.user.getServer() == null) { + this.user.setClientEntityId(login.getEntityId()); + this.user.setServerEntityId(login.getEntityId()); + Packet1Login modLogin; + if (((PacketDecoder)this.ch.getHandle().pipeline().get((Class)PacketDecoder.class)).getProtocol() == Forge.getInstance()) { + modLogin = new Forge1Login(login.getEntityId(), login.getLevelType(), login.getGameMode(), login.getDimension(), login.getDifficulty(), login.getUnused(), (byte)this.user.getPendingConnection().getListener().getTabListSize()); + } + else { + modLogin = new Packet1Login(login.getEntityId(), login.getLevelType(), login.getGameMode(), (byte)login.getDimension(), login.getDifficulty(), login.getUnused(), (byte)this.user.getPendingConnection().getListener().getTabListSize()); + } + this.user.unsafe().sendPacket(modLogin); + } + else { + this.user.getTabList().onServerChange(); + final Scoreboard serverScoreboard = this.user.getServerSentScoreboard(); + for (final Objective objective : serverScoreboard.getObjectives()) { + this.user.unsafe().sendPacket(new PacketCEScoreboardObjective(objective.getName(), objective.getValue(), (byte)1)); + } + for (final Team team : serverScoreboard.getTeams()) { + this.user.unsafe().sendPacket(new PacketD1Team(team.getName())); + } + serverScoreboard.clear(); + this.user.sendDimensionSwitch(); + this.user.setServerEntityId(login.getEntityId()); + this.user.unsafe().sendPacket(new Packet9Respawn(login.getDimension(), login.getDifficulty(), login.getGameMode(), (short)256, login.getLevelType())); + this.user.getServer().setObsolete(true); + this.user.getServer().disconnect("Quitting"); + } + if (!this.user.isActive()) { + server.disconnect("Quitting"); + this.bungee.getLogger().warning("No client connected for pending server!"); + return; + } + this.target.addPlayer(this.user); + this.user.getPendingConnects().remove(this.target); + this.user.setServer(server); + ((HandlerBoss)this.ch.getHandle().pipeline().get((Class)HandlerBoss.class)).setHandler(new DownstreamBridge(this.bungee, this.user, server)); + } + this.bungee.getPluginManager().callEvent(new ServerSwitchEvent(this.user)); + this.thisState = State.FINISHED; + throw new CancelSendSignal(); + } + + @Override + public void handle(final PacketFDEncryptionRequest encryptRequest) throws Exception { + Preconditions.checkState(this.thisState == State.ENCRYPT_REQUEST, (Object)"Not expecting ENCRYPT_REQUEST"); + if (this.user.getPendingConnection().getForgeLogin() != null) { + final PublicKey publickey = EncryptionUtil.getPubkey(encryptRequest); + this.secretkey = EncryptionUtil.getSecret(); + final byte[] shared = EncryptionUtil.encrypt(publickey, this.secretkey.getEncoded()); + final byte[] token = EncryptionUtil.encrypt(publickey, encryptRequest.getVerifyToken()); + this.ch.write(new PacketFCEncryptionResponse(shared, token)); + final Cipher encrypt = EncryptionUtil.getCipher(1, this.secretkey); + this.ch.getHandle().pipeline().addBefore(PipelineUtils.PACKET_DECODE_HANDLER, PipelineUtils.ENCRYPT_HANDLER, (ChannelHandler)new CipherEncoder(encrypt)); + this.thisState = State.ENCRYPT_RESPONSE; + } + else { + this.thisState = State.LOGIN; + } + } + + @Override + public void handle(final PacketFCEncryptionResponse encryptResponse) throws Exception { + Preconditions.checkState(this.thisState == State.ENCRYPT_RESPONSE, (Object)"Not expecting ENCRYPT_RESPONSE"); + final Cipher decrypt = EncryptionUtil.getCipher(2, this.secretkey); + this.ch.getHandle().pipeline().addBefore(PipelineUtils.PACKET_DECODE_HANDLER, PipelineUtils.DECRYPT_HANDLER, (ChannelHandler)new CipherDecoder(decrypt)); + this.ch.write(this.user.getPendingConnection().getForgeLogin()); + this.ch.write(PacketConstants.CLIENT_LOGIN); + this.thisState = State.LOGIN; + } + + @Override + public void handle(final PacketFFKick kick) throws Exception { + ServerInfo def = this.bungee.getServerInfo(this.user.getPendingConnection().getListener().getFallbackServer()); + if (Objects.equals(this.target, def)) { + def = null; + } + final ServerKickEvent event = this.bungee.getPluginManager().callEvent(new ServerKickEvent(this.user, kick.getMessage(), def)); + if (event.isCancelled() && event.getCancelServer() != null) { + this.user.connect(event.getCancelServer()); + return; + } + final String message = this.bungee.getTranslation("connect_kick") + this.target.getName() + ": " + kick.getMessage(); + if (this.user.getServer() == null) { + this.user.disconnect(message); + } + else { + this.user.sendMessage(message); + } + } + + @Override + public void handle(final PacketFAPluginMessage pluginMessage) throws Exception { + if (pluginMessage.equals(PacketConstants.I_AM_BUNGEE)) { + throw new IllegalStateException("May not connect to another BungeCord!"); + } + if (pluginMessage.getTag().equals("FML") && (pluginMessage.getData()[0] & 0xFF) == 0x0) { + final ByteArrayDataInput in = ByteStreams.newDataInput(pluginMessage.getData()); + in.readUnsignedByte(); + for (int count = in.readInt(), i = 0; i < count; ++i) { + in.readUTF(); + } + if (in.readByte() != 0) { + ((PacketDecoder)this.ch.getHandle().pipeline().get((Class)PacketDecoder.class)).setProtocol(Forge.getInstance()); + } + } + this.user.unsafe().sendPacket(pluginMessage); + if (!this.sentMessages && this.user.getPendingConnection().getForgeLogin() != null) { + for (final PacketFAPluginMessage message : this.user.getPendingConnection().getLoginMessages()) { + this.ch.write(message); + } + this.sentMessages = true; + } + } + + @Override + public String toString() { + return "[" + this.user.getName() + "] <-> ServerConnector [" + this.target.getName() + "]"; + } + + @ConstructorProperties({ "bungee", "user", "target" }) + public ServerConnector(final ProxyServer bungee, final UserConnection user, final BungeeServerInfo target) { + this.thisState = State.ENCRYPT_REQUEST; + this.bungee = bungee; + this.user = user; + this.target = target; + } + + private enum State + { + ENCRYPT_REQUEST, + ENCRYPT_RESPONSE, + LOGIN, + FINISHED; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/UserConnection.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/UserConnection.java new file mode 100644 index 0000000..cb3d9da --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/UserConnection.java @@ -0,0 +1,386 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee; + +import net.md_5.bungee.api.connection.Server; +import net.md_5.bungee.api.connection.PendingConnection; +import java.beans.ConstructorProperties; +import net.md_5.bungee.util.CaseInsensitiveSet; +import java.util.HashSet; +import net.md_5.bungee.api.config.TexturePackInfo; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.event.PermissionCheckEvent; +import java.util.Collections; +import java.net.InetSocketAddress; +import net.md_5.bungee.protocol.packet.PacketFAPluginMessage; +import net.md_5.bungee.protocol.packet.Packet3Chat; +import net.md_5.bungee.protocol.packet.PacketFFKick; +import java.util.logging.Level; +import io.netty.util.concurrent.GenericFutureListener; +import io.netty.util.internal.PlatformDependent; +import java.net.SocketAddress; +import io.netty.channel.ChannelOption; +import io.netty.channel.ChannelHandler; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.bootstrap.Bootstrap; +import io.netty.util.concurrent.Future; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import net.md_5.bungee.netty.PacketHandler; +import net.md_5.bungee.netty.HandlerBoss; +import net.md_5.bungee.netty.PipelineUtils; +import io.netty.channel.Channel; +import io.netty.channel.ChannelInitializer; +import net.md_5.bungee.api.ChatColor; +import java.util.Objects; +import net.md_5.bungee.api.event.ServerConnectEvent; +import net.md_5.bungee.protocol.packet.DefinedPacket; +import com.google.common.base.Preconditions; +import java.util.Iterator; +import net.md_5.bungee.api.connection.Connection; +import net.md_5.bungee.api.score.Scoreboard; +import net.md_5.bungee.protocol.packet.PacketCCSettings; +import net.md_5.bungee.api.tab.TabListHandler; +import net.md_5.bungee.api.config.ServerInfo; +import java.util.Collection; +import net.md_5.bungee.connection.InitialHandler; +import net.md_5.bungee.netty.ChannelWrapper; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +public final class UserConnection implements ProxiedPlayer { + private final ProxyServer bungee; + private final ChannelWrapper ch; + private final String name; + private final InitialHandler pendingConnection; + private ServerConnection server; + private final Object switchMutex; + private final Collection pendingConnects; + private TabListHandler tabList; + private int sentPingId; + private long sentPingTime; + private int ping; + private final Collection groups; + private final Collection permissions; + private int clientEntityId; + private int serverEntityId; + private PacketCCSettings settings; + private final Scoreboard serverSentScoreboard; + private String displayName; + private final Connection.Unsafe unsafe; + + public void init() { + this.displayName = this.name; + try { + this.tabList = (TabListHandler) this.getPendingConnection().getListener().getTabList().getDeclaredConstructor((Class[]) new Class[0]).newInstance(new Object[0]); + } catch (ReflectiveOperationException ex) { + throw new RuntimeException(ex); + } + this.tabList.init(this); + final Collection g = this.bungee.getConfigurationAdapter().getGroups(this.name); + for (final String s : g) { + this.addGroups(s); + } + } + + @Override + public void setTabList(final TabListHandler tabList) { + tabList.init(this); + this.tabList = tabList; + } + + public void sendPacket(final byte[] b) { + this.ch.write(b); + } + + @Deprecated + public boolean isActive() { + return !this.ch.isClosed(); + } + + @Override + public void setDisplayName(final String name) { + Preconditions.checkNotNull((Object) name, (Object) "displayName"); + Preconditions.checkArgument(name.length() <= 16, (Object) "Display name cannot be longer than 16 characters"); + this.getTabList().onDisconnect(); + this.displayName = name; + this.getTabList().onConnect(); + } + + @Override + public void connect(final ServerInfo target) { + this.connect(target, false); + } + + void sendDimensionSwitch() { + this.unsafe().sendPacket(PacketConstants.DIM1_SWITCH); + this.unsafe().sendPacket(PacketConstants.DIM2_SWITCH); + } + + public void connectNow(final ServerInfo target) { + this.sendDimensionSwitch(); + this.connect(target); + } + + public void connect(final ServerInfo info, final boolean retry) { + final ServerConnectEvent event = new ServerConnectEvent(this, info); + if (this.bungee.getPluginManager().callEvent(event).isCancelled()) { + return; + } + final BungeeServerInfo target = (BungeeServerInfo) event.getTarget(); + if (this.getServer() != null && Objects.equals(this.getServer().getInfo(), target)) { + //this.sendMessage(ChatColor.RED + "Cannot connect to server you are already on!"); + return; + } + if (this.pendingConnects.contains(target)) { + this.sendMessage(ChatColor.RED + "Already connecting to this server!"); + return; + } + this.pendingConnects.add(target); + final ChannelInitializer initializer = new ChannelInitializer() { + protected void initChannel(final Channel ch) throws Exception { + PipelineUtils.BASE.initChannel(ch); + ((HandlerBoss) ch.pipeline().get((Class) HandlerBoss.class)).setHandler(new ServerConnector(UserConnection.this.bungee, UserConnection.this, target)); + } + }; + final ChannelFutureListener listener = (ChannelFutureListener) new ChannelFutureListener() { + public void operationComplete(final ChannelFuture future) throws Exception { + if (!future.isSuccess()) { + future.channel().close(); + UserConnection.this.pendingConnects.remove(target); + final ServerInfo def = ProxyServer.getInstance().getServers().get(UserConnection.this.getPendingConnection().getListener().getFallbackServer()); + if ((retry & target != def) && (UserConnection.this.getServer() == null || def != UserConnection.this.getServer().getInfo())) { + UserConnection.this.sendMessage(UserConnection.this.bungee.getTranslation("fallback_lobby")); + UserConnection.this.connect(def, false); + } else if (UserConnection.this.server == null) { + UserConnection.this.disconnect(UserConnection.this.bungee.getTranslation("fallback_kick") + future.cause().getClass().getName()); + } else { + UserConnection.this.sendMessage(UserConnection.this.bungee.getTranslation("fallback_kick") + future.cause().getClass().getName()); + } + } + } + }; + final Bootstrap b = ((Bootstrap) ((Bootstrap) ((Bootstrap) ((Bootstrap) new Bootstrap().channel((Class) NioSocketChannel.class)).group((EventLoopGroup) BungeeCord.getInstance().eventLoops)).handler((ChannelHandler) initializer)) + .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Integer.valueOf(5000))).remoteAddress((SocketAddress) target.getAddress()); + if (!PlatformDependent.isWindows()) { + b.localAddress(this.getPendingConnection().getListener().getHost().getHostString(), 0); + } + b.connect().addListener((GenericFutureListener) listener); + } + + @Override + public synchronized void disconnect(final String reason) { + if (this.ch.getHandle().isActive()) { + this.bungee.getLogger().log(Level.INFO, "[" + this.getName() + "] disconnected with: " + reason); + this.unsafe().sendPacket(new PacketFFKick(reason)); + this.ch.close(); + if (this.server != null) { + this.server.disconnect("Quitting"); + } + } + } + + @Override + public void chat(final String message) { + Preconditions.checkState(this.server != null, (Object) "Not connected to server"); + this.server.getCh().write(new Packet3Chat(message)); + } + + @Override + public void sendMessage(final String message) { + this.unsafe().sendPacket(new Packet3Chat(message)); + } + + @Override + public void sendMessages(final String... messages) { + for (final String message : messages) { + this.sendMessage(message); + } + } + + @Override + public void sendData(final String channel, final byte[] data) { + this.unsafe().sendPacket(new PacketFAPluginMessage(channel, data)); + } + + @Override + public InetSocketAddress getAddress() { + return (InetSocketAddress) this.ch.getHandle().remoteAddress(); + } + + @Override + public Collection getGroups() { + return Collections.unmodifiableCollection((Collection) this.groups); + } + + @Override + public void addGroups(final String... groups) { + for (final String group : groups) { + this.groups.add(group); + for (final String permission : this.bungee.getConfigurationAdapter().getPermissions(group)) { + this.setPermission(permission, true); + } + } + } + + @Override + public void removeGroups(final String... groups) { + for (final String group : groups) { + this.groups.remove(group); + for (final String permission : this.bungee.getConfigurationAdapter().getPermissions(group)) { + this.setPermission(permission, false); + } + } + } + + @Override + public boolean hasPermission(final String permission) { + return this.bungee.getPluginManager().callEvent(new PermissionCheckEvent(this, permission, this.permissions.contains(permission))).hasPermission(); + } + + @Override + public void setPermission(final String permission, final boolean value) { + if (value) { + this.permissions.add(permission); + } else { + this.permissions.remove(permission); + } + } + + @Override + public String toString() { + return this.name; + } + + @Override + public void setTexturePack(final TexturePackInfo pack) { + this.unsafe().sendPacket(new PacketFAPluginMessage("MC|TPack", (pack.getUrl() + "\u0000" + pack.getSize()).getBytes())); + } + + @Override + public Connection.Unsafe unsafe() { + return this.unsafe; + } + + @ConstructorProperties({ "bungee", "ch", "name", "pendingConnection" }) + public UserConnection(final ProxyServer bungee, final ChannelWrapper ch, final String name, final InitialHandler pendingConnection) { + this.switchMutex = new Object(); + this.pendingConnects = new HashSet(); + this.ping = 100; + this.groups = (Collection) new CaseInsensitiveSet(); + this.permissions = (Collection) new CaseInsensitiveSet(); + this.serverSentScoreboard = new Scoreboard(); + this.unsafe = new Connection.Unsafe() { + @Override + public void sendPacket(final DefinedPacket packet) { + UserConnection.this.ch.write(packet); + } + }; + if (bungee == null) { + throw new NullPointerException("bungee"); + } + if (ch == null) { + throw new NullPointerException("ch"); + } + if (name == null) { + throw new NullPointerException("name"); + } + this.bungee = bungee; + this.ch = ch; + this.name = name; + this.pendingConnection = pendingConnection; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public InitialHandler getPendingConnection() { + return this.pendingConnection; + } + + @Override + public ServerConnection getServer() { + return this.server; + } + + public void setServer(final ServerConnection server) { + this.server = server; + } + + public Object getSwitchMutex() { + return this.switchMutex; + } + + public Collection getPendingConnects() { + return this.pendingConnects; + } + + @Override + public TabListHandler getTabList() { + return this.tabList; + } + + public int getSentPingId() { + return this.sentPingId; + } + + public void setSentPingId(final int sentPingId) { + this.sentPingId = sentPingId; + } + + public long getSentPingTime() { + return this.sentPingTime; + } + + public void setSentPingTime(final long sentPingTime) { + this.sentPingTime = sentPingTime; + } + + @Override + public int getPing() { + return this.ping; + } + + public void setPing(final int ping) { + this.ping = ping; + } + + public int getClientEntityId() { + return this.clientEntityId; + } + + public void setClientEntityId(final int clientEntityId) { + this.clientEntityId = clientEntityId; + } + + public int getServerEntityId() { + return this.serverEntityId; + } + + public void setServerEntityId(final int serverEntityId) { + this.serverEntityId = serverEntityId; + } + + public PacketCCSettings getSettings() { + return this.settings; + } + + public void setSettings(final PacketCCSettings settings) { + this.settings = settings; + } + + public Scoreboard getServerSentScoreboard() { + return this.serverSentScoreboard; + } + + @Override + public String getDisplayName() { + return this.displayName; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/Util.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/Util.java new file mode 100644 index 0000000..4d8e43f --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/Util.java @@ -0,0 +1,44 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee; + +import java.util.Iterator; +import java.util.Collection; +import java.net.InetSocketAddress; + +public class Util { + private static final int DEFAULT_PORT = 25565; + + public static InetSocketAddress getAddr(final String hostline) { + final String[] split = hostline.split(":"); + int port = 25565; + if (split.length > 1) { + port = Integer.parseInt(split[1]); + } + return new InetSocketAddress(split[0], port); + } + + public static String hex(final int i) { + return String.format("0x%02X", i); + } + + public static String exception(final Throwable t) { + final StackTraceElement[] trace = t.getStackTrace(); + return t.getClass().getSimpleName() + " : " + t.getMessage() + ((trace.length > 0) ? (" @ " + t.getStackTrace()[0].getClassName() + ":" + t.getStackTrace()[0].getLineNumber()) : ""); + } + + public static String csv(final Collection objects) { + return format(objects, ", "); + } + + public static String format(final Collection objects, final String separators) { + final StringBuilder ret = new StringBuilder(); + for (final Object o : objects) { + ret.append(o); + ret.append(separators); + } + return (ret.length() == 0) ? "" : ret.substring(0, ret.length() - separators.length()); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/Callback.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/Callback.java new file mode 100644 index 0000000..2291dd0 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/Callback.java @@ -0,0 +1,9 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api; + +public interface Callback { + void done(final V p0, final Throwable p1); +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/ChatColor.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/ChatColor.java new file mode 100644 index 0000000..cda85ac --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/ChatColor.java @@ -0,0 +1,60 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + +public enum ChatColor { + BLACK('0'), DARK_BLUE('1'), DARK_GREEN('2'), DARK_AQUA('3'), DARK_RED('4'), DARK_PURPLE('5'), GOLD('6'), GRAY('7'), DARK_GRAY('8'), BLUE('9'), GREEN('a'), AQUA('b'), RED('c'), LIGHT_PURPLE('d'), YELLOW('e'), WHITE('f'), MAGIC('k'), + BOLD('l'), STRIKETHROUGH('m'), UNDERLINE('n'), ITALIC('o'), RESET('r'); + + public static final char COLOR_CHAR = '§'; + private static final Pattern STRIP_COLOR_PATTERN; + private static final Map BY_CHAR; + private final char code; + private final String toString; + + private ChatColor(final char code) { + this.code = code; + this.toString = new String(new char[] { '§', code }); + } + + @Override + public String toString() { + return this.toString; + } + + public static String stripColor(final String input) { + if (input == null) { + return null; + } + return ChatColor.STRIP_COLOR_PATTERN.matcher(input).replaceAll(""); + } + + public static String translateAlternateColorCodes(final char altColorChar, final String textToTranslate) { + final char[] b = textToTranslate.toCharArray(); + for (int i = 0; i < b.length - 1; ++i) { + if (b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf(b[i + 1]) > -1) { + b[i] = '§'; + b[i + 1] = Character.toLowerCase(b[i + 1]); + } + } + return new String(b); + } + + public static ChatColor getByChar(final char code) { + return ChatColor.BY_CHAR.get(code); + } + + static { + STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + String.valueOf('§') + "[0-9A-FK-OR]"); + BY_CHAR = new HashMap(); + for (final ChatColor colour : values()) { + ChatColor.BY_CHAR.put(colour.code, colour); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/CommandSender.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/CommandSender.java new file mode 100644 index 0000000..7f93805 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/CommandSender.java @@ -0,0 +1,25 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api; + +import java.util.Collection; + +public interface CommandSender { + String getName(); + + void sendMessage(final String p0); + + void sendMessages(final String... p0); + + Collection getGroups(); + + void addGroups(final String... p0); + + void removeGroups(final String... p0); + + boolean hasPermission(final String p0); + + void setPermission(final String p0, final boolean p1); +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/ProxyServer.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/ProxyServer.java new file mode 100644 index 0000000..493de3f --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/ProxyServer.java @@ -0,0 +1,86 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api; + +import net.md_5.bungee.api.tab.CustomTabList; +import net.md_5.bungee.api.scheduler.TaskScheduler; +import java.io.File; +import java.net.InetSocketAddress; +import net.md_5.bungee.api.config.ConfigurationAdapter; +import net.md_5.bungee.api.plugin.PluginManager; +import net.md_5.bungee.api.config.ServerInfo; +import java.util.Map; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import java.util.Collection; +import java.util.logging.Logger; +import com.google.common.base.Preconditions; + +public abstract class ProxyServer { + private static ProxyServer instance; + + public static void setInstance(final ProxyServer instance) { + Preconditions.checkNotNull((Object) instance, (Object) "instance"); + Preconditions.checkArgument(ProxyServer.instance == null, (Object) "Instance already set"); + ProxyServer.instance = instance; + } + + public abstract String getName(); + + public abstract String getVersion(); + + public abstract String getTranslation(final String p0); + + public abstract Logger getLogger(); + + public abstract Collection getPlayers(); + + public abstract ProxiedPlayer getPlayer(final String p0); + + public abstract Map getServers(); + + public abstract ServerInfo getServerInfo(final String p0); + + public abstract PluginManager getPluginManager(); + + public abstract ConfigurationAdapter getConfigurationAdapter(); + + public abstract void setConfigurationAdapter(final ConfigurationAdapter p0); + + public abstract ReconnectHandler getReconnectHandler(); + + public abstract void setReconnectHandler(final ReconnectHandler p0); + + public abstract void stop(); + + public abstract void start() throws Exception; + + public abstract void registerChannel(final String p0); + + public abstract void unregisterChannel(final String p0); + + public abstract Collection getChannels(); + + public abstract String getGameVersion(); + + public abstract byte getProtocolVersion(); + + public abstract ServerInfo constructServerInfo(final String p0, final InetSocketAddress p1, final boolean p2); + + public abstract CommandSender getConsole(); + + public abstract File getPluginsFolder(); + + public abstract TaskScheduler getScheduler(); + + public abstract int getOnlineCount(); + + public abstract void broadcast(final String p0); + + public abstract CustomTabList customTabList(final ProxiedPlayer p0); + + public static ProxyServer getInstance() { + return ProxyServer.instance; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/ReconnectHandler.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/ReconnectHandler.java new file mode 100644 index 0000000..3e8c187 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/ReconnectHandler.java @@ -0,0 +1,18 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api; + +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +public interface ReconnectHandler { + ServerInfo getServer(final ProxiedPlayer p0); + + void setServer(final ProxiedPlayer p0); + + void save(); + + void close(); +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/ServerPing.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/ServerPing.java new file mode 100644 index 0000000..c729d55 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/ServerPing.java @@ -0,0 +1,107 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api; + +import java.beans.ConstructorProperties; + +public class ServerPing { + private final byte protocolVersion; + private final String gameVersion; + private final String motd; + private final int currentPlayers; + private final int maxPlayers; + + @ConstructorProperties({ "protocolVersion", "gameVersion", "motd", "currentPlayers", "maxPlayers" }) + public ServerPing(final byte protocolVersion, final String gameVersion, final String motd, final int currentPlayers, final int maxPlayers) { + this.protocolVersion = protocolVersion; + this.gameVersion = gameVersion; + this.motd = motd; + this.currentPlayers = currentPlayers; + this.maxPlayers = maxPlayers; + } + + public byte getProtocolVersion() { + return this.protocolVersion; + } + + public String getGameVersion() { + return this.gameVersion; + } + + public String getMotd() { + return this.motd; + } + + public int getCurrentPlayers() { + return this.currentPlayers; + } + + public int getMaxPlayers() { + return this.maxPlayers; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof ServerPing)) { + return false; + } + final ServerPing other = (ServerPing) o; + if (!other.canEqual(this)) { + return false; + } + if (this.getProtocolVersion() != other.getProtocolVersion()) { + return false; + } + final Object this$gameVersion = this.getGameVersion(); + final Object other$gameVersion = other.getGameVersion(); + Label_0078: { + if (this$gameVersion == null) { + if (other$gameVersion == null) { + break Label_0078; + } + } else if (this$gameVersion.equals(other$gameVersion)) { + break Label_0078; + } + return false; + } + final Object this$motd = this.getMotd(); + final Object other$motd = other.getMotd(); + if (this$motd == null) { + if (other$motd == null) { + return this.getCurrentPlayers() == other.getCurrentPlayers() && this.getMaxPlayers() == other.getMaxPlayers(); + } + } else if (this$motd.equals(other$motd)) { + return this.getCurrentPlayers() == other.getCurrentPlayers() && this.getMaxPlayers() == other.getMaxPlayers(); + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof ServerPing; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = result * 31 + this.getProtocolVersion(); + final Object $gameVersion = this.getGameVersion(); + result = result * 31 + (($gameVersion == null) ? 0 : $gameVersion.hashCode()); + final Object $motd = this.getMotd(); + result = result * 31 + (($motd == null) ? 0 : $motd.hashCode()); + result = result * 31 + this.getCurrentPlayers(); + result = result * 31 + this.getMaxPlayers(); + return result; + } + + @Override + public String toString() { + return "ServerPing(protocolVersion=" + this.getProtocolVersion() + ", gameVersion=" + this.getGameVersion() + ", motd=" + this.getMotd() + ", currentPlayers=" + this.getCurrentPlayers() + ", maxPlayers=" + this.getMaxPlayers() + + ")"; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/config/AuthServiceInfo.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/config/AuthServiceInfo.java new file mode 100644 index 0000000..fd52e63 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/config/AuthServiceInfo.java @@ -0,0 +1,35 @@ +package net.md_5.bungee.api.config; + +import java.io.File; + +public class AuthServiceInfo { + + private final boolean enabled; + private final String limbo; + private final File authfile; + private final int timeout; + + public AuthServiceInfo(boolean enabled, String limbo, File authfile, int timeout) { + this.enabled = enabled; + this.limbo = limbo; + this.authfile = authfile; + this.timeout = timeout; + } + + public boolean isEnabled() { + return enabled; + } + + public String getLimbo() { + return limbo; + } + + public File getAuthfile() { + return authfile; + } + + public int getTimeout() { + return timeout; + } + +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/config/ConfigurationAdapter.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/config/ConfigurationAdapter.java new file mode 100644 index 0000000..b57e542 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/config/ConfigurationAdapter.java @@ -0,0 +1,28 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.config; + +import java.util.Collection; +import java.util.Map; + +public interface ConfigurationAdapter { + void load(); + + int getInt(final String p0, final int p1); + + String getString(final String p0, final String p1); + + boolean getBoolean(final String p0, final boolean p1); + + Map getServers(); + + Collection getListeners(); + + Collection getGroups(final String p0); + + Collection getPermissions(final String p0); + + AuthServiceInfo getAuthSettings(); +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/config/ListenerInfo.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/config/ListenerInfo.java new file mode 100644 index 0000000..801c1be --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/config/ListenerInfo.java @@ -0,0 +1,223 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.config; + +import java.beans.ConstructorProperties; +import net.md_5.bungee.api.tab.TabListHandler; +import java.util.Map; +import java.net.InetSocketAddress; + +public class ListenerInfo { + private final InetSocketAddress host; + private final String motd; + private final int maxPlayers; + private final int tabListSize; + private final String defaultServer; + private final String fallbackServer; + private final boolean forceDefault; + private final boolean websocket; + private final Map forcedHosts; + private final TexturePackInfo texturePack; + private final Class tabList; + + @ConstructorProperties({ "host", "motd", "maxPlayers", "tabListSize", "defaultServer", "fallbackServer", "forceDefault", "websocket", "forcedHosts", "texturePack", "tabList" }) + public ListenerInfo(final InetSocketAddress host, final String motd, final int maxPlayers, final int tabListSize, final String defaultServer, final String fallbackServer, final boolean forceDefault, final boolean websocket, + final Map forcedHosts, final TexturePackInfo texturePack, final Class tabList) { + this.host = host; + this.motd = motd; + this.maxPlayers = maxPlayers; + this.tabListSize = tabListSize; + this.defaultServer = defaultServer; + this.fallbackServer = fallbackServer; + this.forceDefault = forceDefault; + this.websocket = websocket; + this.forcedHosts = forcedHosts; + this.texturePack = texturePack; + this.tabList = tabList; + } + + public InetSocketAddress getHost() { + return this.host; + } + + public String getMotd() { + return this.motd; + } + + public int getMaxPlayers() { + return this.maxPlayers; + } + + public int getTabListSize() { + return this.tabListSize; + } + + public String getDefaultServer() { + return this.defaultServer; + } + + public String getFallbackServer() { + return this.fallbackServer; + } + + public boolean isForceDefault() { + return this.forceDefault; + } + + public Map getForcedHosts() { + return this.forcedHosts; + } + + public TexturePackInfo getTexturePack() { + return this.texturePack; + } + + public Class getTabList() { + return this.tabList; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof ListenerInfo)) { + return false; + } + final ListenerInfo other = (ListenerInfo) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$host = this.getHost(); + final Object other$host = other.getHost(); + Label_0065: { + if (this$host == null) { + if (other$host == null) { + break Label_0065; + } + } else if (this$host.equals(other$host)) { + break Label_0065; + } + return false; + } + final Object this$motd = this.getMotd(); + final Object other$motd = other.getMotd(); + Label_0102: { + if (this$motd == null) { + if (other$motd == null) { + break Label_0102; + } + } else if (this$motd.equals(other$motd)) { + break Label_0102; + } + return false; + } + if (this.getMaxPlayers() != other.getMaxPlayers()) { + return false; + } + if (this.getTabListSize() != other.getTabListSize()) { + return false; + } + final Object this$defaultServer = this.getDefaultServer(); + final Object other$defaultServer = other.getDefaultServer(); + Label_0165: { + if (this$defaultServer == null) { + if (other$defaultServer == null) { + break Label_0165; + } + } else if (this$defaultServer.equals(other$defaultServer)) { + break Label_0165; + } + return false; + } + final Object this$fallbackServer = this.getFallbackServer(); + final Object other$fallbackServer = other.getFallbackServer(); + Label_0202: { + if (this$fallbackServer == null) { + if (other$fallbackServer == null) { + break Label_0202; + } + } else if (this$fallbackServer.equals(other$fallbackServer)) { + break Label_0202; + } + return false; + } + if (this.isForceDefault() != other.isForceDefault()) { + return false; + } + final Object this$forcedHosts = this.getForcedHosts(); + final Object other$forcedHosts = other.getForcedHosts(); + Label_0252: { + if (this$forcedHosts == null) { + if (other$forcedHosts == null) { + break Label_0252; + } + } else if (this$forcedHosts.equals(other$forcedHosts)) { + break Label_0252; + } + return false; + } + final Object this$texturePack = this.getTexturePack(); + final Object other$texturePack = other.getTexturePack(); + Label_0289: { + if (this$texturePack == null) { + if (other$texturePack == null) { + break Label_0289; + } + } else if (this$texturePack.equals(other$texturePack)) { + break Label_0289; + } + return false; + } + final Object this$tabList = this.getTabList(); + final Object other$tabList = other.getTabList(); + if (this$tabList == null) { + if (other$tabList == null) { + return true; + } + } else if (this$tabList.equals(other$tabList)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof ListenerInfo; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $host = this.getHost(); + result = result * 31 + (($host == null) ? 0 : $host.hashCode()); + final Object $motd = this.getMotd(); + result = result * 31 + (($motd == null) ? 0 : $motd.hashCode()); + result = result * 31 + this.getMaxPlayers(); + result = result * 31 + this.getTabListSize(); + final Object $defaultServer = this.getDefaultServer(); + result = result * 31 + (($defaultServer == null) ? 0 : $defaultServer.hashCode()); + final Object $fallbackServer = this.getFallbackServer(); + result = result * 31 + (($fallbackServer == null) ? 0 : $fallbackServer.hashCode()); + result = result * 31 + (this.isForceDefault() ? 1231 : 1237); + final Object $forcedHosts = this.getForcedHosts(); + result = result * 31 + (($forcedHosts == null) ? 0 : $forcedHosts.hashCode()); + final Object $texturePack = this.getTexturePack(); + result = result * 31 + (($texturePack == null) ? 0 : $texturePack.hashCode()); + final Object $tabList = this.getTabList(); + result = result * 31 + (($tabList == null) ? 0 : $tabList.hashCode()); + return result; + } + + @Override + public String toString() { + return "ListenerInfo(host=" + this.getHost() + ", motd=" + this.getMotd() + ", maxPlayers=" + this.getMaxPlayers() + ", tabListSize=" + this.getTabListSize() + ", defaultServer=" + this.getDefaultServer() + ", fallbackServer=" + + this.getFallbackServer() + ", forceDefault=" + this.isForceDefault() + ", websocket=" + this.isWebsocket() + ", forcedHosts=" + this.getForcedHosts() + ", texturePack=" + this.getTexturePack() + ", tabList=" + this.getTabList() + ")"; + } + + public boolean isWebsocket() { + return websocket; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/config/ServerInfo.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/config/ServerInfo.java new file mode 100644 index 0000000..98705ed --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/config/ServerInfo.java @@ -0,0 +1,26 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.config; + +import net.md_5.bungee.api.ServerPing; +import net.md_5.bungee.api.Callback; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import java.util.Collection; +import java.net.InetSocketAddress; + +public interface ServerInfo { + String getName(); + + InetSocketAddress getAddress(); + + Collection getPlayers(); + + boolean canAccess(final CommandSender p0); + + void sendData(final String p0, final byte[] p1); + + void ping(final Callback p0); +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/config/TexturePackInfo.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/config/TexturePackInfo.java new file mode 100644 index 0000000..5e8ade5 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/config/TexturePackInfo.java @@ -0,0 +1,69 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.config; + +import java.beans.ConstructorProperties; + +public class TexturePackInfo { + private final String url; + private final int size; + + @ConstructorProperties({ "url", "size" }) + public TexturePackInfo(final String url, final int size) { + this.url = url; + this.size = size; + } + + public String getUrl() { + return this.url; + } + + public int getSize() { + return this.size; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof TexturePackInfo)) { + return false; + } + final TexturePackInfo other = (TexturePackInfo) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$url = this.getUrl(); + final Object other$url = other.getUrl(); + if (this$url == null) { + if (other$url == null) { + return this.getSize() == other.getSize(); + } + } else if (this$url.equals(other$url)) { + return this.getSize() == other.getSize(); + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof TexturePackInfo; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $url = this.getUrl(); + result = result * 31 + (($url == null) ? 0 : $url.hashCode()); + result = result * 31 + this.getSize(); + return result; + } + + @Override + public String toString() { + return "TexturePackInfo(url=" + this.getUrl() + ", size=" + this.getSize() + ")"; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/connection/ConnectedPlayer.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/connection/ConnectedPlayer.java new file mode 100644 index 0000000..c4431cd --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/connection/ConnectedPlayer.java @@ -0,0 +1,8 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.connection; + +public interface ConnectedPlayer extends ProxiedPlayer { +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/connection/Connection.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/connection/Connection.java new file mode 100644 index 0000000..22fba2d --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/connection/Connection.java @@ -0,0 +1,20 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.connection; + +import net.md_5.bungee.protocol.packet.DefinedPacket; +import java.net.InetSocketAddress; + +public interface Connection { + InetSocketAddress getAddress(); + + void disconnect(final String p0); + + Unsafe unsafe(); + + public interface Unsafe { + void sendPacket(final DefinedPacket p0); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/connection/PendingConnection.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/connection/PendingConnection.java new file mode 100644 index 0000000..24cbaba --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/connection/PendingConnection.java @@ -0,0 +1,18 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.connection; + +import net.md_5.bungee.api.config.ListenerInfo; +import java.net.InetSocketAddress; + +public interface PendingConnection extends Connection { + String getName(); + + byte getVersion(); + + InetSocketAddress getVirtualHost(); + + ListenerInfo getListener(); +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/connection/ProxiedPlayer.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/connection/ProxiedPlayer.java new file mode 100644 index 0000000..e8c35a2 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/connection/ProxiedPlayer.java @@ -0,0 +1,34 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.connection; + +import net.md_5.bungee.api.tab.TabListHandler; +import net.md_5.bungee.api.config.TexturePackInfo; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.CommandSender; + +public interface ProxiedPlayer extends Connection, CommandSender { + String getDisplayName(); + + void setDisplayName(final String p0); + + void connect(final ServerInfo p0); + + Server getServer(); + + int getPing(); + + void sendData(final String p0, final byte[] p1); + + PendingConnection getPendingConnection(); + + void chat(final String p0); + + void setTexturePack(final TexturePackInfo p0); + + void setTabList(final TabListHandler p0); + + TabListHandler getTabList(); +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/connection/Server.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/connection/Server.java new file mode 100644 index 0000000..ee6b394 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/connection/Server.java @@ -0,0 +1,13 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.connection; + +import net.md_5.bungee.api.config.ServerInfo; + +public interface Server extends Connection { + ServerInfo getInfo(); + + void sendData(final String p0, final byte[] p1); +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java new file mode 100644 index 0000000..0d15d10 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java @@ -0,0 +1,159 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.event; + +import java.beans.ConstructorProperties; +import java.util.Map; +import java.util.Collections; +import java.util.concurrent.ConcurrentHashMap; +import com.google.common.base.Preconditions; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicBoolean; +import net.md_5.bungee.api.plugin.Plugin; +import java.util.Set; +import net.md_5.bungee.api.Callback; +import net.md_5.bungee.api.plugin.Event; + +public class AsyncEvent extends Event { + private final Callback done; + private final Set intents; + private final AtomicBoolean fired; + private final AtomicInteger latch; + + @Override + public void postCall() { + this.fired.set(true); + if (this.latch.get() == 0) { + this.done.done((T) this, null); + } + } + + public void registerIntent(final Plugin plugin) { + Preconditions.checkState(!this.fired.get(), "Event %s has already been fired", new Object[] { this }); + Preconditions.checkState(!this.intents.contains(plugin), "Plugin %s already registered intent for event %s", new Object[] { plugin, this }); + this.intents.add(plugin); + this.latch.incrementAndGet(); + } + + public void completeIntent(final Plugin plugin) { + Preconditions.checkState(this.intents.contains(plugin), "Plugin %s has not registered intent for event %s", new Object[] { plugin, this }); + this.intents.remove(plugin); + if (this.latch.decrementAndGet() == 0 && this.fired.get()) { + this.done.done((T) this, null); + } + } + + @ConstructorProperties({ "done" }) + public AsyncEvent(final Callback done) { + this.intents = Collections.newSetFromMap(new ConcurrentHashMap()); + this.fired = new AtomicBoolean(); + this.latch = new AtomicInteger(); + this.done = done; + } + + public Callback getDone() { + return this.done; + } + + public Set getIntents() { + return this.intents; + } + + public AtomicBoolean getFired() { + return this.fired; + } + + public AtomicInteger getLatch() { + return this.latch; + } + + @Override + public String toString() { + return "AsyncEvent(super=" + super.toString() + ", done=" + this.getDone() + ", intents=" + this.getIntents() + ", fired=" + this.getFired() + ", latch=" + this.getLatch() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof AsyncEvent)) { + return false; + } + final AsyncEvent other = (AsyncEvent) o; + if (!other.canEqual(this)) { + return false; + } + if (!super.equals(o)) { + return false; + } + final Object this$done = this.getDone(); + final Object other$done = other.getDone(); + Label_0075: { + if (this$done == null) { + if (other$done == null) { + break Label_0075; + } + } else if (this$done.equals(other$done)) { + break Label_0075; + } + return false; + } + final Object this$intents = this.getIntents(); + final Object other$intents = other.getIntents(); + Label_0112: { + if (this$intents == null) { + if (other$intents == null) { + break Label_0112; + } + } else if (this$intents.equals(other$intents)) { + break Label_0112; + } + return false; + } + final Object this$fired = this.getFired(); + final Object other$fired = other.getFired(); + Label_0149: { + if (this$fired == null) { + if (other$fired == null) { + break Label_0149; + } + } else if (this$fired.equals(other$fired)) { + break Label_0149; + } + return false; + } + final Object this$latch = this.getLatch(); + final Object other$latch = other.getLatch(); + if (this$latch == null) { + if (other$latch == null) { + return true; + } + } else if (this$latch.equals(other$latch)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof AsyncEvent; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = result * 31 + super.hashCode(); + final Object $done = this.getDone(); + result = result * 31 + (($done == null) ? 0 : $done.hashCode()); + final Object $intents = this.getIntents(); + result = result * 31 + (($intents == null) ? 0 : $intents.hashCode()); + final Object $fired = this.getFired(); + result = result * 31 + (($fired == null) ? 0 : $fired.hashCode()); + final Object $latch = this.getLatch(); + result = result * 31 + (($latch == null) ? 0 : $latch.hashCode()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ChatEvent.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ChatEvent.java new file mode 100644 index 0000000..f8b2d96 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ChatEvent.java @@ -0,0 +1,91 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.event; + +import net.md_5.bungee.api.connection.Connection; +import net.md_5.bungee.api.plugin.Cancellable; + +public class ChatEvent extends TargetedEvent implements Cancellable { + private boolean cancelled; + private String message; + + public ChatEvent(final Connection sender, final Connection receiver, final String message) { + super(sender, receiver); + this.message = message; + } + + public boolean isCommand() { + return this.message.length() > 0 && this.message.charAt(0) == '/'; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + public String getMessage() { + return this.message; + } + + @Override + public void setCancelled(final boolean cancelled) { + this.cancelled = cancelled; + } + + public void setMessage(final String message) { + this.message = message; + } + + @Override + public String toString() { + return "ChatEvent(super=" + super.toString() + ", cancelled=" + this.isCancelled() + ", message=" + this.getMessage() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof ChatEvent)) { + return false; + } + final ChatEvent other = (ChatEvent) o; + if (!other.canEqual(this)) { + return false; + } + if (!super.equals(o)) { + return false; + } + if (this.isCancelled() != other.isCancelled()) { + return false; + } + final Object this$message = this.getMessage(); + final Object other$message = other.getMessage(); + if (this$message == null) { + if (other$message == null) { + return true; + } + } else if (this$message.equals(other$message)) { + return true; + } + return false; + } + + @Override + public boolean canEqual(final Object other) { + return other instanceof ChatEvent; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = result * 31 + super.hashCode(); + result = result * 31 + (this.isCancelled() ? 1231 : 1237); + final Object $message = this.getMessage(); + result = result * 31 + (($message == null) ? 0 : $message.hashCode()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/LoginEvent.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/LoginEvent.java new file mode 100644 index 0000000..7fa2aa5 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/LoginEvent.java @@ -0,0 +1,103 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.event; + +import net.md_5.bungee.api.Callback; +import net.md_5.bungee.api.connection.PendingConnection; +import net.md_5.bungee.api.plugin.Cancellable; + +public class LoginEvent extends AsyncEvent implements Cancellable { + private boolean cancelled; + private String cancelReason; + private final PendingConnection connection; + + public LoginEvent(final PendingConnection connection, final Callback done) { + super(done); + this.connection = connection; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + public String getCancelReason() { + return this.cancelReason; + } + + public PendingConnection getConnection() { + return this.connection; + } + + @Override + public void setCancelled(final boolean cancelled) { + this.cancelled = cancelled; + } + + public void setCancelReason(final String cancelReason) { + this.cancelReason = cancelReason; + } + + @Override + public String toString() { + return "LoginEvent(cancelled=" + this.isCancelled() + ", cancelReason=" + this.getCancelReason() + ", connection=" + this.getConnection() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof LoginEvent)) { + return false; + } + final LoginEvent other = (LoginEvent) o; + if (!other.canEqual(this)) { + return false; + } + if (this.isCancelled() != other.isCancelled()) { + return false; + } + final Object this$cancelReason = this.getCancelReason(); + final Object other$cancelReason = other.getCancelReason(); + Label_0078: { + if (this$cancelReason == null) { + if (other$cancelReason == null) { + break Label_0078; + } + } else if (this$cancelReason.equals(other$cancelReason)) { + break Label_0078; + } + return false; + } + final Object this$connection = this.getConnection(); + final Object other$connection = other.getConnection(); + if (this$connection == null) { + if (other$connection == null) { + return true; + } + } else if (this$connection.equals(other$connection)) { + return true; + } + return false; + } + + @Override + public boolean canEqual(final Object other) { + return other instanceof LoginEvent; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = result * 31 + (this.isCancelled() ? 1231 : 1237); + final Object $cancelReason = this.getCancelReason(); + result = result * 31 + (($cancelReason == null) ? 0 : $cancelReason.hashCode()); + final Object $connection = this.getConnection(); + result = result * 31 + (($connection == null) ? 0 : $connection.hashCode()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/PermissionCheckEvent.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/PermissionCheckEvent.java new file mode 100644 index 0000000..2fb3c95 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/PermissionCheckEvent.java @@ -0,0 +1,95 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.event; + +import java.beans.ConstructorProperties; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.plugin.Event; + +public class PermissionCheckEvent extends Event { + private final CommandSender sender; + private final String permission; + private boolean hasPermission; + + public boolean hasPermission() { + return this.hasPermission; + } + + public CommandSender getSender() { + return this.sender; + } + + public String getPermission() { + return this.permission; + } + + public void setHasPermission(final boolean hasPermission) { + this.hasPermission = hasPermission; + } + + @ConstructorProperties({ "sender", "permission", "hasPermission" }) + public PermissionCheckEvent(final CommandSender sender, final String permission, final boolean hasPermission) { + this.sender = sender; + this.permission = permission; + this.hasPermission = hasPermission; + } + + @Override + public String toString() { + return "PermissionCheckEvent(sender=" + this.getSender() + ", permission=" + this.getPermission() + ", hasPermission=" + this.hasPermission + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PermissionCheckEvent)) { + return false; + } + final PermissionCheckEvent other = (PermissionCheckEvent) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$sender = this.getSender(); + final Object other$sender = other.getSender(); + Label_0065: { + if (this$sender == null) { + if (other$sender == null) { + break Label_0065; + } + } else if (this$sender.equals(other$sender)) { + break Label_0065; + } + return false; + } + final Object this$permission = this.getPermission(); + final Object other$permission = other.getPermission(); + if (this$permission == null) { + if (other$permission == null) { + return this.hasPermission == other.hasPermission; + } + } else if (this$permission.equals(other$permission)) { + return this.hasPermission == other.hasPermission; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof PermissionCheckEvent; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $sender = this.getSender(); + result = result * 31 + (($sender == null) ? 0 : $sender.hashCode()); + final Object $permission = this.getPermission(); + result = result * 31 + (($permission == null) ? 0 : $permission.hashCode()); + result = result * 31 + (this.hasPermission ? 1231 : 1237); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/PlayerDisconnectEvent.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/PlayerDisconnectEvent.java new file mode 100644 index 0000000..e0d9e5d --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/PlayerDisconnectEvent.java @@ -0,0 +1,64 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.event; + +import java.beans.ConstructorProperties; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Event; + +public class PlayerDisconnectEvent extends Event { + private final ProxiedPlayer player; + + @ConstructorProperties({ "player" }) + public PlayerDisconnectEvent(final ProxiedPlayer player) { + this.player = player; + } + + public ProxiedPlayer getPlayer() { + return this.player; + } + + @Override + public String toString() { + return "PlayerDisconnectEvent(player=" + this.getPlayer() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PlayerDisconnectEvent)) { + return false; + } + final PlayerDisconnectEvent other = (PlayerDisconnectEvent) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$player = this.getPlayer(); + final Object other$player = other.getPlayer(); + if (this$player == null) { + if (other$player == null) { + return true; + } + } else if (this$player.equals(other$player)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof PlayerDisconnectEvent; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $player = this.getPlayer(); + result = result * 31 + (($player == null) ? 0 : $player.hashCode()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/PluginMessageEvent.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/PluginMessageEvent.java new file mode 100644 index 0000000..58f75a5 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/PluginMessageEvent.java @@ -0,0 +1,91 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.event; + +import java.util.Arrays; +import net.md_5.bungee.api.connection.Connection; +import net.md_5.bungee.api.plugin.Cancellable; + +public class PluginMessageEvent extends TargetedEvent implements Cancellable { + private boolean cancelled; + private final String tag; + private final byte[] data; + + public PluginMessageEvent(final Connection sender, final Connection receiver, final String tag, final byte[] data) { + super(sender, receiver); + this.tag = tag; + this.data = data; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + public String getTag() { + return this.tag; + } + + public byte[] getData() { + return this.data; + } + + @Override + public void setCancelled(final boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public String toString() { + return "PluginMessageEvent(super=" + super.toString() + ", cancelled=" + this.isCancelled() + ", tag=" + this.getTag() + ", data=" + Arrays.toString(this.getData()) + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PluginMessageEvent)) { + return false; + } + final PluginMessageEvent other = (PluginMessageEvent) o; + if (!other.canEqual(this)) { + return false; + } + if (!super.equals(o)) { + return false; + } + if (this.isCancelled() != other.isCancelled()) { + return false; + } + final Object this$tag = this.getTag(); + final Object other$tag = other.getTag(); + if (this$tag == null) { + if (other$tag == null) { + return Arrays.equals(this.getData(), other.getData()); + } + } else if (this$tag.equals(other$tag)) { + return Arrays.equals(this.getData(), other.getData()); + } + return false; + } + + @Override + public boolean canEqual(final Object other) { + return other instanceof PluginMessageEvent; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = result * 31 + super.hashCode(); + result = result * 31 + (this.isCancelled() ? 1231 : 1237); + final Object $tag = this.getTag(); + result = result * 31 + (($tag == null) ? 0 : $tag.hashCode()); + result = result * 31 + Arrays.hashCode(this.getData()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/PostLoginEvent.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/PostLoginEvent.java new file mode 100644 index 0000000..d5aa89a --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/PostLoginEvent.java @@ -0,0 +1,64 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.event; + +import java.beans.ConstructorProperties; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Event; + +public class PostLoginEvent extends Event { + private final ProxiedPlayer player; + + @ConstructorProperties({ "player" }) + public PostLoginEvent(final ProxiedPlayer player) { + this.player = player; + } + + public ProxiedPlayer getPlayer() { + return this.player; + } + + @Override + public String toString() { + return "PostLoginEvent(player=" + this.getPlayer() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PostLoginEvent)) { + return false; + } + final PostLoginEvent other = (PostLoginEvent) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$player = this.getPlayer(); + final Object other$player = other.getPlayer(); + if (this$player == null) { + if (other$player == null) { + return true; + } + } else if (this$player.equals(other$player)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof PostLoginEvent; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $player = this.getPlayer(); + result = result * 31 + (($player == null) ? 0 : $player.hashCode()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ProxyPingEvent.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ProxyPingEvent.java new file mode 100644 index 0000000..aaeb85a --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ProxyPingEvent.java @@ -0,0 +1,89 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.event; + +import java.beans.ConstructorProperties; +import net.md_5.bungee.api.ServerPing; +import net.md_5.bungee.api.connection.PendingConnection; +import net.md_5.bungee.api.plugin.Event; + +public class ProxyPingEvent extends Event { + private final PendingConnection connection; + private ServerPing response; + + public PendingConnection getConnection() { + return this.connection; + } + + public ServerPing getResponse() { + return this.response; + } + + public void setResponse(final ServerPing response) { + this.response = response; + } + + @ConstructorProperties({ "connection", "response" }) + public ProxyPingEvent(final PendingConnection connection, final ServerPing response) { + this.connection = connection; + this.response = response; + } + + @Override + public String toString() { + return "ProxyPingEvent(connection=" + this.getConnection() + ", response=" + this.getResponse() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof ProxyPingEvent)) { + return false; + } + final ProxyPingEvent other = (ProxyPingEvent) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$connection = this.getConnection(); + final Object other$connection = other.getConnection(); + Label_0065: { + if (this$connection == null) { + if (other$connection == null) { + break Label_0065; + } + } else if (this$connection.equals(other$connection)) { + break Label_0065; + } + return false; + } + final Object this$response = this.getResponse(); + final Object other$response = other.getResponse(); + if (this$response == null) { + if (other$response == null) { + return true; + } + } else if (this$response.equals(other$response)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof ProxyPingEvent; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $connection = this.getConnection(); + result = result * 31 + (($connection == null) ? 0 : $connection.hashCode()); + final Object $response = this.getResponse(); + result = result * 31 + (($response == null) ? 0 : $response.hashCode()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ServerConnectEvent.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ServerConnectEvent.java new file mode 100644 index 0000000..3fafc25 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ServerConnectEvent.java @@ -0,0 +1,100 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.event; + +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Cancellable; +import net.md_5.bungee.api.plugin.Event; + +public class ServerConnectEvent extends Event implements Cancellable { + private final ProxiedPlayer player; + private ServerInfo target; + private boolean cancelled; + + public ServerConnectEvent(final ProxiedPlayer player, final ServerInfo target) { + this.player = player; + this.target = target; + } + + public ProxiedPlayer getPlayer() { + return this.player; + } + + public ServerInfo getTarget() { + return this.target; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + public void setTarget(final ServerInfo target) { + this.target = target; + } + + @Override + public void setCancelled(final boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public String toString() { + return "ServerConnectEvent(player=" + this.getPlayer() + ", target=" + this.getTarget() + ", cancelled=" + this.isCancelled() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof ServerConnectEvent)) { + return false; + } + final ServerConnectEvent other = (ServerConnectEvent) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$player = this.getPlayer(); + final Object other$player = other.getPlayer(); + Label_0065: { + if (this$player == null) { + if (other$player == null) { + break Label_0065; + } + } else if (this$player.equals(other$player)) { + break Label_0065; + } + return false; + } + final Object this$target = this.getTarget(); + final Object other$target = other.getTarget(); + if (this$target == null) { + if (other$target == null) { + return this.isCancelled() == other.isCancelled(); + } + } else if (this$target.equals(other$target)) { + return this.isCancelled() == other.isCancelled(); + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof ServerConnectEvent; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $player = this.getPlayer(); + result = result * 31 + (($player == null) ? 0 : $player.hashCode()); + final Object $target = this.getTarget(); + result = result * 31 + (($target == null) ? 0 : $target.hashCode()); + result = result * 31 + (this.isCancelled() ? 1231 : 1237); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ServerConnectedEvent.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ServerConnectedEvent.java new file mode 100644 index 0000000..1a337ba --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ServerConnectedEvent.java @@ -0,0 +1,85 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.event; + +import java.beans.ConstructorProperties; +import net.md_5.bungee.api.connection.Server; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Event; + +public class ServerConnectedEvent extends Event { + private final ProxiedPlayer player; + private final Server server; + + @ConstructorProperties({ "player", "server" }) + public ServerConnectedEvent(final ProxiedPlayer player, final Server server) { + this.player = player; + this.server = server; + } + + public ProxiedPlayer getPlayer() { + return this.player; + } + + public Server getServer() { + return this.server; + } + + @Override + public String toString() { + return "ServerConnectedEvent(player=" + this.getPlayer() + ", server=" + this.getServer() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof ServerConnectedEvent)) { + return false; + } + final ServerConnectedEvent other = (ServerConnectedEvent) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$player = this.getPlayer(); + final Object other$player = other.getPlayer(); + Label_0065: { + if (this$player == null) { + if (other$player == null) { + break Label_0065; + } + } else if (this$player.equals(other$player)) { + break Label_0065; + } + return false; + } + final Object this$server = this.getServer(); + final Object other$server = other.getServer(); + if (this$server == null) { + if (other$server == null) { + return true; + } + } else if (this$server.equals(other$server)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof ServerConnectedEvent; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $player = this.getPlayer(); + result = result * 31 + (($player == null) ? 0 : $player.hashCode()); + final Object $server = this.getServer(); + result = result * 31 + (($server == null) ? 0 : $server.hashCode()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ServerKickEvent.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ServerKickEvent.java new file mode 100644 index 0000000..044f385 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ServerKickEvent.java @@ -0,0 +1,127 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.event; + +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Cancellable; +import net.md_5.bungee.api.plugin.Event; + +public class ServerKickEvent extends Event implements Cancellable { + private boolean cancelled; + private final ProxiedPlayer player; + private String kickReason; + private ServerInfo cancelServer; + + public ServerKickEvent(final ProxiedPlayer player, final String kickReason, final ServerInfo cancelServer) { + this.player = player; + this.kickReason = kickReason; + this.cancelServer = cancelServer; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + public ProxiedPlayer getPlayer() { + return this.player; + } + + public String getKickReason() { + return this.kickReason; + } + + public ServerInfo getCancelServer() { + return this.cancelServer; + } + + @Override + public void setCancelled(final boolean cancelled) { + this.cancelled = cancelled; + } + + public void setKickReason(final String kickReason) { + this.kickReason = kickReason; + } + + public void setCancelServer(final ServerInfo cancelServer) { + this.cancelServer = cancelServer; + } + + @Override + public String toString() { + return "ServerKickEvent(cancelled=" + this.isCancelled() + ", player=" + this.getPlayer() + ", kickReason=" + this.getKickReason() + ", cancelServer=" + this.getCancelServer() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof ServerKickEvent)) { + return false; + } + final ServerKickEvent other = (ServerKickEvent) o; + if (!other.canEqual(this)) { + return false; + } + if (this.isCancelled() != other.isCancelled()) { + return false; + } + final Object this$player = this.getPlayer(); + final Object other$player = other.getPlayer(); + Label_0078: { + if (this$player == null) { + if (other$player == null) { + break Label_0078; + } + } else if (this$player.equals(other$player)) { + break Label_0078; + } + return false; + } + final Object this$kickReason = this.getKickReason(); + final Object other$kickReason = other.getKickReason(); + Label_0115: { + if (this$kickReason == null) { + if (other$kickReason == null) { + break Label_0115; + } + } else if (this$kickReason.equals(other$kickReason)) { + break Label_0115; + } + return false; + } + final Object this$cancelServer = this.getCancelServer(); + final Object other$cancelServer = other.getCancelServer(); + if (this$cancelServer == null) { + if (other$cancelServer == null) { + return true; + } + } else if (this$cancelServer.equals(other$cancelServer)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof ServerKickEvent; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = result * 31 + (this.isCancelled() ? 1231 : 1237); + final Object $player = this.getPlayer(); + result = result * 31 + (($player == null) ? 0 : $player.hashCode()); + final Object $kickReason = this.getKickReason(); + result = result * 31 + (($kickReason == null) ? 0 : $kickReason.hashCode()); + final Object $cancelServer = this.getCancelServer(); + result = result * 31 + (($cancelServer == null) ? 0 : $cancelServer.hashCode()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ServerSwitchEvent.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ServerSwitchEvent.java new file mode 100644 index 0000000..943a275 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/ServerSwitchEvent.java @@ -0,0 +1,64 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.event; + +import java.beans.ConstructorProperties; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Event; + +public class ServerSwitchEvent extends Event { + private final ProxiedPlayer player; + + @ConstructorProperties({ "player" }) + public ServerSwitchEvent(final ProxiedPlayer player) { + this.player = player; + } + + public ProxiedPlayer getPlayer() { + return this.player; + } + + @Override + public String toString() { + return "ServerSwitchEvent(player=" + this.getPlayer() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof ServerSwitchEvent)) { + return false; + } + final ServerSwitchEvent other = (ServerSwitchEvent) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$player = this.getPlayer(); + final Object other$player = other.getPlayer(); + if (this$player == null) { + if (other$player == null) { + return true; + } + } else if (this$player.equals(other$player)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof ServerSwitchEvent; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $player = this.getPlayer(); + result = result * 31 + (($player == null) ? 0 : $player.hashCode()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/TargetedEvent.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/TargetedEvent.java new file mode 100644 index 0000000..deba907 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/event/TargetedEvent.java @@ -0,0 +1,84 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.event; + +import java.beans.ConstructorProperties; +import net.md_5.bungee.api.connection.Connection; +import net.md_5.bungee.api.plugin.Event; + +public abstract class TargetedEvent extends Event { + private final Connection sender; + private final Connection receiver; + + public Connection getSender() { + return this.sender; + } + + public Connection getReceiver() { + return this.receiver; + } + + @Override + public String toString() { + return "TargetedEvent(sender=" + this.getSender() + ", receiver=" + this.getReceiver() + ")"; + } + + @ConstructorProperties({ "sender", "receiver" }) + public TargetedEvent(final Connection sender, final Connection receiver) { + this.sender = sender; + this.receiver = receiver; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof TargetedEvent)) { + return false; + } + final TargetedEvent other = (TargetedEvent) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$sender = this.getSender(); + final Object other$sender = other.getSender(); + Label_0065: { + if (this$sender == null) { + if (other$sender == null) { + break Label_0065; + } + } else if (this$sender.equals(other$sender)) { + break Label_0065; + } + return false; + } + final Object this$receiver = this.getReceiver(); + final Object other$receiver = other.getReceiver(); + if (this$receiver == null) { + if (other$receiver == null) { + return true; + } + } else if (this$receiver.equals(other$receiver)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof TargetedEvent; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $sender = this.getSender(); + result = result * 31 + (($sender == null) ? 0 : $sender.hashCode()); + final Object $receiver = this.getReceiver(); + result = result * 31 + (($receiver == null) ? 0 : $receiver.hashCode()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/Cancellable.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/Cancellable.java new file mode 100644 index 0000000..7df9105 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/Cancellable.java @@ -0,0 +1,11 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.plugin; + +public interface Cancellable { + boolean isCancelled(); + + void setCancelled(final boolean p0); +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/Command.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/Command.java new file mode 100644 index 0000000..60e9314 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/Command.java @@ -0,0 +1,97 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.plugin; + +import java.util.Arrays; +import net.md_5.bungee.api.CommandSender; +import com.google.common.base.Preconditions; + +public abstract class Command { + private final String name; + private final String permission; + private final String[] aliases; + + public Command(final String name) { + this(name, null, new String[0]); + } + + public Command(final String name, final String permission, final String... aliases) { + Preconditions.checkArgument(name != null, (Object) "name"); + this.name = name; + this.permission = permission; + this.aliases = aliases; + } + + public abstract void execute(final CommandSender p0, final String[] p1); + + public String getName() { + return this.name; + } + + public String getPermission() { + return this.permission; + } + + public String[] getAliases() { + return this.aliases; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Command)) { + return false; + } + final Command other = (Command) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$name = this.getName(); + final Object other$name = other.getName(); + Label_0065: { + if (this$name == null) { + if (other$name == null) { + break Label_0065; + } + } else if (this$name.equals(other$name)) { + break Label_0065; + } + return false; + } + final Object this$permission = this.getPermission(); + final Object other$permission = other.getPermission(); + if (this$permission == null) { + if (other$permission == null) { + return Arrays.deepEquals(this.getAliases(), other.getAliases()); + } + } else if (this$permission.equals(other$permission)) { + return Arrays.deepEquals(this.getAliases(), other.getAliases()); + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof Command; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $name = this.getName(); + result = result * 31 + (($name == null) ? 0 : $name.hashCode()); + final Object $permission = this.getPermission(); + result = result * 31 + (($permission == null) ? 0 : $permission.hashCode()); + result = result * 31 + Arrays.deepHashCode(this.getAliases()); + return result; + } + + @Override + public String toString() { + return "Command(name=" + this.getName() + ", permission=" + this.getPermission() + ", aliases=" + Arrays.deepToString(this.getAliases()) + ")"; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/Event.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/Event.java new file mode 100644 index 0000000..a121fef --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/Event.java @@ -0,0 +1,10 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.plugin; + +public abstract class Event { + public void postCall() { + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/Listener.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/Listener.java new file mode 100644 index 0000000..1758449 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/Listener.java @@ -0,0 +1,8 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.plugin; + +public interface Listener { +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/Plugin.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/Plugin.java new file mode 100644 index 0000000..b39883a --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/Plugin.java @@ -0,0 +1,64 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.plugin; + +import java.io.InputStream; +import java.util.logging.Logger; +import java.io.File; +import net.md_5.bungee.api.ProxyServer; + +public class Plugin { + private PluginDescription description; + private ProxyServer proxy; + private File file; + private Logger logger; + + protected Plugin() { + } + + protected Plugin(PluginDescription forceDesc) { + this.description = forceDesc; + } + + public void onLoad() { + } + + public void onEnable() { + } + + public void onDisable() { + } + + public final File getDataFolder() { + return new File(this.getProxy().getPluginsFolder(), this.getDescription().getName()); + } + + public final InputStream getResourceAsStream(final String name) { + return this.getClass().getClassLoader().getResourceAsStream(name); + } + + final void init(final ProxyServer proxy, final PluginDescription description) { + this.proxy = proxy; + this.description = (this.description == null ? description : this.description); + this.file = description.getFile(); + this.logger = new PluginLogger(this); + } + + public PluginDescription getDescription() { + return this.description; + } + + public ProxyServer getProxy() { + return this.proxy; + } + + public File getFile() { + return this.file; + } + + public Logger getLogger() { + return this.logger; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/PluginClassloader.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/PluginClassloader.java new file mode 100644 index 0000000..09e74f3 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/PluginClassloader.java @@ -0,0 +1,47 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.plugin; + +import java.util.HashSet; +import java.util.Iterator; +import java.net.URL; +import java.util.Set; +import java.net.URLClassLoader; + +public class PluginClassloader extends URLClassLoader { + private static final Set allLoaders; + + public PluginClassloader(final URL[] urls) { + super(urls); + PluginClassloader.allLoaders.add(this); + } + + @Override + protected Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException { + return this.loadClass0(name, resolve, true); + } + + private Class loadClass0(final String name, final boolean resolve, final boolean checkOther) throws ClassNotFoundException { + try { + return super.loadClass(name, resolve); + } catch (ClassNotFoundException ex) { + if (checkOther) { + for (final PluginClassloader loader : PluginClassloader.allLoaders) { + if (loader != this) { + try { + return loader.loadClass0(name, resolve, false); + } catch (ClassNotFoundException ex2) { + } + } + } + } + throw new ClassNotFoundException(name); + } + } + + static { + allLoaders = new HashSet(); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/PluginDescription.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/PluginDescription.java new file mode 100644 index 0000000..e20949d --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/PluginDescription.java @@ -0,0 +1,196 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.plugin; + +import java.beans.ConstructorProperties; +import java.util.HashSet; +import java.io.File; +import java.util.Set; + +public class PluginDescription { + private String name; + private String main; + private String version; + private String author; + private Set depends; + private File file; + + public String getName() { + return this.name; + } + + public String getMain() { + return this.main; + } + + public String getVersion() { + return this.version; + } + + public String getAuthor() { + return this.author; + } + + public Set getDepends() { + return this.depends; + } + + public File getFile() { + return this.file; + } + + public void setName(final String name) { + this.name = name; + } + + public void setMain(final String main) { + this.main = main; + } + + public void setVersion(final String version) { + this.version = version; + } + + public void setAuthor(final String author) { + this.author = author; + } + + public void setDepends(final Set depends) { + this.depends = depends; + } + + public void setFile(final File file) { + this.file = file; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PluginDescription)) { + return false; + } + final PluginDescription other = (PluginDescription) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$name = this.getName(); + final Object other$name = other.getName(); + Label_0065: { + if (this$name == null) { + if (other$name == null) { + break Label_0065; + } + } else if (this$name.equals(other$name)) { + break Label_0065; + } + return false; + } + final Object this$main = this.getMain(); + final Object other$main = other.getMain(); + Label_0102: { + if (this$main == null) { + if (other$main == null) { + break Label_0102; + } + } else if (this$main.equals(other$main)) { + break Label_0102; + } + return false; + } + final Object this$version = this.getVersion(); + final Object other$version = other.getVersion(); + Label_0139: { + if (this$version == null) { + if (other$version == null) { + break Label_0139; + } + } else if (this$version.equals(other$version)) { + break Label_0139; + } + return false; + } + final Object this$author = this.getAuthor(); + final Object other$author = other.getAuthor(); + Label_0176: { + if (this$author == null) { + if (other$author == null) { + break Label_0176; + } + } else if (this$author.equals(other$author)) { + break Label_0176; + } + return false; + } + final Object this$depends = this.getDepends(); + final Object other$depends = other.getDepends(); + Label_0213: { + if (this$depends == null) { + if (other$depends == null) { + break Label_0213; + } + } else if (this$depends.equals(other$depends)) { + break Label_0213; + } + return false; + } + final Object this$file = this.getFile(); + final Object other$file = other.getFile(); + if (this$file == null) { + if (other$file == null) { + return true; + } + } else if (this$file.equals(other$file)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof PluginDescription; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $name = this.getName(); + result = result * 31 + (($name == null) ? 0 : $name.hashCode()); + final Object $main = this.getMain(); + result = result * 31 + (($main == null) ? 0 : $main.hashCode()); + final Object $version = this.getVersion(); + result = result * 31 + (($version == null) ? 0 : $version.hashCode()); + final Object $author = this.getAuthor(); + result = result * 31 + (($author == null) ? 0 : $author.hashCode()); + final Object $depends = this.getDepends(); + result = result * 31 + (($depends == null) ? 0 : $depends.hashCode()); + final Object $file = this.getFile(); + result = result * 31 + (($file == null) ? 0 : $file.hashCode()); + return result; + } + + @Override + public String toString() { + return "PluginDescription(name=" + this.getName() + ", main=" + this.getMain() + ", version=" + this.getVersion() + ", author=" + this.getAuthor() + ", depends=" + this.getDepends() + ", file=" + this.getFile() + ")"; + } + + public PluginDescription() { + this.depends = new HashSet(); + this.file = null; + } + + @ConstructorProperties({ "name", "main", "version", "author", "depends", "file" }) + public PluginDescription(final String name, final String main, final String version, final String author, final Set depends, final File file) { + this.depends = new HashSet(); + this.file = null; + this.name = name; + this.main = main; + this.version = version; + this.author = author; + this.depends = depends; + this.file = file; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/PluginLogger.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/PluginLogger.java new file mode 100644 index 0000000..559e046 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/PluginLogger.java @@ -0,0 +1,25 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.plugin; + +import java.util.logging.LogRecord; +import net.md_5.bungee.api.ProxyServer; +import java.util.logging.Logger; + +public class PluginLogger extends Logger { + private String pluginName; + + protected PluginLogger(final Plugin plugin) { + super(plugin.getClass().getCanonicalName(), null); + this.pluginName = "[" + plugin.getDescription().getName() + "] "; + this.setParent(ProxyServer.getInstance().getLogger()); + } + + @Override + public void log(final LogRecord logRecord) { + logRecord.setMessage(this.pluginName + logRecord.getMessage()); + super.log(logRecord); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java new file mode 100644 index 0000000..b885e17 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java @@ -0,0 +1,222 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.plugin; + +import java.beans.ConstructorProperties; +import java.lang.reflect.Method; +import java.io.InputStream; +import java.util.jar.JarEntry; +import java.util.zip.ZipEntry; +import java.util.jar.JarFile; +import com.google.common.base.Preconditions; +import java.io.File; +import java.net.URLClassLoader; +import java.net.URL; +import java.util.Iterator; +import java.util.Stack; +import java.util.Collection; +import java.util.logging.Level; +import net.md_5.bungee.api.ChatColor; +import java.util.Arrays; +import net.md_5.bungee.api.CommandSender; +import java.lang.annotation.Annotation; +import net.md_5.bungee.event.EventHandler; +import com.google.common.eventbus.Subscribe; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import net.md_5.bungee.event.EventBus; +import org.yaml.snakeyaml.Yaml; +import net.md_5.bungee.api.ProxyServer; +import java.util.regex.Pattern; + +public class PluginManager { + private static final Pattern argsSplit; + private final ProxyServer proxy; + private final Yaml yaml; + private final EventBus eventBus; + private final Map plugins; + private final Map commandMap; + private Map toLoad; + + public PluginManager(final ProxyServer proxy) { + this.yaml = new Yaml(); + this.plugins = new LinkedHashMap(); + this.commandMap = new HashMap(); + this.toLoad = new HashMap(); + this.proxy = proxy; + this.eventBus = new EventBus(proxy.getLogger(), (Class[]) new Class[] { Subscribe.class, EventHandler.class }); + } + + public void registerCommand(final Plugin plugin, final Command command) { + this.commandMap.put(command.getName().toLowerCase(), command); + for (final String alias : command.getAliases()) { + this.commandMap.put(alias.toLowerCase(), command); + } + } + + public void unregisterCommand(final Command command) { + this.commandMap.values().remove(command); + } + + public boolean dispatchCommand(final CommandSender sender, final String commandLine) { + final String[] split = PluginManager.argsSplit.split(commandLine); + final Command command = this.commandMap.get(split[0].toLowerCase()); + if (command == null) { + return false; + } + final String permission = command.getPermission(); + if (permission != null && !permission.isEmpty() && !sender.hasPermission(permission)) { + sender.sendMessage(this.proxy.getTranslation("no_permission")); + return true; + } + final String[] args = Arrays.copyOfRange(split, 1, split.length); + try { + command.execute(sender, args); + } catch (Exception ex) { + sender.sendMessage(ChatColor.RED + "An internal error occurred whilst executing this command, please check the console log for details."); + ProxyServer.getInstance().getLogger().log(Level.WARNING, "Error in dispatching command", ex); + } + return true; + } + + public Collection getPlugins() { + return this.plugins.values(); + } + + public Plugin getPlugin(final String name) { + return this.plugins.get(name); + } + + public void loadAndEnablePlugins() { + final Map pluginStatuses = new HashMap(); + for (final Map.Entry entry : this.toLoad.entrySet()) { + final PluginDescription plugin = entry.getValue(); + if (!this.enablePlugin(pluginStatuses, new Stack(), plugin)) { + ProxyServer.getInstance().getLogger().warning("Failed to enable " + entry.getKey()); + } + } + this.toLoad.clear(); + this.toLoad = null; + for (final Plugin plugin2 : this.plugins.values()) { + try { + plugin2.onEnable(); + ProxyServer.getInstance().getLogger().log(Level.INFO, "Enabled plugin {0} version {1} by {2}", + new Object[] { plugin2.getDescription().getName(), plugin2.getDescription().getVersion(), plugin2.getDescription().getAuthor() }); + } catch (Throwable t) { + ProxyServer.getInstance().getLogger().log(Level.WARNING, "Exception encountered when loading plugin: " + plugin2.getDescription().getName(), t); + } + } + } + + private boolean enablePlugin(final Map pluginStatuses, final Stack dependStack, final PluginDescription plugin) { + if (pluginStatuses.containsKey(plugin)) { + return pluginStatuses.get(plugin); + } + boolean status = true; + for (final String dependName : plugin.getDepends()) { + final PluginDescription depend = this.toLoad.get(dependName); + Boolean dependStatus = (depend != null) ? pluginStatuses.get(depend) : Boolean.FALSE; + if (dependStatus == null) { + if (dependStack.contains(depend)) { + final StringBuilder dependencyGraph = new StringBuilder(); + for (final PluginDescription element : dependStack) { + dependencyGraph.append(element.getName()).append(" -> "); + } + dependencyGraph.append(plugin.getName()).append(" -> ").append(dependName); + ProxyServer.getInstance().getLogger().log(Level.WARNING, "Circular dependency detected: " + (Object) dependencyGraph); + status = false; + } else { + dependStack.push(plugin); + dependStatus = this.enablePlugin(pluginStatuses, dependStack, depend); + dependStack.pop(); + } + } + if (dependStatus == Boolean.FALSE) { + ProxyServer.getInstance().getLogger().log(Level.WARNING, "{0} (required by {1}) is unavailable", new Object[] { depend.getName(), plugin.getName() }); + status = false; + } + if (!status) { + break; + } + } + if (status) { + try { + final URLClassLoader loader = new PluginClassloader(new URL[] { plugin.getFile().toURI().toURL() }); + final Class main = loader.loadClass(plugin.getMain()); + final Plugin clazz = (Plugin) main.getDeclaredConstructor((Class[]) new Class[0]).newInstance(new Object[0]); + clazz.init(this.proxy, plugin); + this.plugins.put(plugin.getName(), clazz); + clazz.onLoad(); + ProxyServer.getInstance().getLogger().log(Level.INFO, "Loaded plugin {0} version {1} by {2}", new Object[] { plugin.getName(), plugin.getVersion(), plugin.getAuthor() }); + } catch (Throwable t) { + this.proxy.getLogger().log(Level.WARNING, "Error enabling plugin " + plugin.getName(), t); + } + } + pluginStatuses.put(plugin, status); + return status; + } + + public void addInternalPlugin(Plugin plug) { + this.plugins.put(plug.getDescription().getName(), plug); + plug.init(proxy, plug.getDescription()); + } + + public void detectPlugins(final File folder) { + Preconditions.checkNotNull((Object) folder, (Object) "folder"); + Preconditions.checkArgument(folder.isDirectory(), (Object) "Must load from a directory"); + for (final File file : folder.listFiles()) { + if (file.isFile() && file.getName().endsWith(".jar")) { + try (final JarFile jar = new JarFile(file)) { + final JarEntry pdf = jar.getJarEntry("plugin.yml"); + Preconditions.checkNotNull((Object) pdf, (Object) "Plugin must have a plugin.yml"); + try (final InputStream in = jar.getInputStream(pdf)) { + final PluginDescription desc = (PluginDescription) this.yaml.loadAs(in, (Class) PluginDescription.class); + desc.setFile(file); + this.toLoad.put(desc.getName(), desc); + } + } catch (Exception ex) { + ProxyServer.getInstance().getLogger().log(Level.WARNING, "Could not load plugin from file " + file, ex); + } + } + } + } + + public T callEvent(final T event) { + Preconditions.checkNotNull((Object) event, (Object) "event"); + final long start = System.nanoTime(); + this.eventBus.post(event); + event.postCall(); + final long elapsed = start - System.nanoTime(); + if (elapsed > 250000L) { + ProxyServer.getInstance().getLogger().log(Level.WARNING, "Event {0} took more {1}ns to process!", new Object[] { event, elapsed }); + } + return event; + } + + public void registerListener(final Plugin plugin, final Listener listener) { + for (final Method method : listener.getClass().getDeclaredMethods()) { + if (method.isAnnotationPresent((Class) Subscribe.class)) { + this.proxy.getLogger().log(Level.WARNING, + "Listener " + listener + " has registered using depreceated subscribe annotation!" + " Please advice author to update to @EventHandler." + " As a server owner you may safely ignore this.", new Exception()); + } + } + this.eventBus.register(listener); + } + + @ConstructorProperties({ "proxy", "eventBus" }) + public PluginManager(final ProxyServer proxy, final EventBus eventBus) { + this.yaml = new Yaml(); + this.plugins = new LinkedHashMap(); + this.commandMap = new HashMap(); + this.toLoad = new HashMap(); + this.proxy = proxy; + this.eventBus = eventBus; + } + + static { + argsSplit = Pattern.compile(" "); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/scheduler/ScheduledTask.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/scheduler/ScheduledTask.java new file mode 100644 index 0000000..c33f6dd --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/scheduler/ScheduledTask.java @@ -0,0 +1,18 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.scheduler; + +import java.util.concurrent.TimeUnit; +import net.md_5.bungee.api.plugin.Plugin; + +public interface ScheduledTask { + int getId(); + + Plugin getOwner(); + + Runnable getTask(); + + long getDelay(final TimeUnit p0); +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/scheduler/TaskScheduler.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/scheduler/TaskScheduler.java new file mode 100644 index 0000000..1cd4fe7 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/scheduler/TaskScheduler.java @@ -0,0 +1,22 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.scheduler; + +import java.util.concurrent.TimeUnit; +import net.md_5.bungee.api.plugin.Plugin; + +public interface TaskScheduler { + void cancel(final int p0); + + void cancel(final ScheduledTask p0); + + int cancel(final Plugin p0); + + ScheduledTask runAsync(final Plugin p0, final Runnable p1); + + ScheduledTask schedule(final Plugin p0, final Runnable p1, final long p2, final TimeUnit p3); + + ScheduledTask schedule(final Plugin p0, final Runnable p1, final long p2, final long p3, final TimeUnit p4); +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/score/Objective.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/score/Objective.java new file mode 100644 index 0000000..60a2724 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/score/Objective.java @@ -0,0 +1,82 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.score; + +import java.beans.ConstructorProperties; + +public class Objective { + private final String name; + private final String value; + + @ConstructorProperties({ "name", "value" }) + public Objective(final String name, final String value) { + this.name = name; + this.value = value; + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Objective)) { + return false; + } + final Objective other = (Objective) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$name = this.getName(); + final Object other$name = other.getName(); + Label_0065: { + if (this$name == null) { + if (other$name == null) { + break Label_0065; + } + } else if (this$name.equals(other$name)) { + break Label_0065; + } + return false; + } + final Object this$value = this.getValue(); + final Object other$value = other.getValue(); + if (this$value == null) { + if (other$value == null) { + return true; + } + } else if (this$value.equals(other$value)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof Objective; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $name = this.getName(); + result = result * 31 + (($name == null) ? 0 : $name.hashCode()); + final Object $value = this.getValue(); + result = result * 31 + (($value == null) ? 0 : $value.hashCode()); + return result; + } + + @Override + public String toString() { + return "Objective(name=" + this.getName() + ", value=" + this.getValue() + ")"; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/score/Position.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/score/Position.java new file mode 100644 index 0000000..8cc5d54 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/score/Position.java @@ -0,0 +1,9 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.score; + +public enum Position { + LIST, SIDEBAR, BELOW; +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/score/Score.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/score/Score.java new file mode 100644 index 0000000..360626c --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/score/Score.java @@ -0,0 +1,89 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.score; + +import java.beans.ConstructorProperties; + +public class Score { + private final String itemName; + private final String scoreName; + private final int value; + + @ConstructorProperties({ "itemName", "scoreName", "value" }) + public Score(final String itemName, final String scoreName, final int value) { + this.itemName = itemName; + this.scoreName = scoreName; + this.value = value; + } + + public String getItemName() { + return this.itemName; + } + + public String getScoreName() { + return this.scoreName; + } + + public int getValue() { + return this.value; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Score)) { + return false; + } + final Score other = (Score) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$itemName = this.getItemName(); + final Object other$itemName = other.getItemName(); + Label_0065: { + if (this$itemName == null) { + if (other$itemName == null) { + break Label_0065; + } + } else if (this$itemName.equals(other$itemName)) { + break Label_0065; + } + return false; + } + final Object this$scoreName = this.getScoreName(); + final Object other$scoreName = other.getScoreName(); + if (this$scoreName == null) { + if (other$scoreName == null) { + return this.getValue() == other.getValue(); + } + } else if (this$scoreName.equals(other$scoreName)) { + return this.getValue() == other.getValue(); + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof Score; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $itemName = this.getItemName(); + result = result * 31 + (($itemName == null) ? 0 : $itemName.hashCode()); + final Object $scoreName = this.getScoreName(); + result = result * 31 + (($scoreName == null) ? 0 : $scoreName.hashCode()); + result = result * 31 + this.getValue(); + return result; + } + + @Override + public String toString() { + return "Score(itemName=" + this.getItemName() + ", scoreName=" + this.getScoreName() + ", value=" + this.getValue() + ")"; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/score/Scoreboard.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/score/Scoreboard.java new file mode 100644 index 0000000..ff076d8 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/score/Scoreboard.java @@ -0,0 +1,192 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.score; + +import java.util.HashMap; +import com.google.common.base.Preconditions; +import java.util.Collections; +import java.util.Collection; +import java.util.Map; + +public class Scoreboard { + private String name; + private Position position; + private final Map objectives; + private final Map scores; + private final Map teams; + + public Collection getObjectives() { + return Collections.unmodifiableCollection((Collection) this.objectives.values()); + } + + public Collection getScores() { + return Collections.unmodifiableCollection((Collection) this.scores.values()); + } + + public Collection getTeams() { + return Collections.unmodifiableCollection((Collection) this.teams.values()); + } + + public void addObjective(final Objective objective) { + Preconditions.checkNotNull((Object) objective, (Object) "objective"); + Preconditions.checkArgument(!this.objectives.containsKey(objective.getName()), "Objective %s already exists in this scoreboard", new Object[] { objective.getName() }); + this.objectives.put(objective.getName(), objective); + } + + public void addScore(final Score score) { + Preconditions.checkNotNull((Object) score, (Object) "score"); + this.scores.put(score.getItemName(), score); + } + + public void addTeam(final Team team) { + Preconditions.checkNotNull((Object) team, (Object) "team"); + Preconditions.checkArgument(!this.teams.containsKey(team.getName()), "Team %s already exists in this scoreboard", new Object[] { team.getName() }); + this.teams.put(team.getName(), team); + } + + public Team getTeam(final String name) { + return this.teams.get(name); + } + + public void removeObjective(final String objectiveName) { + this.objectives.remove(objectiveName); + } + + public void removeScore(final String scoreName) { + this.scores.remove(scoreName); + } + + public void removeTeam(final String teamName) { + this.teams.remove(teamName); + } + + public void clear() { + this.name = null; + this.position = null; + this.objectives.clear(); + this.scores.clear(); + this.teams.clear(); + } + + public String getName() { + return this.name; + } + + public Position getPosition() { + return this.position; + } + + public void setName(final String name) { + this.name = name; + } + + public void setPosition(final Position position) { + this.position = position; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Scoreboard)) { + return false; + } + final Scoreboard other = (Scoreboard) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$name = this.getName(); + final Object other$name = other.getName(); + Label_0065: { + if (this$name == null) { + if (other$name == null) { + break Label_0065; + } + } else if (this$name.equals(other$name)) { + break Label_0065; + } + return false; + } + final Object this$position = this.getPosition(); + final Object other$position = other.getPosition(); + Label_0102: { + if (this$position == null) { + if (other$position == null) { + break Label_0102; + } + } else if (this$position.equals(other$position)) { + break Label_0102; + } + return false; + } + final Object this$objectives = this.getObjectives(); + final Object other$objectives = other.getObjectives(); + Label_0139: { + if (this$objectives == null) { + if (other$objectives == null) { + break Label_0139; + } + } else if (this$objectives.equals(other$objectives)) { + break Label_0139; + } + return false; + } + final Object this$scores = this.getScores(); + final Object other$scores = other.getScores(); + Label_0176: { + if (this$scores == null) { + if (other$scores == null) { + break Label_0176; + } + } else if (this$scores.equals(other$scores)) { + break Label_0176; + } + return false; + } + final Object this$teams = this.getTeams(); + final Object other$teams = other.getTeams(); + if (this$teams == null) { + if (other$teams == null) { + return true; + } + } else if (this$teams.equals(other$teams)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof Scoreboard; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $name = this.getName(); + result = result * 31 + (($name == null) ? 0 : $name.hashCode()); + final Object $position = this.getPosition(); + result = result * 31 + (($position == null) ? 0 : $position.hashCode()); + final Object $objectives = this.getObjectives(); + result = result * 31 + (($objectives == null) ? 0 : $objectives.hashCode()); + final Object $scores = this.getScores(); + result = result * 31 + (($scores == null) ? 0 : $scores.hashCode()); + final Object $teams = this.getTeams(); + result = result * 31 + (($teams == null) ? 0 : $teams.hashCode()); + return result; + } + + @Override + public String toString() { + return "Scoreboard(name=" + this.getName() + ", position=" + this.getPosition() + ", objectives=" + this.getObjectives() + ", scores=" + this.getScores() + ", teams=" + this.getTeams() + ")"; + } + + public Scoreboard() { + this.objectives = new HashMap(); + this.scores = new HashMap(); + this.teams = new HashMap(); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/score/Team.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/score/Team.java new file mode 100644 index 0000000..091469b --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/score/Team.java @@ -0,0 +1,183 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.score; + +import java.beans.ConstructorProperties; +import java.util.HashSet; +import java.util.Collections; +import java.util.Collection; +import java.util.Set; + +public class Team { + private final String name; + private String displayName; + private String prefix; + private String suffix; + private boolean friendlyFire; + private Set players; + + public Collection getPlayers() { + return (Collection) Collections.unmodifiableSet((Set) this.players); + } + + public void addPlayer(final String name) { + this.players.add(name); + } + + public void removePlayer(final String name) { + this.players.remove(name); + } + + @ConstructorProperties({ "name" }) + public Team(final String name) { + this.players = new HashSet(); + if (name == null) { + throw new NullPointerException("name"); + } + this.name = name; + } + + public String getName() { + return this.name; + } + + public String getDisplayName() { + return this.displayName; + } + + public String getPrefix() { + return this.prefix; + } + + public String getSuffix() { + return this.suffix; + } + + public boolean isFriendlyFire() { + return this.friendlyFire; + } + + public void setDisplayName(final String displayName) { + this.displayName = displayName; + } + + public void setPrefix(final String prefix) { + this.prefix = prefix; + } + + public void setSuffix(final String suffix) { + this.suffix = suffix; + } + + public void setFriendlyFire(final boolean friendlyFire) { + this.friendlyFire = friendlyFire; + } + + public void setPlayers(final Set players) { + this.players = players; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Team)) { + return false; + } + final Team other = (Team) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$name = this.getName(); + final Object other$name = other.getName(); + Label_0065: { + if (this$name == null) { + if (other$name == null) { + break Label_0065; + } + } else if (this$name.equals(other$name)) { + break Label_0065; + } + return false; + } + final Object this$displayName = this.getDisplayName(); + final Object other$displayName = other.getDisplayName(); + Label_0102: { + if (this$displayName == null) { + if (other$displayName == null) { + break Label_0102; + } + } else if (this$displayName.equals(other$displayName)) { + break Label_0102; + } + return false; + } + final Object this$prefix = this.getPrefix(); + final Object other$prefix = other.getPrefix(); + Label_0139: { + if (this$prefix == null) { + if (other$prefix == null) { + break Label_0139; + } + } else if (this$prefix.equals(other$prefix)) { + break Label_0139; + } + return false; + } + final Object this$suffix = this.getSuffix(); + final Object other$suffix = other.getSuffix(); + Label_0176: { + if (this$suffix == null) { + if (other$suffix == null) { + break Label_0176; + } + } else if (this$suffix.equals(other$suffix)) { + break Label_0176; + } + return false; + } + if (this.isFriendlyFire() != other.isFriendlyFire()) { + return false; + } + final Object this$players = this.getPlayers(); + final Object other$players = other.getPlayers(); + if (this$players == null) { + if (other$players == null) { + return true; + } + } else if (this$players.equals(other$players)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof Team; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $name = this.getName(); + result = result * 31 + (($name == null) ? 0 : $name.hashCode()); + final Object $displayName = this.getDisplayName(); + result = result * 31 + (($displayName == null) ? 0 : $displayName.hashCode()); + final Object $prefix = this.getPrefix(); + result = result * 31 + (($prefix == null) ? 0 : $prefix.hashCode()); + final Object $suffix = this.getSuffix(); + result = result * 31 + (($suffix == null) ? 0 : $suffix.hashCode()); + result = result * 31 + (this.isFriendlyFire() ? 1231 : 1237); + final Object $players = this.getPlayers(); + result = result * 31 + (($players == null) ? 0 : $players.hashCode()); + return result; + } + + @Override + public String toString() { + return "Team(name=" + this.getName() + ", displayName=" + this.getDisplayName() + ", prefix=" + this.getPrefix() + ", suffix=" + this.getSuffix() + ", friendlyFire=" + this.isFriendlyFire() + ", players=" + this.getPlayers() + ")"; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/tab/CustomTabList.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/tab/CustomTabList.java new file mode 100644 index 0000000..b0e0006 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/tab/CustomTabList.java @@ -0,0 +1,21 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.tab; + +public interface CustomTabList extends TabListHandler { + void clear(); + + int getColumns(); + + int getRows(); + + int getSize(); + + String setSlot(final int p0, final int p1, final String p2); + + String setSlot(final int p0, final int p1, final String p2, final boolean p3); + + void update(); +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/tab/TabListAdapter.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/tab/TabListAdapter.java new file mode 100644 index 0000000..3f8661b --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/tab/TabListAdapter.java @@ -0,0 +1,36 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.tab; + +import net.md_5.bungee.api.connection.ProxiedPlayer; + +public abstract class TabListAdapter implements TabListHandler { + private ProxiedPlayer player; + + @Override + public void init(final ProxiedPlayer player) { + this.player = player; + } + + @Override + public void onConnect() { + } + + @Override + public void onDisconnect() { + } + + @Override + public void onServerChange() { + } + + @Override + public void onPingChange(final int ping) { + } + + public ProxiedPlayer getPlayer() { + return this.player; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/api/tab/TabListHandler.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/tab/TabListHandler.java new file mode 100644 index 0000000..2e7ca50 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/api/tab/TabListHandler.java @@ -0,0 +1,21 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.api.tab; + +import net.md_5.bungee.api.connection.ProxiedPlayer; + +public interface TabListHandler { + void init(final ProxiedPlayer p0); + + void onConnect(); + + void onServerChange(); + + void onPingChange(final int p0); + + void onDisconnect(); + + boolean onListUpdate(final String p0, final boolean p1, final int p2); +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandAlert.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandAlert.java new file mode 100644 index 0000000..d77d5ab --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandAlert.java @@ -0,0 +1,37 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.command; + +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.plugin.Command; + +public class CommandAlert extends Command { + public CommandAlert() { + super("alert", "bungeecord.command.alert", new String[0]); + } + + @Override + public void execute(final CommandSender sender, final String[] args) { + if (args.length == 0) { + sender.sendMessage(ChatColor.RED + "You must supply a message."); + } else { + final StringBuilder builder = new StringBuilder(); + if (args[0].startsWith("&h")) { + args[0] = args[0].substring(2, args[0].length()); + } else { + builder.append(ProxyServer.getInstance().getTranslation("alert")); + } + for (final String s : args) { + builder.append(ChatColor.translateAlternateColorCodes('&', s)); + builder.append(" "); + } + final String message = builder.substring(0, builder.length() - 1); + ProxyServer.getInstance().broadcast(message); + ProxyServer.getInstance().getConsole().sendMessage(message); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandBungee.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandBungee.java new file mode 100644 index 0000000..5cc0e2b --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandBungee.java @@ -0,0 +1,21 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.command; + +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.plugin.Command; + +public class CommandBungee extends Command { + public CommandBungee() { + super("bungee"); + } + + @Override + public void execute(final CommandSender sender, final String[] args) { + sender.sendMessage(ChatColor.BLUE + "This server is running BungeeCord version " + ProxyServer.getInstance().getVersion() + " by md_5"); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandEnd.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandEnd.java new file mode 100644 index 0000000..2e52624 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandEnd.java @@ -0,0 +1,20 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.command; + +import net.md_5.bungee.BungeeCord; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.plugin.Command; + +public class CommandEnd extends Command { + public CommandEnd() { + super("end", "bungeecord.command.end", new String[0]); + } + + @Override + public void execute(final CommandSender sender, final String[] args) { + BungeeCord.getInstance().stop(); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandFind.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandFind.java new file mode 100644 index 0000000..d146f5e --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandFind.java @@ -0,0 +1,31 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.command; + +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.plugin.Command; + +public class CommandFind extends Command { + public CommandFind() { + super("find", "bungeecord.command.find", new String[0]); + } + + @Override + public void execute(final CommandSender sender, final String[] args) { + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "Please follow this command by a user name"); + } else { + final ProxiedPlayer player = ProxyServer.getInstance().getPlayer(args[0]); + if (player == null || player.getServer() == null) { + sender.sendMessage(ChatColor.RED + "That user is not online"); + } else { + sender.sendMessage(ChatColor.BLUE + args[0] + " is online at " + player.getServer().getInfo().getName()); + } + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandIP.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandIP.java new file mode 100644 index 0000000..376fbfb --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandIP.java @@ -0,0 +1,31 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.command; + +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.plugin.Command; + +public class CommandIP extends Command { + public CommandIP() { + super("ip", "bungeecord.command.ip", new String[0]); + } + + @Override + public void execute(final CommandSender sender, final String[] args) { + if (args.length < 1) { + sender.sendMessage(ChatColor.RED + "Please follow this command by a user name"); + return; + } + final ProxiedPlayer user = ProxyServer.getInstance().getPlayer(args[0]); + if (user == null) { + sender.sendMessage(ChatColor.RED + "That user is not online"); + } else { + sender.sendMessage(ChatColor.BLUE + "IP of " + args[0] + " is " + user.getAddress()); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandList.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandList.java new file mode 100644 index 0000000..10d50e8 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandList.java @@ -0,0 +1,53 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.command; + +import java.util.List; +import java.util.Iterator; +import java.util.Collection; +import net.md_5.bungee.Util; +import java.util.Comparator; +import java.util.Collections; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import java.util.ArrayList; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.plugin.Command; + +public class CommandList extends Command { + public CommandList() { + super("glist", "bungeecord.command.list", new String[0]); + } + + @Override + public void execute(final CommandSender sender, final String[] args) { + for (final ServerInfo server : ProxyServer.getInstance().getServers().values()) { + if (!server.canAccess(sender)) { + continue; + } + final Collection serverPlayers = server.getPlayers(); + final StringBuilder message = new StringBuilder(); + message.append(ChatColor.GREEN); + message.append("["); + message.append(server.getName()); + message.append("] "); + message.append(ChatColor.YELLOW); + message.append("("); + message.append(serverPlayers.size()); + message.append("): "); + message.append(ChatColor.RESET); + final List players = new ArrayList(); + for (final ProxiedPlayer player : serverPlayers) { + players.add(player.getDisplayName()); + } + Collections.sort(players, String.CASE_INSENSITIVE_ORDER); + message.append(Util.format(players, ChatColor.RESET + ", ")); + sender.sendMessage(message.toString()); + } + sender.sendMessage(ProxyServer.getInstance().getTranslation("total_players") + ProxyServer.getInstance().getOnlineCount()); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandPerms.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandPerms.java new file mode 100644 index 0000000..1db3eea --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandPerms.java @@ -0,0 +1,35 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.command; + +import java.util.Iterator; +import java.util.Set; +import net.md_5.bungee.api.ChatColor; +import java.util.Collection; +import net.md_5.bungee.api.ProxyServer; +import java.util.HashSet; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.plugin.Command; + +public class CommandPerms extends Command { + public CommandPerms() { + super("perms"); + } + + @Override + public void execute(final CommandSender sender, final String[] args) { + final StringBuilder groups = new StringBuilder(); + final Set permissions = new HashSet(); + for (final String group : sender.getGroups()) { + groups.append(group); + groups.append(", "); + permissions.addAll(ProxyServer.getInstance().getConfigurationAdapter().getPermissions(group)); + } + sender.sendMessage(ChatColor.GOLD + "You have the following groups: " + groups.substring(0, groups.length() - 2)); + for (final String permission : permissions) { + sender.sendMessage(ChatColor.BLUE + "- " + permission); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandReload.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandReload.java new file mode 100644 index 0000000..d5d2b37 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandReload.java @@ -0,0 +1,24 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.command; + +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.BungeeCord; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.plugin.Command; + +public class CommandReload extends Command { + public CommandReload() { + super("greload", "bungeecord.command.reload", new String[0]); + } + + @Override + public void execute(final CommandSender sender, final String[] args) { + BungeeCord.getInstance().config.load(); + BungeeCord.getInstance().stopListeners(); + BungeeCord.getInstance().startListeners(); + sender.sendMessage(ChatColor.BOLD.toString() + ChatColor.RED.toString() + "BungeeCord has been reloaded." + " This is NOT advisable and you will not be supported with any issues that arise! Please restart BungeeCord ASAP."); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandSend.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandSend.java new file mode 100644 index 0000000..21ee18b --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandSend.java @@ -0,0 +1,61 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.command; + +import java.util.Iterator; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.plugin.Command; + +public class CommandSend extends Command { + public CommandSend() { + super("send", "bungeecord.command.send", new String[0]); + } + + @Override + public void execute(final CommandSender sender, final String[] args) { + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Not enough arguments, usage: /send "); + return; + } + final ServerInfo target = ProxyServer.getInstance().getServerInfo(args[1]); + if (target == null) { + sender.sendMessage(ProxyServer.getInstance().getTranslation("no_server")); + return; + } + if (args[0].equalsIgnoreCase("all")) { + for (final ProxiedPlayer p : ProxyServer.getInstance().getPlayers()) { + this.summon(p, target, sender); + } + } else if (args[0].equalsIgnoreCase("current")) { + if (!(sender instanceof ProxiedPlayer)) { + sender.sendMessage(ChatColor.RED + "Only in game players can use this command"); + return; + } + final ProxiedPlayer player = (ProxiedPlayer) sender; + for (final ProxiedPlayer p2 : player.getServer().getInfo().getPlayers()) { + this.summon(p2, target, sender); + } + } else { + final ProxiedPlayer player = ProxyServer.getInstance().getPlayer(args[0]); + if (player == null) { + sender.sendMessage(ChatColor.RED + "That player is not online"); + return; + } + this.summon(player, target, sender); + } + sender.sendMessage(ChatColor.GREEN + "Successfully summoned player(s)"); + } + + private void summon(final ProxiedPlayer player, final ServerInfo target, final CommandSender sender) { + if (player.getServer() != null && !player.getServer().getInfo().equals(target)) { + player.connect(target); + player.sendMessage(ChatColor.GOLD + "Summoned to " + target.getName() + " by " + sender.getName()); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandServer.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandServer.java new file mode 100644 index 0000000..85f69fe --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/CommandServer.java @@ -0,0 +1,51 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.command; + +import java.util.Iterator; +import java.util.Map; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.plugin.Command; + +public class CommandServer extends Command { + public CommandServer() { + super("server", "bungeecord.command.server", new String[0]); + } + + @Override + public void execute(final CommandSender sender, final String[] args) { + if (!(sender instanceof ProxiedPlayer)) { + return; + } + final ProxiedPlayer player = (ProxiedPlayer) sender; + final Map servers = ProxyServer.getInstance().getServers(); + if (args.length == 0) { + player.sendMessage(ProxyServer.getInstance().getTranslation("current_server") + player.getServer().getInfo().getName()); + final StringBuilder serverList = new StringBuilder(); + for (final ServerInfo server : servers.values()) { + if (server.canAccess(player)) { + serverList.append(server.getName()); + serverList.append(", "); + } + } + if (serverList.length() != 0) { + serverList.setLength(serverList.length() - 2); + } + player.sendMessage(ProxyServer.getInstance().getTranslation("server_list") + serverList.toString()); + } else { + final ServerInfo server2 = servers.get(args[0]); + if (server2 == null) { + player.sendMessage(ProxyServer.getInstance().getTranslation("no_server")); + } else if (!server2.canAccess(player)) { + player.sendMessage(ProxyServer.getInstance().getTranslation("no_server_permission")); + } else { + player.connect(server2); + } + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/command/ConsoleCommandSender.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/ConsoleCommandSender.java new file mode 100644 index 0000000..c9f4cd4 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/command/ConsoleCommandSender.java @@ -0,0 +1,68 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.command; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Collection; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.CommandSender; + +public class ConsoleCommandSender implements CommandSender { + private static final ConsoleCommandSender instance; + + private ConsoleCommandSender() { + } + + @Override + public void sendMessage(final String message) { + ProxyServer.getInstance().getLogger().info(message); + } + + @Override + public void sendMessages(final String... messages) { + for (final String message : messages) { + this.sendMessage(message); + } + } + + @Override + public String getName() { + return "CONSOLE"; + } + + @Override + public Collection getGroups() { + return (Collection) new HashSet(); + } + + @Override + public void addGroups(final String... groups) { + throw new UnsupportedOperationException("Console may not have groups"); + } + + @Override + public void removeGroups(final String... groups) { + throw new UnsupportedOperationException("Console may not have groups"); + } + + @Override + public boolean hasPermission(final String permission) { + return true; + } + + @Override + public void setPermission(final String permission, final boolean value) { + throw new UnsupportedOperationException("Console has all permissions"); + } + + public static ConsoleCommandSender getInstance() { + return ConsoleCommandSender.instance; + } + + static { + instance = new ConsoleCommandSender(); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/config/Configuration.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/config/Configuration.java new file mode 100644 index 0000000..dc17dcf --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/config/Configuration.java @@ -0,0 +1,91 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.config; + +import net.md_5.bungee.api.config.AuthServiceInfo; +import net.md_5.bungee.api.config.ConfigurationAdapter; +import java.util.Map; +import net.md_5.bungee.util.CaseInsensitiveMap; +import com.google.common.base.Preconditions; +import net.md_5.bungee.api.ProxyServer; +import java.util.UUID; +import net.md_5.bungee.api.config.ServerInfo; +import gnu.trove.map.TMap; +import net.md_5.bungee.api.config.ListenerInfo; +import java.util.Collection; + +public class Configuration { + private int timeout; + private String uuid; + private Collection listeners; + private TMap servers; + private AuthServiceInfo authInfo; + private boolean onlineMode; + private int playerLimit; + + public Configuration() { + this.timeout = 30000; + this.uuid = UUID.randomUUID().toString(); + this.onlineMode = true; + this.playerLimit = -1; + } + + public void load() { + final ConfigurationAdapter adapter = ProxyServer.getInstance().getConfigurationAdapter(); + adapter.load(); + this.listeners = adapter.getListeners(); + this.timeout = adapter.getInt("timeout", this.timeout); + this.uuid = adapter.getString("stats", this.uuid); + this.authInfo = adapter.getAuthSettings(); + this.onlineMode = false; + this.playerLimit = adapter.getInt("player_limit", this.playerLimit); + Preconditions.checkArgument(this.listeners != null && !this.listeners.isEmpty(), (Object) "No listeners defined."); + final Map newServers = adapter.getServers(); + Preconditions.checkArgument(newServers != null && !newServers.isEmpty(), (Object) "No servers defined"); + if (this.servers == null) { + this.servers = (TMap) new CaseInsensitiveMap(newServers); + } else { + for (final ServerInfo oldServer : this.servers.values()) { + Preconditions.checkArgument(newServers.containsValue(oldServer), "Server %s removed on reload!", new Object[] { oldServer.getName() }); + } + for (final Map.Entry newServer : newServers.entrySet()) { + if (!this.servers.containsValue(newServer.getValue())) { + this.servers.put(newServer.getKey(), newServer.getValue()); + } + } + } + for (final ListenerInfo listener : this.listeners) { + Preconditions.checkArgument(this.servers.containsKey((Object) listener.getDefaultServer()), "Default server %s is not defined", new Object[] { listener.getDefaultServer() }); + } + } + + public int getTimeout() { + return this.timeout; + } + + public String getUuid() { + return this.uuid; + } + + public Collection getListeners() { + return this.listeners; + } + + public TMap getServers() { + return this.servers; + } + + public boolean isOnlineMode() { + return this.onlineMode; + } + + public int getPlayerLimit() { + return this.playerLimit; + } + + public AuthServiceInfo getAuthInfo() { + return authInfo; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/config/YamlConfig.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/config/YamlConfig.java new file mode 100644 index 0000000..eabe946 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/config/YamlConfig.java @@ -0,0 +1,209 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.config; + +import net.md_5.bungee.tab.ServerUnique; +import net.md_5.bungee.tab.GlobalPing; +import net.md_5.bungee.tab.Global; +import net.md_5.bungee.api.tab.TabListHandler; +import net.md_5.bungee.api.config.TexturePackInfo; +import net.md_5.bungee.api.ChatColor; +import java.util.HashSet; +import net.md_5.bungee.api.config.ListenerInfo; +import java.util.Collection; +import java.net.InetSocketAddress; +import java.util.Iterator; +import net.md_5.bungee.Util; +import net.md_5.bungee.api.config.ServerInfo; +import java.util.logging.Level; +import net.md_5.bungee.api.ProxyServer; +import java.io.Writer; +import java.io.FileWriter; +import java.util.LinkedHashMap; +import java.io.InputStream; +import java.util.Collections; +import java.util.Arrays; +import java.util.HashMap; +import java.io.IOException; +import net.md_5.bungee.util.CaseInsensitiveMap; +import java.io.FileInputStream; +import org.yaml.snakeyaml.DumperOptions; +import java.io.File; +import java.util.Map; +import org.yaml.snakeyaml.Yaml; + +import net.md_5.bungee.api.config.AuthServiceInfo; +import net.md_5.bungee.api.config.ConfigurationAdapter; + +public class YamlConfig implements ConfigurationAdapter { + private Yaml yaml; + private Map config; + private final File file; + + public YamlConfig() { + this.file = new File("config.yml"); + } + + @Override + public void load() { + try { + this.file.createNewFile(); + final DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + this.yaml = new Yaml(options); + try (final InputStream is = new FileInputStream(this.file)) { + this.config = (Map) this.yaml.load(is); + } + if (this.config == null) { + this.config = (Map) new CaseInsensitiveMap(); + } else { + this.config = (Map) new CaseInsensitiveMap(this.config); + } + } catch (IOException ex) { + throw new RuntimeException("Could not load configuration!", ex); + } + final Map permissions = this.get("permissions", new HashMap()); + if (permissions.isEmpty()) { + permissions.put("default", Arrays.asList("bungeecord.command.server", "bungeecord.command.list")); + permissions.put("admin", Arrays.asList("bungeecord.command.alert", "bungeecord.command.end", "bungeecord.command.ip", "bungeecord.command.reload")); + } + final Map groups = this.get("groups", new HashMap()); + if (groups.isEmpty()) { + groups.put("lax1dude", Collections.singletonList("admin")); + } + final Map auth = this.get("authservice", new HashMap()); + if(auth.isEmpty()) { + auth.put("enabled", false); + auth.put("limbo", "lobby"); + auth.put("authfile", "passwords.yml"); + auth.put("timeout", 30); + } + } + + private T get(final String path, final T def) { + return this.get(path, def, this.config); + } + + private T get(final String path, final T def, final Map submap) { + final int index = path.indexOf(46); + if (index == -1) { + Object val = submap.get(path); + if (val == null && def != null) { + val = def; + submap.put(path, def); + this.save(); + } + return (T) val; + } + final String first = path.substring(0, index); + final String second = path.substring(index + 1, path.length()); + Map sub = (Map) submap.get(first); + if (sub == null) { + sub = new LinkedHashMap(); + submap.put(first, sub); + } + return (T) this.get(second, (Object) def, sub); + } + + private void save() { + try (final FileWriter wr = new FileWriter(this.file)) { + this.yaml.dump((Object) this.config, (Writer) wr); + } catch (IOException ex) { + ProxyServer.getInstance().getLogger().log(Level.WARNING, "Could not save config", ex); + } + } + + @Override + public int getInt(final String path, final int def) { + return this.get(path, def); + } + + @Override + public String getString(final String path, final String def) { + return this.get(path, def); + } + + @Override + public boolean getBoolean(final String path, final boolean def) { + return this.get(path, def); + } + + @Override + public Map getServers() { + final Map base = this.get("servers", (Map) Collections.singletonMap("lobby", new HashMap())); + final Map ret = new HashMap(); + for (final Map.Entry entry : base.entrySet()) { + final Map val = entry.getValue(); + final String name = entry.getKey(); + final String addr = this.get("address", "localhost:25501", val); + final boolean restricted = this.get("restricted", false, val); + final InetSocketAddress address = Util.getAddr(addr); + final ServerInfo info = ProxyServer.getInstance().constructServerInfo(name, address, restricted); + ret.put(name, info); + } + return ret; + } + + @Override + public Collection getListeners() { + final Collection base = this.get("listeners", (Collection) Arrays.asList(new HashMap())); + final Map forcedDef = new HashMap(); + //forcedDef.put("pvp.md-5.net", "pvp"); + final Collection ret = new HashSet(); + for (final Map val : base) { + String motd = this.get("motd", "&6&lbungeecord eaglercraft server |>", val); + motd = ChatColor.translateAlternateColorCodes('&', motd); + final int maxPlayers = this.get("max_players", 60, val); + final String defaultServer = this.get("default_server", "lobby", val); + final String fallbackServer = this.get("fallback_server", defaultServer, val); + final boolean forceDefault = this.get("force_default_server", true, val); + final boolean websocket = this.get("websocket", true, val); + final String host = this.get("host", "0.0.0.0:25565", val); + final int tabListSize = this.get("tab_size", 60, val); + final InetSocketAddress address = Util.getAddr(host); + final Map forced = (Map) new CaseInsensitiveMap(this.get("forced_hosts", forcedDef, val)); + final String textureURL = this.get("texture_url", (String) null, val); + final int textureSize = this.get("texture_size", 16, val); + final TexturePackInfo texture = (textureURL == null) ? null : new TexturePackInfo(textureURL, textureSize); + final String tabListName = this.get("tab_list", "GLOBAL_PING", val); + DefaultTabList value = DefaultTabList.valueOf(tabListName.toUpperCase()); + if (value == null) { + value = DefaultTabList.GLOBAL_PING; + } + final ListenerInfo info = new ListenerInfo(address, motd, maxPlayers, tabListSize, defaultServer, fallbackServer, forceDefault, websocket, forced, texture, value.clazz); + ret.add(info); + } + return ret; + } + + @Override + public Collection getGroups(final String player) { + final Collection groups = this.get("groups." + player, (Collection) null); + final Collection ret = (groups == null) ? new HashSet() : new HashSet(groups); + ret.add("default"); + return ret; + } + + @Override + public Collection getPermissions(final String group) { + return this.get("permissions." + group, (Collection) Collections.EMPTY_LIST); + } + + private enum DefaultTabList { + GLOBAL((Class) Global.class), GLOBAL_PING((Class) GlobalPing.class), SERVER((Class) ServerUnique.class); + + private final Class clazz; + + private DefaultTabList(final Class clazz) { + this.clazz = clazz; + } + } + + @Override + public AuthServiceInfo getAuthSettings() { + final Map auth = this.get("authservice", new HashMap()); + return new AuthServiceInfo(this.get("enabled", true, auth), this.get("limbo", "lobby", auth), new File(this.get("authfile", "passwords.yml", auth)), this.get("timeout", 30, auth)); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/connection/CancelSendSignal.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/connection/CancelSendSignal.java new file mode 100644 index 0000000..a0bdda3 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/connection/CancelSendSignal.java @@ -0,0 +1,17 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.connection; + +public class CancelSendSignal extends Error { + @Override + public Throwable initCause(final Throwable cause) { + return this; + } + + @Override + public Throwable fillInStackTrace() { + return this; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java new file mode 100644 index 0000000..39012fb --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java @@ -0,0 +1,285 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.connection; + +import java.beans.ConstructorProperties; +import net.md_5.bungee.api.event.ServerKickEvent; +import java.util.Objects; +import net.md_5.bungee.protocol.packet.PacketFFKick; +import java.util.Iterator; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteArrayDataInput; +import java.util.Collection; +import net.md_5.bungee.api.connection.Connection; +import net.md_5.bungee.api.event.PluginMessageEvent; +import com.google.common.io.ByteStreams; +import net.md_5.bungee.protocol.packet.PacketFAPluginMessage; +import net.md_5.bungee.api.score.Team; +import net.md_5.bungee.protocol.packet.PacketD1Team; +import net.md_5.bungee.api.score.Position; +import net.md_5.bungee.protocol.packet.PacketD0DisplayScoreboard; +import net.md_5.bungee.api.score.Score; +import net.md_5.bungee.protocol.packet.PacketCFScoreboardScore; +import net.md_5.bungee.api.score.Scoreboard; +import net.md_5.bungee.api.score.Objective; +import net.md_5.bungee.protocol.packet.PacketCEScoreboardObjective; +import net.md_5.bungee.protocol.packet.PacketC9PlayerListItem; +import net.md_5.bungee.protocol.packet.Packet0KeepAlive; +import net.md_5.bungee.EntityMap; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.netty.ChannelWrapper; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.Util; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.ServerConnection; +import net.md_5.bungee.UserConnection; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.netty.PacketHandler; + +public class DownstreamBridge extends PacketHandler { + private final ProxyServer bungee; + private final UserConnection con; + private final ServerConnection server; + + @Override + public void exception(final Throwable t) throws Exception { + final ServerInfo def = this.bungee.getServerInfo(this.con.getPendingConnection().getListener().getFallbackServer()); + if (this.server.getInfo() != def) { + this.con.connectNow(def); + this.con.sendMessage(ChatColor.RED + "The server you were previously on went down, you have been connected to the lobby"); + } else { + this.con.disconnect(Util.exception(t)); + } + } + + @Override + public void disconnected(final ChannelWrapper channel) throws Exception { + this.server.getInfo().removePlayer(this.con); + this.bungee.getReconnectHandler().setServer(this.con); + if (!this.server.isObsolete()) { + this.con.disconnect(this.bungee.getTranslation("lost_connection")); + } + } + + @Override + public void handle(final byte[] buf) throws Exception { + if (!this.server.isObsolete()) { + EntityMap.rewrite(buf, this.con.getServerEntityId(), this.con.getClientEntityId()); + this.con.sendPacket(buf); + } + } + + @Override + public void handle(final Packet0KeepAlive alive) throws Exception { + this.con.setSentPingId(alive.getRandomId()); + this.con.setSentPingTime(System.currentTimeMillis()); + } + + @Override + public void handle(final PacketC9PlayerListItem playerList) throws Exception { + if (!this.con.getTabList().onListUpdate(playerList.getUsername(), playerList.isOnline(), playerList.getPing())) { + throw new CancelSendSignal(); + } + } + + @Override + public void handle(final PacketCEScoreboardObjective objective) throws Exception { + final Scoreboard serverScoreboard = this.con.getServerSentScoreboard(); + switch (objective.getAction()) { + case 0: { + serverScoreboard.addObjective(new Objective(objective.getName(), objective.getText())); + break; + } + case 1: { + serverScoreboard.removeObjective(objective.getName()); + break; + } + } + } + + @Override + public void handle(final PacketCFScoreboardScore score) throws Exception { + final Scoreboard serverScoreboard = this.con.getServerSentScoreboard(); + switch (score.getAction()) { + case 0: { + final Score s = new Score(score.getItemName(), score.getScoreName(), score.getValue()); + serverScoreboard.removeScore(score.getItemName()); + serverScoreboard.addScore(s); + break; + } + case 1: { + serverScoreboard.removeScore(score.getItemName()); + break; + } + } + } + + @Override + public void handle(final PacketD0DisplayScoreboard displayScoreboard) throws Exception { + final Scoreboard serverScoreboard = this.con.getServerSentScoreboard(); + serverScoreboard.setName(displayScoreboard.getName()); + serverScoreboard.setPosition(Position.values()[displayScoreboard.getPosition()]); + } + + @Override + public void handle(final PacketD1Team team) throws Exception { + final Scoreboard serverScoreboard = this.con.getServerSentScoreboard(); + if (team.getMode() == 1) { + serverScoreboard.removeTeam(team.getName()); + return; + } + Team t; + if (team.getMode() == 0) { + t = new Team(team.getName()); + serverScoreboard.addTeam(t); + } else { + t = serverScoreboard.getTeam(team.getName()); + } + if (t != null) { + if (team.getMode() == 0 || team.getMode() == 2) { + t.setDisplayName(team.getDisplayName()); + t.setPrefix(team.getPrefix()); + t.setSuffix(team.getSuffix()); + t.setFriendlyFire(team.isFriendlyFire()); + } + if (team.getPlayers() != null) { + for (final String s : team.getPlayers()) { + if (team.getMode() == 0 || team.getMode() == 3) { + t.addPlayer(s); + } else { + t.removePlayer(s); + } + } + } + } + } + + @Override + public void handle(final PacketFAPluginMessage pluginMessage) throws Exception { + final ByteArrayDataInput in = ByteStreams.newDataInput(pluginMessage.getData()); + final PluginMessageEvent event = new PluginMessageEvent(this.con.getServer(), this.con, pluginMessage.getTag(), pluginMessage.getData().clone()); + if (this.bungee.getPluginManager().callEvent(event).isCancelled()) { + throw new CancelSendSignal(); + } + if (pluginMessage.getTag().equals("MC|TPack") && this.con.getPendingConnection().getListener().getTexturePack() != null) { + throw new CancelSendSignal(); + } + if (pluginMessage.getTag().equals("BungeeCord")) { + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + final String subChannel = in.readUTF(); + if (subChannel.equals("Forward")) { + final String target = in.readUTF(); + final String channel = in.readUTF(); + final short len = in.readShort(); + final byte[] data = new byte[len]; + in.readFully(data); + out.writeUTF(channel); + out.writeShort(data.length); + out.write(data); + final byte[] payload = out.toByteArray(); + out = null; + if (target.equals("ALL")) { + for (final ServerInfo server : this.bungee.getServers().values()) { + if (server != this.con.getServer().getInfo()) { + server.sendData("BungeeCord", payload); + } + } + } else { + final ServerInfo server2 = this.bungee.getServerInfo(target); + if (server2 != null) { + server2.sendData("BungeeCord", payload); + } + } + } + if (subChannel.equals("Connect")) { + final ServerInfo server3 = this.bungee.getServerInfo(in.readUTF()); + if (server3 != null) { + this.con.connect(server3); + } + } + if (subChannel.equals("IP")) { + out.writeUTF("IP"); + out.writeUTF(this.con.getAddress().getHostString()); + out.writeInt(this.con.getAddress().getPort()); + } + if (subChannel.equals("PlayerCount")) { + final String target = in.readUTF(); + out.writeUTF("PlayerCount"); + if (target.equals("ALL")) { + out.writeUTF("ALL"); + out.writeInt(this.bungee.getOnlineCount()); + } else { + final ServerInfo server4 = this.bungee.getServerInfo(target); + if (server4 != null) { + out.writeUTF(server4.getName()); + out.writeInt(server4.getPlayers().size()); + } + } + } + if (subChannel.equals("PlayerList")) { + final String target = in.readUTF(); + out.writeUTF("PlayerList"); + if (target.equals("ALL")) { + out.writeUTF("ALL"); + out.writeUTF(Util.csv(this.bungee.getPlayers())); + } else { + final ServerInfo server4 = this.bungee.getServerInfo(target); + if (server4 != null) { + out.writeUTF(server4.getName()); + out.writeUTF(Util.csv(server4.getPlayers())); + } + } + } + if (subChannel.equals("GetServers")) { + out.writeUTF("GetServers"); + out.writeUTF(Util.csv(this.bungee.getServers().keySet())); + } + if (subChannel.equals("Message")) { + final ProxiedPlayer target2 = this.bungee.getPlayer(in.readUTF()); + if (target2 != null) { + target2.sendMessage(in.readUTF()); + } + } + if (subChannel.equals("GetServer")) { + out.writeUTF("GetServer"); + out.writeUTF(this.server.getInfo().getName()); + } + if (out != null) { + final byte[] b = out.toByteArray(); + if (b.length != 0) { + this.con.getServer().sendData("BungeeCord", b); + } + } + } + } + + @Override + public void handle(final PacketFFKick kick) throws Exception { + ServerInfo def = this.bungee.getServerInfo(this.con.getPendingConnection().getListener().getFallbackServer()); + if (Objects.equals(this.server.getInfo(), def)) { + def = null; + } + final ServerKickEvent event = this.bungee.getPluginManager().callEvent(new ServerKickEvent(this.con, kick.getMessage(), def)); + if (event.isCancelled() && event.getCancelServer() != null) { + this.con.connectNow(event.getCancelServer()); + } else { + this.con.disconnect(this.bungee.getTranslation("server_kick") + event.getKickReason()); + } + this.server.setObsolete(true); + throw new CancelSendSignal(); + } + + @Override + public String toString() { + return "[" + this.con.getName() + "] <-> DownstreamBridge <-> [" + this.server.getInfo().getName() + "]"; + } + + @ConstructorProperties({ "bungee", "con", "server" }) + public DownstreamBridge(final ProxyServer bungee, final UserConnection con, final ServerConnection server) { + this.bungee = bungee; + this.con = con; + this.server = server; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/connection/InitialHandler.java new file mode 100644 index 0000000..dfbd4ec --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/connection/InitialHandler.java @@ -0,0 +1,274 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.connection; + +import java.beans.ConstructorProperties; +import java.util.ArrayList; +import java.net.InetSocketAddress; +import net.md_5.bungee.protocol.packet.PacketFFKick; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.netty.HandlerBoss; +import net.md_5.bungee.api.event.PostLoginEvent; +import net.md_5.bungee.UserConnection; +import net.md_5.bungee.protocol.packet.PacketCDClientStatus; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import java.security.GeneralSecurityException; +import net.md_5.bungee.netty.CipherEncoder; +import net.md_5.bungee.api.event.LoginEvent; +import net.md_5.bungee.api.Callback; +import javax.crypto.Cipher; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.net.URLEncoder; +import io.netty.channel.ChannelHandler; +import net.md_5.bungee.netty.CipherDecoder; +import net.md_5.bungee.netty.PipelineUtils; +import java.security.Key; +import net.md_5.bungee.protocol.packet.PacketFCEncryptionResponse; +import net.md_5.bungee.EncryptionUtil; +import net.md_5.bungee.protocol.packet.DefinedPacket; +import net.md_5.bungee.PacketConstants; +import net.md_5.bungee.BungeeCord; +import java.util.logging.Level; +import net.md_5.bungee.protocol.Protocol; +import net.md_5.bungee.protocol.Forge; +import net.md_5.bungee.netty.PacketDecoder; +import com.google.common.base.Preconditions; +import net.md_5.bungee.api.event.ProxyPingEvent; +import net.md_5.bungee.api.ServerPing; +import net.md_5.bungee.protocol.packet.PacketFEPing; +import net.md_5.bungee.Util; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.connection.Connection; +import javax.crypto.SecretKey; +import net.md_5.bungee.protocol.packet.PacketFAPluginMessage; +import java.util.List; +import net.md_5.bungee.protocol.packet.PacketFDEncryptionRequest; +import net.md_5.bungee.protocol.packet.Packet2Handshake; +import net.md_5.bungee.protocol.packet.Packet1Login; +import net.md_5.bungee.api.config.ListenerInfo; +import net.md_5.bungee.netty.ChannelWrapper; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.PendingConnection; +import net.md_5.bungee.netty.PacketHandler; + +public class InitialHandler extends PacketHandler implements PendingConnection { + private final ProxyServer bungee; + private ChannelWrapper ch; + private final ListenerInfo listener; + private Packet1Login forgeLogin; + private Packet2Handshake handshake; + private PacketFDEncryptionRequest request; + private List loginMessages; + private List registerMessages; + private State thisState; + private SecretKey sharedKey; + private final Connection.Unsafe unsafe; + + @Override + public void connected(final ChannelWrapper channel) throws Exception { + this.ch = channel; + } + + @Override + public void exception(final Throwable t) throws Exception { + this.disconnect(ChatColor.RED + Util.exception(t)); + } + + @Override + public void handle(final PacketFAPluginMessage pluginMessage) throws Exception { + if (pluginMessage.getTag().equals("REGISTER")) { + this.registerMessages.add(pluginMessage); + } else { + this.loginMessages.add(pluginMessage); + } + } + + @Override + public void handle(final PacketFEPing ping) throws Exception { + ServerPing response = new ServerPing(this.bungee.getProtocolVersion(), this.bungee.getGameVersion(), this.listener.getMotd(), this.bungee.getOnlineCount(), this.listener.getMaxPlayers()); + response = this.bungee.getPluginManager().callEvent(new ProxyPingEvent(this, response)).getResponse(); + final String kickMessage = ChatColor.DARK_BLUE + "\u0000" + response.getProtocolVersion() + "\u0000" + response.getGameVersion() + "\u0000" + response.getMotd() + "\u0000" + response.getCurrentPlayers() + "\u0000" + + response.getMaxPlayers(); + this.disconnect(kickMessage); + } + + @Override + public void handle(final Packet1Login login) throws Exception { + Preconditions.checkState(this.thisState == State.LOGIN, (Object) "Not expecting FORGE LOGIN"); + Preconditions.checkState(this.forgeLogin == null, (Object) "Already received FORGE LOGIN"); + this.forgeLogin = login; + ((PacketDecoder) this.ch.getHandle().pipeline().get((Class) PacketDecoder.class)).setProtocol(Forge.getInstance()); + } + + @Override + public void handle(final Packet2Handshake handshake) throws Exception { + Preconditions.checkState(this.thisState == State.HANDSHAKE, (Object) "Not expecting HANDSHAKE"); + this.handshake = handshake; + this.bungee.getLogger().log(Level.INFO, "{0} has connected", this); + boolean skipEncryption = false; + if (handshake.getProcolVersion() == 69) { + skipEncryption = true; + this.handshake.swapProtocol((byte) 61); + }else if(handshake.getProcolVersion() != 61) { + this.disconnect("minecraft 1.5.2 required for eaglercraft backdoor access"); + } + if (handshake.getUsername().length() > 16) { + this.disconnect("Cannot have username longer than 16 characters"); + return; + } + final int limit = BungeeCord.getInstance().config.getPlayerLimit(); + if (limit > 0 && this.bungee.getOnlineCount() > limit) { + this.disconnect(this.bungee.getTranslation("proxy_full")); + return; + } + if (!BungeeCord.getInstance().config.isOnlineMode() && this.bungee.getPlayer(handshake.getUsername()) != null) { + this.disconnect(this.bungee.getTranslation("already_connected")); + return; + } + this.unsafe().sendPacket(PacketConstants.I_AM_BUNGEE); + this.unsafe().sendPacket(PacketConstants.FORGE_MOD_REQUEST); + if(skipEncryption) { + InitialHandler.this.thisState = State.LOGIN; + handle((PacketCDClientStatus)null); + }else { + this.unsafe().sendPacket(this.request = EncryptionUtil.encryptRequest()); + this.thisState = State.ENCRYPT; + } + } + + @Override + public void handle(final PacketFCEncryptionResponse encryptResponse) throws Exception { + Preconditions.checkState(this.thisState == State.ENCRYPT, (Object) "Not expecting ENCRYPT"); + this.sharedKey = EncryptionUtil.getSecret(encryptResponse, this.request); + final Cipher decrypt = EncryptionUtil.getCipher(2, this.sharedKey); + this.ch.getHandle().pipeline().addBefore(PipelineUtils.PACKET_DECODE_HANDLER, PipelineUtils.DECRYPT_HANDLER, (ChannelHandler)new CipherDecoder(decrypt)); + this.finish(); + } + + private void finish() throws GeneralSecurityException { + final ProxiedPlayer old = this.bungee.getPlayer(this.handshake.getUsername()); + if (old != null) { + old.disconnect(this.bungee.getTranslation("already_connected")); + } + final Callback complete = new Callback() { + @Override + public void done(final LoginEvent result, final Throwable error) { + if (result.isCancelled()) { + InitialHandler.this.disconnect(result.getCancelReason()); + } + if (InitialHandler.this.ch.isClosed()) { + return; + } + InitialHandler.this.thisState = State.LOGIN; + InitialHandler.this.ch.getHandle().eventLoop().execute((Runnable)new Runnable() { + @Override + public void run() { + InitialHandler.this.unsafe().sendPacket(new PacketFCEncryptionResponse(new byte[0], new byte[0])); + try { + final Cipher encrypt = EncryptionUtil.getCipher(1, InitialHandler.this.sharedKey); + InitialHandler.this.ch.getHandle().pipeline().addBefore(PipelineUtils.DECRYPT_HANDLER, PipelineUtils.ENCRYPT_HANDLER, (ChannelHandler)new CipherEncoder(encrypt)); + } + catch (GeneralSecurityException ex) { + InitialHandler.this.disconnect("Cipher error: " + Util.exception(ex)); + } + } + }); + } + }; + this.bungee.getPluginManager().callEvent(new LoginEvent(this, complete)); + } + + @Override + public void handle(final PacketCDClientStatus clientStatus) throws Exception { + Preconditions.checkState(this.thisState == State.LOGIN, (Object) "Not expecting LOGIN"); + final UserConnection userCon = new UserConnection(this.bungee, this.ch, this.getName(), this); + userCon.init(); + this.bungee.getPluginManager().callEvent(new PostLoginEvent(userCon)); + ((HandlerBoss) this.ch.getHandle().pipeline().get((Class) HandlerBoss.class)).setHandler(new UpstreamBridge(this.bungee, userCon)); + final ServerInfo server = this.bungee.getReconnectHandler().getServer(userCon); + userCon.connect(server, true); + this.thisState = State.FINISHED; + throw new CancelSendSignal(); + } + + @Override + public synchronized void disconnect(final String reason) { + if (!this.ch.isClosed()) { + this.unsafe().sendPacket(new PacketFFKick(reason)); + this.ch.close(); + } + } + + @Override + public String getName() { + return (this.handshake == null) ? null : this.handshake.getUsername(); + } + + @Override + public byte getVersion() { + return (byte) ((this.handshake == null) ? -1 : this.handshake.getProcolVersion()); + } + + @Override + public InetSocketAddress getVirtualHost() { + return (this.handshake == null) ? null : new InetSocketAddress(this.handshake.getHost(), this.handshake.getPort()); + } + + @Override + public InetSocketAddress getAddress() { + return (InetSocketAddress) this.ch.getHandle().remoteAddress(); + } + + @Override + public Connection.Unsafe unsafe() { + return this.unsafe; + } + + @Override + public String toString() { + return "[" + ((this.getName() != null) ? this.getName() : this.getAddress()) + "] <-> InitialHandler"; + } + + @ConstructorProperties({ "bungee", "listener" }) + public InitialHandler(final ProxyServer bungee, final ListenerInfo listener) { + this.loginMessages = new ArrayList(); + this.registerMessages = new ArrayList(); + this.thisState = State.HANDSHAKE; + this.unsafe = new Connection.Unsafe() { + @Override + public void sendPacket(final DefinedPacket packet) { + InitialHandler.this.ch.write(packet); + } + }; + this.bungee = bungee; + this.listener = listener; + } + + @Override + public ListenerInfo getListener() { + return this.listener; + } + + public Packet1Login getForgeLogin() { + return this.forgeLogin; + } + + public Packet2Handshake getHandshake() { + return this.handshake; + } + + public List getLoginMessages() { + return this.loginMessages; + } + + public List getRegisterMessages() { + return this.registerMessages; + } + + private enum State { + HANDSHAKE, ENCRYPT, LOGIN, FINISHED; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/connection/PingHandler.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/connection/PingHandler.java new file mode 100644 index 0000000..6e55bf1 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/connection/PingHandler.java @@ -0,0 +1,51 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.connection; + +import java.beans.ConstructorProperties; +import net.md_5.bungee.protocol.packet.PacketFFKick; +import net.md_5.bungee.netty.ChannelWrapper; +import net.md_5.bungee.api.ServerPing; +import net.md_5.bungee.api.Callback; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.netty.PacketHandler; + +public class PingHandler extends PacketHandler { + private final ServerInfo target; + private final Callback callback; + private static final byte[] pingBuf; + + @Override + public void connected(final ChannelWrapper channel) throws Exception { + channel.write(PingHandler.pingBuf); + } + + @Override + public void exception(final Throwable t) throws Exception { + this.callback.done(null, t); + } + + @Override + public void handle(final PacketFFKick kick) throws Exception { + final String[] split = kick.getMessage().split("\u0000"); + final ServerPing ping = new ServerPing(Byte.parseByte(split[1]), split[2], split[3], Integer.parseInt(split[4]), Integer.parseInt(split[5])); + this.callback.done(ping, null); + } + + @Override + public String toString() { + return "[Ping Handler] -> " + this.target.getName(); + } + + @ConstructorProperties({ "target", "callback" }) + public PingHandler(final ServerInfo target, final Callback callback) { + this.target = target; + this.callback = callback; + } + + static { + pingBuf = new byte[] { -2, 1 }; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java new file mode 100644 index 0000000..2b448ba --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java @@ -0,0 +1,113 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.connection; + +import net.md_5.bungee.api.event.PluginMessageEvent; +import net.md_5.bungee.protocol.packet.PacketFAPluginMessage; +import net.md_5.bungee.protocol.packet.PacketCCSettings; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.Connection; +import net.md_5.bungee.api.event.ChatEvent; +import net.md_5.bungee.protocol.packet.Packet3Chat; +import net.md_5.bungee.protocol.packet.Packet0KeepAlive; +import net.md_5.bungee.EntityMap; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.PlayerDisconnectEvent; +import net.md_5.bungee.netty.ChannelWrapper; +import net.md_5.bungee.Util; +import net.md_5.bungee.api.config.TexturePackInfo; +import net.md_5.bungee.protocol.packet.DefinedPacket; +import net.md_5.bungee.BungeeCord; +import net.md_5.bungee.UserConnection; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.netty.PacketHandler; + +public class UpstreamBridge extends PacketHandler { + private final ProxyServer bungee; + private final UserConnection con; + + public UpstreamBridge(final ProxyServer bungee, final UserConnection con) { + this.bungee = bungee; + this.con = con; + BungeeCord.getInstance().addConnection(con); + con.getTabList().onConnect(); + con.unsafe().sendPacket(BungeeCord.getInstance().registerChannels()); + final TexturePackInfo texture = con.getPendingConnection().getListener().getTexturePack(); + if (texture != null) { + con.setTexturePack(texture); + } + } + + @Override + public void exception(final Throwable t) throws Exception { + this.con.disconnect(Util.exception(t)); + } + + @Override + public void disconnected(final ChannelWrapper channel) throws Exception { + final PlayerDisconnectEvent event = new PlayerDisconnectEvent(this.con); + this.bungee.getPluginManager().callEvent(event); + this.con.getTabList().onDisconnect(); + BungeeCord.getInstance().removeConnection(this.con); + if (this.con.getServer() != null) { + this.con.getServer().disconnect("Quitting"); + } + } + + @Override + public void handle(final byte[] buf) throws Exception { + EntityMap.rewrite(buf, this.con.getClientEntityId(), this.con.getServerEntityId()); + if (this.con.getServer() != null) { + this.con.getServer().getCh().write(buf); + } + } + + @Override + public void handle(final Packet0KeepAlive alive) throws Exception { + if (alive.getRandomId() == this.con.getSentPingId()) { + final int newPing = (int) (System.currentTimeMillis() - this.con.getSentPingTime()); + this.con.getTabList().onPingChange(newPing); + this.con.setPing(newPing); + } + } + + @Override + public void handle(final Packet3Chat chat) throws Exception { + final ChatEvent chatEvent = new ChatEvent(this.con, this.con.getServer(), chat.getMessage()); + if (this.bungee.getPluginManager().callEvent(chatEvent).isCancelled()) { + throw new CancelSendSignal(); + } + if (chatEvent.isCommand() && this.bungee.getPluginManager().dispatchCommand(this.con, chat.getMessage().substring(1))) { + throw new CancelSendSignal(); + } + } + + @Override + public void handle(final PacketCCSettings settings) throws Exception { + this.con.setSettings(settings); + } + + @Override + public void handle(final PacketFAPluginMessage pluginMessage) throws Exception { + if (pluginMessage.getTag().equals("BungeeCord")) { + throw new CancelSendSignal(); + } + if (pluginMessage.getTag().equals("FML") && (pluginMessage.getData()[0] & 0xFF) == 0x1) { + throw new CancelSendSignal(); + } + final PluginMessageEvent event = new PluginMessageEvent(this.con, this.con.getServer(), pluginMessage.getTag(), pluginMessage.getData().clone()); + if (this.bungee.getPluginManager().callEvent(event).isCancelled()) { + throw new CancelSendSignal(); + } + if (pluginMessage.getTag().equals("REGISTER")) { + this.con.getPendingConnection().getRegisterMessages().add(pluginMessage); + } + } + + @Override + public String toString() { + return "[" + this.con.getName() + "] -> UpstreamBridge"; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/eaglercraft/PluginEaglerAuth.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/eaglercraft/PluginEaglerAuth.java new file mode 100644 index 0000000..81316ef --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/eaglercraft/PluginEaglerAuth.java @@ -0,0 +1,55 @@ +package net.md_5.bungee.eaglercraft; + +import java.util.Collections; +import java.util.HashSet; + +import net.md_5.bungee.PacketConstants; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.PostLoginEvent; +import net.md_5.bungee.api.event.ServerConnectEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.api.plugin.Plugin; +import net.md_5.bungee.api.plugin.PluginDescription; +import net.md_5.bungee.event.EventHandler; +import net.md_5.bungee.protocol.packet.Packet1Login; +import net.md_5.bungee.protocol.packet.Packet9Respawn; + +public class PluginEaglerAuth extends Plugin implements Listener { + + public PluginEaglerAuth() { + super(new PluginDescription("EaglerAuth", PluginEaglerAuth.class.getName(), "1.0.0", "LAX1DUDE", Collections.emptySet(), null)); + } + + @Override + public void onLoad() { + + } + + @Override + public void onEnable() { + getProxy().getPluginManager().registerListener(this, this); + } + + @Override + public void onDisable() { + + } + + private final HashSet playersInLimbo = new HashSet(); + + @EventHandler + public void onPostLogin(PostLoginEvent event) { + //playersInLimbo.add(event.getPlayer()); + } + + @EventHandler + public void onServerConnect(ServerConnectEvent event) { + ProxiedPlayer player = event.getPlayer(); + //if(playersInLimbo.contains(player)) { + // event.setCancelled(true); + // player.unsafe().sendPacket(new Packet1Login(0, "END", (byte) 1, 1, (byte) 0, (byte) 0, (byte) 1)); + // player.unsafe().sendPacket(new Packet9Respawn(1, (byte) 0, (byte) 1, (short) 255, "END")); + //} + } + +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/eaglercraft/PluginEaglerSkins.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/eaglercraft/PluginEaglerSkins.java new file mode 100644 index 0000000..921bcc8 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/eaglercraft/PluginEaglerSkins.java @@ -0,0 +1,67 @@ +package net.md_5.bungee.eaglercraft; + +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.HashMap; + +import net.md_5.bungee.UserConnection; +import net.md_5.bungee.api.event.PlayerDisconnectEvent; +import net.md_5.bungee.api.event.PluginMessageEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.api.plugin.Plugin; +import net.md_5.bungee.api.plugin.PluginDescription; +import net.md_5.bungee.event.EventHandler; + +public class PluginEaglerSkins extends Plugin implements Listener { + + private final HashMap skinCollection = new HashMap(); + + private static final int[] SKIN_DATA_SIZE = new int[] { 64*32*4, 64*64*4, 128*64*4, 128*128*4, 1 }; + + public PluginEaglerSkins() { + super(new PluginDescription("EaglerSkins", PluginEaglerSkins.class.getName(), "1.0.0", "LAX1DUDE", Collections.emptySet(), null)); + } + + public void onLoad() { + + } + + public void onEnable() { + getProxy().getPluginManager().registerListener(this, this); + } + + public void onDisable() { + + } + + @EventHandler + public void onPluginMessage(PluginMessageEvent event) { + if(event.getSender() instanceof UserConnection && event.getData().length > 0) { + String user = ((UserConnection)event.getSender()).getName(); + byte[] msg = event.getData(); + if("EAG|MySkin".equals(event.getTag())) { + int t = (int)msg[0] & 0xFF; + if(t >= 0 && t < SKIN_DATA_SIZE.length && msg.length == (SKIN_DATA_SIZE[t] + 1)) { + skinCollection.put(user, msg); + } + }else if("EAG|FetchSkin".equals(event.getTag())) { + if(msg.length > 2) { + String fetch = new String(msg, 2, msg.length - 2, StandardCharsets.UTF_8); + byte[] data; + if((data = skinCollection.get(fetch)) != null) { + byte[] conc = new byte[data.length + 2]; + conc[0] = msg[0]; conc[1] = msg[1]; //synchronization cookie + System.arraycopy(data, 0, conc, 2, data.length); + ((UserConnection)event.getSender()).sendData("EAG|UserSkin", conc); + } + } + } + } + } + + @EventHandler + public void onPlayerDisconnect(PlayerDisconnectEvent event) { + skinCollection.remove(event.getPlayer().getName()); + } + +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/eaglercraft/WebSocketListener.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/eaglercraft/WebSocketListener.java new file mode 100644 index 0000000..ff87ca0 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/eaglercraft/WebSocketListener.java @@ -0,0 +1,66 @@ +package net.md_5.bungee.eaglercraft; + +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; + +import org.java_websocket.WebSocket; +import org.java_websocket.handshake.ClientHandshake; +import org.java_websocket.server.WebSocketServer; + +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.config.ListenerInfo; + +public class WebSocketListener extends WebSocketServer { + + private InetSocketAddress bungeeProxy; + private ProxyServer bungeeCord; + + public WebSocketListener(ListenerInfo info, InetSocketAddress sock, ProxyServer bungeeCord) { + super(info.getHost()); + this.setTcpNoDelay(true); + this.setConnectionLostTimeout(5); + this.start(); + this.bungeeProxy = sock; + this.bungeeCord = bungeeCord; + } + + @Override + public void onClose(WebSocket arg0, int arg1, String arg2, boolean arg3) { + if(arg0.getAttachment() != null) { + ((WebSocketProxy)arg0.getAttachment()).killConnection(); + } + System.out.println("websocket closed - " + arg0.getRemoteSocketAddress()); + } + + @Override + public void onError(WebSocket arg0, Exception arg1) { + arg1.printStackTrace(); + } + + @Override + public void onMessage(WebSocket arg0, String arg1) { + } + + @Override + public void onMessage(WebSocket arg0, ByteBuffer arg1) { + if(arg0.getAttachment() != null) { + ((WebSocketProxy)arg0.getAttachment()).sendPacket(arg1); + } + } + + @Override + public void onOpen(WebSocket arg0, ClientHandshake arg1) { + System.out.println("websocket opened - " + arg0.getRemoteSocketAddress()); + WebSocketProxy proxyObj = new WebSocketProxy(arg0, bungeeProxy); + arg0.setAttachment(proxyObj); + if(!proxyObj.connect()) { + arg0.close(); + } + } + + @Override + public void onStart() { + + } + +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/eaglercraft/WebSocketProxy.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/eaglercraft/WebSocketProxy.java new file mode 100644 index 0000000..69738c0 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/eaglercraft/WebSocketProxy.java @@ -0,0 +1,92 @@ +package net.md_5.bungee.eaglercraft; + +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; + +import org.java_websocket.WebSocket; + +import io.netty.bootstrap.Bootstrap; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; + +/** + * Not the ideal solution but what are we supposed to do + * + */ +public class WebSocketProxy extends SimpleChannelInboundHandler { + + private WebSocket client; + private InetSocketAddress tcpListener; + private NioSocketChannel tcpChannel; + + private static final EventLoopGroup group = new NioEventLoopGroup(4); + + public WebSocketProxy(WebSocket w, InetSocketAddress addr) { + client = w; + tcpListener = addr; + tcpChannel = null; + } + + public void killConnection() { + if(client.isOpen()) { + client.close(); + } + if(tcpChannel != null && tcpChannel.isOpen()) { + try { + tcpChannel.disconnect().sync(); + } catch (InterruptedException e) { + ; + } + } + } + + public boolean connect() { + try { + if(tcpChannel == null) { + Bootstrap clientBootstrap = new Bootstrap(); + clientBootstrap.group(group); + clientBootstrap.channel(NioSocketChannel.class); + clientBootstrap.remoteAddress(tcpListener); + clientBootstrap.option(ChannelOption.TCP_NODELAY, true); + clientBootstrap.handler(new ChannelInitializer() { + protected void initChannel(SocketChannel socketChannel) throws Exception { + socketChannel.pipeline().addLast(WebSocketProxy.this); + } + }); + tcpChannel = (NioSocketChannel) clientBootstrap.connect().sync().channel(); + return true; + } + }catch(Throwable t) { + t.printStackTrace(); + } + return false; + } + + @Override + protected void messageReceived(ChannelHandlerContext arg0, ByteBuf buffer) throws Exception { + ByteBuffer toSend = ByteBuffer.allocateDirect(buffer.capacity()); + toSend.put(buffer.nioBuffer()); + toSend.flip(); + client.send(toSend); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + cause.printStackTrace(); + } + + public void sendPacket(ByteBuffer arg1) { + if(tcpChannel != null && tcpChannel.isOpen()) { + tcpChannel.write(Unpooled.wrappedBuffer(arg1)); + } + } + +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/event/EventBus.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/event/EventBus.java new file mode 100644 index 0000000..bec77ba --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/event/EventBus.java @@ -0,0 +1,128 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.event; + +import java.util.HashSet; +import java.util.Set; +import java.util.Iterator; +import java.lang.reflect.InvocationTargetException; +import java.text.MessageFormat; +import java.util.logging.Level; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.HashMap; +import java.lang.annotation.Annotation; +import java.util.logging.Logger; +import java.util.concurrent.locks.ReadWriteLock; +import java.lang.reflect.Method; +import java.util.Map; + +public class EventBus { + private final Map, Map> eventToHandler; + private final ReadWriteLock lock; + private final Logger logger; + private final Class[] annotations; + + public EventBus() { + this((Logger) null, (Class[]) null); + } + + public EventBus(final Logger logger) { + this(logger, (Class[]) null); + } + + public EventBus(final Class... annotations) { + this((Logger) null, annotations); + } + + public EventBus(final Logger logger, final Class... annotations) { + this.eventToHandler = new HashMap, Map>(); + this.lock = new ReentrantReadWriteLock(); + this.logger = ((logger == null) ? Logger.getGlobal() : logger); + this.annotations = ((annotations == null || annotations.length == 0) ? new Class[] { EventHandler.class } : annotations); + } + + public void post(final Object event) { + this.lock.readLock().lock(); + try { + final Map handlers = this.eventToHandler.get(event.getClass()); + if (handlers != null) { + for (final Map.Entry handler : handlers.entrySet()) { + for (final Method method : handler.getValue()) { + try { + method.invoke(handler.getKey(), event); + } catch (IllegalAccessException ex) { + throw new Error("Method became inaccessible: " + event, ex); + } catch (IllegalArgumentException ex2) { + throw new Error("Method rejected target/argument: " + event, ex2); + } catch (InvocationTargetException ex3) { + this.logger.log(Level.WARNING, MessageFormat.format("Error dispatching event {0} to listener {1}", event, handler.getKey()), ex3.getCause()); + } + } + } + } + } finally { + this.lock.readLock().unlock(); + } + } + + private Map, Set> findHandlers(final Object listener) { + final Map, Set> handler = new HashMap, Set>(); + for (final Method m : listener.getClass().getDeclaredMethods()) { + for (final Class annotation : this.annotations) { + if (m.isAnnotationPresent(annotation)) { + final Class[] params = m.getParameterTypes(); + if (params.length == 1) { + Set existing = handler.get(params[0]); + if (existing == null) { + existing = new HashSet(); + handler.put(params[0], existing); + } + existing.add(m); + break; + } + this.logger.log(Level.INFO, "Method {0} in class {1} annotated with {2} does not have single argument", new Object[] { m, listener.getClass(), annotation }); + } + } + } + return handler; + } + + public void register(final Object listener) { + final Map, Set> handler = this.findHandlers(listener); + this.lock.writeLock().lock(); + try { + for (final Map.Entry, Set> e : handler.entrySet()) { + Map a = this.eventToHandler.get(e.getKey()); + if (a == null) { + a = new HashMap(); + this.eventToHandler.put(e.getKey(), a); + } + final Method[] baked = new Method[e.getValue().size()]; + a.put(listener, e.getValue().toArray(baked)); + } + } finally { + this.lock.writeLock().unlock(); + } + } + + public void unregister(final Object listener) { + final Map, Set> handler = this.findHandlers(listener); + this.lock.writeLock().lock(); + try { + for (final Map.Entry, Set> e : handler.entrySet()) { + final Map a = this.eventToHandler.get(e.getKey()); + if (a != null) { + a.remove(listener); + if (!a.isEmpty()) { + continue; + } + this.eventToHandler.remove(e.getKey()); + } + } + } finally { + this.lock.writeLock().unlock(); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/event/EventHandler.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/event/EventHandler.java new file mode 100644 index 0000000..1920c2f --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/event/EventHandler.java @@ -0,0 +1,16 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.event; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Retention; +import java.lang.annotation.Annotation; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD }) +public @interface EventHandler { +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/log/BungeeLogger.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/log/BungeeLogger.java new file mode 100644 index 0000000..a8bc900 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/log/BungeeLogger.java @@ -0,0 +1,47 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.log; + +import java.util.logging.LogRecord; +import java.io.IOException; +import java.util.logging.Handler; +import java.util.logging.FileHandler; +import java.util.logging.Formatter; +import net.md_5.bungee.BungeeCord; +import java.util.logging.Logger; + +public class BungeeLogger extends Logger { + private final BungeeCord bungee; + private final ColouredWriter writer; + private final Formatter formatter; + private final LogDispatcher dispatcher; + + public BungeeLogger(final BungeeCord bungee) { + super("BungeeCord", null); + this.formatter = new ConciseFormatter(); + this.dispatcher = new LogDispatcher(this); + this.bungee = bungee; + this.writer = new ColouredWriter(bungee.getConsoleReader()); + try { + final FileHandler handler = new FileHandler("proxy.log", 16777216, 8, true); + handler.setFormatter(this.formatter); + this.addHandler(handler); + } catch (IOException ex) { + System.err.println("Could not register logger!"); + ex.printStackTrace(); + } + this.dispatcher.start(); + } + + @Override + public void log(final LogRecord record) { + this.dispatcher.queue(record); + } + + void doLog(final LogRecord record) { + super.log(record); + this.writer.print(this.formatter.format(record)); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/log/ColouredWriter.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/log/ColouredWriter.java new file mode 100644 index 0000000..bf29edd --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/log/ColouredWriter.java @@ -0,0 +1,58 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.log; + +import java.io.IOException; +import org.fusesource.jansi.Ansi; +import java.util.EnumMap; +import jline.console.ConsoleReader; +import net.md_5.bungee.api.ChatColor; +import java.util.Map; + +public class ColouredWriter { + private final Map replacements; + private final ChatColor[] colors; + private final ConsoleReader console; + + public ColouredWriter(final ConsoleReader console) { + this.replacements = new EnumMap(ChatColor.class); + this.colors = ChatColor.values(); + this.console = console; + this.replacements.put(ChatColor.BLACK, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.BLACK).boldOff().toString()); + this.replacements.put(ChatColor.DARK_BLUE, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.BLUE).boldOff().toString()); + this.replacements.put(ChatColor.DARK_GREEN, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.GREEN).boldOff().toString()); + this.replacements.put(ChatColor.DARK_AQUA, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.CYAN).boldOff().toString()); + this.replacements.put(ChatColor.DARK_RED, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.RED).boldOff().toString()); + this.replacements.put(ChatColor.DARK_PURPLE, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.MAGENTA).boldOff().toString()); + this.replacements.put(ChatColor.GOLD, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.YELLOW).boldOff().toString()); + this.replacements.put(ChatColor.GRAY, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.WHITE).boldOff().toString()); + this.replacements.put(ChatColor.DARK_GRAY, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.BLACK).bold().toString()); + this.replacements.put(ChatColor.BLUE, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.BLUE).bold().toString()); + this.replacements.put(ChatColor.GREEN, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.GREEN).bold().toString()); + this.replacements.put(ChatColor.AQUA, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.CYAN).bold().toString()); + this.replacements.put(ChatColor.RED, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.RED).bold().toString()); + this.replacements.put(ChatColor.LIGHT_PURPLE, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.MAGENTA).bold().toString()); + this.replacements.put(ChatColor.YELLOW, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.YELLOW).bold().toString()); + this.replacements.put(ChatColor.WHITE, Ansi.ansi().a(Ansi.Attribute.RESET).fg(Ansi.Color.WHITE).bold().toString()); + this.replacements.put(ChatColor.MAGIC, Ansi.ansi().a(Ansi.Attribute.BLINK_SLOW).toString()); + this.replacements.put(ChatColor.BOLD, Ansi.ansi().a(Ansi.Attribute.UNDERLINE_DOUBLE).toString()); + this.replacements.put(ChatColor.STRIKETHROUGH, Ansi.ansi().a(Ansi.Attribute.STRIKETHROUGH_ON).toString()); + this.replacements.put(ChatColor.UNDERLINE, Ansi.ansi().a(Ansi.Attribute.UNDERLINE).toString()); + this.replacements.put(ChatColor.ITALIC, Ansi.ansi().a(Ansi.Attribute.ITALIC).toString()); + this.replacements.put(ChatColor.RESET, Ansi.ansi().a(Ansi.Attribute.RESET).toString()); + } + + public void print(String s) { + for (final ChatColor color : this.colors) { + s = s.replaceAll("(?i)" + color.toString(), this.replacements.get(color)); + } + try { + this.console.print((CharSequence) ('\r' + s + Ansi.ansi().reset().toString())); + this.console.drawLine(); + this.console.flush(); + } catch (IOException ex) { + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/log/ConciseFormatter.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/log/ConciseFormatter.java new file mode 100644 index 0000000..7745629 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/log/ConciseFormatter.java @@ -0,0 +1,38 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.log; + +import java.io.Writer; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.logging.LogRecord; +import java.text.SimpleDateFormat; +import java.text.DateFormat; +import java.util.logging.Formatter; + +public class ConciseFormatter extends Formatter { + private final DateFormat date; + + public ConciseFormatter() { + this.date = new SimpleDateFormat("HH:mm:ss"); + } + + @Override + public String format(final LogRecord record) { + final StringBuilder formatted = new StringBuilder(); + formatted.append(this.date.format(record.getMillis())); + formatted.append(" ["); + formatted.append(record.getLevel().getLocalizedName()); + formatted.append("] "); + formatted.append(this.formatMessage(record)); + formatted.append('\n'); + if (record.getThrown() != null) { + final StringWriter writer = new StringWriter(); + record.getThrown().printStackTrace(new PrintWriter(writer)); + formatted.append(writer); + } + return formatted.toString(); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/log/LogDispatcher.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/log/LogDispatcher.java new file mode 100644 index 0000000..083841c --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/log/LogDispatcher.java @@ -0,0 +1,43 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.log; + +import java.util.Iterator; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.logging.LogRecord; +import java.util.concurrent.BlockingQueue; + +public class LogDispatcher extends Thread { + private final BungeeLogger logger; + private final BlockingQueue queue; + + public LogDispatcher(final BungeeLogger logger) { + super("BungeeCord Logger Thread - " + logger); + this.queue = new LinkedBlockingQueue(); + this.logger = logger; + } + + @Override + public void run() { + while (!this.isInterrupted()) { + LogRecord record; + try { + record = this.queue.take(); + } catch (InterruptedException ex) { + continue; + } + this.logger.doLog(record); + } + for (final LogRecord record2 : this.queue) { + this.logger.doLog(record2); + } + } + + public void queue(final LogRecord record) { + if (!this.isInterrupted()) { + this.queue.add(record); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/log/LoggingOutputStream.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/log/LoggingOutputStream.java new file mode 100644 index 0000000..c76b0a6 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/log/LoggingOutputStream.java @@ -0,0 +1,36 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.log; + +import java.beans.ConstructorProperties; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.io.ByteArrayOutputStream; + +public class LoggingOutputStream extends ByteArrayOutputStream { + private static final String separator; + private final Logger logger; + private final Level level; + + @Override + public void flush() throws IOException { + final String contents = this.toString(); + super.reset(); + if (!contents.isEmpty() && !contents.equals(LoggingOutputStream.separator)) { + this.logger.logp(this.level, "", "", contents); + } + } + + @ConstructorProperties({ "logger", "level" }) + public LoggingOutputStream(final Logger logger, final Level level) { + this.logger = logger; + this.level = level; + } + + static { + separator = System.getProperty("line.separator"); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java new file mode 100644 index 0000000..3430f00 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java @@ -0,0 +1,38 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.netty; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.Channel; + +public class ChannelWrapper { + private final Channel ch; + private volatile boolean closed; + + public ChannelWrapper(final ChannelHandlerContext ctx) { + this.ch = ctx.channel(); + } + + public synchronized void write(final Object packet) { + if (!this.closed) { + this.ch.write(packet); + } + } + + public synchronized void close() { + if (!this.closed) { + this.closed = true; + this.ch.close(); + } + } + + public Channel getHandle() { + return this.ch; + } + + public boolean isClosed() { + return this.closed; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/CipherBase.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/CipherBase.java new file mode 100644 index 0000000..92f2d81 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/CipherBase.java @@ -0,0 +1,65 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.netty; + +import java.beans.ConstructorProperties; +import javax.crypto.ShortBufferException; +import io.netty.channel.ChannelHandlerContext; +import io.netty.buffer.ByteBuf; +import javax.crypto.Cipher; + +public class CipherBase { + private final Cipher cipher; + private ThreadLocal heapInLocal; + private ThreadLocal heapOutLocal; + + private byte[] bufToByte(final ByteBuf in) { + byte[] heapIn = this.heapInLocal.get(); + final int readableBytes = in.readableBytes(); + if (heapIn.length < readableBytes) { + heapIn = new byte[readableBytes]; + this.heapInLocal.set(heapIn); + } + in.readBytes(heapIn, 0, readableBytes); + return heapIn; + } + + protected ByteBuf cipher(final ChannelHandlerContext ctx, final ByteBuf in) throws ShortBufferException { + final int readableBytes = in.readableBytes(); + final byte[] heapIn = this.bufToByte(in); + final ByteBuf heapOut = ctx.alloc().heapBuffer(this.cipher.getOutputSize(readableBytes)); + heapOut.writerIndex(this.cipher.update(heapIn, 0, readableBytes, heapOut.array(), heapOut.arrayOffset())); + return heapOut; + } + + protected void cipher(final ByteBuf in, final ByteBuf out) throws ShortBufferException { + final int readableBytes = in.readableBytes(); + final byte[] heapIn = this.bufToByte(in); + byte[] heapOut = this.heapOutLocal.get(); + final int outputSize = this.cipher.getOutputSize(readableBytes); + if (heapOut.length < outputSize) { + heapOut = new byte[outputSize]; + this.heapOutLocal.set(heapOut); + } + out.writeBytes(heapOut, 0, this.cipher.update(heapIn, 0, readableBytes, heapOut)); + } + + @ConstructorProperties({ "cipher" }) + protected CipherBase(final Cipher cipher) { + this.heapInLocal = new EmptyByteThreadLocal(); + this.heapOutLocal = new EmptyByteThreadLocal(); + if (cipher == null) { + throw new NullPointerException("cipher"); + } + this.cipher = cipher; + } + + private static class EmptyByteThreadLocal extends ThreadLocal { + @Override + protected byte[] initialValue() { + return new byte[0]; + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/CipherDecoder.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/CipherDecoder.java new file mode 100644 index 0000000..c2f03df --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/CipherDecoder.java @@ -0,0 +1,23 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.netty; + +import io.netty.channel.MessageList; +import io.netty.channel.ChannelHandlerContext; +import javax.crypto.Cipher; +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.MessageToMessageDecoder; + +public class CipherDecoder extends MessageToMessageDecoder { + private final CipherBase cipher; + + public CipherDecoder(final Cipher cipher) { + this.cipher = new CipherBase(cipher); + } + + protected void decode(final ChannelHandlerContext ctx, final ByteBuf msg, final MessageList out) throws Exception { + out.add((Object) this.cipher.cipher(ctx, msg)); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/CipherEncoder.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/CipherEncoder.java new file mode 100644 index 0000000..68184c1 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/CipherEncoder.java @@ -0,0 +1,22 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.netty; + +import io.netty.channel.ChannelHandlerContext; +import javax.crypto.Cipher; +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.MessageToByteEncoder; + +public class CipherEncoder extends MessageToByteEncoder { + private final CipherBase cipher; + + public CipherEncoder(final Cipher cipher) { + this.cipher = new CipherBase(cipher); + } + + protected void encode(final ChannelHandlerContext ctx, final ByteBuf in, final ByteBuf out) throws Exception { + this.cipher.cipher(in, out); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/DefinedPacketEncoder.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/DefinedPacketEncoder.java new file mode 100644 index 0000000..da47687 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/DefinedPacketEncoder.java @@ -0,0 +1,19 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.netty; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelHandler; +import net.md_5.bungee.protocol.packet.DefinedPacket; +import io.netty.handler.codec.MessageToByteEncoder; + +@ChannelHandler.Sharable +public class DefinedPacketEncoder extends MessageToByteEncoder { + protected void encode(final ChannelHandlerContext ctx, final DefinedPacket msg, final ByteBuf out) throws Exception { + out.writeByte(msg.getId()); + msg.write(out); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/HandlerBoss.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/HandlerBoss.java new file mode 100644 index 0000000..4d432e9 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/HandlerBoss.java @@ -0,0 +1,89 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.netty; + +import java.io.IOException; +import io.netty.handler.timeout.ReadTimeoutException; +import java.util.Iterator; +import net.md_5.bungee.connection.CancelSendSignal; +import net.md_5.bungee.protocol.packet.AbstractPacketHandler; +import io.netty.channel.MessageList; +import java.util.logging.Level; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.connection.PingHandler; +import net.md_5.bungee.connection.InitialHandler; +import io.netty.channel.ChannelHandlerContext; +import com.google.common.base.Preconditions; +import io.netty.channel.ChannelInboundHandlerAdapter; + +public class HandlerBoss extends ChannelInboundHandlerAdapter { + private ChannelWrapper channel; + private PacketHandler handler; + + public void setHandler(final PacketHandler handler) { + Preconditions.checkArgument(handler != null, (Object) "handler"); + this.handler = handler; + } + + public void channelActive(final ChannelHandlerContext ctx) throws Exception { + if (this.handler != null) { + this.channel = new ChannelWrapper(ctx); + this.handler.connected(this.channel); + if (!(this.handler instanceof InitialHandler) && !(this.handler instanceof PingHandler)) { + ProxyServer.getInstance().getLogger().log(Level.INFO, "{0} has connected", this.handler); + } + } + } + + public void channelInactive(final ChannelHandlerContext ctx) throws Exception { + if (this.handler != null) { + this.handler.disconnected(this.channel); + if (!(this.handler instanceof InitialHandler) && !(this.handler instanceof PingHandler)) { + ProxyServer.getInstance().getLogger().log(Level.INFO, "{0} has disconnected", this.handler); + } + } + } + + public void messageReceived(final ChannelHandlerContext ctx, final MessageList msgs) throws Exception { + for (final Object msg : msgs) { + if (this.handler != null && ctx.channel().isActive()) { + if (msg instanceof PacketWrapper) { + boolean sendPacket = true; + try { + ((PacketWrapper) msg).packet.handle(this.handler); + } catch (CancelSendSignal ex) { + sendPacket = false; + } + if (!sendPacket) { + continue; + } + this.handler.handle(((PacketWrapper) msg).buf); + } else { + this.handler.handle((byte[]) msg); + } + } + } + } + + public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) throws Exception { + if (ctx.channel().isActive()) { + if (cause instanceof ReadTimeoutException) { + ProxyServer.getInstance().getLogger().log(Level.WARNING, this.handler + " - read timed out"); + } else if (cause instanceof IOException) { + ProxyServer.getInstance().getLogger().log(Level.WARNING, this.handler + " - IOException: " + cause.getMessage()); + } else { + ProxyServer.getInstance().getLogger().log(Level.SEVERE, this.handler + " - encountered exception", cause); + } + if (this.handler != null) { + try { + this.handler.exception(cause); + } catch (Exception ex) { + ProxyServer.getInstance().getLogger().log(Level.SEVERE, this.handler + " - exception processing exception", ex); + } + } + ctx.close(); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/PacketDecoder.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/PacketDecoder.java new file mode 100644 index 0000000..d7f60bc --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/PacketDecoder.java @@ -0,0 +1,48 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.netty; + +import java.beans.ConstructorProperties; +import net.md_5.bungee.protocol.packet.DefinedPacket; +import io.netty.channel.MessageList; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import net.md_5.bungee.protocol.Protocol; +import io.netty.handler.codec.ReplayingDecoder; + +public class PacketDecoder extends ReplayingDecoder { + private Protocol protocol; + + protected void decode(final ChannelHandlerContext ctx, final ByteBuf in, final MessageList out) throws Exception { + while (true) { + final int startIndex = in.readerIndex(); + final DefinedPacket packet = this.protocol.read(in.readUnsignedByte(), in); + final int endIndex = in.readerIndex(); + final byte[] buf = new byte[endIndex - startIndex]; + in.readerIndex(startIndex); + in.readBytes(buf, 0, buf.length); + in.readerIndex(endIndex); + this.checkpoint(); + if (packet != null) { + out.add((Object) new PacketWrapper(packet, buf)); + } else { + out.add((Object) buf); + } + } + } + + @ConstructorProperties({ "protocol" }) + public PacketDecoder(final Protocol protocol) { + this.protocol = protocol; + } + + public Protocol getProtocol() { + return this.protocol; + } + + public void setProtocol(final Protocol protocol) { + this.protocol = protocol; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/PacketHandler.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/PacketHandler.java new file mode 100644 index 0000000..acb24ac --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/PacketHandler.java @@ -0,0 +1,24 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.netty; + +import net.md_5.bungee.protocol.packet.AbstractPacketHandler; + +public abstract class PacketHandler extends AbstractPacketHandler { + @Override + public abstract String toString(); + + public void exception(final Throwable t) throws Exception { + } + + public void handle(final byte[] buf) throws Exception { + } + + public void connected(final ChannelWrapper channel) throws Exception { + } + + public void disconnected(final ChannelWrapper channel) throws Exception { + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/PacketWrapper.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/PacketWrapper.java new file mode 100644 index 0000000..5f2c1f0 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/PacketWrapper.java @@ -0,0 +1,17 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.netty; + +import net.md_5.bungee.protocol.packet.DefinedPacket; + +public class PacketWrapper { + DefinedPacket packet; + byte[] buf; + + public PacketWrapper(final DefinedPacket packet, final byte[] buf) { + this.packet = packet; + this.buf = buf; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/PipelineUtils.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/PipelineUtils.java new file mode 100644 index 0000000..23e6333 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/netty/PipelineUtils.java @@ -0,0 +1,85 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.netty; + +import net.md_5.bungee.protocol.Protocol; +import net.md_5.bungee.protocol.Vanilla; +import io.netty.channel.ChannelHandler; +import io.netty.handler.timeout.ReadTimeoutHandler; +import java.util.concurrent.TimeUnit; +import net.md_5.bungee.BungeeCord; +import io.netty.channel.ChannelException; +import io.netty.channel.ChannelOption; +import net.md_5.bungee.ServerConnector; +import net.md_5.bungee.connection.InitialHandler; +import net.md_5.bungee.api.ProxyServer; +import io.netty.handler.codec.bytes.ByteArrayEncoder; +import io.netty.channel.Channel; +import io.netty.channel.ChannelInitializer; +import net.md_5.bungee.BungeeServerInfo; +import net.md_5.bungee.UserConnection; +import net.md_5.bungee.api.config.ListenerInfo; +import io.netty.util.AttributeKey; + +public class PipelineUtils { + public static final AttributeKey LISTENER; + public static final AttributeKey USER; + public static final AttributeKey TARGET; + public static final ChannelInitializer SERVER_CHILD; + public static final ChannelInitializer CLIENT; + public static final Base BASE; + private static final DefinedPacketEncoder packetEncoder; + private static final ByteArrayEncoder arrayEncoder; + public static String TIMEOUT_HANDLER; + public static String PACKET_DECODE_HANDLER; + public static String PACKET_ENCODE_HANDLER; + public static String ARRAY_ENCODE_HANDLER; + public static String BOSS_HANDLER; + public static String ENCRYPT_HANDLER; + public static String DECRYPT_HANDLER; + + static { + LISTENER = new AttributeKey("ListerInfo"); + USER = new AttributeKey("User"); + TARGET = new AttributeKey("Target"); + SERVER_CHILD = new ChannelInitializer() { + protected void initChannel(final Channel ch) throws Exception { + PipelineUtils.BASE.initChannel(ch); + ((HandlerBoss) ch.pipeline().get((Class) HandlerBoss.class)).setHandler(new InitialHandler(ProxyServer.getInstance(), (ListenerInfo) ch.attr((AttributeKey) PipelineUtils.LISTENER).get())); + } + }; + CLIENT = new ChannelInitializer() { + protected void initChannel(final Channel ch) throws Exception { + PipelineUtils.BASE.initChannel(ch); + ((HandlerBoss) ch.pipeline().get((Class) HandlerBoss.class)) + .setHandler(new ServerConnector(ProxyServer.getInstance(), (UserConnection) ch.attr((AttributeKey) PipelineUtils.USER).get(), (BungeeServerInfo) ch.attr((AttributeKey) PipelineUtils.TARGET).get())); + } + }; + BASE = new Base(); + packetEncoder = new DefinedPacketEncoder(); + arrayEncoder = new ByteArrayEncoder(); + PipelineUtils.TIMEOUT_HANDLER = "timeout"; + PipelineUtils.PACKET_DECODE_HANDLER = "packet-decoder"; + PipelineUtils.PACKET_ENCODE_HANDLER = "packet-encoder"; + PipelineUtils.ARRAY_ENCODE_HANDLER = "array-encoder"; + PipelineUtils.BOSS_HANDLER = "inbound-boss"; + PipelineUtils.ENCRYPT_HANDLER = "encrypt"; + PipelineUtils.DECRYPT_HANDLER = "decrypt"; + } + + public static final class Base extends ChannelInitializer { + public void initChannel(final Channel ch) throws Exception { + try { + ch.config().setOption(ChannelOption.IP_TOS, Integer.valueOf(24)); + } catch (ChannelException ex) { + } + ch.pipeline().addLast(PipelineUtils.TIMEOUT_HANDLER, (ChannelHandler) new ReadTimeoutHandler((long) BungeeCord.getInstance().config.getTimeout(), TimeUnit.MILLISECONDS)); + ch.pipeline().addLast(PipelineUtils.PACKET_DECODE_HANDLER, (ChannelHandler) new PacketDecoder(Vanilla.getInstance())); + ch.pipeline().addLast(PipelineUtils.PACKET_ENCODE_HANDLER, (ChannelHandler) PipelineUtils.packetEncoder); + ch.pipeline().addLast(PipelineUtils.ARRAY_ENCODE_HANDLER, (ChannelHandler) PipelineUtils.arrayEncoder); + ch.pipeline().addLast(PipelineUtils.BOSS_HANDLER, (ChannelHandler) new HandlerBoss()); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/Forge.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/Forge.java new file mode 100644 index 0000000..a568d77 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/Forge.java @@ -0,0 +1,37 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol; + +import net.md_5.bungee.protocol.packet.DefinedPacket; +import io.netty.buffer.ByteBuf; +import net.md_5.bungee.protocol.skip.PacketReader; +import net.md_5.bungee.protocol.packet.forge.Forge1Login; + +public class Forge extends Vanilla { + private static final Forge instance; + + public Forge() { + this.classes[1] = Forge1Login.class; + this.skipper = new PacketReader(this); + } + + @Override + public DefinedPacket read(final short packetId, final ByteBuf buf) { + final int start = buf.readerIndex(); + DefinedPacket packet = Vanilla.read(packetId, buf, this); + if (buf.readerIndex() == start) { + packet = super.read(packetId, buf); + } + return packet; + } + + public static Forge getInstance() { + return Forge.instance; + } + + static { + instance = new Forge(); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/OpCode.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/OpCode.java new file mode 100644 index 0000000..df1a39b --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/OpCode.java @@ -0,0 +1,9 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol; + +public enum OpCode { + BOOLEAN, BULK_CHUNK, BYTE, BYTE_INT, DOUBLE, FLOAT, INT, INT_3, INT_BYTE, ITEM, LONG, METADATA, OPTIONAL_MOTION, SHORT, SHORT_BYTE, SHORT_ITEM, STRING, USHORT_BYTE; +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/Protocol.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/Protocol.java new file mode 100644 index 0000000..f4eb7e5 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/Protocol.java @@ -0,0 +1,22 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol; + +import java.lang.reflect.Constructor; +import net.md_5.bungee.protocol.packet.DefinedPacket; +import io.netty.buffer.ByteBuf; +import net.md_5.bungee.protocol.skip.PacketReader; + +public interface Protocol { + PacketReader getSkipper(); + + DefinedPacket read(final short p0, final ByteBuf p1); + + OpCode[][] getOpCodes(); + + Class[] getClasses(); + + Constructor[] getConstructors(); +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/Vanilla.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/Vanilla.java new file mode 100644 index 0000000..c519126 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/Vanilla.java @@ -0,0 +1,198 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol; + +import java.lang.reflect.InvocationTargetException; +import io.netty.buffer.ByteBuf; +import net.md_5.bungee.protocol.packet.PacketFFKick; +import net.md_5.bungee.protocol.packet.PacketFEPing; +import net.md_5.bungee.protocol.packet.PacketFDEncryptionRequest; +import net.md_5.bungee.protocol.packet.PacketFCEncryptionResponse; +import net.md_5.bungee.protocol.packet.PacketFAPluginMessage; +import net.md_5.bungee.protocol.packet.PacketD1Team; +import net.md_5.bungee.protocol.packet.PacketD0DisplayScoreboard; +import net.md_5.bungee.protocol.packet.PacketCFScoreboardScore; +import net.md_5.bungee.protocol.packet.PacketCEScoreboardObjective; +import net.md_5.bungee.protocol.packet.PacketCDClientStatus; +import net.md_5.bungee.protocol.packet.PacketCCSettings; +import net.md_5.bungee.protocol.packet.PacketC9PlayerListItem; +import net.md_5.bungee.protocol.packet.Packet9Respawn; +import net.md_5.bungee.protocol.packet.Packet3Chat; +import net.md_5.bungee.protocol.packet.Packet2Handshake; +import net.md_5.bungee.protocol.packet.Packet1Login; +import net.md_5.bungee.protocol.packet.Packet0KeepAlive; +import net.md_5.bungee.protocol.skip.PacketReader; +import java.lang.reflect.Constructor; +import net.md_5.bungee.protocol.packet.DefinedPacket; + +public class Vanilla implements Protocol { + public static final byte PROTOCOL_VERSION = 61; + public static final String GAME_VERSION = "1.5.2"; + private static final Vanilla instance; + private final OpCode[][] opCodes; + protected Class[] classes; + private Constructor[] constructors; + protected PacketReader skipper; + + public Vanilla() { + this.opCodes = new OpCode[256][]; + this.classes = (Class[]) new Class[256]; + this.constructors = (Constructor[]) new Constructor[256]; + this.opCodes[4] = new OpCode[] { OpCode.LONG, OpCode.LONG }; + this.opCodes[5] = new OpCode[] { OpCode.INT, OpCode.SHORT, OpCode.ITEM }; + this.opCodes[6] = new OpCode[] { OpCode.INT, OpCode.INT, OpCode.INT }; + this.opCodes[7] = new OpCode[] { OpCode.INT, OpCode.INT, OpCode.BOOLEAN }; + this.opCodes[8] = new OpCode[] { OpCode.SHORT, OpCode.SHORT, OpCode.FLOAT }; + this.opCodes[10] = new OpCode[] { OpCode.BOOLEAN }; + this.opCodes[11] = new OpCode[] { OpCode.DOUBLE, OpCode.DOUBLE, OpCode.DOUBLE, OpCode.DOUBLE, OpCode.BOOLEAN }; + this.opCodes[12] = new OpCode[] { OpCode.FLOAT, OpCode.FLOAT, OpCode.BOOLEAN }; + this.opCodes[13] = new OpCode[] { OpCode.DOUBLE, OpCode.DOUBLE, OpCode.DOUBLE, OpCode.DOUBLE, OpCode.FLOAT, OpCode.FLOAT, OpCode.BOOLEAN }; + this.opCodes[14] = new OpCode[] { OpCode.BYTE, OpCode.INT, OpCode.BYTE, OpCode.INT, OpCode.BYTE }; + this.opCodes[15] = new OpCode[] { OpCode.INT, OpCode.BYTE, OpCode.INT, OpCode.BYTE, OpCode.ITEM, OpCode.BYTE, OpCode.BYTE, OpCode.BYTE }; + this.opCodes[16] = new OpCode[] { OpCode.SHORT }; + this.opCodes[17] = new OpCode[] { OpCode.INT, OpCode.BYTE, OpCode.INT, OpCode.BYTE, OpCode.INT }; + this.opCodes[18] = new OpCode[] { OpCode.INT, OpCode.BYTE }; + this.opCodes[19] = new OpCode[] { OpCode.INT, OpCode.BYTE }; + this.opCodes[20] = new OpCode[] { OpCode.INT, OpCode.STRING, OpCode.INT, OpCode.INT, OpCode.INT, OpCode.BYTE, OpCode.BYTE, OpCode.SHORT, OpCode.METADATA }; + this.opCodes[22] = new OpCode[] { OpCode.INT, OpCode.INT }; + this.opCodes[23] = new OpCode[] { OpCode.INT, OpCode.BYTE, OpCode.INT, OpCode.INT, OpCode.INT, OpCode.BYTE, OpCode.BYTE, OpCode.OPTIONAL_MOTION }; + this.opCodes[24] = new OpCode[] { OpCode.INT, OpCode.BYTE, OpCode.INT, OpCode.INT, OpCode.INT, OpCode.BYTE, OpCode.BYTE, OpCode.BYTE, OpCode.SHORT, OpCode.SHORT, OpCode.SHORT, OpCode.METADATA }; + this.opCodes[25] = new OpCode[] { OpCode.INT, OpCode.STRING, OpCode.INT, OpCode.INT, OpCode.INT, OpCode.INT }; + this.opCodes[26] = new OpCode[] { OpCode.INT, OpCode.INT, OpCode.INT, OpCode.INT, OpCode.SHORT }; + this.opCodes[28] = new OpCode[] { OpCode.INT, OpCode.SHORT, OpCode.SHORT, OpCode.SHORT }; + this.opCodes[29] = new OpCode[] { OpCode.BYTE_INT }; + this.opCodes[30] = new OpCode[] { OpCode.INT }; + this.opCodes[31] = new OpCode[] { OpCode.INT, OpCode.BYTE, OpCode.BYTE, OpCode.BYTE }; + this.opCodes[32] = new OpCode[] { OpCode.INT, OpCode.BYTE, OpCode.BYTE }; + this.opCodes[33] = new OpCode[] { OpCode.INT, OpCode.BYTE, OpCode.BYTE, OpCode.BYTE, OpCode.BYTE, OpCode.BYTE }; + this.opCodes[34] = new OpCode[] { OpCode.INT, OpCode.INT, OpCode.INT, OpCode.INT, OpCode.BYTE, OpCode.BYTE }; + this.opCodes[35] = new OpCode[] { OpCode.INT, OpCode.BYTE }; + this.opCodes[38] = new OpCode[] { OpCode.INT, OpCode.BYTE }; + this.opCodes[39] = new OpCode[] { OpCode.INT, OpCode.INT }; + this.opCodes[40] = new OpCode[] { OpCode.INT, OpCode.METADATA }; + this.opCodes[41] = new OpCode[] { OpCode.INT, OpCode.BYTE, OpCode.BYTE, OpCode.SHORT }; + this.opCodes[42] = new OpCode[] { OpCode.INT, OpCode.BYTE }; + this.opCodes[43] = new OpCode[] { OpCode.FLOAT, OpCode.SHORT, OpCode.SHORT }; + this.opCodes[51] = new OpCode[] { OpCode.INT, OpCode.INT, OpCode.BOOLEAN, OpCode.SHORT, OpCode.SHORT, OpCode.INT_BYTE }; + this.opCodes[52] = new OpCode[] { OpCode.INT, OpCode.INT, OpCode.SHORT, OpCode.INT_BYTE }; + this.opCodes[53] = new OpCode[] { OpCode.INT, OpCode.BYTE, OpCode.INT, OpCode.SHORT, OpCode.BYTE }; + this.opCodes[54] = new OpCode[] { OpCode.INT, OpCode.SHORT, OpCode.INT, OpCode.BYTE, OpCode.BYTE, OpCode.SHORT }; + this.opCodes[55] = new OpCode[] { OpCode.INT, OpCode.INT, OpCode.INT, OpCode.INT, OpCode.BYTE }; + this.opCodes[56] = new OpCode[] { OpCode.BULK_CHUNK }; + this.opCodes[60] = new OpCode[] { OpCode.DOUBLE, OpCode.DOUBLE, OpCode.DOUBLE, OpCode.FLOAT, OpCode.INT_3, OpCode.FLOAT, OpCode.FLOAT, OpCode.FLOAT }; + this.opCodes[61] = new OpCode[] { OpCode.INT, OpCode.INT, OpCode.BYTE, OpCode.INT, OpCode.INT, OpCode.BOOLEAN }; + this.opCodes[62] = new OpCode[] { OpCode.STRING, OpCode.INT, OpCode.INT, OpCode.INT, OpCode.FLOAT, OpCode.BYTE }; + this.opCodes[63] = new OpCode[] { OpCode.STRING, OpCode.FLOAT, OpCode.FLOAT, OpCode.FLOAT, OpCode.FLOAT, OpCode.FLOAT, OpCode.FLOAT, OpCode.FLOAT, OpCode.INT }; + this.opCodes[70] = new OpCode[] { OpCode.BYTE, OpCode.BYTE }; + this.opCodes[71] = new OpCode[] { OpCode.INT, OpCode.BYTE, OpCode.INT, OpCode.INT, OpCode.INT }; + this.opCodes[100] = new OpCode[] { OpCode.BYTE, OpCode.BYTE, OpCode.STRING, OpCode.BYTE, OpCode.BOOLEAN }; + this.opCodes[101] = new OpCode[] { OpCode.BYTE }; + this.opCodes[102] = new OpCode[] { OpCode.BYTE, OpCode.SHORT, OpCode.BYTE, OpCode.SHORT, OpCode.BOOLEAN, OpCode.ITEM }; + this.opCodes[103] = new OpCode[] { OpCode.BYTE, OpCode.SHORT, OpCode.ITEM }; + this.opCodes[104] = new OpCode[] { OpCode.BYTE, OpCode.SHORT_ITEM }; + this.opCodes[105] = new OpCode[] { OpCode.BYTE, OpCode.SHORT, OpCode.SHORT }; + this.opCodes[106] = new OpCode[] { OpCode.BYTE, OpCode.SHORT, OpCode.BOOLEAN }; + this.opCodes[107] = new OpCode[] { OpCode.SHORT, OpCode.ITEM }; + this.opCodes[108] = new OpCode[] { OpCode.BYTE, OpCode.BYTE }; + this.opCodes[130] = new OpCode[] { OpCode.INT, OpCode.SHORT, OpCode.INT, OpCode.STRING, OpCode.STRING, OpCode.STRING, OpCode.STRING }; + this.opCodes[131] = new OpCode[] { OpCode.SHORT, OpCode.SHORT, OpCode.USHORT_BYTE }; + this.opCodes[132] = new OpCode[] { OpCode.INT, OpCode.SHORT, OpCode.INT, OpCode.BYTE, OpCode.SHORT_BYTE }; + this.opCodes[195] = new OpCode[] { OpCode.SHORT, OpCode.SHORT, OpCode.INT_BYTE }; + this.opCodes[200] = new OpCode[] { OpCode.INT, OpCode.BYTE }; + this.opCodes[202] = new OpCode[] { OpCode.BYTE, OpCode.BYTE, OpCode.BYTE }; + this.opCodes[203] = new OpCode[] { OpCode.STRING }; + this.classes[0] = Packet0KeepAlive.class; + this.classes[1] = Packet1Login.class; + this.classes[2] = Packet2Handshake.class; + this.classes[3] = Packet3Chat.class; + this.classes[9] = Packet9Respawn.class; + this.classes[201] = PacketC9PlayerListItem.class; + this.classes[204] = PacketCCSettings.class; + this.classes[205] = PacketCDClientStatus.class; + this.classes[206] = PacketCEScoreboardObjective.class; + this.classes[207] = PacketCFScoreboardScore.class; + this.classes[208] = PacketD0DisplayScoreboard.class; + this.classes[209] = PacketD1Team.class; + this.classes[250] = PacketFAPluginMessage.class; + this.classes[252] = PacketFCEncryptionResponse.class; + this.classes[253] = PacketFDEncryptionRequest.class; + this.classes[254] = PacketFEPing.class; + this.classes[255] = PacketFFKick.class; + this.skipper = new PacketReader(this); + } + + @Override + public DefinedPacket read(final short packetId, final ByteBuf buf) { + final int start = buf.readerIndex(); + final DefinedPacket packet = read(packetId, buf, this); + if (buf.readerIndex() == start) { + throw new RuntimeException("Unknown packet id " + packetId); + } + return packet; + } + + public static DefinedPacket read(final short id, final ByteBuf buf, final Protocol protocol) { + final DefinedPacket packet = packet(id, protocol); + if (packet != null) { + packet.read(buf); + return packet; + } + protocol.getSkipper().tryRead(id, buf); + return null; + } + + public static DefinedPacket packet(final short id, final Protocol protocol) { + DefinedPacket ret = null; + final Class clazz = protocol.getClasses()[id]; + if (clazz != null) { + try { + Constructor constructor = protocol.getConstructors()[id]; + if (constructor == null) { + constructor = clazz.getDeclaredConstructor((Class[]) new Class[0]); + constructor.setAccessible(true); + protocol.getConstructors()[id] = constructor; + } + if (constructor != null) { + ret = (DefinedPacket) constructor.newInstance(new Object[0]); + } + } catch (NoSuchMethodException ex) { + } catch (SecurityException ex2) { + } catch (InstantiationException ex3) { + } catch (IllegalAccessException ex4) { + } catch (IllegalArgumentException ex5) { + } catch (InvocationTargetException ex6) { + } + } + return ret; + } + + public static Vanilla getInstance() { + return Vanilla.instance; + } + + @Override + public OpCode[][] getOpCodes() { + return this.opCodes; + } + + @Override + public Class[] getClasses() { + return this.classes; + } + + @Override + public Constructor[] getConstructors() { + return this.constructors; + } + + @Override + public PacketReader getSkipper() { + return this.skipper; + } + + static { + instance = new Vanilla(); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/AbstractPacketHandler.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/AbstractPacketHandler.java new file mode 100644 index 0000000..855560a --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/AbstractPacketHandler.java @@ -0,0 +1,58 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +public abstract class AbstractPacketHandler { + public void handle(final Packet0KeepAlive alive) throws Exception { + } + + public void handle(final Packet1Login login) throws Exception { + } + + public void handle(final Packet2Handshake handshake) throws Exception { + } + + public void handle(final Packet3Chat chat) throws Exception { + } + + public void handle(final Packet9Respawn respawn) throws Exception { + } + + public void handle(final PacketC9PlayerListItem playerList) throws Exception { + } + + public void handle(final PacketCCSettings settings) throws Exception { + } + + public void handle(final PacketCDClientStatus clientStatus) throws Exception { + } + + public void handle(final PacketCEScoreboardObjective objective) throws Exception { + } + + public void handle(final PacketCFScoreboardScore score) throws Exception { + } + + public void handle(final PacketD0DisplayScoreboard displayScoreboard) throws Exception { + } + + public void handle(final PacketD1Team team) throws Exception { + } + + public void handle(final PacketFAPluginMessage pluginMessage) throws Exception { + } + + public void handle(final PacketFCEncryptionResponse encryptResponse) throws Exception { + } + + public void handle(final PacketFDEncryptionRequest encryptRequest) throws Exception { + } + + public void handle(final PacketFEPing ping) throws Exception { + } + + public void handle(final PacketFFKick kick) throws Exception { + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/DefinedPacket.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/DefinedPacket.java new file mode 100644 index 0000000..56529e8 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/DefinedPacket.java @@ -0,0 +1,64 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import java.beans.ConstructorProperties; +import io.netty.buffer.ByteBuf; + +public abstract class DefinedPacket { + private final int id; + + public final int getId() { + return this.id; + } + + public void writeString(final String s, final ByteBuf buf) { + buf.writeShort(s.length()); + for (final char c : s.toCharArray()) { + buf.writeChar((int) c); + } + } + + public String readString(final ByteBuf buf) { + final short len = buf.readShort(); + final char[] chars = new char[len]; + for (int i = 0; i < len; ++i) { + chars[i] = buf.readChar(); + } + return new String(chars); + } + + public void writeArray(final byte[] b, final ByteBuf buf) { + buf.writeShort(b.length); + buf.writeBytes(b); + } + + public byte[] readArray(final ByteBuf buf) { + final short len = buf.readShort(); + final byte[] ret = new byte[len]; + buf.readBytes(ret); + return ret; + } + + public abstract void read(final ByteBuf p0); + + public abstract void write(final ByteBuf p0); + + public abstract void handle(final AbstractPacketHandler p0) throws Exception; + + @Override + public abstract boolean equals(final Object p0); + + @Override + public abstract int hashCode(); + + @Override + public abstract String toString(); + + @ConstructorProperties({ "id" }) + public DefinedPacket(final int id) { + this.id = id; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/Packet0KeepAlive.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/Packet0KeepAlive.java new file mode 100644 index 0000000..2ce22fd --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/Packet0KeepAlive.java @@ -0,0 +1,63 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; + +public class Packet0KeepAlive extends DefinedPacket { + private int randomId; + + private Packet0KeepAlive() { + super(0); + } + + @Override + public void read(final ByteBuf buf) { + this.randomId = buf.readInt(); + } + + @Override + public void write(final ByteBuf buf) { + buf.writeInt(this.randomId); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + public int getRandomId() { + return this.randomId; + } + + @Override + public String toString() { + return "Packet0KeepAlive(randomId=" + this.getRandomId() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Packet0KeepAlive)) { + return false; + } + final Packet0KeepAlive other = (Packet0KeepAlive) o; + return other.canEqual(this) && this.getRandomId() == other.getRandomId(); + } + + public boolean canEqual(final Object other) { + return other instanceof Packet0KeepAlive; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = result * 31 + this.getRandomId(); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/Packet1Login.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/Packet1Login.java new file mode 100644 index 0000000..486956b --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/Packet1Login.java @@ -0,0 +1,145 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; + +public class Packet1Login extends DefinedPacket { + protected int entityId; + protected String levelType; + protected byte gameMode; + protected int dimension; + protected byte difficulty; + protected byte unused; + protected byte maxPlayers; + + protected Packet1Login() { + super(1); + } + + public Packet1Login(final int entityId, final String levelType, final byte gameMode, final byte dimension, final byte difficulty, final byte unused, final byte maxPlayers) { + this(entityId, levelType, gameMode, (int) dimension, difficulty, unused, maxPlayers); + } + + public Packet1Login(final int entityId, final String levelType, final byte gameMode, final int dimension, final byte difficulty, final byte unused, final byte maxPlayers) { + this(); + this.entityId = entityId; + this.levelType = levelType; + this.gameMode = gameMode; + this.dimension = dimension; + this.difficulty = difficulty; + this.unused = unused; + this.maxPlayers = maxPlayers; + } + + @Override + public void read(final ByteBuf buf) { + this.entityId = buf.readInt(); + this.levelType = this.readString(buf); + this.gameMode = buf.readByte(); + this.dimension = buf.readByte(); + this.difficulty = buf.readByte(); + this.unused = buf.readByte(); + this.maxPlayers = buf.readByte(); + } + + @Override + public void write(final ByteBuf buf) { + buf.writeInt(this.entityId); + this.writeString(this.levelType, buf); + buf.writeByte((int) this.gameMode); + buf.writeByte(this.dimension); + buf.writeByte((int) this.difficulty); + buf.writeByte((int) this.unused); + buf.writeByte((int) this.maxPlayers); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + public int getEntityId() { + return this.entityId; + } + + public String getLevelType() { + return this.levelType; + } + + public byte getGameMode() { + return this.gameMode; + } + + public int getDimension() { + return this.dimension; + } + + public byte getDifficulty() { + return this.difficulty; + } + + public byte getUnused() { + return this.unused; + } + + public byte getMaxPlayers() { + return this.maxPlayers; + } + + @Override + public String toString() { + return "Packet1Login(entityId=" + this.getEntityId() + ", levelType=" + this.getLevelType() + ", gameMode=" + this.getGameMode() + ", dimension=" + this.getDimension() + ", difficulty=" + this.getDifficulty() + ", unused=" + + this.getUnused() + ", maxPlayers=" + this.getMaxPlayers() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Packet1Login)) { + return false; + } + final Packet1Login other = (Packet1Login) o; + if (!other.canEqual(this)) { + return false; + } + if (this.getEntityId() != other.getEntityId()) { + return false; + } + final Object this$levelType = this.getLevelType(); + final Object other$levelType = other.getLevelType(); + if (this$levelType == null) { + if (other$levelType == null) { + return this.getGameMode() == other.getGameMode() && this.getDimension() == other.getDimension() && this.getDifficulty() == other.getDifficulty() && this.getUnused() == other.getUnused() + && this.getMaxPlayers() == other.getMaxPlayers(); + } + } else if (this$levelType.equals(other$levelType)) { + return this.getGameMode() == other.getGameMode() && this.getDimension() == other.getDimension() && this.getDifficulty() == other.getDifficulty() && this.getUnused() == other.getUnused() + && this.getMaxPlayers() == other.getMaxPlayers(); + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof Packet1Login; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = result * 31 + this.getEntityId(); + final Object $levelType = this.getLevelType(); + result = result * 31 + (($levelType == null) ? 0 : $levelType.hashCode()); + result = result * 31 + this.getGameMode(); + result = result * 31 + this.getDimension(); + result = result * 31 + this.getDifficulty(); + result = result * 31 + this.getUnused(); + result = result * 31 + this.getMaxPlayers(); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/Packet2Handshake.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/Packet2Handshake.java new file mode 100644 index 0000000..2a28d0b --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/Packet2Handshake.java @@ -0,0 +1,120 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; + +public class Packet2Handshake extends DefinedPacket { + private byte procolVersion; + private String username; + private String host; + private int port; + + private Packet2Handshake() { + super(2); + } + + @Override + public void read(final ByteBuf buf) { + this.procolVersion = buf.readByte(); + this.username = this.readString(buf); + this.host = this.readString(buf); + this.port = buf.readInt(); + } + + @Override + public void write(final ByteBuf buf) { + buf.writeByte((int) this.procolVersion); + this.writeString(this.username, buf); + this.writeString(this.host, buf); + buf.writeInt(this.port); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + public byte getProcolVersion() { + return this.procolVersion; + } + + public void swapProtocol(byte b) { + this.procolVersion = (byte)b; + } + + public String getUsername() { + return this.username; + } + + public String getHost() { + return this.host; + } + + public int getPort() { + return this.port; + } + + @Override + public String toString() { + return "Packet2Handshake(procolVersion=" + this.getProcolVersion() + ", username=" + this.getUsername() + ", host=" + this.getHost() + ", port=" + this.getPort() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Packet2Handshake)) { + return false; + } + final Packet2Handshake other = (Packet2Handshake) o; + if (!other.canEqual(this)) { + return false; + } + if (this.getProcolVersion() != other.getProcolVersion()) { + return false; + } + final Object this$username = this.getUsername(); + final Object other$username = other.getUsername(); + Label_0078: { + if (this$username == null) { + if (other$username == null) { + break Label_0078; + } + } else if (this$username.equals(other$username)) { + break Label_0078; + } + return false; + } + final Object this$host = this.getHost(); + final Object other$host = other.getHost(); + if (this$host == null) { + if (other$host == null) { + return this.getPort() == other.getPort(); + } + } else if (this$host.equals(other$host)) { + return this.getPort() == other.getPort(); + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof Packet2Handshake; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = result * 31 + this.getProcolVersion(); + final Object $username = this.getUsername(); + result = result * 31 + (($username == null) ? 0 : $username.hashCode()); + final Object $host = this.getHost(); + result = result * 31 + (($host == null) ? 0 : $host.hashCode()); + result = result * 31 + this.getPort(); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/Packet3Chat.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/Packet3Chat.java new file mode 100644 index 0000000..71d2cd1 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/Packet3Chat.java @@ -0,0 +1,81 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; + +public class Packet3Chat extends DefinedPacket { + private String message; + + private Packet3Chat() { + super(3); + } + + public Packet3Chat(final String message) { + this(); + this.message = message; + } + + @Override + public void read(final ByteBuf buf) { + this.message = this.readString(buf); + } + + @Override + public void write(final ByteBuf buf) { + this.writeString(this.message, buf); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + public String getMessage() { + return this.message; + } + + @Override + public String toString() { + return "Packet3Chat(message=" + this.getMessage() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Packet3Chat)) { + return false; + } + final Packet3Chat other = (Packet3Chat) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$message = this.getMessage(); + final Object other$message = other.getMessage(); + if (this$message == null) { + if (other$message == null) { + return true; + } + } else if (this$message.equals(other$message)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof Packet3Chat; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $message = this.getMessage(); + result = result * 31 + (($message == null) ? 0 : $message.hashCode()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/Packet9Respawn.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/Packet9Respawn.java new file mode 100644 index 0000000..d3b51a9 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/Packet9Respawn.java @@ -0,0 +1,109 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; + +public class Packet9Respawn extends DefinedPacket { + private int dimension; + private byte difficulty; + private byte gameMode; + private short worldHeight; + private String levelType; + + private Packet9Respawn() { + super(9); + } + + public Packet9Respawn(final int dimension, final byte difficulty, final byte gameMode, final short worldHeight, final String levelType) { + this(); + this.dimension = dimension; + this.difficulty = difficulty; + this.gameMode = gameMode; + this.worldHeight = worldHeight; + this.levelType = levelType; + } + + @Override + public void read(final ByteBuf buf) { + this.dimension = buf.readInt(); + this.difficulty = buf.readByte(); + this.gameMode = buf.readByte(); + this.worldHeight = buf.readShort(); + this.levelType = this.readString(buf); + } + + @Override + public void write(final ByteBuf buf) { + buf.writeInt(this.dimension); + buf.writeByte((int) this.difficulty); + buf.writeByte((int) this.gameMode); + buf.writeShort((int) this.worldHeight); + this.writeString(this.levelType, buf); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + @Override + public String toString() { + return "Packet9Respawn(dimension=" + this.dimension + ", difficulty=" + this.difficulty + ", gameMode=" + this.gameMode + ", worldHeight=" + this.worldHeight + ", levelType=" + this.levelType + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Packet9Respawn)) { + return false; + } + final Packet9Respawn other = (Packet9Respawn) o; + if (!other.canEqual(this)) { + return false; + } + if (this.dimension != other.dimension) { + return false; + } + if (this.difficulty != other.difficulty) { + return false; + } + if (this.gameMode != other.gameMode) { + return false; + } + if (this.worldHeight != other.worldHeight) { + return false; + } + final Object this$levelType = this.levelType; + final Object other$levelType = other.levelType; + if (this$levelType == null) { + if (other$levelType == null) { + return true; + } + } else if (this$levelType.equals(other$levelType)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof Packet9Respawn; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = result * 31 + this.dimension; + result = result * 31 + this.difficulty; + result = result * 31 + this.gameMode; + result = result * 31 + this.worldHeight; + final Object $levelType = this.levelType; + result = result * 31 + (($levelType == null) ? 0 : $levelType.hashCode()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketC9PlayerListItem.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketC9PlayerListItem.java new file mode 100644 index 0000000..8a9a61b --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketC9PlayerListItem.java @@ -0,0 +1,99 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; + +public class PacketC9PlayerListItem extends DefinedPacket { + private String username; + private boolean online; + private short ping; + + private PacketC9PlayerListItem() { + super(201); + } + + public PacketC9PlayerListItem(final String username, final boolean online, final short ping) { + super(201); + this.username = username; + this.online = online; + this.ping = ping; + } + + @Override + public void read(final ByteBuf buf) { + this.username = this.readString(buf); + this.online = buf.readBoolean(); + this.ping = buf.readShort(); + } + + @Override + public void write(final ByteBuf buf) { + this.writeString(this.username, buf); + buf.writeBoolean(this.online); + buf.writeShort((int) this.ping); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + public String getUsername() { + return this.username; + } + + public boolean isOnline() { + return this.online; + } + + public short getPing() { + return this.ping; + } + + @Override + public String toString() { + return "PacketC9PlayerListItem(username=" + this.getUsername() + ", online=" + this.isOnline() + ", ping=" + this.getPing() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PacketC9PlayerListItem)) { + return false; + } + final PacketC9PlayerListItem other = (PacketC9PlayerListItem) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$username = this.getUsername(); + final Object other$username = other.getUsername(); + if (this$username == null) { + if (other$username == null) { + return this.isOnline() == other.isOnline() && this.getPing() == other.getPing(); + } + } else if (this$username.equals(other$username)) { + return this.isOnline() == other.isOnline() && this.getPing() == other.getPing(); + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof PacketC9PlayerListItem; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $username = this.getUsername(); + result = result * 31 + (($username == null) ? 0 : $username.hashCode()); + result = result * 31 + (this.isOnline() ? 1231 : 1237); + result = result * 31 + this.getPing(); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketCCSettings.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketCCSettings.java new file mode 100644 index 0000000..0c9ea49 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketCCSettings.java @@ -0,0 +1,88 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; + +public class PacketCCSettings extends DefinedPacket { + private String locale; + private byte viewDistance; + private byte chatFlags; + private byte difficulty; + private boolean showCape; + + private PacketCCSettings() { + super(204); + } + + @Override + public void read(final ByteBuf buf) { + this.locale = this.readString(buf); + this.viewDistance = buf.readByte(); + this.chatFlags = buf.readByte(); + this.difficulty = buf.readByte(); + this.showCape = buf.readBoolean(); + } + + @Override + public void write(final ByteBuf buf) { + this.writeString(this.locale, buf); + buf.writeByte((int) this.viewDistance); + buf.writeByte((int) this.chatFlags); + buf.writeByte((int) this.difficulty); + buf.writeBoolean(this.showCape); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + @Override + public String toString() { + return "PacketCCSettings(locale=" + this.locale + ", viewDistance=" + this.viewDistance + ", chatFlags=" + this.chatFlags + ", difficulty=" + this.difficulty + ", showCape=" + this.showCape + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PacketCCSettings)) { + return false; + } + final PacketCCSettings other = (PacketCCSettings) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$locale = this.locale; + final Object other$locale = other.locale; + if (this$locale == null) { + if (other$locale == null) { + return this.viewDistance == other.viewDistance && this.chatFlags == other.chatFlags && this.difficulty == other.difficulty && this.showCape == other.showCape; + } + } else if (this$locale.equals(other$locale)) { + return this.viewDistance == other.viewDistance && this.chatFlags == other.chatFlags && this.difficulty == other.difficulty && this.showCape == other.showCape; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof PacketCCSettings; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $locale = this.locale; + result = result * 31 + (($locale == null) ? 0 : $locale.hashCode()); + result = result * 31 + this.viewDistance; + result = result * 31 + this.chatFlags; + result = result * 31 + this.difficulty; + result = result * 31 + (this.showCape ? 1231 : 1237); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketCDClientStatus.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketCDClientStatus.java new file mode 100644 index 0000000..6a936bb --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketCDClientStatus.java @@ -0,0 +1,64 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; + +public class PacketCDClientStatus extends DefinedPacket { + private byte payload; + + private PacketCDClientStatus() { + super(205); + } + + public PacketCDClientStatus(final byte payload) { + this(); + this.payload = payload; + } + + @Override + public void read(final ByteBuf buf) { + this.payload = buf.readByte(); + } + + @Override + public void write(final ByteBuf buf) { + buf.writeByte((int) this.payload); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + @Override + public String toString() { + return "PacketCDClientStatus(payload=" + this.payload + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PacketCDClientStatus)) { + return false; + } + final PacketCDClientStatus other = (PacketCDClientStatus) o; + return other.canEqual(this) && this.payload == other.payload; + } + + public boolean canEqual(final Object other) { + return other instanceof PacketCDClientStatus; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = result * 31 + this.payload; + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketCEScoreboardObjective.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketCEScoreboardObjective.java new file mode 100644 index 0000000..a7d1158 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketCEScoreboardObjective.java @@ -0,0 +1,112 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; + +public class PacketCEScoreboardObjective extends DefinedPacket { + private String name; + private String text; + private byte action; + + private PacketCEScoreboardObjective() { + super(206); + } + + public PacketCEScoreboardObjective(final String name, final String text, final byte action) { + this(); + this.name = name; + this.text = text; + this.action = action; + } + + @Override + public void read(final ByteBuf buf) { + this.name = this.readString(buf); + this.text = this.readString(buf); + this.action = buf.readByte(); + } + + @Override + public void write(final ByteBuf buf) { + this.writeString(this.name, buf); + this.writeString(this.text, buf); + buf.writeByte((int) this.action); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + public String getName() { + return this.name; + } + + public String getText() { + return this.text; + } + + public byte getAction() { + return this.action; + } + + @Override + public String toString() { + return "PacketCEScoreboardObjective(name=" + this.getName() + ", text=" + this.getText() + ", action=" + this.getAction() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PacketCEScoreboardObjective)) { + return false; + } + final PacketCEScoreboardObjective other = (PacketCEScoreboardObjective) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$name = this.getName(); + final Object other$name = other.getName(); + Label_0065: { + if (this$name == null) { + if (other$name == null) { + break Label_0065; + } + } else if (this$name.equals(other$name)) { + break Label_0065; + } + return false; + } + final Object this$text = this.getText(); + final Object other$text = other.getText(); + if (this$text == null) { + if (other$text == null) { + return this.getAction() == other.getAction(); + } + } else if (this$text.equals(other$text)) { + return this.getAction() == other.getAction(); + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof PacketCEScoreboardObjective; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $name = this.getName(); + result = result * 31 + (($name == null) ? 0 : $name.hashCode()); + final Object $text = this.getText(); + result = result * 31 + (($text == null) ? 0 : $text.hashCode()); + result = result * 31 + this.getAction(); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketCFScoreboardScore.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketCFScoreboardScore.java new file mode 100644 index 0000000..de9ff0a --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketCFScoreboardScore.java @@ -0,0 +1,120 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; + +public class PacketCFScoreboardScore extends DefinedPacket { + private String itemName; + private byte action; + private String scoreName; + private int value; + + private PacketCFScoreboardScore() { + super(207); + } + + @Override + public void read(final ByteBuf buf) { + this.itemName = this.readString(buf); + this.action = buf.readByte(); + if (this.action != 1) { + this.scoreName = this.readString(buf); + this.value = buf.readInt(); + } + } + + @Override + public void write(final ByteBuf buf) { + this.writeString(this.itemName, buf); + buf.writeByte((int) this.action); + if (this.action != 1) { + this.writeString(this.scoreName, buf); + buf.writeInt(this.value); + } + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + public String getItemName() { + return this.itemName; + } + + public byte getAction() { + return this.action; + } + + public String getScoreName() { + return this.scoreName; + } + + public int getValue() { + return this.value; + } + + @Override + public String toString() { + return "PacketCFScoreboardScore(itemName=" + this.getItemName() + ", action=" + this.getAction() + ", scoreName=" + this.getScoreName() + ", value=" + this.getValue() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PacketCFScoreboardScore)) { + return false; + } + final PacketCFScoreboardScore other = (PacketCFScoreboardScore) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$itemName = this.getItemName(); + final Object other$itemName = other.getItemName(); + Label_0065: { + if (this$itemName == null) { + if (other$itemName == null) { + break Label_0065; + } + } else if (this$itemName.equals(other$itemName)) { + break Label_0065; + } + return false; + } + if (this.getAction() != other.getAction()) { + return false; + } + final Object this$scoreName = this.getScoreName(); + final Object other$scoreName = other.getScoreName(); + if (this$scoreName == null) { + if (other$scoreName == null) { + return this.getValue() == other.getValue(); + } + } else if (this$scoreName.equals(other$scoreName)) { + return this.getValue() == other.getValue(); + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof PacketCFScoreboardScore; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $itemName = this.getItemName(); + result = result * 31 + (($itemName == null) ? 0 : $itemName.hashCode()); + result = result * 31 + this.getAction(); + final Object $scoreName = this.getScoreName(); + result = result * 31 + (($scoreName == null) ? 0 : $scoreName.hashCode()); + result = result * 31 + this.getValue(); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketD0DisplayScoreboard.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketD0DisplayScoreboard.java new file mode 100644 index 0000000..b1b6573 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketD0DisplayScoreboard.java @@ -0,0 +1,87 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; + +public class PacketD0DisplayScoreboard extends DefinedPacket { + private byte position; + private String name; + + private PacketD0DisplayScoreboard() { + super(208); + } + + @Override + public void read(final ByteBuf buf) { + this.position = buf.readByte(); + this.name = this.readString(buf); + } + + @Override + public void write(final ByteBuf buf) { + buf.writeByte((int) this.position); + this.writeString(this.name, buf); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + public byte getPosition() { + return this.position; + } + + public String getName() { + return this.name; + } + + @Override + public String toString() { + return "PacketD0DisplayScoreboard(position=" + this.getPosition() + ", name=" + this.getName() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PacketD0DisplayScoreboard)) { + return false; + } + final PacketD0DisplayScoreboard other = (PacketD0DisplayScoreboard) o; + if (!other.canEqual(this)) { + return false; + } + if (this.getPosition() != other.getPosition()) { + return false; + } + final Object this$name = this.getName(); + final Object other$name = other.getName(); + if (this$name == null) { + if (other$name == null) { + return true; + } + } else if (this$name.equals(other$name)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof PacketD0DisplayScoreboard; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = result * 31 + this.getPosition(); + final Object $name = this.getName(); + result = result * 31 + (($name == null) ? 0 : $name.hashCode()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketD1Team.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketD1Team.java new file mode 100644 index 0000000..4e5831a --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketD1Team.java @@ -0,0 +1,194 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import java.util.Arrays; +import io.netty.buffer.ByteBuf; + +public class PacketD1Team extends DefinedPacket { + private String name; + private byte mode; + private String displayName; + private String prefix; + private String suffix; + private boolean friendlyFire; + private short playerCount; + private String[] players; + + private PacketD1Team() { + super(209); + } + + public PacketD1Team(final String name) { + this(); + this.name = name; + this.mode = 1; + } + + @Override + public void read(final ByteBuf buf) { + this.name = this.readString(buf); + this.mode = buf.readByte(); + if (this.mode == 0 || this.mode == 2) { + this.displayName = this.readString(buf); + this.prefix = this.readString(buf); + this.suffix = this.readString(buf); + this.friendlyFire = buf.readBoolean(); + } + if (this.mode == 0 || this.mode == 3 || this.mode == 4) { + this.players = new String[buf.readShort()]; + for (int i = 0; i < this.getPlayers().length; ++i) { + this.players[i] = this.readString(buf); + } + } + } + + @Override + public void write(final ByteBuf buf) { + this.writeString(this.name, buf); + buf.writeByte((int) this.mode); + if (this.mode == 0 || this.mode == 2) { + this.writeString(this.displayName, buf); + this.writeString(this.prefix, buf); + this.writeString(this.suffix, buf); + buf.writeBoolean(this.friendlyFire); + } + if (this.mode == 0 || this.mode == 3 || this.mode == 4) { + buf.writeShort(this.players.length); + for (int i = 0; i < this.players.length; ++i) { + this.writeString(this.players[i], buf); + } + } + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + public String getName() { + return this.name; + } + + public byte getMode() { + return this.mode; + } + + public String getDisplayName() { + return this.displayName; + } + + public String getPrefix() { + return this.prefix; + } + + public String getSuffix() { + return this.suffix; + } + + public boolean isFriendlyFire() { + return this.friendlyFire; + } + + public short getPlayerCount() { + return this.playerCount; + } + + public String[] getPlayers() { + return this.players; + } + + @Override + public String toString() { + return "PacketD1Team(name=" + this.getName() + ", mode=" + this.getMode() + ", displayName=" + this.getDisplayName() + ", prefix=" + this.getPrefix() + ", suffix=" + this.getSuffix() + ", friendlyFire=" + this.isFriendlyFire() + + ", playerCount=" + this.getPlayerCount() + ", players=" + Arrays.deepToString(this.getPlayers()) + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PacketD1Team)) { + return false; + } + final PacketD1Team other = (PacketD1Team) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$name = this.getName(); + final Object other$name = other.getName(); + Label_0065: { + if (this$name == null) { + if (other$name == null) { + break Label_0065; + } + } else if (this$name.equals(other$name)) { + break Label_0065; + } + return false; + } + if (this.getMode() != other.getMode()) { + return false; + } + final Object this$displayName = this.getDisplayName(); + final Object other$displayName = other.getDisplayName(); + Label_0115: { + if (this$displayName == null) { + if (other$displayName == null) { + break Label_0115; + } + } else if (this$displayName.equals(other$displayName)) { + break Label_0115; + } + return false; + } + final Object this$prefix = this.getPrefix(); + final Object other$prefix = other.getPrefix(); + Label_0152: { + if (this$prefix == null) { + if (other$prefix == null) { + break Label_0152; + } + } else if (this$prefix.equals(other$prefix)) { + break Label_0152; + } + return false; + } + final Object this$suffix = this.getSuffix(); + final Object other$suffix = other.getSuffix(); + if (this$suffix == null) { + if (other$suffix == null) { + return this.isFriendlyFire() == other.isFriendlyFire() && this.getPlayerCount() == other.getPlayerCount() && Arrays.deepEquals(this.getPlayers(), other.getPlayers()); + } + } else if (this$suffix.equals(other$suffix)) { + return this.isFriendlyFire() == other.isFriendlyFire() && this.getPlayerCount() == other.getPlayerCount() && Arrays.deepEquals(this.getPlayers(), other.getPlayers()); + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof PacketD1Team; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $name = this.getName(); + result = result * 31 + (($name == null) ? 0 : $name.hashCode()); + result = result * 31 + this.getMode(); + final Object $displayName = this.getDisplayName(); + result = result * 31 + (($displayName == null) ? 0 : $displayName.hashCode()); + final Object $prefix = this.getPrefix(); + result = result * 31 + (($prefix == null) ? 0 : $prefix.hashCode()); + final Object $suffix = this.getSuffix(); + result = result * 31 + (($suffix == null) ? 0 : $suffix.hashCode()); + result = result * 31 + (this.isFriendlyFire() ? 1231 : 1237); + result = result * 31 + this.getPlayerCount(); + result = result * 31 + Arrays.deepHashCode(this.getPlayers()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketFAPluginMessage.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketFAPluginMessage.java new file mode 100644 index 0000000..21cf27e --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketFAPluginMessage.java @@ -0,0 +1,91 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import java.util.Arrays; +import io.netty.buffer.ByteBuf; + +public class PacketFAPluginMessage extends DefinedPacket { + private String tag; + private byte[] data; + + private PacketFAPluginMessage() { + super(250); + } + + public PacketFAPluginMessage(final String tag, final byte[] data) { + this(); + this.tag = tag; + this.data = data; + } + + @Override + public void read(final ByteBuf buf) { + this.tag = this.readString(buf); + this.data = this.readArray(buf); + } + + @Override + public void write(final ByteBuf buf) { + this.writeString(this.tag, buf); + this.writeArray(this.data, buf); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + public String getTag() { + return this.tag; + } + + public byte[] getData() { + return this.data; + } + + @Override + public String toString() { + return "PacketFAPluginMessage(tag=" + this.getTag() + ", data=" + Arrays.toString(this.getData()) + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PacketFAPluginMessage)) { + return false; + } + final PacketFAPluginMessage other = (PacketFAPluginMessage) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$tag = this.getTag(); + final Object other$tag = other.getTag(); + if (this$tag == null) { + if (other$tag == null) { + return Arrays.equals(this.getData(), other.getData()); + } + } else if (this$tag.equals(other$tag)) { + return Arrays.equals(this.getData(), other.getData()); + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof PacketFAPluginMessage; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $tag = this.getTag(); + result = result * 31 + (($tag == null) ? 0 : $tag.hashCode()); + result = result * 31 + Arrays.hashCode(this.getData()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketFCEncryptionResponse.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketFCEncryptionResponse.java new file mode 100644 index 0000000..3070ddd --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketFCEncryptionResponse.java @@ -0,0 +1,78 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import java.util.Arrays; +import io.netty.buffer.ByteBuf; + +public class PacketFCEncryptionResponse extends DefinedPacket { + private byte[] sharedSecret; + private byte[] verifyToken; + + private PacketFCEncryptionResponse() { + super(252); + } + + public PacketFCEncryptionResponse(final byte[] sharedSecret, final byte[] verifyToken) { + this(); + this.sharedSecret = sharedSecret; + this.verifyToken = verifyToken; + } + + @Override + public void read(final ByteBuf buf) { + this.sharedSecret = this.readArray(buf); + this.verifyToken = this.readArray(buf); + } + + @Override + public void write(final ByteBuf buf) { + this.writeArray(this.sharedSecret, buf); + this.writeArray(this.verifyToken, buf); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + public byte[] getSharedSecret() { + return this.sharedSecret; + } + + public byte[] getVerifyToken() { + return this.verifyToken; + } + + @Override + public String toString() { + return "PacketFCEncryptionResponse(sharedSecret=" + Arrays.toString(this.getSharedSecret()) + ", verifyToken=" + Arrays.toString(this.getVerifyToken()) + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PacketFCEncryptionResponse)) { + return false; + } + final PacketFCEncryptionResponse other = (PacketFCEncryptionResponse) o; + return other.canEqual(this) && Arrays.equals(this.getSharedSecret(), other.getSharedSecret()) && Arrays.equals(this.getVerifyToken(), other.getVerifyToken()); + } + + public boolean canEqual(final Object other) { + return other instanceof PacketFCEncryptionResponse; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = result * 31 + Arrays.hashCode(this.getSharedSecret()); + result = result * 31 + Arrays.hashCode(this.getVerifyToken()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketFDEncryptionRequest.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketFDEncryptionRequest.java new file mode 100644 index 0000000..c5ee4ed --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketFDEncryptionRequest.java @@ -0,0 +1,100 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import java.util.Arrays; +import io.netty.buffer.ByteBuf; + +public class PacketFDEncryptionRequest extends DefinedPacket { + private String serverId; + private byte[] publicKey; + private byte[] verifyToken; + + private PacketFDEncryptionRequest() { + super(253); + } + + public PacketFDEncryptionRequest(final String serverId, final byte[] publicKey, final byte[] verifyToken) { + this(); + this.serverId = serverId; + this.publicKey = publicKey; + this.verifyToken = verifyToken; + } + + @Override + public void read(final ByteBuf buf) { + this.serverId = this.readString(buf); + this.publicKey = this.readArray(buf); + this.verifyToken = this.readArray(buf); + } + + @Override + public void write(final ByteBuf buf) { + this.writeString(this.serverId, buf); + this.writeArray(this.publicKey, buf); + this.writeArray(this.verifyToken, buf); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + public String getServerId() { + return this.serverId; + } + + public byte[] getPublicKey() { + return this.publicKey; + } + + public byte[] getVerifyToken() { + return this.verifyToken; + } + + @Override + public String toString() { + return "PacketFDEncryptionRequest(serverId=" + this.getServerId() + ", publicKey=" + Arrays.toString(this.getPublicKey()) + ", verifyToken=" + Arrays.toString(this.getVerifyToken()) + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PacketFDEncryptionRequest)) { + return false; + } + final PacketFDEncryptionRequest other = (PacketFDEncryptionRequest) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$serverId = this.getServerId(); + final Object other$serverId = other.getServerId(); + if (this$serverId == null) { + if (other$serverId == null) { + return Arrays.equals(this.getPublicKey(), other.getPublicKey()) && Arrays.equals(this.getVerifyToken(), other.getVerifyToken()); + } + } else if (this$serverId.equals(other$serverId)) { + return Arrays.equals(this.getPublicKey(), other.getPublicKey()) && Arrays.equals(this.getVerifyToken(), other.getVerifyToken()); + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof PacketFDEncryptionRequest; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $serverId = this.getServerId(); + result = result * 31 + (($serverId == null) ? 0 : $serverId.hashCode()); + result = result * 31 + Arrays.hashCode(this.getPublicKey()); + result = result * 31 + Arrays.hashCode(this.getVerifyToken()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketFEPing.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketFEPing.java new file mode 100644 index 0000000..1aeb175 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketFEPing.java @@ -0,0 +1,59 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; + +public class PacketFEPing extends DefinedPacket { + private byte version; + + private PacketFEPing() { + super(254); + } + + @Override + public void read(final ByteBuf buf) { + this.version = buf.readByte(); + } + + @Override + public void write(final ByteBuf buf) { + buf.writeByte((int) this.version); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + @Override + public String toString() { + return "PacketFEPing(version=" + this.version + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PacketFEPing)) { + return false; + } + final PacketFEPing other = (PacketFEPing) o; + return other.canEqual(this) && this.version == other.version; + } + + public boolean canEqual(final Object other) { + return other instanceof PacketFEPing; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = result * 31 + this.version; + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketFFKick.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketFFKick.java new file mode 100644 index 0000000..3da69d0 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/PacketFFKick.java @@ -0,0 +1,81 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; + +public class PacketFFKick extends DefinedPacket { + private String message; + + private PacketFFKick() { + super(255); + } + + public PacketFFKick(final String message) { + this(); + this.message = message; + } + + @Override + public void read(final ByteBuf buf) { + this.message = this.readString(buf); + } + + @Override + public void write(final ByteBuf buf) { + this.writeString(this.message, buf); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + public String getMessage() { + return this.message; + } + + @Override + public String toString() { + return "PacketFFKick(message=" + this.getMessage() + ")"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof PacketFFKick)) { + return false; + } + final PacketFFKick other = (PacketFFKick) o; + if (!other.canEqual(this)) { + return false; + } + final Object this$message = this.getMessage(); + final Object other$message = other.getMessage(); + if (this$message == null) { + if (other$message == null) { + return true; + } + } else if (this$message.equals(other$message)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof PacketFFKick; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + final Object $message = this.getMessage(); + result = result * 31 + (($message == null) ? 0 : $message.hashCode()); + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/forge/Forge1Login.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/forge/Forge1Login.java new file mode 100644 index 0000000..c722a1c --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/packet/forge/Forge1Login.java @@ -0,0 +1,73 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.packet.forge; + +import net.md_5.bungee.protocol.packet.AbstractPacketHandler; +import io.netty.buffer.ByteBuf; +import net.md_5.bungee.protocol.packet.Packet1Login; + +public class Forge1Login extends Packet1Login { + private Forge1Login() { + } + + public Forge1Login(final int entityId, final String levelType, final byte gameMode, final int dimension, final byte difficulty, final byte unused, final byte maxPlayers) { + super(entityId, levelType, gameMode, dimension, difficulty, unused, maxPlayers); + } + + @Override + public void read(final ByteBuf buf) { + this.entityId = buf.readInt(); + this.levelType = this.readString(buf); + this.gameMode = buf.readByte(); + this.dimension = buf.readInt(); + this.difficulty = buf.readByte(); + this.unused = buf.readByte(); + this.maxPlayers = buf.readByte(); + } + + @Override + public void write(final ByteBuf buf) { + buf.writeInt(this.entityId); + this.writeString(this.levelType, buf); + buf.writeByte((int) this.gameMode); + buf.writeInt(this.dimension); + buf.writeByte((int) this.difficulty); + buf.writeByte((int) this.unused); + buf.writeByte((int) this.maxPlayers); + } + + @Override + public void handle(final AbstractPacketHandler handler) throws Exception { + handler.handle(this); + } + + @Override + public String toString() { + return "Forge1Login()"; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Forge1Login)) { + return false; + } + final Forge1Login other = (Forge1Login) o; + return other.canEqual(this); + } + + @Override + public boolean canEqual(final Object other) { + return other instanceof Forge1Login; + } + + @Override + public int hashCode() { + final int result = 1; + return result; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/BulkChunk.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/BulkChunk.java new file mode 100644 index 0000000..0ad9668 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/BulkChunk.java @@ -0,0 +1,17 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.skip; + +import io.netty.buffer.ByteBuf; + +public class BulkChunk extends Instruction { + @Override + void read(final ByteBuf in) { + final short count = in.readShort(); + final int size = in.readInt(); + in.readBoolean(); + in.skipBytes(size + count * 12); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/ByteHeader.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/ByteHeader.java new file mode 100644 index 0000000..2d9e2de --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/ByteHeader.java @@ -0,0 +1,22 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.skip; + +import io.netty.buffer.ByteBuf; + +class ByteHeader extends Instruction { + private final Instruction child; + + ByteHeader(final Instruction child) { + this.child = child; + } + + @Override + void read(final ByteBuf in) { + for (byte size = in.readByte(), b = 0; b < size; ++b) { + this.child.read(in); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/Instruction.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/Instruction.java new file mode 100644 index 0000000..a590c6d --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/Instruction.java @@ -0,0 +1,53 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.skip; + +import io.netty.buffer.ByteBuf; + +abstract class Instruction { + static final Instruction BOOLEAN; + static final Instruction BULK_CHUNK; + static final Instruction BYTE; + static final Instruction DOUBLE; + static final Instruction FLOAT; + static final Instruction INT; + static final Instruction INT_3; + static final Instruction INT_BYTE; + static final Instruction ITEM; + static final Instruction LONG; + static final Instruction METADATA; + static final Instruction OPTIONAL_MOTION; + static final Instruction SHORT; + static final Instruction SHORT_BYTE; + static final Instruction SHORT_ITEM; + static final Instruction STRING; + static final Instruction USHORT_BYTE; + static final Instruction BYTE_INT; + static final Instruction STRING_ARRAY; + + abstract void read(final ByteBuf p0); + + static { + BOOLEAN = new Jump(1); + BULK_CHUNK = new BulkChunk(); + BYTE = new Jump(1); + DOUBLE = new Jump(8); + FLOAT = new Jump(4); + INT = new Jump(4); + INT_3 = new IntHeader(new Jump(3)); + INT_BYTE = new IntHeader(Instruction.BYTE); + ITEM = new Item(); + LONG = new Jump(8); + METADATA = new MetaData(); + OPTIONAL_MOTION = new OptionalMotion(); + SHORT = new Jump(2); + SHORT_BYTE = new ShortHeader(Instruction.BYTE); + SHORT_ITEM = new ShortHeader(Instruction.ITEM); + STRING = new ShortHeader(new Jump(2)); + USHORT_BYTE = new UnsignedShortByte(); + BYTE_INT = new ByteHeader(Instruction.INT); + STRING_ARRAY = new ShortHeader(Instruction.STRING); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/IntHeader.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/IntHeader.java new file mode 100644 index 0000000..76a366c --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/IntHeader.java @@ -0,0 +1,22 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.skip; + +import io.netty.buffer.ByteBuf; + +class IntHeader extends Instruction { + private final Instruction child; + + IntHeader(final Instruction child) { + this.child = child; + } + + @Override + void read(final ByteBuf in) { + for (int size = in.readInt(), i = 0; i < size; ++i) { + this.child.read(in); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/Item.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/Item.java new file mode 100644 index 0000000..b69e027 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/Item.java @@ -0,0 +1,18 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.skip; + +import io.netty.buffer.ByteBuf; + +class Item extends Instruction { + @Override + void read(final ByteBuf in) { + final short type = in.readShort(); + if (type >= 0) { + in.skipBytes(3); + Item.SHORT_BYTE.read(in); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/Jump.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/Jump.java new file mode 100644 index 0000000..b1e5896 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/Jump.java @@ -0,0 +1,23 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.skip; + +import io.netty.buffer.ByteBuf; + +class Jump extends Instruction { + final int len; + + Jump(final int len) { + if (len < 0) { + throw new IndexOutOfBoundsException(); + } + this.len = len; + } + + @Override + void read(final ByteBuf in) { + in.skipBytes(this.len); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/MetaData.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/MetaData.java new file mode 100644 index 0000000..2f06add --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/MetaData.java @@ -0,0 +1,49 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.skip; + +import io.netty.buffer.ByteBuf; + +class MetaData extends Instruction { + @Override + void read(final ByteBuf in) { + for (int x = in.readUnsignedByte(); x != 127; x = in.readUnsignedByte()) { + final int type = x >> 5; + switch (type) { + case 0: { + MetaData.BYTE.read(in); + break; + } + case 1: { + MetaData.SHORT.read(in); + break; + } + case 2: { + MetaData.INT.read(in); + break; + } + case 3: { + MetaData.FLOAT.read(in); + break; + } + case 4: { + MetaData.STRING.read(in); + break; + } + case 5: { + MetaData.ITEM.read(in); + break; + } + case 6: { + in.skipBytes(12); + break; + } + default: { + throw new IllegalArgumentException("Unknown metadata type " + type); + } + } + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/OptionalMotion.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/OptionalMotion.java new file mode 100644 index 0000000..0a8d99c --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/OptionalMotion.java @@ -0,0 +1,17 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.skip; + +import io.netty.buffer.ByteBuf; + +class OptionalMotion extends Instruction { + @Override + void read(final ByteBuf in) { + final int data = in.readInt(); + if (data > 0) { + in.skipBytes(6); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/PacketReader.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/PacketReader.java new file mode 100644 index 0000000..fb602f4 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/PacketReader.java @@ -0,0 +1,58 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.skip; + +import io.netty.buffer.ByteBuf; +import net.md_5.bungee.protocol.OpCode; +import java.util.List; +import java.util.ArrayList; +import net.md_5.bungee.protocol.Protocol; + +public class PacketReader { + private final Instruction[][] instructions; + + public PacketReader(final Protocol protocol) { + this.instructions = new Instruction[protocol.getOpCodes().length][]; + for (int i = 0; i < this.instructions.length; ++i) { + final List output = new ArrayList(); + final OpCode[] enums = protocol.getOpCodes()[i]; + if (enums != null) { + for (final OpCode struct : enums) { + try { + output.add((Instruction) Instruction.class.getDeclaredField(struct.name()).get(null)); + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex3) { + throw new UnsupportedOperationException("No definition for " + struct.name()); + } + } + final List crushed = new ArrayList(); + int nextJumpSize = 0; + for (final Instruction child : output) { + if (child instanceof Jump) { + nextJumpSize += ((Jump) child).len; + } else { + if (nextJumpSize != 0) { + crushed.add(new Jump(nextJumpSize)); + } + crushed.add(child); + nextJumpSize = 0; + } + } + if (nextJumpSize != 0) { + crushed.add(new Jump(nextJumpSize)); + } + this.instructions[i] = crushed.toArray(new Instruction[crushed.size()]); + } + } + } + + public void tryRead(final short packetId, final ByteBuf in) { + final Instruction[] packetDef = this.instructions[packetId]; + if (packetDef != null) { + for (final Instruction instruction : packetDef) { + instruction.read(in); + } + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/ShortHeader.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/ShortHeader.java new file mode 100644 index 0000000..c7ff540 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/ShortHeader.java @@ -0,0 +1,22 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.skip; + +import io.netty.buffer.ByteBuf; + +class ShortHeader extends Instruction { + private final Instruction child; + + ShortHeader(final Instruction child) { + this.child = child; + } + + @Override + void read(final ByteBuf in) { + for (short size = in.readShort(), s = 0; s < size; ++s) { + this.child.read(in); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/UnsignedShortByte.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/UnsignedShortByte.java new file mode 100644 index 0000000..b24f98b --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/protocol/skip/UnsignedShortByte.java @@ -0,0 +1,15 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.protocol.skip; + +import io.netty.buffer.ByteBuf; + +class UnsignedShortByte extends Instruction { + @Override + void read(final ByteBuf in) { + final int size = in.readUnsignedShort(); + in.skipBytes(size); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/reconnect/AbstractReconnectManager.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/reconnect/AbstractReconnectManager.java new file mode 100644 index 0000000..9884596 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/reconnect/AbstractReconnectManager.java @@ -0,0 +1,33 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.reconnect; + +import net.md_5.bungee.api.config.ListenerInfo; +import com.google.common.base.Preconditions; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.ReconnectHandler; + +public abstract class AbstractReconnectManager implements ReconnectHandler { + @Override + public ServerInfo getServer(final ProxiedPlayer player) { + final ListenerInfo listener = player.getPendingConnection().getListener(); + String forced = listener.getForcedHosts().get(player.getPendingConnection().getVirtualHost().getHostString()); + if (forced == null && listener.isForceDefault()) { + forced = listener.getDefaultServer(); + } + final String server = (forced == null) ? this.getStoredServer(player) : forced; + final String name = (server != null) ? server : listener.getDefaultServer(); + ServerInfo info = ProxyServer.getInstance().getServerInfo(name); + if (info == null) { + info = ProxyServer.getInstance().getServerInfo(listener.getDefaultServer()); + } + Preconditions.checkState(info != null, (Object) "Default server not defined"); + return info; + } + + protected abstract String getStoredServer(final ProxiedPlayer p0); +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/reconnect/SQLReconnectHandler.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/reconnect/SQLReconnectHandler.java new file mode 100644 index 0000000..6545a53 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/reconnect/SQLReconnectHandler.java @@ -0,0 +1,72 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.reconnect; + +import java.sql.ResultSet; +import java.util.logging.Level; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import java.sql.SQLException; +import java.sql.PreparedStatement; +import java.sql.DriverManager; +import java.sql.Connection; + +public class SQLReconnectHandler extends AbstractReconnectManager { + private final Connection connection; + + public SQLReconnectHandler() throws ClassNotFoundException, SQLException { + Class.forName("org.sqlite.JDBC"); + this.connection = DriverManager.getConnection("jdbc:sqlite:bungee.sqlite"); + try (final PreparedStatement ps = this.connection.prepareStatement("CREATE TABLE IF NOT EXISTS players (playerId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,username TEXT NOT NULL UNIQUE COLLATE NOCASE,seen INTEGER,server TEXT);")) { + ps.executeUpdate(); + } + } + + @Override + protected String getStoredServer(final ProxiedPlayer player) { + String server = null; + try (final PreparedStatement ps = this.connection.prepareStatement("SELECT server FROM players WHERE username = ?")) { + ps.setString(1, player.getName()); + try (final ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + server = rs.getString(1); + } else { + try (final PreparedStatement playerUpdate = this.connection.prepareStatement("INSERT INTO players( username ) VALUES( ? )")) { + playerUpdate.setString(1, player.getName()); + playerUpdate.executeUpdate(); + } + } + } + } catch (SQLException ex) { + ProxyServer.getInstance().getLogger().log(Level.WARNING, "Could not load location for player " + player.getName(), ex); + } + return server; + } + + @Override + public void setServer(final ProxiedPlayer player) { + try (final PreparedStatement ps = this.connection.prepareStatement("UPDATE players SET server = ?, seen = ? WHERE username = ?")) { + ps.setString(1, player.getServer().getInfo().getName()); + ps.setInt(2, (int) (System.currentTimeMillis() / 1000L)); + ps.setString(3, player.getName()); + ps.executeUpdate(); + } catch (SQLException ex) { + ProxyServer.getInstance().getLogger().log(Level.WARNING, "Could not save location for player " + player.getName() + " on server " + player.getServer().getInfo().getName(), ex); + } + } + + @Override + public void save() { + } + + @Override + public void close() { + try { + this.connection.close(); + } catch (SQLException ex) { + ProxyServer.getInstance().getLogger().log(Level.WARNING, "Error closing SQLite connection", ex); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/scheduler/BungeeScheduler.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/scheduler/BungeeScheduler.java new file mode 100644 index 0000000..afbf4c3 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/scheduler/BungeeScheduler.java @@ -0,0 +1,80 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.scheduler; + +import com.google.common.base.Preconditions; +import net.md_5.bungee.BungeeCord; +import java.util.concurrent.TimeUnit; +import java.util.Set; +import java.util.HashSet; +import net.md_5.bungee.api.scheduler.ScheduledTask; +import com.google.common.collect.Multimaps; +import com.google.common.collect.HashMultimap; +import gnu.trove.TCollections; +import gnu.trove.map.hash.TIntObjectHashMap; +import net.md_5.bungee.api.plugin.Plugin; +import com.google.common.collect.Multimap; +import gnu.trove.map.TIntObjectMap; +import java.util.concurrent.atomic.AtomicInteger; +import net.md_5.bungee.api.scheduler.TaskScheduler; + +public class BungeeScheduler implements TaskScheduler { + private final AtomicInteger taskCounter; + private final TIntObjectMap tasks; + private final Multimap tasksByPlugin; + + public BungeeScheduler() { + this.taskCounter = new AtomicInteger(); + this.tasks = (TIntObjectMap) TCollections.synchronizedMap((TIntObjectMap) new TIntObjectHashMap()); + this.tasksByPlugin = (Multimap) Multimaps.synchronizedMultimap((Multimap) HashMultimap.create()); + } + + @Override + public void cancel(final int id) { + final BungeeTask task = (BungeeTask) this.tasks.remove(id); + this.tasksByPlugin.values().remove(task); + task.getFuture().cancel(false); + } + + @Override + public void cancel(final ScheduledTask task) { + this.cancel(task.getId()); + } + + @Override + public int cancel(final Plugin plugin) { + final Set toRemove = new HashSet(); + for (final ScheduledTask task : this.tasksByPlugin.get((Plugin) plugin)) { + toRemove.add(task); + } + for (final ScheduledTask task : toRemove) { + this.cancel(task); + } + return toRemove.size(); + } + + @Override + public ScheduledTask runAsync(final Plugin owner, final Runnable task) { + return this.schedule(owner, task, 0L, TimeUnit.MILLISECONDS); + } + + @Override + public ScheduledTask schedule(final Plugin owner, final Runnable task, final long delay, final TimeUnit unit) { + return this.prepare(owner, task).setFuture(BungeeCord.getInstance().executors.schedule(task, delay, unit)); + } + + @Override + public ScheduledTask schedule(final Plugin owner, final Runnable task, final long delay, final long period, final TimeUnit unit) { + return this.prepare(owner, task).setFuture(BungeeCord.getInstance().executors.scheduleWithFixedDelay(task, delay, period, unit)); + } + + private BungeeTask prepare(final Plugin owner, final Runnable task) { + Preconditions.checkNotNull((Object) owner, (Object) "owner"); + Preconditions.checkNotNull((Object) task, (Object) "task"); + final BungeeTask prepared = new BungeeTask(this.taskCounter.getAndIncrement(), owner, task); + this.tasks.put(prepared.getId(), (BungeeTask) prepared); + return prepared; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/scheduler/BungeeTask.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/scheduler/BungeeTask.java new file mode 100644 index 0000000..0ee44e5 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/scheduler/BungeeTask.java @@ -0,0 +1,128 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.scheduler; + +import java.beans.ConstructorProperties; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.ScheduledFuture; +import net.md_5.bungee.api.plugin.Plugin; +import net.md_5.bungee.api.scheduler.ScheduledTask; + +public class BungeeTask implements ScheduledTask { + private final int id; + private final Plugin owner; + private final Runnable task; + private ScheduledFuture future; + + @Override + public long getDelay(final TimeUnit unit) { + return this.future.getDelay(unit); + } + + BungeeTask setFuture(final ScheduledFuture future) { + this.future = future; + return this; + } + + @ConstructorProperties({ "id", "owner", "task" }) + public BungeeTask(final int id, final Plugin owner, final Runnable task) { + this.id = id; + this.owner = owner; + this.task = task; + } + + @Override + public int getId() { + return this.id; + } + + @Override + public Plugin getOwner() { + return this.owner; + } + + @Override + public Runnable getTask() { + return this.task; + } + + public ScheduledFuture getFuture() { + return this.future; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof BungeeTask)) { + return false; + } + final BungeeTask other = (BungeeTask) o; + if (!other.canEqual(this)) { + return false; + } + if (this.getId() != other.getId()) { + return false; + } + final Object this$owner = this.getOwner(); + final Object other$owner = other.getOwner(); + Label_0078: { + if (this$owner == null) { + if (other$owner == null) { + break Label_0078; + } + } else if (this$owner.equals(other$owner)) { + break Label_0078; + } + return false; + } + final Object this$task = this.getTask(); + final Object other$task = other.getTask(); + Label_0115: { + if (this$task == null) { + if (other$task == null) { + break Label_0115; + } + } else if (this$task.equals(other$task)) { + break Label_0115; + } + return false; + } + final Object this$future = this.getFuture(); + final Object other$future = other.getFuture(); + if (this$future == null) { + if (other$future == null) { + return true; + } + } else if (this$future.equals(other$future)) { + return true; + } + return false; + } + + public boolean canEqual(final Object other) { + return other instanceof BungeeTask; + } + + @Override + public int hashCode() { + final int PRIME = 31; + int result = 1; + result = result * 31 + this.getId(); + final Object $owner = this.getOwner(); + result = result * 31 + (($owner == null) ? 0 : $owner.hashCode()); + final Object $task = this.getTask(); + result = result * 31 + (($task == null) ? 0 : $task.hashCode()); + final Object $future = this.getFuture(); + result = result * 31 + (($future == null) ? 0 : $future.hashCode()); + return result; + } + + @Override + public String toString() { + return "BungeeTask(id=" + this.getId() + ", owner=" + this.getOwner() + ", task=" + this.getTask() + ", future=" + this.getFuture() + ")"; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/scheduler/BungeeThreadPool.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/scheduler/BungeeThreadPool.java new file mode 100644 index 0000000..f729b26 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/scheduler/BungeeThreadPool.java @@ -0,0 +1,27 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.scheduler; + +import java.util.logging.Level; +import net.md_5.bungee.api.ProxyServer; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ScheduledThreadPoolExecutor; + +public class BungeeThreadPool extends ScheduledThreadPoolExecutor { + public BungeeThreadPool(final ThreadFactory threadFactory) { + super(Integer.MAX_VALUE, threadFactory); + this.setKeepAliveTime(5L, TimeUnit.MINUTES); + this.allowCoreThreadTimeOut(true); + } + + @Override + protected void afterExecute(final Runnable r, final Throwable t) { + super.afterExecute(r, t); + if (t != null) { + ProxyServer.getInstance().getLogger().log(Level.SEVERE, "Task caused exception whilst running", t); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/tab/Custom.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/tab/Custom.java new file mode 100644 index 0000000..386d0bc --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/tab/Custom.java @@ -0,0 +1,136 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.tab; + +import net.md_5.bungee.protocol.packet.PacketC9PlayerListItem; +import net.md_5.bungee.api.ChatColor; +import com.google.common.base.Preconditions; +import java.util.HashSet; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import java.util.Collection; +import net.md_5.bungee.api.tab.CustomTabList; +import net.md_5.bungee.api.tab.TabListAdapter; + +public class Custom extends TabListAdapter implements CustomTabList { + private static final int ROWS = 20; + private static final int COLUMNS = 3; + private static final char[] FILLER; + private static final int MAX_LEN = 16; + private final Collection sentStuff; + private String[][] sent; + private String[][] slots; + private int rowLim; + private int colLim; + + public Custom(final ProxiedPlayer player) { + this.sentStuff = new HashSet(); + this.sent = new String[20][3]; + this.slots = new String[20][3]; + this.init(player); + } + + @Override + public synchronized String setSlot(final int row, final int column, final String text) { + return this.setSlot(row, column, text, true); + } + + @Override + public synchronized String setSlot(int row, int column, String text, final boolean update) { + Preconditions.checkArgument(row > 0 && row <= 20, (Object) "row out of range"); + Preconditions.checkArgument(column > 0 && column <= 3, (Object) "column out of range"); + if (text != null) { + Preconditions.checkArgument(text.length() <= 16, "text must be <= %s chars", new Object[] { 16 }); + Preconditions.checkArgument(!ChatColor.stripColor(text).isEmpty(), (Object) "Text cannot consist entirely of colour codes"); + text = this.attempt(text); + this.sentStuff.add(text); + if (this.rowLim < row || this.colLim < column) { + this.rowLim = row; + this.colLim = column; + } + } else { + this.sentStuff.remove(text); + } + this.slots[--row][--column] = text; + if (update) { + this.update(); + } + return text; + } + + private String attempt(final String s) { + for (final char c : Custom.FILLER) { + final String attempt = s + Character.toString('§') + c; + if (!this.sentStuff.contains(attempt)) { + return attempt; + } + } + if (s.length() <= 12) { + return this.attempt(s + Character.toString('§') + Custom.FILLER[0]); + } + throw new IllegalArgumentException("List already contains all variants of string"); + } + + @Override + public synchronized void update() { + this.clear(); + for (int i = 0; i < this.rowLim; ++i) { + for (int j = 0; j < this.colLim; ++j) { + final String text = (this.slots[i][j] != null) ? this.slots[i][j] : new StringBuilder().append(base(i)).append(base(j)).toString(); + this.sent[i][j] = text; + this.getPlayer().unsafe().sendPacket(new PacketC9PlayerListItem(text, true, (short) 0)); + } + } + } + + @Override + public synchronized void clear() { + for (int i = 0; i < this.rowLim; ++i) { + for (int j = 0; j < this.colLim; ++j) { + if (this.sent[i][j] != null) { + final String text = this.sent[i][j]; + this.sent[i][j] = null; + this.getPlayer().unsafe().sendPacket(new PacketC9PlayerListItem(text, false, (short) 9999)); + } + } + } + } + + @Override + public synchronized int getRows() { + return 20; + } + + @Override + public synchronized int getColumns() { + return 3; + } + + @Override + public synchronized int getSize() { + return 60; + } + + @Override + public boolean onListUpdate(final String name, final boolean online, final int ping) { + return false; + } + + private static char[] base(final int n) { + final String hex = Integer.toHexString(n + 1); + final char[] alloc = new char[hex.length() * 2]; + for (int i = 0; i < alloc.length; ++i) { + if (i % 2 == 0) { + alloc[i] = '§'; + } else { + alloc[i] = hex.charAt(i / 2); + } + } + return alloc; + } + + static { + FILLER = new char[] { '0', '1', '2', '2', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/tab/Global.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/tab/Global.java new file mode 100644 index 0000000..8ec303f --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/tab/Global.java @@ -0,0 +1,43 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.tab; + +import java.util.Iterator; +import net.md_5.bungee.BungeeCord; +import net.md_5.bungee.protocol.packet.DefinedPacket; +import net.md_5.bungee.protocol.packet.PacketC9PlayerListItem; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.tab.TabListAdapter; + +public class Global extends TabListAdapter { + private boolean sentPing; + + @Override + public void onConnect() { + for (final ProxiedPlayer p : ProxyServer.getInstance().getPlayers()) { + this.getPlayer().unsafe().sendPacket(new PacketC9PlayerListItem(p.getDisplayName(), true, (short) p.getPing())); + } + BungeeCord.getInstance().broadcast(new PacketC9PlayerListItem(this.getPlayer().getDisplayName(), true, (short) this.getPlayer().getPing())); + } + + @Override + public void onPingChange(final int ping) { + if (!this.sentPing) { + this.sentPing = true; + BungeeCord.getInstance().broadcast(new PacketC9PlayerListItem(this.getPlayer().getDisplayName(), true, (short) this.getPlayer().getPing())); + } + } + + @Override + public void onDisconnect() { + BungeeCord.getInstance().broadcast(new PacketC9PlayerListItem(this.getPlayer().getDisplayName(), false, (short) 9999)); + } + + @Override + public boolean onListUpdate(final String name, final boolean online, final int ping) { + return false; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/tab/GlobalPing.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/tab/GlobalPing.java new file mode 100644 index 0000000..90a816d --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/tab/GlobalPing.java @@ -0,0 +1,22 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.tab; + +import net.md_5.bungee.protocol.packet.DefinedPacket; +import net.md_5.bungee.protocol.packet.PacketC9PlayerListItem; +import net.md_5.bungee.BungeeCord; + +public class GlobalPing extends Global { + private static final int PING_THRESHOLD = 20; + private int lastPing; + + @Override + public void onPingChange(final int ping) { + if (ping - 20 > this.lastPing && ping + 20 < this.lastPing) { + this.lastPing = ping; + BungeeCord.getInstance().broadcast(new PacketC9PlayerListItem(this.getPlayer().getDisplayName(), true, (short) ping)); + } + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/tab/ServerUnique.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/tab/ServerUnique.java new file mode 100644 index 0000000..855f3a7 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/tab/ServerUnique.java @@ -0,0 +1,40 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.tab; + +import java.util.Iterator; +import net.md_5.bungee.protocol.packet.DefinedPacket; +import net.md_5.bungee.protocol.packet.PacketC9PlayerListItem; +import java.util.HashSet; +import java.util.Collection; +import net.md_5.bungee.api.tab.TabListAdapter; + +public class ServerUnique extends TabListAdapter { + private final Collection usernames; + + public ServerUnique() { + this.usernames = new HashSet(); + } + + @Override + public void onServerChange() { + synchronized (this.usernames) { + for (final String username : this.usernames) { + this.getPlayer().unsafe().sendPacket(new PacketC9PlayerListItem(username, false, (short) 9999)); + } + this.usernames.clear(); + } + } + + @Override + public boolean onListUpdate(final String name, final boolean online, final int ping) { + if (online) { + this.usernames.add(name); + } else { + this.usernames.remove(name); + } + return true; + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/util/CaseInsensitiveHashingStrategy.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/util/CaseInsensitiveHashingStrategy.java new file mode 100644 index 0000000..0b3da6d --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/util/CaseInsensitiveHashingStrategy.java @@ -0,0 +1,23 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.util; + +import gnu.trove.strategy.HashingStrategy; + +class CaseInsensitiveHashingStrategy implements HashingStrategy { + static final CaseInsensitiveHashingStrategy INSTANCE; + + public int computeHashCode(final Object object) { + return ((String) object).toLowerCase().hashCode(); + } + + public boolean equals(final Object o1, final Object o2) { + return o1.equals(o2) || (o1 instanceof String && o2 instanceof String && ((String) o1).toLowerCase().equals(((String) o2).toLowerCase())); + } + + static { + INSTANCE = new CaseInsensitiveHashingStrategy(); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/util/CaseInsensitiveMap.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/util/CaseInsensitiveMap.java new file mode 100644 index 0000000..67ba884 --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/util/CaseInsensitiveMap.java @@ -0,0 +1,19 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.util; + +import java.util.Map; +import gnu.trove.strategy.HashingStrategy; +import gnu.trove.map.hash.TCustomHashMap; + +public class CaseInsensitiveMap extends TCustomHashMap { + public CaseInsensitiveMap() { + super((HashingStrategy) CaseInsensitiveHashingStrategy.INSTANCE); + } + + public CaseInsensitiveMap(final Map map) { + super((HashingStrategy) CaseInsensitiveHashingStrategy.INSTANCE, (Map) map); + } +} diff --git a/eaglercraftbungee/src/main/java/net/md_5/bungee/util/CaseInsensitiveSet.java b/eaglercraftbungee/src/main/java/net/md_5/bungee/util/CaseInsensitiveSet.java new file mode 100644 index 0000000..2543e8c --- /dev/null +++ b/eaglercraftbungee/src/main/java/net/md_5/bungee/util/CaseInsensitiveSet.java @@ -0,0 +1,19 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package net.md_5.bungee.util; + +import java.util.Collection; +import gnu.trove.strategy.HashingStrategy; +import gnu.trove.set.hash.TCustomHashSet; + +public class CaseInsensitiveSet extends TCustomHashSet { + public CaseInsensitiveSet() { + super((HashingStrategy) CaseInsensitiveHashingStrategy.INSTANCE); + } + + public CaseInsensitiveSet(final Collection collection) { + super((HashingStrategy) CaseInsensitiveHashingStrategy.INSTANCE, (Collection) collection); + } +} diff --git a/epkcompiler/.classpath b/epkcompiler/.classpath new file mode 100644 index 0000000..5774550 --- /dev/null +++ b/epkcompiler/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/epkcompiler/.project b/epkcompiler/.project new file mode 100644 index 0000000..adac065 --- /dev/null +++ b/epkcompiler/.project @@ -0,0 +1,17 @@ + + + PackageCompiler + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/epkcompiler/out.epk b/epkcompiler/out.epk new file mode 100644 index 0000000..50403d0 Binary files /dev/null and b/epkcompiler/out.epk differ diff --git a/epkcompiler/src/CompilePackage.java b/epkcompiler/src/CompilePackage.java new file mode 100644 index 0000000..35ddb37 --- /dev/null +++ b/epkcompiler/src/CompilePackage.java @@ -0,0 +1,65 @@ +import java.io.ByteArrayOutputStream; +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.nio.charset.Charset; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; + +import com.jcraft.jzlib.Deflater; +import com.jcraft.jzlib.DeflaterOutputStream; + +public class CompilePackage { + + private static ArrayList files = new ArrayList(); + + public static void main(String[] args) throws IOException, NoSuchAlgorithmException { + File root = new File(args[0]); + listDirectory(root); + ByteArrayOutputStream osb = new ByteArrayOutputStream(); + DataOutputStream os = new DataOutputStream(osb); + String start = root.getAbsolutePath(); + os.write("EAGPKG!!".getBytes(Charset.forName("UTF-8"))); + os.writeUTF("\n\n # eaglercraft package file - assets copyright mojang ab\n # eagler eagler eagler eagler eagler eagler eagler\n\n"); + Deflater d = new Deflater(9); + os = new DataOutputStream(new DeflaterOutputStream(osb, d)); + MessageDigest md = MessageDigest.getInstance("SHA-1"); + for(File f : files) { + os.writeUTF(""); + String p = f.getAbsolutePath().replace(start, "").replace('\\', '/'); + if(p.startsWith("/")) p = p.substring(1); + os.writeUTF(p); + + InputStream stream = new FileInputStream(f); + byte[] targetArray = new byte[stream.available()]; + stream.read(targetArray); + stream.close(); + + os.write(md.digest(targetArray)); + os.writeInt(targetArray.length); + os.write(targetArray); + os.writeUTF(""); + } + os.writeUTF(" end"); + os.flush(); + os.close(); + FileOutputStream out = new FileOutputStream(new File("out.epk")); + out.write(osb.toByteArray()); + out.close(); + } + + public static void listDirectory(File dir) { + for(File f : dir.listFiles()) { + if(f.isDirectory()) { + listDirectory(f); + }else { + files.add(f); + } + } + } + +} diff --git a/epkcompiler/src/com/jcraft/jzlib/Adler32.java b/epkcompiler/src/com/jcraft/jzlib/Adler32.java new file mode 100644 index 0000000..02a07e1 --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/Adler32.java @@ -0,0 +1,118 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class Adler32 implements Checksum { + + // largest prime smaller than 65536 + static final private int BASE=65521; + // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 + static final private int NMAX=5552; + + private long s1=1L; + private long s2=0L; + + public void reset(long init){ + s1=init&0xffff; + s2=(init>>16)&0xffff; + } + + public void reset(){ + s1=1L; + s2=0L; + } + + public long getValue(){ + return ((s2<<16)|s1); + } + + public void update(byte[] buf, int index, int len){ + + if(len==1){ + s1+=buf[index++]&0xff; s2+=s1; + s1%=BASE; + s2%=BASE; + return; + } + + int len1 = len/NMAX; + int len2 = len%NMAX; + while(len1-->0) { + int k=NMAX; + len-=k; + while(k-->0){ + s1+=buf[index++]&0xff; s2+=s1; + } + s1%=BASE; + s2%=BASE; + } + + int k=len2; + len-=k; + while(k-->0){ + s1+=buf[index++]&0xff; s2+=s1; + } + s1%=BASE; + s2%=BASE; + } + + public Adler32 copy(){ + Adler32 foo = new Adler32(); + foo.s1 = this.s1; + foo.s2 = this.s2; + return foo; + } + + // The following logic has come from zlib.1.2. + static long combine(long adler1, long adler2, long len2){ + long BASEL = (long)BASE; + long sum1; + long sum2; + long rem; // unsigned int + + rem = len2 % BASEL; + sum1 = adler1 & 0xffffL; + sum2 = rem * sum1; + sum2 %= BASEL; // MOD(sum2); + sum1 += (adler2 & 0xffffL) + BASEL - 1; + sum2 += ((adler1 >> 16) & 0xffffL) + ((adler2 >> 16) & 0xffffL) + BASEL - rem; + if (sum1 >= BASEL) sum1 -= BASEL; + if (sum1 >= BASEL) sum1 -= BASEL; + if (sum2 >= (BASEL << 1)) sum2 -= (BASEL << 1); + if (sum2 >= BASEL) sum2 -= BASEL; + return sum1 | (sum2 << 16); + } + +} diff --git a/epkcompiler/src/com/jcraft/jzlib/CRC32.java b/epkcompiler/src/com/jcraft/jzlib/CRC32.java new file mode 100644 index 0000000..a1b6e75 --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/CRC32.java @@ -0,0 +1,157 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class CRC32 implements Checksum { + + /* + * The following logic has come from RFC1952. + */ + private int v = 0; + private static int[] crc_table = null; + static { + crc_table = new int[256]; + for (int n = 0; n < 256; n++) { + int c = n; + for (int k = 8; --k >= 0; ) { + if ((c & 1) != 0) + c = 0xedb88320 ^ (c >>> 1); + else + c = c >>> 1; + } + crc_table[n] = c; + } + } + + public void update (byte[] buf, int index, int len) { + int c = ~v; + while (--len >= 0) + c = crc_table[(c^buf[index++])&0xff]^(c >>> 8); + v = ~c; + } + + public void reset(){ + v = 0; + } + + public void reset(long vv){ + v = (int)(vv&0xffffffffL); + } + + public long getValue(){ + return (long)(v&0xffffffffL); + } + + // The following logic has come from zlib.1.2. + private static final int GF2_DIM = 32; + static long combine(long crc1, long crc2, long len2){ + long row; + long[] even = new long[GF2_DIM]; + long[] odd = new long[GF2_DIM]; + + // degenerate case (also disallow negative lengths) + if (len2 <= 0) + return crc1; + + // put operator for one zero bit in odd + odd[0] = 0xedb88320L; // CRC-32 polynomial + row = 1; + for (int n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + // put operator for two zero bits in even + gf2_matrix_square(even, odd); + + // put operator for four zero bits in odd + gf2_matrix_square(odd, even); + + // apply len2 zeros to crc1 (first square will put the operator for one + // zero byte, eight zero bits, in even) + do { + // apply zeros operator for this bit of len2 + gf2_matrix_square(even, odd); + if ((len2 & 1)!=0) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + // if no more bits set, then done + if (len2 == 0) + break; + + // another iteration of the loop with odd and even swapped + gf2_matrix_square(odd, even); + if ((len2 & 1)!=0) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + // if no more bits set, then done + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; + } + + private static long gf2_matrix_times(long[] mat, long vec){ + long sum = 0; + int index = 0; + while (vec!=0) { + if ((vec & 1)!=0) + sum ^= mat[index]; + vec >>= 1; + index++; + } + return sum; + } + + static final void gf2_matrix_square(long[] square, long[] mat) { + for (int n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); + } + + public CRC32 copy(){ + CRC32 foo = new CRC32(); + foo.v = this.v; + return foo; + } + + public static int[] getCRC32Table(){ + int[] tmp = new int[crc_table.length]; + System.arraycopy(crc_table, 0, tmp, 0, tmp.length); + return tmp; + } +} diff --git a/epkcompiler/src/com/jcraft/jzlib/Checksum.java b/epkcompiler/src/com/jcraft/jzlib/Checksum.java new file mode 100644 index 0000000..1139093 --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/Checksum.java @@ -0,0 +1,43 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +interface Checksum { + void update(byte[] buf, int index, int len); + void reset(); + void reset(long init); + long getValue(); + Checksum copy(); +} diff --git a/epkcompiler/src/com/jcraft/jzlib/Deflate.java b/epkcompiler/src/com/jcraft/jzlib/Deflate.java new file mode 100644 index 0000000..cfda0f0 --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/Deflate.java @@ -0,0 +1,1757 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +public +final class Deflate implements Cloneable { + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_DEFAULT_COMPRESSION=-1; + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_MEM_LEVEL=8; + + static class Config{ + int good_length; // reduce lazy search above this match length + int max_lazy; // do not perform lazy search above this match length + int nice_length; // quit search above this match length + int max_chain; + int func; + Config(int good_length, int max_lazy, + int nice_length, int max_chain, int func){ + this.good_length=good_length; + this.max_lazy=max_lazy; + this.nice_length=nice_length; + this.max_chain=max_chain; + this.func=func; + } + } + + static final private int STORED=0; + static final private int FAST=1; + static final private int SLOW=2; + static final private Config[] config_table; + static{ + config_table=new Config[10]; + // good lazy nice chain + config_table[0]=new Config(0, 0, 0, 0, STORED); + config_table[1]=new Config(4, 4, 8, 4, FAST); + config_table[2]=new Config(4, 5, 16, 8, FAST); + config_table[3]=new Config(4, 6, 32, 32, FAST); + + config_table[4]=new Config(4, 4, 16, 16, SLOW); + config_table[5]=new Config(8, 16, 32, 32, SLOW); + config_table[6]=new Config(8, 16, 128, 128, SLOW); + config_table[7]=new Config(8, 32, 128, 256, SLOW); + config_table[8]=new Config(32, 128, 258, 1024, SLOW); + config_table[9]=new Config(32, 258, 258, 4096, SLOW); + } + + static final private String[] z_errmsg = { + "need dictionary", // Z_NEED_DICT 2 + "stream end", // Z_STREAM_END 1 + "", // Z_OK 0 + "file error", // Z_ERRNO (-1) + "stream error", // Z_STREAM_ERROR (-2) + "data error", // Z_DATA_ERROR (-3) + "insufficient memory", // Z_MEM_ERROR (-4) + "buffer error", // Z_BUF_ERROR (-5) + "incompatible version",// Z_VERSION_ERROR (-6) + "" + }; + + // block not completed, need more input or more output + static final private int NeedMore=0; + + // block flush performed + static final private int BlockDone=1; + + // finish started, need only more output at next deflate + static final private int FinishStarted=2; + + // finish done, accept no more input or output + static final private int FinishDone=3; + + // preset dictionary flag in zlib header + static final private int PRESET_DICT=0x20; + + static final private int Z_FILTERED=1; + static final private int Z_HUFFMAN_ONLY=2; + static final private int Z_DEFAULT_STRATEGY=0; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + static final private int INIT_STATE=42; + static final private int BUSY_STATE=113; + static final private int FINISH_STATE=666; + + // The deflate compression method + static final private int Z_DEFLATED=8; + + static final private int STORED_BLOCK=0; + static final private int STATIC_TREES=1; + static final private int DYN_TREES=2; + + // The three kinds of block type + static final private int Z_BINARY=0; + static final private int Z_ASCII=1; + static final private int Z_UNKNOWN=2; + + static final private int Buf_size=8*2; + + // repeat previous bit length 3-6 times (2 bits of repeat count) + static final private int REP_3_6=16; + + // repeat a zero length 3-10 times (3 bits of repeat count) + static final private int REPZ_3_10=17; + + // repeat a zero length 11-138 times (7 bits of repeat count) + static final private int REPZ_11_138=18; + + static final private int MIN_MATCH=3; + static final private int MAX_MATCH=258; + static final private int MIN_LOOKAHEAD=(MAX_MATCH+MIN_MATCH+1); + + static final private int MAX_BITS=15; + static final private int D_CODES=30; + static final private int BL_CODES=19; + static final private int LENGTH_CODES=29; + static final private int LITERALS=256; + static final private int L_CODES=(LITERALS+1+LENGTH_CODES); + static final private int HEAP_SIZE=(2*L_CODES+1); + + static final private int END_BLOCK=256; + + ZStream strm; // pointer back to this zlib stream + int status; // as the name implies + byte[] pending_buf; // output still pending + int pending_buf_size; // size of pending_buf + int pending_out; // next pending byte to output to the stream + int pending; // nb of bytes in the pending buffer + int wrap = 1; + byte data_type; // UNKNOWN, BINARY or ASCII + byte method; // STORED (for zip only) or DEFLATED + int last_flush; // value of flush param for previous deflate call + + int w_size; // LZ77 window size (32K by default) + int w_bits; // log2(w_size) (8..16) + int w_mask; // w_size - 1 + + byte[] window; + // Sliding window. Input bytes are read into the second half of the window, + // and move to the first half later to keep a dictionary of at least wSize + // bytes. With this organization, matches are limited to a distance of + // wSize-MAX_MATCH bytes, but this ensures that IO is always + // performed with a length multiple of the block size. Also, it limits + // the window size to 64K, which is quite useful on MSDOS. + // To do: use the user input buffer as sliding window. + + int window_size; + // Actual size of window: 2*wSize, except when the user input buffer + // is directly used as sliding window. + + short[] prev; + // Link to older string with same hash index. To limit the size of this + // array to 64K, this link is maintained only for the last 32K strings. + // An index in this array is thus a window index modulo 32K. + + short[] head; // Heads of the hash chains or NIL. + + int ins_h; // hash index of string to be inserted + int hash_size; // number of elements in hash table + int hash_bits; // log2(hash_size) + int hash_mask; // hash_size-1 + + // Number of bits by which ins_h must be shifted at each input + // step. It must be such that after MIN_MATCH steps, the oldest + // byte no longer takes part in the hash key, that is: + // hash_shift * MIN_MATCH >= hash_bits + int hash_shift; + + // Window position at the beginning of the current output block. Gets + // negative when the window is moved backwards. + + int block_start; + + int match_length; // length of best match + int prev_match; // previous match + int match_available; // set if previous match exists + int strstart; // start of string to insert + int match_start; // start of matching string + int lookahead; // number of valid bytes ahead in window + + // Length of the best match at previous step. Matches not greater than this + // are discarded. This is used in the lazy match evaluation. + int prev_length; + + // To speed up deflation, hash chains are never searched beyond this + // length. A higher limit improves compression ratio but degrades the speed. + int max_chain_length; + + // Attempt to find a better match only when the current match is strictly + // smaller than this value. This mechanism is used only for compression + // levels >= 4. + int max_lazy_match; + + // Insert new strings in the hash table only if the match length is not + // greater than this length. This saves time but degrades compression. + // max_insert_length is used only for compression levels <= 3. + + int level; // compression level (1..9) + int strategy; // favor or force Huffman coding + + // Use a faster search when the previous match is longer than this + int good_match; + + // Stop searching when current match exceeds this + int nice_match; + + short[] dyn_ltree; // literal and length tree + short[] dyn_dtree; // distance tree + short[] bl_tree; // Huffman tree for bit lengths + + Tree l_desc=new Tree(); // desc for literal tree + Tree d_desc=new Tree(); // desc for distance tree + Tree bl_desc=new Tree(); // desc for bit length tree + + // number of codes at each bit length for an optimal tree + short[] bl_count=new short[MAX_BITS+1]; + // working area to be used in Tree#gen_codes() + short[] next_code=new short[MAX_BITS+1]; + + // heap used to build the Huffman trees + int[] heap=new int[2*L_CODES+1]; + + int heap_len; // number of elements in the heap + int heap_max; // element of largest frequency + // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + // The same heap array is used to build all trees. + + // Depth of each subtree used as tie breaker for trees of equal frequency + byte[] depth=new byte[2*L_CODES+1]; + + byte[] l_buf; // index for literals or lengths */ + + // Size of match buffer for literals/lengths. There are 4 reasons for + // limiting lit_bufsize to 64K: + // - frequencies can be kept in 16 bit counters + // - if compression is not successful for the first block, all input + // data is still in the window so we can still emit a stored block even + // when input comes from standard input. (This can also be done for + // all blocks if lit_bufsize is not greater than 32K.) + // - if compression is not successful for a file smaller than 64K, we can + // even emit a stored file instead of a stored block (saving 5 bytes). + // This is applicable only for zip (not gzip or zlib). + // - creating new Huffman trees less frequently may not provide fast + // adaptation to changes in the input data statistics. (Take for + // example a binary file with poorly compressible code followed by + // a highly compressible string table.) Smaller buffer sizes give + // fast adaptation but have of course the overhead of transmitting + // trees more frequently. + // - I can't count above 4 + int lit_bufsize; + + int last_lit; // running index in l_buf + + // Buffer for distances. To simplify the code, d_buf and l_buf have + // the same number of elements. To use different lengths, an extra flag + // array would be necessary. + + int d_buf; // index of pendig_buf + + int opt_len; // bit length of current block with optimal trees + int static_len; // bit length of current block with static trees + int matches; // number of string matches in current block + int last_eob_len; // bit length of EOB code for last block + + // Output buffer. bits are inserted starting at the bottom (least + // significant bits). + short bi_buf; + + // Number of valid bits in bi_buf. All bits above the last valid bit + // are always zero. + int bi_valid; + + GZIPHeader gheader = null; + + Deflate(ZStream strm){ + this.strm=strm; + dyn_ltree=new short[HEAP_SIZE*2]; + dyn_dtree=new short[(2*D_CODES+1)*2]; // distance tree + bl_tree=new short[(2*BL_CODES+1)*2]; // Huffman tree for bit lengths + } + + void lm_init() { + window_size=2*w_size; + + head[hash_size-1]=0; + for(int i=0; i= 3; max_blindex--) { + if (bl_tree[Tree.bl_order[max_blindex]*2+1] != 0) break; + } + // Update opt_len to include the bit length tree and counts + opt_len += 3*(max_blindex+1) + 5+5+4; + + return max_blindex; + } + + + // Send the header for a block using dynamic Huffman trees: the counts, the + // lengths of the bit length codes, the literal tree and the distance tree. + // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + void send_all_trees(int lcodes, int dcodes, int blcodes){ + int rank; // index in bl_order + + send_bits(lcodes-257, 5); // not +255 as stated in appnote.txt + send_bits(dcodes-1, 5); + send_bits(blcodes-4, 4); // not -3 as stated in appnote.txt + for (rank = 0; rank < blcodes; rank++) { + send_bits(bl_tree[Tree.bl_order[rank]*2+1], 3); + } + send_tree(dyn_ltree, lcodes-1); // literal tree + send_tree(dyn_dtree, dcodes-1); // distance tree + } + + // Send a literal or distance tree in compressed form, using the codes in + // bl_tree. + void send_tree (short[] tree,// the tree to be sent + int max_code // and its largest code of non zero frequency + ){ + int n; // iterates over all tree elements + int prevlen = -1; // last emitted length + int curlen; // length of current code + int nextlen = tree[0*2+1]; // length of next code + int count = 0; // repeat count of the current code + int max_count = 7; // max repeat count + int min_count = 4; // min repeat count + + if (nextlen == 0){ max_count = 138; min_count = 3; } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[(n+1)*2+1]; + if(++count < max_count && curlen == nextlen) { + continue; + } + else if(count < min_count) { + do { send_code(curlen, bl_tree); } while (--count != 0); + } + else if(curlen != 0){ + if(curlen != prevlen){ + send_code(curlen, bl_tree); count--; + } + send_code(REP_3_6, bl_tree); + send_bits(count-3, 2); + } + else if(count <= 10){ + send_code(REPZ_3_10, bl_tree); + send_bits(count-3, 3); + } + else{ + send_code(REPZ_11_138, bl_tree); + send_bits(count-11, 7); + } + count = 0; prevlen = curlen; + if(nextlen == 0){ + max_count = 138; min_count = 3; + } + else if(curlen == nextlen){ + max_count = 6; min_count = 3; + } + else{ + max_count = 7; min_count = 4; + } + } + } + + // Output a byte on the stream. + // IN assertion: there is enough room in pending_buf. + final void put_byte(byte[] p, int start, int len){ + System.arraycopy(p, start, pending_buf, pending, len); + pending+=len; + } + + final void put_byte(byte c){ + pending_buf[pending++]=c; + } + final void put_short(int w) { + put_byte((byte)(w/*&0xff*/)); + put_byte((byte)(w>>>8)); + } + final void putShortMSB(int b){ + put_byte((byte)(b>>8)); + put_byte((byte)(b/*&0xff*/)); + } + + final void send_code(int c, short[] tree){ + int c2=c*2; + send_bits((tree[c2]&0xffff), (tree[c2+1]&0xffff)); + } + + void send_bits(int value, int length){ + int len = length; + if (bi_valid > (int)Buf_size - len) { + int val = value; +// bi_buf |= (val << bi_valid); + bi_buf |= ((val << bi_valid)&0xffff); + put_short(bi_buf); + bi_buf = (short)(val >>> (Buf_size - bi_valid)); + bi_valid += len - Buf_size; + } else { +// bi_buf |= (value) << bi_valid; + bi_buf |= (((value) << bi_valid)&0xffff); + bi_valid += len; + } + } + + // Send one empty static block to give enough lookahead for inflate. + // This takes 10 bits, of which 7 may remain in the bit buffer. + // The current inflate code requires 9 bits of lookahead. If the + // last two codes for the previous block (real code plus EOB) were coded + // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + // the last real code. In this case we send two empty static blocks instead + // of one. (There are no problems if the previous block is stored or fixed.) + // To simplify the code, we assume the worst case of last real code encoded + // on one bit only. + void _tr_align(){ + send_bits(STATIC_TREES<<1, 3); + send_code(END_BLOCK, StaticTree.static_ltree); + + bi_flush(); + + // Of the 10 bits for the empty block, we have already sent + // (10 - bi_valid) bits. The lookahead for the last real code (before + // the EOB of the previous block) was thus at least one plus the length + // of the EOB plus what we have just sent of the empty static block. + if (1 + last_eob_len + 10 - bi_valid < 9) { + send_bits(STATIC_TREES<<1, 3); + send_code(END_BLOCK, StaticTree.static_ltree); + bi_flush(); + } + last_eob_len = 7; + } + + + // Save the match info and tally the frequency counts. Return true if + // the current block must be flushed. + boolean _tr_tally (int dist, // distance of matched string + int lc // match length-MIN_MATCH or unmatched char (if dist==0) + ){ + + pending_buf[d_buf+last_lit*2] = (byte)(dist>>>8); + pending_buf[d_buf+last_lit*2+1] = (byte)dist; + + l_buf[last_lit] = (byte)lc; last_lit++; + + if (dist == 0) { + // lc is the unmatched char + dyn_ltree[lc*2]++; + } + else { + matches++; + // Here, lc is the match length - MIN_MATCH + dist--; // dist = match distance - 1 + dyn_ltree[(Tree._length_code[lc]+LITERALS+1)*2]++; + dyn_dtree[Tree.d_code(dist)*2]++; + } + + if ((last_lit & 0x1fff) == 0 && level > 2) { + // Compute an upper bound for the compressed length + int out_length = last_lit*8; + int in_length = strstart - block_start; + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (int)dyn_dtree[dcode*2] * + (5L+Tree.extra_dbits[dcode]); + } + out_length >>>= 3; + if ((matches < (last_lit/2)) && out_length < in_length/2) return true; + } + + return (last_lit == lit_bufsize-1); + // We avoid equality with lit_bufsize because of wraparound at 64K + // on 16 bit machines and because stored blocks are restricted to + // 64K-1 bytes. + } + + // Send the block data compressed using the given Huffman trees + void compress_block(short[] ltree, short[] dtree){ + int dist; // distance of matched string + int lc; // match length or unmatched char (if dist == 0) + int lx = 0; // running index in l_buf + int code; // the code to send + int extra; // number of extra bits to send + + if (last_lit != 0){ + do{ + dist=((pending_buf[d_buf+lx*2]<<8)&0xff00)| + (pending_buf[d_buf+lx*2+1]&0xff); + lc=(l_buf[lx])&0xff; lx++; + + if(dist == 0){ + send_code(lc, ltree); // send a literal byte + } + else{ + // Here, lc is the match length - MIN_MATCH + code = Tree._length_code[lc]; + + send_code(code+LITERALS+1, ltree); // send the length code + extra = Tree.extra_lbits[code]; + if(extra != 0){ + lc -= Tree.base_length[code]; + send_bits(lc, extra); // send the extra length bits + } + dist--; // dist is now the match distance - 1 + code = Tree.d_code(dist); + + send_code(code, dtree); // send the distance code + extra = Tree.extra_dbits[code]; + if (extra != 0) { + dist -= Tree.base_dist[code]; + send_bits(dist, extra); // send the extra distance bits + } + } // literal or match pair ? + + // Check that the overlay between pending_buf and d_buf+l_buf is ok: + } + while (lx < last_lit); + } + + send_code(END_BLOCK, ltree); + last_eob_len = ltree[END_BLOCK*2+1]; + } + + // Set the data type to ASCII or BINARY, using a crude approximation: + // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + // IN assertion: the fields freq of dyn_ltree are set and the total of all + // frequencies does not exceed 64K (to fit in an int on 16 bit machines). + void set_data_type(){ + int n = 0; + int ascii_freq = 0; + int bin_freq = 0; + while(n<7){ bin_freq += dyn_ltree[n*2]; n++;} + while(n<128){ ascii_freq += dyn_ltree[n*2]; n++;} + while(n (ascii_freq >>> 2) ? Z_BINARY : Z_ASCII); + } + + // Flush the bit buffer, keeping at most 7 bits in it. + void bi_flush(){ + if (bi_valid == 16) { + put_short(bi_buf); + bi_buf=0; + bi_valid=0; + } + else if (bi_valid >= 8) { + put_byte((byte)bi_buf); + bi_buf>>>=8; + bi_valid-=8; + } + } + + // Flush the bit buffer and align the output on a byte boundary + void bi_windup(){ + if (bi_valid > 8) { + put_short(bi_buf); + } else if (bi_valid > 0) { + put_byte((byte)bi_buf); + } + bi_buf = 0; + bi_valid = 0; + } + + // Copy a stored block, storing first the length and its + // one's complement if requested. + void copy_block(int buf, // the input data + int len, // its length + boolean header // true if block header must be written + ){ + int index=0; + bi_windup(); // align on byte boundary + last_eob_len = 8; // enough lookahead for inflate + + if (header) { + put_short((short)len); + put_short((short)~len); + } + + // while(len--!=0) { + // put_byte(window[buf+index]); + // index++; + // } + put_byte(window, buf, len); + } + + void flush_block_only(boolean eof){ + _tr_flush_block(block_start>=0 ? block_start : -1, + strstart-block_start, + eof); + block_start=strstart; + strm.flush_pending(); + } + + // Copy without compression as much as possible from the input stream, return + // the current block state. + // This function does not insert new strings in the dictionary since + // uncompressible data is probably not useful. This function is used + // only for the level=0 compression option. + // NOTE: this function should be optimized to avoid extra copying from + // window to pending_buf. + int deflate_stored(int flush){ + // Stored blocks are limited to 0xffff bytes, pending_buf is limited + // to pending_buf_size, and each stored block has a 5 byte header: + + int max_block_size = 0xffff; + int max_start; + + if(max_block_size > pending_buf_size - 5) { + max_block_size = pending_buf_size - 5; + } + + // Copy as much as possible from input to output: + while(true){ + // Fill the window as much as possible: + if(lookahead<=1){ + fill_window(); + if(lookahead==0 && flush==Z_NO_FLUSH) return NeedMore; + if(lookahead==0) break; // flush the current block + } + + strstart+=lookahead; + lookahead=0; + + // Emit a stored block if pending_buf will be full: + max_start=block_start+max_block_size; + if(strstart==0|| strstart>=max_start) { + // strstart == 0 is possible when wraparound on 16-bit machine + lookahead = (int)(strstart-max_start); + strstart = (int)max_start; + + flush_block_only(false); + if(strm.avail_out==0) return NeedMore; + + } + + // Flush if we may have to slide, otherwise block_start may become + // negative and the data will be gone: + if(strstart-block_start >= w_size-MIN_LOOKAHEAD) { + flush_block_only(false); + if(strm.avail_out==0) return NeedMore; + } + } + + flush_block_only(flush == Z_FINISH); + if(strm.avail_out==0) + return (flush == Z_FINISH) ? FinishStarted : NeedMore; + + return flush == Z_FINISH ? FinishDone : BlockDone; + } + + // Send a stored block + void _tr_stored_block(int buf, // input block + int stored_len, // length of input block + boolean eof // true if this is the last block for a file + ){ + send_bits((STORED_BLOCK<<1)+(eof?1:0), 3); // send block type + copy_block(buf, stored_len, true); // with header + } + + // Determine the best encoding for the current block: dynamic trees, static + // trees or store, and output the encoded block to the zip file. + void _tr_flush_block(int buf, // input block, or NULL if too old + int stored_len, // length of input block + boolean eof // true if this is the last block for a file + ) { + int opt_lenb, static_lenb;// opt_len and static_len in bytes + int max_blindex = 0; // index of last bit length code of non zero freq + + // Build the Huffman trees unless a stored block is forced + if(level > 0) { + // Check if the file is ascii or binary + if(data_type == Z_UNKNOWN) set_data_type(); + + // Construct the literal and distance trees + l_desc.build_tree(this); + + d_desc.build_tree(this); + + // At this point, opt_len and static_len are the total bit lengths of + // the compressed block data, excluding the tree representations. + + // Build the bit length tree for the above two trees, and get the index + // in bl_order of the last bit length code to send. + max_blindex=build_bl_tree(); + + // Determine the best encoding. Compute first the block length in bytes + opt_lenb=(opt_len+3+7)>>>3; + static_lenb=(static_len+3+7)>>>3; + + if(static_lenb<=opt_lenb) opt_lenb=static_lenb; + } + else { + opt_lenb=static_lenb=stored_len+5; // force a stored block + } + + if(stored_len+4<=opt_lenb && buf != -1){ + // 4: two words for the lengths + // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + // Otherwise we can't have processed more than WSIZE input bytes since + // the last block flush, because compression would have been + // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + // transform a block into a stored block. + _tr_stored_block(buf, stored_len, eof); + } + else if(static_lenb == opt_lenb){ + send_bits((STATIC_TREES<<1)+(eof?1:0), 3); + compress_block(StaticTree.static_ltree, StaticTree.static_dtree); + } + else{ + send_bits((DYN_TREES<<1)+(eof?1:0), 3); + send_all_trees(l_desc.max_code+1, d_desc.max_code+1, max_blindex+1); + compress_block(dyn_ltree, dyn_dtree); + } + + // The above check is made mod 2^32, for files larger than 512 MB + // and uLong implemented on 32 bits. + + init_block(); + + if(eof){ + bi_windup(); + } + } + + // Fill the window when the lookahead becomes insufficient. + // Updates strstart and lookahead. + // + // IN assertion: lookahead < MIN_LOOKAHEAD + // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + // At least one byte has been read, or avail_in == 0; reads are + // performed for at least two bytes (required for the zip translate_eol + // option -- not supported here). + void fill_window(){ + int n, m; + int p; + int more; // Amount of free space at the end of the window. + + do{ + more = (window_size-lookahead-strstart); + + // Deal with !@#$% 64K limit: + if(more==0 && strstart==0 && lookahead==0){ + more = w_size; + } + else if(more==-1) { + // Very unlikely, but possible on 16 bit machine if strstart == 0 + // and lookahead == 1 (input done one byte at time) + more--; + + // If the window is almost full and there is insufficient lookahead, + // move the upper half to the lower one to make room in the upper half. + } + else if(strstart >= w_size+ w_size-MIN_LOOKAHEAD) { + System.arraycopy(window, w_size, window, 0, w_size); + match_start-=w_size; + strstart-=w_size; // we now have strstart >= MAX_DIST + block_start-=w_size; + + // Slide the hash table (could be avoided with 32 bit values + // at the expense of memory usage). We slide even when level == 0 + // to keep the hash table consistent if we switch back to level > 0 + // later. (Using level 0 permanently is not an optimal usage of + // zlib, so we don't care about this pathological case.) + + n = hash_size; + p=n; + do { + m = (head[--p]&0xffff); + head[p]=(m>=w_size ? (short)(m-w_size) : 0); + } + while (--n != 0); + + n = w_size; + p = n; + do { + m = (prev[--p]&0xffff); + prev[p] = (m >= w_size ? (short)(m-w_size) : 0); + // If n is not on any hash chain, prev[n] is garbage but + // its value will never be used. + } + while (--n!=0); + more += w_size; + } + + if (strm.avail_in == 0) return; + + // If there was no sliding: + // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + // more == window_size - lookahead - strstart + // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + // => more >= window_size - 2*WSIZE + 2 + // In the BIG_MEM or MMAP case (not yet supported), + // window_size == input_size + MIN_LOOKAHEAD && + // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + // Otherwise, window_size == 2*WSIZE so more >= 2. + // If there was sliding, more >= WSIZE. So in all cases, more >= 2. + + n = strm.read_buf(window, strstart + lookahead, more); + lookahead += n; + + // Initialize the hash value now that we have some input: + if(lookahead >= MIN_MATCH) { + ins_h = window[strstart]&0xff; + ins_h=(((ins_h)<= MIN_MATCH){ + ins_h=(((ins_h)<=MIN_MATCH){ + // check_match(strstart, match_start, match_length); + + bflush=_tr_tally(strstart-match_start, match_length-MIN_MATCH); + + lookahead -= match_length; + + // Insert new strings in the hash table only if the match length + // is not too large. This saves time but degrades compression. + if(match_length <= max_lazy_match && + lookahead >= MIN_MATCH) { + match_length--; // string at strstart already in hash table + do{ + strstart++; + + ins_h=((ins_h<= MIN_MATCH) { + ins_h=(((ins_h)< 4096))) { + + // If prev_match is also MIN_MATCH, match_start is garbage + // but we will ignore the current match anyway. + match_length = MIN_MATCH-1; + } + } + + // If there was a match at the previous step and the current + // match is not better, output the previous match: + if(prev_length >= MIN_MATCH && match_length <= prev_length) { + int max_insert = strstart + lookahead - MIN_MATCH; + // Do not insert strings in hash table beyond this. + + // check_match(strstart-1, prev_match, prev_length); + + bflush=_tr_tally(strstart-1-prev_match, prev_length - MIN_MATCH); + + // Insert in hash table all strings up to the end of the match. + // strstart-1 and strstart are already inserted. If there is not + // enough lookahead, the last two strings are not inserted in + // the hash table. + lookahead -= prev_length-1; + prev_length -= 2; + do{ + if(++strstart <= max_insert) { + ins_h=(((ins_h)<(w_size-MIN_LOOKAHEAD) ? + strstart-(w_size-MIN_LOOKAHEAD) : 0; + int nice_match=this.nice_match; + + // Stop when cur_match becomes <= limit. To simplify the code, + // we prevent matches with the string of window index 0. + + int wmask = w_mask; + + int strend = strstart + MAX_MATCH; + byte scan_end1 = window[scan+best_len-1]; + byte scan_end = window[scan+best_len]; + + // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + // It is easy to get rid of this optimization if necessary. + + // Do not waste too much time if we already have a good match: + if (prev_length >= good_match) { + chain_length >>= 2; + } + + // Do not look for matches beyond the end of the input. This is necessary + // to make deflate deterministic. + if (nice_match > lookahead) nice_match = lookahead; + + do { + match = cur_match; + + // Skip to next match if the match length cannot increase + // or if the match length is less than 2: + if (window[match+best_len] != scan_end || + window[match+best_len-1] != scan_end1 || + window[match] != window[scan] || + window[++match] != window[scan+1]) continue; + + // The check at best_len-1 can be removed because it will be made + // again later. (This heuristic is not always a win.) + // It is not necessary to compare scan[2] and match[2] since they + // are always equal when the other bytes match, given that + // the hash keys are equal and that HASH_BITS >= 8. + scan += 2; match++; + + // We check for insufficient lookahead only every 8th comparison; + // the 256th check will be made at strstart+258. + do { + } while (window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + scan < strend); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + + if(len>best_len) { + match_start = cur_match; + best_len = len; + if (len >= nice_match) break; + scan_end1 = window[scan+best_len-1]; + scan_end = window[scan+best_len]; + } + + } while ((cur_match = (prev[cur_match & wmask]&0xffff)) > limit + && --chain_length != 0); + + if (best_len <= lookahead) return best_len; + return lookahead; + } + + int deflateInit(int level, int bits, int memlevel){ + return deflateInit(level, Z_DEFLATED, bits, memlevel, + Z_DEFAULT_STRATEGY); + } + + int deflateInit(int level, int bits){ + return deflateInit(level, Z_DEFLATED, bits, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY); + } + int deflateInit(int level){ + return deflateInit(level, MAX_WBITS); + } + private int deflateInit(int level, int method, int windowBits, + int memLevel, int strategy){ + int wrap = 1; + // byte[] my_version=ZLIB_VERSION; + + // + // if (version == null || version[0] != my_version[0] + // || stream_size != sizeof(z_stream)) { + // return Z_VERSION_ERROR; + // } + + strm.msg = null; + + if (level == Z_DEFAULT_COMPRESSION) level = 6; + + if (windowBits < 0) { // undocumented feature: suppress zlib header + wrap = 0; + windowBits = -windowBits; + } + else if(windowBits > 15){ + wrap = 2; + windowBits -= 16; + strm.adler=new CRC32(); + } + + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || + method != Z_DEFLATED || + windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + + strm.dstate = (Deflate)this; + + this.wrap = wrap; + w_bits = windowBits; + w_size = 1 << w_bits; + w_mask = w_size - 1; + + hash_bits = memLevel + 7; + hash_size = 1 << hash_bits; + hash_mask = hash_size - 1; + hash_shift = ((hash_bits+MIN_MATCH-1)/MIN_MATCH); + + window = new byte[w_size*2]; + prev = new short[w_size]; + head = new short[hash_size]; + + lit_bufsize = 1 << (memLevel + 6); // 16K elements by default + + // We overlay pending_buf and d_buf+l_buf. This works since the average + // output size for (length,distance) codes is <= 24 bits. + pending_buf = new byte[lit_bufsize*3]; + pending_buf_size = lit_bufsize*3; + + d_buf = lit_bufsize; + l_buf = new byte[lit_bufsize]; + + this.level = level; + + this.strategy = strategy; + this.method = (byte)method; + + return deflateReset(); + } + + int deflateReset(){ + strm.total_in = strm.total_out = 0; + strm.msg = null; // + strm.data_type = Z_UNKNOWN; + + pending = 0; + pending_out = 0; + + if(wrap < 0){ + wrap = -wrap; + } + status = (wrap==0) ? BUSY_STATE : INIT_STATE; + strm.adler.reset(); + + last_flush = Z_NO_FLUSH; + + tr_init(); + lm_init(); + return Z_OK; + } + + int deflateEnd(){ + if(status!=INIT_STATE && status!=BUSY_STATE && status!=FINISH_STATE){ + return Z_STREAM_ERROR; + } + // Deallocate in reverse order of allocations: + pending_buf=null; + l_buf=null; + head=null; + prev=null; + window=null; + // free + // dstate=null; + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; + } + + int deflateParams(int _level, int _strategy){ + int err=Z_OK; + + if(_level == Z_DEFAULT_COMPRESSION){ + _level = 6; + } + if(_level < 0 || _level > 9 || + _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + + if(config_table[level].func!=config_table[_level].func && + strm.total_in != 0) { + // Flush the last buffer: + err = strm.deflate(Z_PARTIAL_FLUSH); + } + + if(level != _level) { + level = _level; + max_lazy_match = config_table[level].max_lazy; + good_match = config_table[level].good_length; + nice_match = config_table[level].nice_length; + max_chain_length = config_table[level].max_chain; + } + strategy = _strategy; + return err; + } + + int deflateSetDictionary (byte[] dictionary, int dictLength){ + int length = dictLength; + int index=0; + + if(dictionary == null || status != INIT_STATE) + return Z_STREAM_ERROR; + + strm.adler.update(dictionary, 0, dictLength); + + if(length < MIN_MATCH) return Z_OK; + if(length > w_size-MIN_LOOKAHEAD){ + length = w_size-MIN_LOOKAHEAD; + index=dictLength-length; // use the tail of the dictionary + } + System.arraycopy(dictionary, index, window, 0, length); + strstart = length; + block_start = length; + + // Insert all strings in the hash table (except for the last two bytes). + // s->lookahead stays null, so s->ins_h will be recomputed at the next + // call of fill_window. + + ins_h = window[0]&0xff; + ins_h=(((ins_h)<Z_FINISH || flush<0){ + return Z_STREAM_ERROR; + } + + if(strm.next_out == null || + (strm.next_in == null && strm.avail_in != 0) || + (status == FINISH_STATE && flush != Z_FINISH)) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_STREAM_ERROR)]; + return Z_STREAM_ERROR; + } + if(strm.avail_out == 0){ + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + old_flush = last_flush; + last_flush = flush; + + // Write the zlib header + if(status == INIT_STATE) { + if(wrap == 2){ + getGZIPHeader().put(this); + status=BUSY_STATE; + strm.adler.reset(); + } + else{ + int header = (Z_DEFLATED+((w_bits-8)<<4))<<8; + int level_flags=((level-1)&0xff)>>1; + + if(level_flags>3) level_flags=3; + header |= (level_flags<<6); + if(strstart!=0) header |= PRESET_DICT; + header+=31-(header % 31); + + status=BUSY_STATE; + putShortMSB(header); + + + // Save the adler32 of the preset dictionary: + if(strstart!=0){ + long adler=strm.adler.getValue(); + putShortMSB((int)(adler>>>16)); + putShortMSB((int)(adler&0xffff)); + } + strm.adler.reset(); + } + } + + // Flush as much pending output as possible + if(pending != 0) { + strm.flush_pending(); + if(strm.avail_out == 0) { + // Since avail_out is 0, deflate will be called again with + // more output space, but possibly with both pending and + // avail_in equal to zero. There won't be anything to do, + // but this is not an error situation so make sure we + // return OK instead of BUF_ERROR at next call of deflate: + last_flush = -1; + return Z_OK; + } + + // Make sure there is something to do and avoid duplicate consecutive + // flushes. For repeated and useless calls with Z_FINISH, we keep + // returning Z_STREAM_END instead of Z_BUFF_ERROR. + } + else if(strm.avail_in==0 && flush <= old_flush && + flush != Z_FINISH) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + // User must not provide more input after the first FINISH: + if(status == FINISH_STATE && strm.avail_in != 0) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + // Start a new block or continue the current one. + if(strm.avail_in!=0 || lookahead!=0 || + (flush != Z_NO_FLUSH && status != FINISH_STATE)) { + int bstate=-1; + switch(config_table[level].func){ + case STORED: + bstate = deflate_stored(flush); + break; + case FAST: + bstate = deflate_fast(flush); + break; + case SLOW: + bstate = deflate_slow(flush); + break; + default: + } + + if (bstate==FinishStarted || bstate==FinishDone) { + status = FINISH_STATE; + } + if (bstate==NeedMore || bstate==FinishStarted) { + if(strm.avail_out == 0) { + last_flush = -1; // avoid BUF_ERROR next call, see above + } + return Z_OK; + // If flush != Z_NO_FLUSH && avail_out == 0, the next call + // of deflate should use the same flush parameter to make sure + // that the flush is complete. So we don't have to output an + // empty block here, this will be done at next call. This also + // ensures that for a very small output buffer, we emit at most + // one empty block. + } + + if (bstate==BlockDone) { + if(flush == Z_PARTIAL_FLUSH) { + _tr_align(); + } + else { // FULL_FLUSH or SYNC_FLUSH + _tr_stored_block(0, 0, false); + // For a full flush, this empty block will be recognized + // as a special marker by inflate_sync(). + if(flush == Z_FULL_FLUSH) { + //state.head[s.hash_size-1]=0; + for(int i=0; i>8)&0xff)); + put_byte((byte)((adler>>16)&0xff)); + put_byte((byte)((adler>>24)&0xff)); + put_byte((byte)(strm.total_in&0xff)); + put_byte((byte)((strm.total_in>>8)&0xff)); + put_byte((byte)((strm.total_in>>16)&0xff)); + put_byte((byte)((strm.total_in>>24)&0xff)); + + getGZIPHeader().setCRC(adler); + } + else{ + // Write the zlib trailer (adler32) + long adler=strm.adler.getValue(); + putShortMSB((int)(adler>>>16)); + putShortMSB((int)(adler&0xffff)); + } + + strm.flush_pending(); + + // If avail_out is zero, the application will call deflate again + // to flush the rest. + + if(wrap > 0) wrap = -wrap; // write the trailer only once! + return pending != 0 ? Z_OK : Z_STREAM_END; + } + + static int deflateCopy(ZStream dest, ZStream src){ + + if(src.dstate == null){ + return Z_STREAM_ERROR; + } + + if(src.next_in!=null){ + dest.next_in = new byte[src.next_in.length]; + System.arraycopy(src.next_in, 0, dest.next_in, 0, src.next_in.length); + } + dest.next_in_index = src.next_in_index; + dest.avail_in = src.avail_in; + dest.total_in = src.total_in; + + if(src.next_out!=null){ + dest.next_out = new byte[src.next_out.length]; + System.arraycopy(src.next_out, 0, dest.next_out ,0 , src.next_out.length); + } + + dest.next_out_index = src.next_out_index; + dest.avail_out = src.avail_out; + dest.total_out = src.total_out; + + dest.msg = src.msg; + dest.data_type = src.data_type; + dest.adler = src.adler.copy(); + + try{ + dest.dstate = (Deflate)src.dstate.clone(); + dest.dstate.strm = dest; + } + catch(CloneNotSupportedException e){ + // + } + return Z_OK; + } + + public Object clone() throws CloneNotSupportedException { + Deflate dest = (Deflate)super.clone(); + + dest.pending_buf = dup(dest.pending_buf); + dest.d_buf = dest.d_buf; + dest.l_buf = dup(dest.l_buf); + dest.window = dup(dest.window); + + dest.prev = dup(dest.prev); + dest.head = dup(dest.head); + dest.dyn_ltree = dup(dest.dyn_ltree); + dest.dyn_dtree = dup(dest.dyn_dtree); + dest.bl_tree = dup(dest.bl_tree); + + dest.bl_count = dup(dest.bl_count); + dest.next_code = dup(dest.next_code); + dest.heap = dup(dest.heap); + dest.depth = dup(dest.depth); + + dest.l_desc.dyn_tree = dest.dyn_ltree; + dest.d_desc.dyn_tree = dest.dyn_dtree; + dest.bl_desc.dyn_tree = dest.bl_tree; + + /* + dest.l_desc.stat_desc = StaticTree.static_l_desc; + dest.d_desc.stat_desc = StaticTree.static_d_desc; + dest.bl_desc.stat_desc = StaticTree.static_bl_desc; + */ + + if(dest.gheader!=null){ + dest.gheader = (GZIPHeader)dest.gheader.clone(); + } + + return dest; + } + + private byte[] dup(byte[] buf){ + byte[] foo = new byte[buf.length]; + System.arraycopy(buf, 0, foo, 0, foo.length); + return foo; + } + private short[] dup(short[] buf){ + short[] foo = new short[buf.length]; + System.arraycopy(buf, 0, foo, 0, foo.length); + return foo; + } + private int[] dup(int[] buf){ + int[] foo = new int[buf.length]; + System.arraycopy(buf, 0, foo, 0, foo.length); + return foo; + } + + synchronized GZIPHeader getGZIPHeader(){ + if(gheader==null){ + gheader = new GZIPHeader(); + } + return gheader; + } +} diff --git a/epkcompiler/src/com/jcraft/jzlib/Deflater.java b/epkcompiler/src/com/jcraft/jzlib/Deflater.java new file mode 100644 index 0000000..ce0580d --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/Deflater.java @@ -0,0 +1,171 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class Deflater extends ZStream{ + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_WBITS=MAX_WBITS; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + private boolean finished = false; + + public Deflater(){ + super(); + } + + public Deflater(int level) throws GZIPException { + this(level, MAX_WBITS); + } + + public Deflater(int level, boolean nowrap) throws GZIPException { + this(level, MAX_WBITS, nowrap); + } + + public Deflater(int level, int bits) throws GZIPException { + this(level, bits, false); + } + + public Deflater(int level, int bits, boolean nowrap) throws GZIPException { + super(); + int ret = init(level, bits, nowrap); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + public Deflater(int level, int bits, int memlevel, JZlib.WrapperType wrapperType) throws GZIPException { + super(); + int ret = init(level, bits, memlevel, wrapperType); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + public Deflater(int level, int bits, int memlevel) throws GZIPException { + super(); + int ret = init(level, bits, memlevel); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + public int init(int level){ + return init(level, MAX_WBITS); + } + public int init(int level, boolean nowrap){ + return init(level, MAX_WBITS, nowrap); + } + public int init(int level, int bits){ + return init(level, bits, false); + } + public int init(int level, int bits, int memlevel, JZlib.WrapperType wrapperType){ + if(bits < 9 || bits > 15){ + return Z_STREAM_ERROR; + } + if(wrapperType == JZlib.W_NONE) { + bits *= -1; + } + else if(wrapperType == JZlib.W_GZIP) { + bits += 16; + } + else if(wrapperType == JZlib.W_ANY) { + return Z_STREAM_ERROR; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return init(level, bits, memlevel); + } + public int init(int level, int bits, int memlevel){ + finished = false; + dstate=new Deflate(this); + return dstate.deflateInit(level, bits, memlevel); + } + public int init(int level, int bits, boolean nowrap){ + finished = false; + dstate=new Deflate(this); + return dstate.deflateInit(level, nowrap?-bits:bits); + } + + public int deflate(int flush){ + if(dstate==null){ + return Z_STREAM_ERROR; + } + int ret = dstate.deflate(flush); + if(ret == Z_STREAM_END) + finished = true; + return ret; + } + public int end(){ + finished = true; + if(dstate==null) return Z_STREAM_ERROR; + int ret=dstate.deflateEnd(); + dstate=null; + free(); + return ret; + } + public int params(int level, int strategy){ + if(dstate==null) return Z_STREAM_ERROR; + return dstate.deflateParams(level, strategy); + } + public int setDictionary (byte[] dictionary, int dictLength){ + if(dstate == null) + return Z_STREAM_ERROR; + return dstate.deflateSetDictionary(dictionary, dictLength); + } + + public boolean finished(){ + return finished; + } + + public int copy(Deflater src){ + this.finished = src.finished; + return Deflate.deflateCopy(this, src); + } +} diff --git a/epkcompiler/src/com/jcraft/jzlib/DeflaterOutputStream.java b/epkcompiler/src/com/jcraft/jzlib/DeflaterOutputStream.java new file mode 100644 index 0000000..3c18836 --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/DeflaterOutputStream.java @@ -0,0 +1,181 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jcraft.jzlib; +import java.io.*; + +public class DeflaterOutputStream extends FilterOutputStream { + + protected final Deflater deflater; + + protected byte[] buffer; + + private boolean closed = false; + + private boolean syncFlush = false; + + private final byte[] buf1 = new byte[1]; + + protected boolean mydeflater = false; + + private boolean close_out = true; + + protected static final int DEFAULT_BUFSIZE = 512; + + public DeflaterOutputStream(OutputStream out) throws IOException { + this(out, + new Deflater(JZlib.Z_DEFAULT_COMPRESSION), + DEFAULT_BUFSIZE, true); + mydeflater = true; + } + + public DeflaterOutputStream(OutputStream out, Deflater def) throws IOException { + this(out, def, DEFAULT_BUFSIZE, true); + } + + public DeflaterOutputStream(OutputStream out, + Deflater deflater, + int size) throws IOException { + this(out, deflater, size, true); + } + public DeflaterOutputStream(OutputStream out, + Deflater deflater, + int size, + boolean close_out) throws IOException { + super(out); + if (out == null || deflater == null) { + throw new NullPointerException(); + } + else if (size <= 0) { + throw new IllegalArgumentException("buffer size must be greater than 0"); + } + this.deflater = deflater; + buffer = new byte[size]; + this.close_out = close_out; + } + + public void write(int b) throws IOException { + buf1[0] = (byte)(b & 0xff); + write(buf1, 0, 1); + } + + public void write(byte[] b, int off, int len) throws IOException { + if (deflater.finished()) { + throw new IOException("finished"); + } + else if (off<0 | len<0 | off+len>b.length) { + throw new IndexOutOfBoundsException(); + } + else if (len == 0) { + return; + } + else { + int flush = syncFlush ? JZlib.Z_SYNC_FLUSH : JZlib.Z_NO_FLUSH; + deflater.setInput(b, off, len, true); + while (deflater.avail_in>0) { + int err = deflate(flush); + if (err == JZlib.Z_STREAM_END) + break; + } + } + } + + public void finish() throws IOException { + while (!deflater.finished()) { + deflate(JZlib.Z_FINISH); + } + } + + public void close() throws IOException { + if (!closed) { + finish(); + if (mydeflater){ + deflater.end(); + } + if(close_out) + out.close(); + closed = true; + } + } + + protected int deflate(int flush) throws IOException { + deflater.setOutput(buffer, 0, buffer.length); + int err = deflater.deflate(flush); + switch(err) { + case JZlib.Z_OK: + case JZlib.Z_STREAM_END: + break; + case JZlib.Z_BUF_ERROR: + if(deflater.avail_in<=0 && flush!=JZlib.Z_FINISH){ + // flush() without any data + break; + } + default: + throw new IOException("failed to deflate: error="+err+" avail_out="+deflater.avail_out); + } + int len = deflater.next_out_index; + if (len > 0) { + out.write(buffer, 0, len); + } + return err; + } + + public void flush() throws IOException { + if (syncFlush && !deflater.finished()) { + while (true) { + int err = deflate(JZlib.Z_SYNC_FLUSH); + if (deflater.next_out_index < buffer.length) + break; + if (err == JZlib.Z_STREAM_END) + break; + } + } + out.flush(); + } + + public long getTotalIn() { + return deflater.getTotalIn(); + } + + public long getTotalOut() { + return deflater.getTotalOut(); + } + + public void setSyncFlush(boolean syncFlush){ + this.syncFlush = syncFlush; + } + + public boolean getSyncFlush(){ + return this.syncFlush; + } + + public Deflater getDeflater(){ + return deflater; + } +} diff --git a/epkcompiler/src/com/jcraft/jzlib/GZIPException.java b/epkcompiler/src/com/jcraft/jzlib/GZIPException.java new file mode 100644 index 0000000..0beef40 --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/GZIPException.java @@ -0,0 +1,44 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +public class GZIPException extends java.io.IOException { + public GZIPException() { + super(); + } + public GZIPException(String s) { + super(s); + } +} diff --git a/epkcompiler/src/com/jcraft/jzlib/GZIPHeader.java b/epkcompiler/src/com/jcraft/jzlib/GZIPHeader.java new file mode 100644 index 0000000..0405e00 --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/GZIPHeader.java @@ -0,0 +1,214 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +import java.io.UnsupportedEncodingException; + +/** + * @see "http://www.ietf.org/rfc/rfc1952.txt" + */ +public class GZIPHeader implements Cloneable { + + public static final byte OS_MSDOS = (byte) 0x00; + public static final byte OS_AMIGA = (byte) 0x01; + public static final byte OS_VMS = (byte) 0x02; + public static final byte OS_UNIX = (byte) 0x03; + public static final byte OS_ATARI = (byte) 0x05; + public static final byte OS_OS2 = (byte) 0x06; + public static final byte OS_MACOS = (byte) 0x07; + public static final byte OS_TOPS20 = (byte) 0x0a; + public static final byte OS_WIN32 = (byte) 0x0b; + public static final byte OS_VMCMS = (byte) 0x04; + public static final byte OS_ZSYSTEM = (byte) 0x08; + public static final byte OS_CPM = (byte) 0x09; + public static final byte OS_QDOS = (byte) 0x0c; + public static final byte OS_RISCOS = (byte) 0x0d; + public static final byte OS_UNKNOWN = (byte) 0xff; + + boolean text = false; + private boolean fhcrc = false; + long time; + int xflags; + int os = 255; + byte[] extra; + byte[] name; + byte[] comment; + int hcrc; + long crc; + boolean done = false; + long mtime = 0; + + public void setModifiedTime(long mtime) { + this.mtime = mtime; + } + + public long getModifiedTime() { + return mtime; + } + + public void setOS(int os) { + if((0<=os && os <=13) || os==255) + this.os=os; + else + throw new IllegalArgumentException("os: "+os); + } + + public int getOS(){ + return os; + } + + public void setName(String name) { + try{ + this.name=name.getBytes("ISO-8859-1"); + } + catch(UnsupportedEncodingException e){ + throw new IllegalArgumentException("name must be in ISO-8859-1 "+name); + } + } + + public String getName(){ + if(name==null) return ""; + try { + return new String(name, "ISO-8859-1"); + } + catch (UnsupportedEncodingException e) { + throw new InternalError(e.toString()); + } + } + + public void setComment(String comment) { + try{ + this.comment=comment.getBytes("ISO-8859-1"); + } + catch(UnsupportedEncodingException e){ + throw new IllegalArgumentException("comment must be in ISO-8859-1 "+name); + } + } + + public String getComment(){ + if(comment==null) return ""; + try { + return new String(comment, "ISO-8859-1"); + } + catch (UnsupportedEncodingException e) { + throw new InternalError(e.toString()); + } + } + + public void setCRC(long crc){ + this.crc = crc; + } + + public long getCRC(){ + return crc; + } + + void put(Deflate d){ + int flag = 0; + if(text){ + flag |= 1; // FTEXT + } + if(fhcrc){ + flag |= 2; // FHCRC + } + if(extra!=null){ + flag |= 4; // FEXTRA + } + if(name!=null){ + flag |= 8; // FNAME + } + if(comment!=null){ + flag |= 16; // FCOMMENT + } + int xfl = 0; + if(d.level == JZlib.Z_BEST_SPEED){ + xfl |= 4; + } + else if (d.level == JZlib.Z_BEST_COMPRESSION){ + xfl |= 2; + } + + d.put_short((short)0x8b1f); // ID1 ID2 + d.put_byte((byte)8); // CM(Compression Method) + d.put_byte((byte)flag); + d.put_byte((byte)mtime); + d.put_byte((byte)(mtime>>8)); + d.put_byte((byte)(mtime>>16)); + d.put_byte((byte)(mtime>>24)); + d.put_byte((byte)xfl); + d.put_byte((byte)os); + + if(extra!=null){ + d.put_byte((byte)extra.length); + d.put_byte((byte)(extra.length>>8)); + d.put_byte(extra, 0, extra.length); + } + + if(name!=null){ + d.put_byte(name, 0, name.length); + d.put_byte((byte)0); + } + + if(comment!=null){ + d.put_byte(comment, 0, comment.length); + d.put_byte((byte)0); + } + } + + @Override + public Object clone() throws CloneNotSupportedException { + GZIPHeader gheader = (GZIPHeader)super.clone(); + byte[] tmp; + if(gheader.extra!=null){ + tmp=new byte[gheader.extra.length]; + System.arraycopy(gheader.extra, 0, tmp, 0, tmp.length); + gheader.extra = tmp; + } + + if(gheader.name!=null){ + tmp=new byte[gheader.name.length]; + System.arraycopy(gheader.name, 0, tmp, 0, tmp.length); + gheader.name = tmp; + } + + if(gheader.comment!=null){ + tmp=new byte[gheader.comment.length]; + System.arraycopy(gheader.comment, 0, tmp, 0, tmp.length); + gheader.comment = tmp; + } + + return gheader; + } +} diff --git a/epkcompiler/src/com/jcraft/jzlib/GZIPInputStream.java b/epkcompiler/src/com/jcraft/jzlib/GZIPInputStream.java new file mode 100644 index 0000000..5d29dca --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/GZIPInputStream.java @@ -0,0 +1,145 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jcraft.jzlib; +import java.io.*; + +public class GZIPInputStream extends InflaterInputStream { + + public GZIPInputStream(InputStream in) throws IOException { + this(in, DEFAULT_BUFSIZE, true); + } + + public GZIPInputStream(InputStream in, + int size, + boolean close_in) throws IOException { + this(in, new Inflater(15+16), size, close_in); + myinflater = true; + } + + public GZIPInputStream(InputStream in, + Inflater inflater, + int size, + boolean close_in) throws IOException { + super(in, inflater, size, close_in); + } + + public long getModifiedtime() { + return inflater.istate.getGZIPHeader().getModifiedTime(); + } + + public int getOS() { + return inflater.istate.getGZIPHeader().getOS(); + } + + public String getName() { + return inflater.istate.getGZIPHeader().getName(); + } + + public String getComment() { + return inflater.istate.getGZIPHeader().getComment(); + } + + public long getCRC() throws GZIPException { + if(inflater.istate.mode != 12 /*DONE*/) + throw new GZIPException("checksum is not calculated yet."); + return inflater.istate.getGZIPHeader().getCRC(); + } + + public void readHeader() throws IOException { + + byte[] empty = "".getBytes(); + inflater.setOutput(empty, 0, 0); + inflater.setInput(empty, 0, 0, false); + + byte[] b = new byte[10]; + + int n = fill(b); + if(n!=10){ + if(n>0){ + inflater.setInput(b, 0, n, false); + //inflater.next_in_index = n; + inflater.next_in_index = 0; + inflater.avail_in = n; + } + throw new IOException("no input"); + } + + inflater.setInput(b, 0, n, false); + + byte[] b1 = new byte[1]; + do{ + if(inflater.avail_in<=0){ + int i = in.read(b1); + if(i<=0) + throw new IOException("no input"); + inflater.setInput(b1, 0, 1, true); + } + + int err = inflater.inflate(JZlib.Z_NO_FLUSH); + + if(err!=0/*Z_OK*/){ + int len = 2048-inflater.next_in.length; + if(len>0){ + byte[] tmp = new byte[len]; + n = fill(tmp); + if(n>0){ + inflater.avail_in += inflater.next_in_index; + inflater.next_in_index = 0; + inflater.setInput(tmp, 0, n, true); + } + } + //inflater.next_in_index = inflater.next_in.length; + inflater.avail_in += inflater.next_in_index; + inflater.next_in_index = 0; + throw new IOException(inflater.msg); + } + } + while(inflater.istate.inParsingHeader()); + } + + private int fill(byte[] buf) { + int len = buf.length; + int n = 0; + do{ + int i = -1; + try { + i = in.read(buf, n, buf.length - n); + } + catch(IOException e){ + } + if(i == -1){ + break; + } + n+=i; + } + while(n>> 1){ + case 0: // stored + {b>>>=(3);k-=(3);} + t = k & 7; // go to byte boundary + + {b>>>=(t);k-=(t);} + mode = LENS; // get length of stored block + break; + case 1: // fixed + InfTree.inflate_trees_fixed(bl, bd, tl, td, z); + codes.init(bl[0], bd[0], tl[0], 0, td[0], 0); + + {b>>>=(3);k-=(3);} + + mode = CODES; + break; + case 2: // dynamic + + {b>>>=(3);k-=(3);} + + mode = TABLE; + break; + case 3: // illegal + + {b>>>=(3);k-=(3);} + mode = BAD; + z.msg = "invalid block type"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + break; + case LENS: + + while(k<(32)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>> 16) & 0xffff) != (b & 0xffff)){ + mode = BAD; + z.msg = "invalid stored block lengths"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + left = (b & 0xffff); + b = k = 0; // dump bits + mode = left!=0 ? STORED : (last!=0 ? DRY : TYPE); + break; + case STORED: + if (n == 0){ + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + + if(m==0){ + if(q==end&&read!=0){ + q=0; m=(int)(qn) t = n; + if(t>m) t = m; + System.arraycopy(z.next_in, p, window, q, t); + p += t; n -= t; + q += t; m -= t; + if ((left -= t) != 0) + break; + mode = last!=0 ? DRY : TYPE; + break; + case TABLE: + + while(k<(14)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)< 29 || ((t >> 5) & 0x1f) > 29) + { + mode = BAD; + z.msg = "too many length or distance symbols"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if(blens==null || blens.length>>=(14);k-=(14);} + + index = 0; + mode = BTREE; + case BTREE: + while (index < 4 + (table >>> 10)){ + while(k<(3)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>>=(3);k-=(3);} + } + + while(index < 19){ + blens[border[index++]] = 0; + } + + bb[0] = 7; + t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); + if (t != Z_OK){ + r = t; + if (r == Z_DATA_ERROR){ + blens=null; + mode = BAD; + } + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + + index = 0; + mode = DTREE; + case DTREE: + while (true){ + t = table; + if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){ + break; + } + + int[] h; + int i, j, c; + + t = bb[0]; + + while(k<(t)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); + blens[index++] = c; + } + else { // c == 16..18 + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + + while(k<(t+i)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); + + j += (b & inflate_mask[i]); + + b>>>=(i);k-=(i); + + i = index; + t = table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)){ + blens=null; + mode = BAD; + z.msg = "invalid bit length repeat"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + + c = c == 16 ? blens[i-1] : 0; + do{ + blens[i++] = c; + } + while (--j!=0); + index = i; + } + } + + tb[0]=-1; + { + bl[0] = 9; // must be <= 9 for lookahead assumptions + bd[0] = 6; // must be <= 9 for lookahead assumptions + t = table; + t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), + 1 + ((t >> 5) & 0x1f), + blens, bl, bd, tli, tdi, hufts, z); + + if (t != Z_OK){ + if (t == Z_DATA_ERROR){ + blens=null; + mode = BAD; + } + r = t; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]); + } + mode = CODES; + case CODES: + bitb=b; bitk=k; + z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + + if ((r = codes.proc(r)) != Z_STREAM_END){ + return inflate_flush(r); + } + r = Z_OK; + codes.free(z); + + p=z.next_in_index; n=z.avail_in;b=bitb;k=bitk; + q=write;m=(int)(q z.avail_out) n = z.avail_out; + if(n!=0 && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if(check && n>0){ + z.adler.update(window, q, n); + } + + // copy as far as end of window + System.arraycopy(window, q, z.next_out, p, n); + p += n; + q += n; + + // see if more to copy at beginning of window + if (q == end){ + // wrap pointers + q = 0; + if (write == end) + write = 0; + + // compute bytes to copy + n = write - q; + if (n > z.avail_out) n = z.avail_out; + if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if(check && n>0){ + z.adler.update(window, q, n); + } + + // copy + System.arraycopy(window, q, z.next_out, p, n); + p += n; + q += n; + } + + // update pointers + z.next_out_index = p; + read = q; + + // done + return r; + } +} diff --git a/epkcompiler/src/com/jcraft/jzlib/InfCodes.java b/epkcompiler/src/com/jcraft/jzlib/InfCodes.java new file mode 100644 index 0000000..aaf69cd --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/InfCodes.java @@ -0,0 +1,610 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final class InfCodes{ + + static final private int[] inflate_mask = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, + 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, + 0x00007fff, 0x0000ffff + }; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + // waiting for "i:"=input, + // "o:"=output, + // "x:"=nothing + static final private int START=0; // x: set up for LEN + static final private int LEN=1; // i: get length/literal/eob next + static final private int LENEXT=2; // i: getting length extra (have base) + static final private int DIST=3; // i: get distance next + static final private int DISTEXT=4;// i: getting distance extra + static final private int COPY=5; // o: copying bytes in window, waiting for space + static final private int LIT=6; // o: got literal, waiting for output space + static final private int WASH=7; // o: got eob, possibly still output waiting + static final private int END=8; // x: got eob and all data flushed + static final private int BADCODE=9;// x: got error + + int mode; // current inflate_codes mode + + // mode dependent information + int len; + + int[] tree; // pointer into tree + int tree_index=0; + int need; // bits needed + + int lit; + + // if EXT or COPY, where and how much + int get; // bits to get for extra + int dist; // distance back to copy from + + byte lbits; // ltree bits decoded per branch + byte dbits; // dtree bits decoder per branch + int[] ltree; // literal/length/eob tree + int ltree_index; // literal/length/eob tree + int[] dtree; // distance tree + int dtree_index; // distance tree + + private final ZStream z; + private final InfBlocks s; + InfCodes(ZStream z, InfBlocks s){ + this.z=z; + this.s=s; + } + + void init(int bl, int bd, + int[] tl, int tl_index, + int[] td, int td_index){ + mode=START; + lbits=(byte)bl; + dbits=(byte)bd; + ltree=tl; + ltree_index=tl_index; + dtree = td; + dtree_index=td_index; + tree=null; + } + + int proc(int r){ + int j; // temporary storage + int[] t; // temporary pointer + int tindex; // temporary pointer + int e; // extra bits or operation + int b=0; // bit buffer + int k=0; // bits in bit buffer + int p=0; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; // bytes to end of window or read pointer + int f; // pointer to copy strings from + + // copy input/output information to locals (UPDATE macro restores) + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; + q=s.write;m=q= 258 && n >= 10){ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + r = inflate_fast(lbits, dbits, + ltree, ltree_index, + dtree, dtree_index, + s, z); + + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; + q=s.write;m=q>>=(tree[tindex+1]); + k-=(tree[tindex+1]); + + e=tree[tindex]; + + if(e == 0){ // literal + lit = tree[tindex+2]; + mode = LIT; + break; + } + if((e & 16)!=0 ){ // length + get = e & 15; + len = tree[tindex+2]; + mode = LENEXT; + break; + } + if ((e & 64) == 0){ // next table + need = e; + tree_index = tindex/3+tree[tindex+2]; + break; + } + if ((e & 32)!=0){ // end of block + mode = WASH; + break; + } + mode = BADCODE; // invalid code + z.msg = "invalid literal/length code"; + r = Z_DATA_ERROR; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + + case LENEXT: // i: getting length extra (have base) + j = get; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + } + n--; b|=(z.next_in[p++]&0xff)<>=j; + k-=j; + + need = dbits; + tree = dtree; + tree_index=dtree_index; + mode = DIST; + case DIST: // i: get distance next + j = need; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + } + n--; b|=(z.next_in[p++]&0xff)<>=tree[tindex+1]; + k-=tree[tindex+1]; + + e = (tree[tindex]); + if((e & 16)!=0){ // distance + get = e & 15; + dist = tree[tindex+2]; + mode = DISTEXT; + break; + } + if ((e & 64) == 0){ // next table + need = e; + tree_index = tindex/3 + tree[tindex+2]; + break; + } + mode = BADCODE; // invalid code + z.msg = "invalid distance code"; + r = Z_DATA_ERROR; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + + case DISTEXT: // i: getting distance extra + j = get; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + } + n--; b|=(z.next_in[p++]&0xff)<>=j; + k-=j; + + mode = COPY; + case COPY: // o: copying bytes in window, waiting for space + f = q - dist; + while(f < 0){ // modulo window size-"while" instead + f += s.end; // of "if" handles invalid distances + } + while (len!=0){ + + if(m==0){ + if(q==s.end&&s.read!=0){q=0;m=q 7){ // return unused byte, if any + k -= 8; + n++; + p--; // can always return one + } + + s.write=q; r=s.inflate_flush(r); + q=s.write;m=q= 258 && n >= 10 + // get literal/length code + while(k<(20)){ // max bits for literal/length code + n--; + b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + s.window[q++] = (byte)tp[tp_index_t_3+2]; + m--; + continue; + } + do { + + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + if((e&16)!=0){ + e &= 15; + c = tp[tp_index_t_3+2] + ((int)b & inflate_mask[e]); + + b>>=e; k-=e; + + // decode distance base of block to copy + while(k<(15)){ // max bits for distance code + n--; + b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + if((e&16)!=0){ + // get extra bits to add to distance base + e &= 15; + while(k<(e)){ // get extra bits (up to 13) + n--; + b|=(z.next_in[p++]&0xff)<>=(e); k-=(e); + + // do the copy + m -= c; + if (q >= d){ // offset before dest + // just copy + r=q-d; + if(q-r>0 && 2>(q-r)){ + s.window[q++]=s.window[r++]; // minimum count is three, + s.window[q++]=s.window[r++]; // so unroll loop a little + c-=2; + } + else{ + System.arraycopy(s.window, r, s.window, q, 2); + q+=2; r+=2; c-=2; + } + } + else{ // else offset after destination + r=q-d; + do{ + r+=s.end; // force pointer in window + }while(r<0); // covers invalid distances + e=s.end-r; + if(c>e){ // if source crosses, + c-=e; // wrapped copy + if(q-r>0 && e>(q-r)){ + do{s.window[q++] = s.window[r++];} + while(--e!=0); + } + else{ + System.arraycopy(s.window, r, s.window, q, e); + q+=e; r+=e; e=0; + } + r = 0; // copy rest from start of window + } + + } + + // copy all or what's left + if(q-r>0 && c>(q-r)){ + do{s.window[q++] = s.window[r++];} + while(--c!=0); + } + else{ + System.arraycopy(s.window, r, s.window, q, c); + q+=c; r+=c; c=0; + } + break; + } + else if((e&64)==0){ + t+=tp[tp_index_t_3+2]; + t+=(b&inflate_mask[e]); + tp_index_t_3=(tp_index+t)*3; + e=tp[tp_index_t_3]; + } + else{ + z.msg = "invalid distance code"; + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_DATA_ERROR; + } + } + while(true); + break; + } + + if((e&64)==0){ + t+=tp[tp_index_t_3+2]; + t+=(b&inflate_mask[e]); + tp_index_t_3=(tp_index+t)*3; + if((e=tp[tp_index_t_3])==0){ + + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + s.window[q++]=(byte)tp[tp_index_t_3+2]; + m--; + break; + } + } + else if((e&32)!=0){ + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_STREAM_END; + } + else{ + z.msg="invalid literal/length code"; + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_DATA_ERROR; + } + } + while(true); + } + while(m>=258 && n>= 10); + + // not enough input or output--restore pointers and return + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_OK; + } +} diff --git a/epkcompiler/src/com/jcraft/jzlib/InfTree.java b/epkcompiler/src/com/jcraft/jzlib/InfTree.java new file mode 100644 index 0000000..80a2b7b --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/InfTree.java @@ -0,0 +1,518 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final class InfTree{ + + static final private int MANY=1440; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + static final int fixed_bl = 9; + static final int fixed_bd = 5; + + static final int[] fixed_tl = { + 96,7,256, 0,8,80, 0,8,16, 84,8,115, + 82,7,31, 0,8,112, 0,8,48, 0,9,192, + 80,7,10, 0,8,96, 0,8,32, 0,9,160, + 0,8,0, 0,8,128, 0,8,64, 0,9,224, + 80,7,6, 0,8,88, 0,8,24, 0,9,144, + 83,7,59, 0,8,120, 0,8,56, 0,9,208, + 81,7,17, 0,8,104, 0,8,40, 0,9,176, + 0,8,8, 0,8,136, 0,8,72, 0,9,240, + 80,7,4, 0,8,84, 0,8,20, 85,8,227, + 83,7,43, 0,8,116, 0,8,52, 0,9,200, + 81,7,13, 0,8,100, 0,8,36, 0,9,168, + 0,8,4, 0,8,132, 0,8,68, 0,9,232, + 80,7,8, 0,8,92, 0,8,28, 0,9,152, + 84,7,83, 0,8,124, 0,8,60, 0,9,216, + 82,7,23, 0,8,108, 0,8,44, 0,9,184, + 0,8,12, 0,8,140, 0,8,76, 0,9,248, + 80,7,3, 0,8,82, 0,8,18, 85,8,163, + 83,7,35, 0,8,114, 0,8,50, 0,9,196, + 81,7,11, 0,8,98, 0,8,34, 0,9,164, + 0,8,2, 0,8,130, 0,8,66, 0,9,228, + 80,7,7, 0,8,90, 0,8,26, 0,9,148, + 84,7,67, 0,8,122, 0,8,58, 0,9,212, + 82,7,19, 0,8,106, 0,8,42, 0,9,180, + 0,8,10, 0,8,138, 0,8,74, 0,9,244, + 80,7,5, 0,8,86, 0,8,22, 192,8,0, + 83,7,51, 0,8,118, 0,8,54, 0,9,204, + 81,7,15, 0,8,102, 0,8,38, 0,9,172, + 0,8,6, 0,8,134, 0,8,70, 0,9,236, + 80,7,9, 0,8,94, 0,8,30, 0,9,156, + 84,7,99, 0,8,126, 0,8,62, 0,9,220, + 82,7,27, 0,8,110, 0,8,46, 0,9,188, + 0,8,14, 0,8,142, 0,8,78, 0,9,252, + 96,7,256, 0,8,81, 0,8,17, 85,8,131, + 82,7,31, 0,8,113, 0,8,49, 0,9,194, + 80,7,10, 0,8,97, 0,8,33, 0,9,162, + 0,8,1, 0,8,129, 0,8,65, 0,9,226, + 80,7,6, 0,8,89, 0,8,25, 0,9,146, + 83,7,59, 0,8,121, 0,8,57, 0,9,210, + 81,7,17, 0,8,105, 0,8,41, 0,9,178, + 0,8,9, 0,8,137, 0,8,73, 0,9,242, + 80,7,4, 0,8,85, 0,8,21, 80,8,258, + 83,7,43, 0,8,117, 0,8,53, 0,9,202, + 81,7,13, 0,8,101, 0,8,37, 0,9,170, + 0,8,5, 0,8,133, 0,8,69, 0,9,234, + 80,7,8, 0,8,93, 0,8,29, 0,9,154, + 84,7,83, 0,8,125, 0,8,61, 0,9,218, + 82,7,23, 0,8,109, 0,8,45, 0,9,186, + 0,8,13, 0,8,141, 0,8,77, 0,9,250, + 80,7,3, 0,8,83, 0,8,19, 85,8,195, + 83,7,35, 0,8,115, 0,8,51, 0,9,198, + 81,7,11, 0,8,99, 0,8,35, 0,9,166, + 0,8,3, 0,8,131, 0,8,67, 0,9,230, + 80,7,7, 0,8,91, 0,8,27, 0,9,150, + 84,7,67, 0,8,123, 0,8,59, 0,9,214, + 82,7,19, 0,8,107, 0,8,43, 0,9,182, + 0,8,11, 0,8,139, 0,8,75, 0,9,246, + 80,7,5, 0,8,87, 0,8,23, 192,8,0, + 83,7,51, 0,8,119, 0,8,55, 0,9,206, + 81,7,15, 0,8,103, 0,8,39, 0,9,174, + 0,8,7, 0,8,135, 0,8,71, 0,9,238, + 80,7,9, 0,8,95, 0,8,31, 0,9,158, + 84,7,99, 0,8,127, 0,8,63, 0,9,222, + 82,7,27, 0,8,111, 0,8,47, 0,9,190, + 0,8,15, 0,8,143, 0,8,79, 0,9,254, + 96,7,256, 0,8,80, 0,8,16, 84,8,115, + 82,7,31, 0,8,112, 0,8,48, 0,9,193, + + 80,7,10, 0,8,96, 0,8,32, 0,9,161, + 0,8,0, 0,8,128, 0,8,64, 0,9,225, + 80,7,6, 0,8,88, 0,8,24, 0,9,145, + 83,7,59, 0,8,120, 0,8,56, 0,9,209, + 81,7,17, 0,8,104, 0,8,40, 0,9,177, + 0,8,8, 0,8,136, 0,8,72, 0,9,241, + 80,7,4, 0,8,84, 0,8,20, 85,8,227, + 83,7,43, 0,8,116, 0,8,52, 0,9,201, + 81,7,13, 0,8,100, 0,8,36, 0,9,169, + 0,8,4, 0,8,132, 0,8,68, 0,9,233, + 80,7,8, 0,8,92, 0,8,28, 0,9,153, + 84,7,83, 0,8,124, 0,8,60, 0,9,217, + 82,7,23, 0,8,108, 0,8,44, 0,9,185, + 0,8,12, 0,8,140, 0,8,76, 0,9,249, + 80,7,3, 0,8,82, 0,8,18, 85,8,163, + 83,7,35, 0,8,114, 0,8,50, 0,9,197, + 81,7,11, 0,8,98, 0,8,34, 0,9,165, + 0,8,2, 0,8,130, 0,8,66, 0,9,229, + 80,7,7, 0,8,90, 0,8,26, 0,9,149, + 84,7,67, 0,8,122, 0,8,58, 0,9,213, + 82,7,19, 0,8,106, 0,8,42, 0,9,181, + 0,8,10, 0,8,138, 0,8,74, 0,9,245, + 80,7,5, 0,8,86, 0,8,22, 192,8,0, + 83,7,51, 0,8,118, 0,8,54, 0,9,205, + 81,7,15, 0,8,102, 0,8,38, 0,9,173, + 0,8,6, 0,8,134, 0,8,70, 0,9,237, + 80,7,9, 0,8,94, 0,8,30, 0,9,157, + 84,7,99, 0,8,126, 0,8,62, 0,9,221, + 82,7,27, 0,8,110, 0,8,46, 0,9,189, + 0,8,14, 0,8,142, 0,8,78, 0,9,253, + 96,7,256, 0,8,81, 0,8,17, 85,8,131, + 82,7,31, 0,8,113, 0,8,49, 0,9,195, + 80,7,10, 0,8,97, 0,8,33, 0,9,163, + 0,8,1, 0,8,129, 0,8,65, 0,9,227, + 80,7,6, 0,8,89, 0,8,25, 0,9,147, + 83,7,59, 0,8,121, 0,8,57, 0,9,211, + 81,7,17, 0,8,105, 0,8,41, 0,9,179, + 0,8,9, 0,8,137, 0,8,73, 0,9,243, + 80,7,4, 0,8,85, 0,8,21, 80,8,258, + 83,7,43, 0,8,117, 0,8,53, 0,9,203, + 81,7,13, 0,8,101, 0,8,37, 0,9,171, + 0,8,5, 0,8,133, 0,8,69, 0,9,235, + 80,7,8, 0,8,93, 0,8,29, 0,9,155, + 84,7,83, 0,8,125, 0,8,61, 0,9,219, + 82,7,23, 0,8,109, 0,8,45, 0,9,187, + 0,8,13, 0,8,141, 0,8,77, 0,9,251, + 80,7,3, 0,8,83, 0,8,19, 85,8,195, + 83,7,35, 0,8,115, 0,8,51, 0,9,199, + 81,7,11, 0,8,99, 0,8,35, 0,9,167, + 0,8,3, 0,8,131, 0,8,67, 0,9,231, + 80,7,7, 0,8,91, 0,8,27, 0,9,151, + 84,7,67, 0,8,123, 0,8,59, 0,9,215, + 82,7,19, 0,8,107, 0,8,43, 0,9,183, + 0,8,11, 0,8,139, 0,8,75, 0,9,247, + 80,7,5, 0,8,87, 0,8,23, 192,8,0, + 83,7,51, 0,8,119, 0,8,55, 0,9,207, + 81,7,15, 0,8,103, 0,8,39, 0,9,175, + 0,8,7, 0,8,135, 0,8,71, 0,9,239, + 80,7,9, 0,8,95, 0,8,31, 0,9,159, + 84,7,99, 0,8,127, 0,8,63, 0,9,223, + 82,7,27, 0,8,111, 0,8,47, 0,9,191, + 0,8,15, 0,8,143, 0,8,79, 0,9,255 + }; + static final int[] fixed_td = { + 80,5,1, 87,5,257, 83,5,17, 91,5,4097, + 81,5,5, 89,5,1025, 85,5,65, 93,5,16385, + 80,5,3, 88,5,513, 84,5,33, 92,5,8193, + 82,5,9, 90,5,2049, 86,5,129, 192,5,24577, + 80,5,2, 87,5,385, 83,5,25, 91,5,6145, + 81,5,7, 89,5,1537, 85,5,97, 93,5,24577, + 80,5,4, 88,5,769, 84,5,49, 92,5,12289, + 82,5,13, 90,5,3073, 86,5,193, 192,5,24577 + }; + + // Tables for deflate from PKZIP's appnote.txt. + static final int[] cplens = { // Copy lengths for literal codes 257..285 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 + }; + + // see note #13 above about 258 + static final int[] cplext = { // Extra bits for literal codes 257..285 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid + }; + + static final int[] cpdist = { // Copy offsets for distance codes 0..29 + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577 + }; + + static final int[] cpdext = { // Extra bits for distance codes + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + // If BMAX needs to be larger than 16, then h and x[] should be uLong. + static final int BMAX=15; // maximum bit length of any code + + int[] hn = null; // hufts used in space + int[] v = null; // work area for huft_build + int[] c = null; // bit length count table + int[] r = null; // table entry for structure assignment + int[] u = null; // table stack + int[] x = null; // bit offsets, then code stack + + private int huft_build(int[] b, // code lengths in bits (all assumed <= BMAX) + int bindex, + int n, // number of codes (assumed <= 288) + int s, // number of simple-valued codes (0..s-1) + int[] d, // list of base values for non-simple codes + int[] e, // list of extra bits for non-simple codes + int[] t, // result: starting table + int[] m, // maximum lookup bits, returns actual + int[] hp,// space for trees + int[] hn,// hufts used in space + int[] v // working area: values in order of bit length + ){ + // Given a list of code lengths and a maximum table size, make a set of + // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + // if the given code set is incomplete (the tables are still built in this + // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of + // lengths), or Z_MEM_ERROR if not enough memory. + + int a; // counter for codes of length k + int f; // i repeats in table every f entries + int g; // maximum code length + int h; // table level + int i; // counter, current code + int j; // counter + int k; // number of bits in current code + int l; // bits per table (returned in m) + int mask; // (1 << w) - 1, to avoid cc -O bug on HP + int p; // pointer into c[], b[], or v[] + int q; // points to current table + int w; // bits before this table == (l * h) + int xp; // pointer into x + int y; // number of dummy codes added + int z; // number of entries in current table + + // Generate counts for each bit length + + p = 0; i = n; + do { + c[b[bindex+p]]++; p++; i--; // assume all entries <= BMAX + }while(i!=0); + + if(c[0] == n){ // null input--all zero length codes + t[0] = -1; + m[0] = 0; + return Z_OK; + } + + // Find minimum and maximum length, bound *m by those + l = m[0]; + for (j = 1; j <= BMAX; j++) + if(c[j]!=0) break; + k = j; // minimum code length + if(l < j){ + l = j; + } + for (i = BMAX; i!=0; i--){ + if(c[i]!=0) break; + } + g = i; // maximum code length + if(l > i){ + l = i; + } + m[0] = l; + + // Adjust last length count to fill out codes, if needed + for (y = 1 << j; j < i; j++, y <<= 1){ + if ((y -= c[j]) < 0){ + return Z_DATA_ERROR; + } + } + if ((y -= c[i]) < 0){ + return Z_DATA_ERROR; + } + c[i] += y; + + // Generate starting offsets into the value table for each length + x[1] = j = 0; + p = 1; xp = 2; + while (--i!=0) { // note that i == g from above + x[xp] = (j += c[p]); + xp++; + p++; + } + + // Make a table of values in order of bit lengths + i = 0; p = 0; + do { + if ((j = b[bindex+p]) != 0){ + v[x[j]++] = i; + } + p++; + } + while (++i < n); + n = x[g]; // set n to length of v + + // Generate the Huffman codes and for each, make the table entries + x[0] = i = 0; // first Huffman code is zero + p = 0; // grab values in bit order + h = -1; // no tables yet--level -1 + w = -l; // bits decoded == (l * h) + u[0] = 0; // just to keep compilers happy + q = 0; // ditto + z = 0; // ditto + + // go through the bit lengths (k already is bits in shortest code) + for (; k <= g; k++){ + a = c[k]; + while (a--!=0){ + // here i is the Huffman code of length k bits for value *p + // make tables up to required level + while (k > w + l){ + h++; + w += l; // previous table always l bits + // compute minimum size table less than or equal to l bits + z = g - w; + z = (z > l) ? l : z; // table size upper limit + if((f=1<<(j=k-w))>a+1){ // try a k-w bit table + // too few codes for k-w bit table + f -= a + 1; // deduct codes from patterns left + xp = k; + if(j < z){ + while (++j < z){ // try smaller tables up to z bits + if((f <<= 1) <= c[++xp]) + break; // enough codes to use up j bits + f -= c[xp]; // else deduct codes from patterns + } + } + } + z = 1 << j; // table entries for j-bit table + + // allocate new table + if (hn[0] + z > MANY){ // (note: doesn't matter for fixed) + return Z_DATA_ERROR; // overflow of MANY + } + u[h] = q = /*hp+*/ hn[0]; // DEBUG + hn[0] += z; + + // connect to last table, if there is one + if(h!=0){ + x[h]=i; // save pattern for backing up + r[0]=(byte)j; // bits in this table + r[1]=(byte)l; // bits to dump before this table + j=i>>>(w - l); + r[2] = (int)(q - u[h-1] - j); // offset to this table + System.arraycopy(r, 0, hp, (u[h-1]+j)*3, 3); // connect to last table + } + else{ + t[0] = q; // first table is returned result + } + } + + // set up table entry in r + r[1] = (byte)(k - w); + if (p >= n){ + r[0] = 128 + 64; // out of values--invalid code + } + else if (v[p] < s){ + r[0] = (byte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block + r[2] = v[p++]; // simple code is just the value + } + else{ + r[0]=(byte)(e[v[p]-s]+16+64); // non-simple--look up in lists + r[2]=d[v[p++] - s]; + } + + // fill code-like entries with r + f=1<<(k-w); + for (j=i>>>w;j>>= 1){ + i ^= j; + } + i ^= j; + + // backup over finished tables + mask = (1 << w) - 1; // needed on HP, cc -O bug + while ((i & mask) != x[h]){ + h--; // don't need to update q + w -= l; + mask = (1 << w) - 1; + } + } + } + // Return Z_BUF_ERROR if we were given an incomplete table + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; + } + + int inflate_trees_bits(int[] c, // 19 code lengths + int[] bb, // bits tree desired/actual depth + int[] tb, // bits tree result + int[] hp, // space for trees + ZStream z // for messages + ){ + int result; + initWorkArea(19); + hn[0]=0; + result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); + + if(result == Z_DATA_ERROR){ + z.msg = "oversubscribed dynamic bit lengths tree"; + } + else if(result == Z_BUF_ERROR || bb[0] == 0){ + z.msg = "incomplete dynamic bit lengths tree"; + result = Z_DATA_ERROR; + } + return result; + } + + int inflate_trees_dynamic(int nl, // number of literal/length codes + int nd, // number of distance codes + int[] c, // that many (total) code lengths + int[] bl, // literal desired/actual bit depth + int[] bd, // distance desired/actual bit depth + int[] tl, // literal/length tree result + int[] td, // distance tree result + int[] hp, // space for trees + ZStream z // for messages + ){ + int result; + + // build literal/length tree + initWorkArea(288); + hn[0]=0; + result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); + if (result != Z_OK || bl[0] == 0){ + if(result == Z_DATA_ERROR){ + z.msg = "oversubscribed literal/length tree"; + } + else if (result != Z_MEM_ERROR){ + z.msg = "incomplete literal/length tree"; + result = Z_DATA_ERROR; + } + return result; + } + + // build distance tree + initWorkArea(288); + result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); + + if (result != Z_OK || (bd[0] == 0 && nl > 257)){ + if (result == Z_DATA_ERROR){ + z.msg = "oversubscribed distance tree"; + } + else if (result == Z_BUF_ERROR) { + z.msg = "incomplete distance tree"; + result = Z_DATA_ERROR; + } + else if (result != Z_MEM_ERROR){ + z.msg = "empty distance tree with lengths"; + result = Z_DATA_ERROR; + } + return result; + } + + return Z_OK; + } + + static int inflate_trees_fixed(int[] bl, //literal desired/actual bit depth + int[] bd, //distance desired/actual bit depth + int[][] tl,//literal/length tree result + int[][] td,//distance tree result + ZStream z //for memory allocation + ){ + bl[0]=fixed_bl; + bd[0]=fixed_bd; + tl[0]=fixed_tl; + td[0]=fixed_td; + return Z_OK; + } + + private void initWorkArea(int vsize){ + if(hn==null){ + hn=new int[1]; + v=new int[vsize]; + c=new int[BMAX+1]; + r=new int[3]; + u=new int[BMAX]; + x=new int[BMAX+1]; + } + if(v.length> 4) + 1; + if(w < 48) + w &= 15; + } + + if(w<8 ||w>15){ + inflateEnd(); + return Z_STREAM_ERROR; + } + if(blocks != null && wbits != w){ + blocks.free(); + blocks=null; + } + + // set window size + wbits=w; + + this.blocks=new InfBlocks(z, 1<>8))&0xff; + + if(((wrap&1)==0 || // check if zlib header allowed + (((this.method << 8)+b) % 31)!=0) && + (this.method&0xf)!=Z_DEFLATED){ + if(wrap == 4){ + z.next_in_index -= 2; + z.avail_in += 2; + z.total_in -= 2; + wrap = 0; + this.mode = BLOCKS; + break; + } + this.mode = BAD; + z.msg = "incorrect header check"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + if((this.method&0xf)!=Z_DEFLATED){ + this.mode = BAD; + z.msg="unknown compression method"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + if(wrap == 4){ + wrap = 1; + } + + if((this.method>>4)+8>this.wbits){ + this.mode = BAD; + z.msg="invalid window size"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + z.adler=new Adler32(); + + if((b&PRESET_DICT)==0){ + this.mode = BLOCKS; + break; + } + this.mode = DICT4; + case DICT4: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + this.mode=DICT3; + case DICT3: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + this.mode=DICT2; + case DICT2: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + this.mode=DICT1; + case DICT1: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need += (z.next_in[z.next_in_index++]&0xffL); + z.adler.reset(this.need); + this.mode = DICT0; + return Z_NEED_DICT; + case DICT0: + this.mode = BAD; + z.msg = "need dictionary"; + this.marker = 0; // can try inflateSync + return Z_STREAM_ERROR; + case BLOCKS: + r = this.blocks.proc(r); + if(r == Z_DATA_ERROR){ + this.mode = BAD; + this.marker = 0; // can try inflateSync + break; + } + if(r == Z_OK){ + r = f; + } + if(r != Z_STREAM_END){ + return r; + } + r = f; + this.was=z.adler.getValue(); + this.blocks.reset(); + if(this.wrap==0){ + this.mode=DONE; + break; + } + this.mode=CHECK4; + case CHECK4: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + this.mode=CHECK3; + case CHECK3: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + this.mode = CHECK2; + case CHECK2: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + this.mode = CHECK1; + case CHECK1: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=(z.next_in[z.next_in_index++]&0xffL); + + if(flags!=0){ // gzip + this.need = ((this.need&0xff000000)>>24 | + (this.need&0x00ff0000)>>8 | + (this.need&0x0000ff00)<<8 | + (this.need&0x0000ffff)<<24)&0xffffffffL; + } + + if(((int)(this.was)) != ((int)(this.need))){ + z.msg = "incorrect data check"; + // chack is delayed + /* + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + */ + } + else if(flags!=0 && gheader!=null){ + gheader.crc = this.need; + } + + this.mode = LENGTH; + case LENGTH: + if (wrap!=0 && flags!=0) { + + try { r=readBytes(4, r, f); } + catch(Return e){ return e.r; } + + if(z.msg!=null && z.msg.equals("incorrect data check")){ + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + } + + if (this.need != (z.total_out & 0xffffffffL)) { + z.msg = "incorrect length check"; + this.mode = BAD; + break; + } + z.msg = null; + } + else { + if(z.msg!=null && z.msg.equals("incorrect data check")){ + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + } + } + + this.mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + + case FLAGS: + + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + + flags = ((int)this.need)&0xffff; + + if ((flags & 0xff) != Z_DEFLATED) { + z.msg = "unknown compression method"; + this.mode = BAD; + break; + } + if ((flags & 0xe000)!=0) { + z.msg = "unknown header flags set"; + this.mode = BAD; + break; + } + + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + + this.mode = TIME; + + case TIME: + try { r=readBytes(4, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null) + gheader.time = this.need; + if ((flags & 0x0200)!=0){ + checksum(4, this.need); + } + this.mode = OS; + case OS: + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.xflags = ((int)this.need)&0xff; + gheader.os = (((int)this.need)>>8)&0xff; + } + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + this.mode = EXLEN; + case EXLEN: + if ((flags & 0x0400)!=0) { + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.extra = new byte[((int)this.need)&0xffff]; + } + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + } + else if(gheader!=null){ + gheader.extra=null; + } + this.mode = EXTRA; + + case EXTRA: + if ((flags & 0x0400)!=0) { + try { + r=readBytes(r, f); + if(gheader!=null){ + byte[] foo = tmp_string.toByteArray(); + tmp_string=null; + if(foo.length == gheader.extra.length){ + System.arraycopy(foo, 0, gheader.extra, 0, foo.length); + } + else{ + z.msg = "bad extra field length"; + this.mode = BAD; + break; + } + } + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.extra=null; + } + this.mode = NAME; + case NAME: + if ((flags & 0x0800)!=0) { + try { + r=readString(r, f); + if(gheader!=null){ + gheader.name=tmp_string.toByteArray(); + } + tmp_string=null; + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.name=null; + } + this.mode = COMMENT; + case COMMENT: + if ((flags & 0x1000)!=0) { + try { + r=readString(r, f); + if(gheader!=null){ + gheader.comment=tmp_string.toByteArray(); + } + tmp_string=null; + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.comment=null; + } + this.mode = HCRC; + case HCRC: + if ((flags & 0x0200)!=0) { + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.hcrc=(int)(this.need&0xffff); + } + if(this.need != (z.adler.getValue()&0xffffL)){ + this.mode = BAD; + z.msg = "header crc mismatch"; + this.marker = 5; // can't try inflateSync + break; + } + } + z.adler = new CRC32(); + + this.mode = BLOCKS; + break; + default: + return Z_STREAM_ERROR; + } + } + } + + int inflateSetDictionary(byte[] dictionary, int dictLength){ + if(z==null || (this.mode != DICT0 && this.wrap != 0)){ + return Z_STREAM_ERROR; + } + + int index=0; + int length = dictLength; + + if(this.mode==DICT0){ + long adler_need=z.adler.getValue(); + z.adler.reset(); + z.adler.update(dictionary, 0, dictLength); + if(z.adler.getValue()!=adler_need){ + return Z_DATA_ERROR; + } + } + + z.adler.reset(); + + if(length >= (1<0){ + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + this.need = this.need | + ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8)); + need_bytes--; + } + if(n==2){ + this.need&=0xffffL; + } + else if(n==4) { + this.need&=0xffffffffL; + } + need_bytes=-1; + return r; + } + class Return extends Exception{ + int r; + Return(int r){this.r=r; } + } + + private java.io.ByteArrayOutputStream tmp_string = null; + private int readString(int r, int f) throws Return{ + if(tmp_string == null){ + tmp_string=new java.io.ByteArrayOutputStream(); + } + int b=0; + do { + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + b = z.next_in[z.next_in_index]; + if(b!=0) tmp_string.write(z.next_in, z.next_in_index, 1); + z.adler.update(z.next_in, z.next_in_index, 1); + z.next_in_index++; + }while(b!=0); + return r; + } + + private int readBytes(int r, int f) throws Return{ + if(tmp_string == null){ + tmp_string=new java.io.ByteArrayOutputStream(); + } + int b=0; + while(this.need>0){ + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + b = z.next_in[z.next_in_index]; + tmp_string.write(z.next_in, z.next_in_index, 1); + z.adler.update(z.next_in, z.next_in_index, 1); + z.next_in_index++; + this.need--; + } + return r; + } + + private void checksum(int n, long v){ + for(int i=0; i>=8; + } + z.adler.update(crcbuf, 0, n); + } + + public GZIPHeader getGZIPHeader(){ + return gheader; + } + + boolean inParsingHeader(){ + switch(mode){ + case HEAD: + case DICT4: + case DICT3: + case DICT2: + case DICT1: + case FLAGS: + case TIME: + case OS: + case EXLEN: + case EXTRA: + case NAME: + case COMMENT: + case HCRC: + return true; + default: + return false; + } + } +} diff --git a/epkcompiler/src/com/jcraft/jzlib/Inflater.java b/epkcompiler/src/com/jcraft/jzlib/Inflater.java new file mode 100644 index 0000000..0fb0b09 --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/Inflater.java @@ -0,0 +1,168 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class Inflater extends ZStream{ + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_WBITS=MAX_WBITS; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + public Inflater() { + super(); + init(); + } + + public Inflater(JZlib.WrapperType wrapperType) throws GZIPException { + this(DEF_WBITS, wrapperType); + } + + public Inflater(int w, JZlib.WrapperType wrapperType) throws GZIPException { + super(); + int ret = init(w, wrapperType); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + public Inflater(int w) throws GZIPException { + this(w, false); + } + + public Inflater(boolean nowrap) throws GZIPException { + this(DEF_WBITS, nowrap); + } + + public Inflater(int w, boolean nowrap) throws GZIPException { + super(); + int ret = init(w, nowrap); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + private boolean finished = false; + + public int init(){ + return init(DEF_WBITS); + } + + public int init(JZlib.WrapperType wrapperType){ + return init(DEF_WBITS, wrapperType); + } + + public int init(int w, JZlib.WrapperType wrapperType) { + boolean nowrap = false; + if(wrapperType == JZlib.W_NONE){ + nowrap = true; + } + else if(wrapperType == JZlib.W_GZIP) { + w += 16; + } + else if(wrapperType == JZlib.W_ANY) { + w |= Inflate.INFLATE_ANY; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return init(w, nowrap); + } + + public int init(boolean nowrap){ + return init(DEF_WBITS, nowrap); + } + + public int init(int w){ + return init(w, false); + } + + public int init(int w, boolean nowrap){ + finished = false; + istate=new Inflate(this); + return istate.inflateInit(nowrap?-w:w); + } + + public int inflate(int f){ + if(istate==null) return Z_STREAM_ERROR; + int ret = istate.inflate(f); + if(ret == Z_STREAM_END) + finished = true; + return ret; + } + + public int end(){ + finished = true; + if(istate==null) return Z_STREAM_ERROR; + int ret=istate.inflateEnd(); +// istate = null; + return ret; + } + + public int sync(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSync(); + } + + public int syncPoint(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSyncPoint(); + } + + public int setDictionary(byte[] dictionary, int dictLength){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSetDictionary(dictionary, dictLength); + } + + public boolean finished(){ + return istate.mode==12 /*DONE*/; + } +} diff --git a/epkcompiler/src/com/jcraft/jzlib/InflaterInputStream.java b/epkcompiler/src/com/jcraft/jzlib/InflaterInputStream.java new file mode 100644 index 0000000..0420582 --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/InflaterInputStream.java @@ -0,0 +1,247 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jcraft.jzlib; +import java.io.*; + +public class InflaterInputStream extends FilterInputStream { + protected final Inflater inflater; + protected byte[] buf; + + private boolean closed = false; + + private boolean eof = false; + + private boolean close_in = true; + + protected static final int DEFAULT_BUFSIZE = 512; + + public InflaterInputStream(InputStream in) throws IOException { + this(in, false); + } + + public InflaterInputStream(InputStream in, boolean nowrap) throws IOException { + this(in, new Inflater(nowrap)); + myinflater = true; + } + + public InflaterInputStream(InputStream in, Inflater inflater) throws IOException { + this(in, inflater, DEFAULT_BUFSIZE); + } + + public InflaterInputStream(InputStream in, + Inflater inflater, int size) throws IOException { + this(in, inflater, size, true); + } + + public InflaterInputStream(InputStream in, + Inflater inflater, + int size, boolean close_in) throws IOException { + super(in); + if (in == null || inflater == null) { + throw new NullPointerException(); + } + else if (size <= 0) { + throw new IllegalArgumentException("buffer size must be greater than 0"); + } + this.inflater = inflater; + buf = new byte[size]; + this.close_in = close_in; + } + + protected boolean myinflater = false; + + private byte[] byte1 = new byte[1]; + + public int read() throws IOException { + if (closed) { throw new IOException("Stream closed"); } + return read(byte1, 0, 1) == -1 ? -1 : byte1[0] & 0xff; + } + + public int read(byte[] b, int off, int len) throws IOException { + if (closed) { throw new IOException("Stream closed"); } + if (b == null) { + throw new NullPointerException(); + } + else if (off < 0 || len < 0 || len > b.length - off) { + throw new IndexOutOfBoundsException(); + } + else if (len == 0) { + return 0; + } + else if (eof) { + return -1; + } + + int n = 0; + inflater.setOutput(b, off, len); + while(!eof) { + if(inflater.avail_in==0) + fill(); + int err = inflater.inflate(JZlib.Z_NO_FLUSH); + n += inflater.next_out_index - off; + off = inflater.next_out_index; + switch(err) { + case JZlib.Z_DATA_ERROR: + throw new IOException(inflater.msg); + case JZlib.Z_STREAM_END: + case JZlib.Z_NEED_DICT: + eof = true; + if(err == JZlib.Z_NEED_DICT) + return -1; + break; + default: + } + if(inflater.avail_out==0) + break; + } + return n; + } + + public int available() throws IOException { + if (closed) { throw new IOException("Stream closed"); } + if (eof) { + return 0; + } + else { + return 1; + } + } + + private byte[] b = new byte[512]; + + public long skip(long n) throws IOException { + if (n < 0) { + throw new IllegalArgumentException("negative skip length"); + } + + if (closed) { throw new IOException("Stream closed"); } + + int max = (int)Math.min(n, Integer.MAX_VALUE); + int total = 0; + while (total < max) { + int len = max - total; + if (len > b.length) { + len = b.length; + } + len = read(b, 0, len); + if (len == -1) { + eof = true; + break; + } + total += len; + } + return total; + } + + public void close() throws IOException { + if (!closed) { + if (myinflater) + inflater.end(); + if(close_in) + in.close(); + closed = true; + } + } + + protected void fill() throws IOException { + if (closed) { throw new IOException("Stream closed"); } + int len = in.read(buf, 0, buf.length); + if (len == -1) { + if(inflater.istate.wrap == 0 && + !inflater.finished()){ + buf[0]=0; + len=1; + } + else if(inflater.istate.was != -1){ // in reading trailer + throw new IOException("footer is not found"); + } + else{ + throw new EOFException("Unexpected end of ZLIB input stream"); + } + } + inflater.setInput(buf, 0, len, true); + } + + public boolean markSupported() { + return false; + } + + public synchronized void mark(int readlimit) { + } + + public synchronized void reset() throws IOException { + throw new IOException("mark/reset not supported"); + } + + public long getTotalIn() { + return inflater.getTotalIn(); + } + + public long getTotalOut() { + return inflater.getTotalOut(); + } + + public byte[] getAvailIn() { + if(inflater.avail_in<=0) + return null; + byte[] tmp = new byte[inflater.avail_in]; + System.arraycopy(inflater.next_in, inflater.next_in_index, + tmp, 0, inflater.avail_in); + return tmp; + } + + public void readHeader() throws IOException { + + byte[] empty = "".getBytes(); + inflater.setInput(empty, 0, 0, false); + inflater.setOutput(empty, 0, 0); + + int err = inflater.inflate(JZlib.Z_NO_FLUSH); + if(!inflater.istate.inParsingHeader()){ + return; + } + + byte[] b1 = new byte[1]; + do{ + int i = in.read(b1); + if(i<=0) + throw new IOException("no input"); + inflater.setInput(b1); + err = inflater.inflate(JZlib.Z_NO_FLUSH); + if(err!=0/*Z_OK*/) + throw new IOException(inflater.msg); + } + while(inflater.istate.inParsingHeader()); + } + + public Inflater getInflater(){ + return inflater; + } +} \ No newline at end of file diff --git a/epkcompiler/src/com/jcraft/jzlib/JZlib.java b/epkcompiler/src/com/jcraft/jzlib/JZlib.java new file mode 100644 index 0000000..a4bb341 --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/JZlib.java @@ -0,0 +1,92 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class JZlib{ + private static final String version="1.1.0"; + public static String version(){return version;} + + static final public int MAX_WBITS=15; // 32K LZ77 window + static final public int DEF_WBITS=MAX_WBITS; + + public enum WrapperType { + NONE, ZLIB, GZIP, ANY + } + + public static final WrapperType W_NONE = WrapperType.NONE; + public static final WrapperType W_ZLIB = WrapperType.ZLIB; + public static final WrapperType W_GZIP = WrapperType.GZIP; + public static final WrapperType W_ANY = WrapperType.ANY; + + // compression levels + static final public int Z_NO_COMPRESSION=0; + static final public int Z_BEST_SPEED=1; + static final public int Z_BEST_COMPRESSION=9; + static final public int Z_DEFAULT_COMPRESSION=(-1); + + // compression strategy + static final public int Z_FILTERED=1; + static final public int Z_HUFFMAN_ONLY=2; + static final public int Z_DEFAULT_STRATEGY=0; + + static final public int Z_NO_FLUSH=0; + static final public int Z_PARTIAL_FLUSH=1; + static final public int Z_SYNC_FLUSH=2; + static final public int Z_FULL_FLUSH=3; + static final public int Z_FINISH=4; + + static final public int Z_OK=0; + static final public int Z_STREAM_END=1; + static final public int Z_NEED_DICT=2; + static final public int Z_ERRNO=-1; + static final public int Z_STREAM_ERROR=-2; + static final public int Z_DATA_ERROR=-3; + static final public int Z_MEM_ERROR=-4; + static final public int Z_BUF_ERROR=-5; + static final public int Z_VERSION_ERROR=-6; + + // The three kinds of block type + static final public byte Z_BINARY = 0; + static final public byte Z_ASCII = 1; + static final public byte Z_UNKNOWN = 2; + + public static long adler32_combine(long adler1, long adler2, long len2){ + return Adler32.combine(adler1, adler2, len2); + } + + public static long crc32_combine(long crc1, long crc2, long len2){ + return CRC32.combine(crc1, crc2, len2); + } +} diff --git a/epkcompiler/src/com/jcraft/jzlib/StaticTree.java b/epkcompiler/src/com/jcraft/jzlib/StaticTree.java new file mode 100644 index 0000000..e35931c --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/StaticTree.java @@ -0,0 +1,148 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final class StaticTree{ + static final private int MAX_BITS=15; + + static final private int BL_CODES=19; + static final private int D_CODES=30; + static final private int LITERALS=256; + static final private int LENGTH_CODES=29; + static final private int L_CODES=(LITERALS+1+LENGTH_CODES); + + // Bit length codes must not exceed MAX_BL_BITS bits + static final int MAX_BL_BITS=7; + + static final short[] static_ltree = { + 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, + 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, + 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, + 252, 8, 2, 8, 130, 8, 66, 8, 194, 8, + 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, + 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, + 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, + 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, + 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, + 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, + 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, + 230, 8, 22, 8, 150, 8, 86, 8, 214, 8, + 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, + 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, + 110, 8, 238, 8, 30, 8, 158, 8, 94, 8, + 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, + 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, + 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, + 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, + 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, + 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, + 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, + 121, 8, 249, 8, 5, 8, 133, 8, 69, 8, + 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, + 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, + 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, + 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, + 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, + 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, + 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, + 211, 9, 467, 9, 51, 9, 307, 9, 179, 9, + 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, + 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, + 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, + 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, + 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, + 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, + 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, + 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, + 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, + 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, + 359, 9, 231, 9, 487, 9, 23, 9, 279, 9, + 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, + 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, + 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, + 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, + 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, + 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, + 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, + 351, 9, 223, 9, 479, 9, 63, 9, 319, 9, + 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, + 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, + 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, + 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, + 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, + 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, + 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, + 163, 8, 99, 8, 227, 8 + }; + + static final short[] static_dtree = { + 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, + 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, + 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, + 30, 5, 1, 5, 17, 5, 9, 5, 25, 5, + 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, + 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 + }; + + static StaticTree static_l_desc = + new StaticTree(static_ltree, Tree.extra_lbits, + LITERALS+1, L_CODES, MAX_BITS); + + static StaticTree static_d_desc = + new StaticTree(static_dtree, Tree.extra_dbits, + 0, D_CODES, MAX_BITS); + + static StaticTree static_bl_desc = + new StaticTree(null, Tree.extra_blbits, + 0, BL_CODES, MAX_BL_BITS); + + short[] static_tree; // static tree or null + int[] extra_bits; // extra bits for each code or null + int extra_base; // base index for extra_bits + int elems; // max number of elements in the tree + int max_length; // max bit length for the codes + + private StaticTree(short[] static_tree, + int[] extra_bits, + int extra_base, + int elems, + int max_length){ + this.static_tree=static_tree; + this.extra_bits=extra_bits; + this.extra_base=extra_base; + this.elems=elems; + this.max_length=max_length; + } +} diff --git a/epkcompiler/src/com/jcraft/jzlib/Tree.java b/epkcompiler/src/com/jcraft/jzlib/Tree.java new file mode 100644 index 0000000..38cb40f --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/Tree.java @@ -0,0 +1,367 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final class Tree{ + static final private int MAX_BITS=15; + static final private int BL_CODES=19; + static final private int D_CODES=30; + static final private int LITERALS=256; + static final private int LENGTH_CODES=29; + static final private int L_CODES=(LITERALS+1+LENGTH_CODES); + static final private int HEAP_SIZE=(2*L_CODES+1); + + // Bit length codes must not exceed MAX_BL_BITS bits + static final int MAX_BL_BITS=7; + + // end of block literal code + static final int END_BLOCK=256; + + // repeat previous bit length 3-6 times (2 bits of repeat count) + static final int REP_3_6=16; + + // repeat a zero length 3-10 times (3 bits of repeat count) + static final int REPZ_3_10=17; + + // repeat a zero length 11-138 times (7 bits of repeat count) + static final int REPZ_11_138=18; + + // extra bits for each length code + static final int[] extra_lbits={ + 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0 + }; + + // extra bits for each distance code + static final int[] extra_dbits={ + 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 + }; + + // extra bits for each bit length code + static final int[] extra_blbits={ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7 + }; + + static final byte[] bl_order={ + 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; + + + // The lengths of the bit length codes are sent in order of decreasing + // probability, to avoid transmitting the lengths for unused bit + // length codes. + + static final int Buf_size=8*2; + + // see definition of array dist_code below + static final int DIST_CODE_LEN=512; + + static final byte[] _dist_code = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, + 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 + }; + + static final byte[] _length_code={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, + 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, + 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 + }; + + static final int[] base_length = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, + 64, 80, 96, 112, 128, 160, 192, 224, 0 + }; + + static final int[] base_dist = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 + }; + + // Mapping from a distance to a distance code. dist is the distance - 1 and + // must not have side effects. _dist_code[256] and _dist_code[257] are never + // used. + static int d_code(int dist){ + return ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>>7)]); + } + + short[] dyn_tree; // the dynamic tree + int max_code; // largest code with non zero frequency + StaticTree stat_desc; // the corresponding static tree + + // Compute the optimal bit lengths for a tree and update the total bit length + // for the current block. + // IN assertion: the fields freq and dad are set, heap[heap_max] and + // above are the tree nodes sorted by increasing frequency. + // OUT assertions: the field len is set to the optimal bit length, the + // array bl_count contains the frequencies for each bit length. + // The length opt_len is updated; static_len is also updated if stree is + // not null. + void gen_bitlen(Deflate s){ + short[] tree = dyn_tree; + short[] stree = stat_desc.static_tree; + int[] extra = stat_desc.extra_bits; + int base = stat_desc.extra_base; + int max_length = stat_desc.max_length; + int h; // heap index + int n, m; // iterate over the tree elements + int bits; // bit length + int xbits; // extra bits + short f; // frequency + int overflow = 0; // number of elements with bit length too large + + for (bits = 0; bits <= MAX_BITS; bits++) s.bl_count[bits] = 0; + + // In a first pass, compute the optimal bit lengths (which may + // overflow in the case of the bit length tree). + tree[s.heap[s.heap_max]*2+1] = 0; // root of the heap + + for(h=s.heap_max+1; h max_length){ bits = max_length; overflow++; } + tree[n*2+1] = (short)bits; + // We overwrite tree[n*2+1] which is no longer needed + + if (n > max_code) continue; // not a leaf node + + s.bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n*2]; + s.opt_len += f * (bits + xbits); + if (stree!=null) s.static_len += f * (stree[n*2+1] + xbits); + } + if (overflow == 0) return; + + // This happens for example on obj2 and pic of the Calgary corpus + // Find the first bit length which could increase: + do { + bits = max_length-1; + while(s.bl_count[bits]==0) bits--; + s.bl_count[bits]--; // move one leaf down the tree + s.bl_count[bits+1]+=2; // move one overflow item as its brother + s.bl_count[max_length]--; + // The brother of the overflow item also moves one step up, + // but this does not affect bl_count[max_length] + overflow -= 2; + } + while (overflow > 0); + + for (bits = max_length; bits != 0; bits--) { + n = s.bl_count[bits]; + while (n != 0) { + m = s.heap[--h]; + if (m > max_code) continue; + if (tree[m*2+1] != bits) { + s.opt_len += ((long)bits - (long)tree[m*2+1])*(long)tree[m*2]; + tree[m*2+1] = (short)bits; + } + n--; + } + } + } + + // Construct one Huffman tree and assigns the code bit strings and lengths. + // Update the total bit length for the current block. + // IN assertion: the field freq is set for all tree elements. + // OUT assertions: the fields len and code are set to the optimal bit length + // and corresponding code. The length opt_len is updated; static_len is + // also updated if stree is not null. The field max_code is set. + void build_tree(Deflate s){ + short[] tree=dyn_tree; + short[] stree=stat_desc.static_tree; + int elems=stat_desc.elems; + int n, m; // iterate over heap elements + int max_code=-1; // largest code with non zero frequency + int node; // new node being created + + // Construct the initial heap, with least frequent element in + // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + // heap[0] is not used. + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + + for(n=0; n=1; n--) + s.pqdownheap(tree, n); + + // Construct the Huffman tree by repeatedly combining the least two + // frequent nodes. + + node=elems; // next internal node of the tree + do{ + // n = node of least frequency + n=s.heap[1]; + s.heap[1]=s.heap[s.heap_len--]; + s.pqdownheap(tree, 1); + m=s.heap[1]; // m = node of next least frequency + + s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency + s.heap[--s.heap_max] = m; + + // Create a new node father of n and m + tree[node*2] = (short)(tree[n*2] + tree[m*2]); + s.depth[node] = (byte)(Math.max(s.depth[n],s.depth[m])+1); + tree[n*2+1] = tree[m*2+1] = (short)node; + + // and insert the new node in the heap + s.heap[1] = node++; + s.pqdownheap(tree, 1); + } + while(s.heap_len>=2); + + s.heap[--s.heap_max] = s.heap[1]; + + // At this point, the fields freq and dad are set. We can now + // generate the bit lengths. + + gen_bitlen(s); + + // The field len is now set, we can generate the bit codes + gen_codes(tree, max_code, s.bl_count, s.next_code); + } + + // Generate the codes for a given tree and bit counts (which need not be + // optimal). + // IN assertion: the array bl_count contains the bit length statistics for + // the given tree and the field len is set for all tree elements. + // OUT assertion: the field code is set for all tree elements of non + // zero code length. + private final static void gen_codes( + short[] tree, // the tree to decorate + int max_code, // largest code with non zero frequency + short[] bl_count, // number of codes at each bit length + short[] next_code){ + short code = 0; // running code value + int bits; // bit index + int n; // code index + + // The distribution counts are first used to generate the code values + // without bit reversal. + next_code[0]=0; + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (short)((code + bl_count[bits-1]) << 1); + } + + // Check that the bit counts in bl_count are consistent. The last code + // must be all ones. + //Assert (code + bl_count[MAX_BITS]-1 == (1<>>=1; + res<<=1; + } + while(--len>0); + return res>>>1; + } +} + diff --git a/epkcompiler/src/com/jcraft/jzlib/ZInputStream.java b/epkcompiler/src/com/jcraft/jzlib/ZInputStream.java new file mode 100644 index 0000000..cbd38e1 --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/ZInputStream.java @@ -0,0 +1,126 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jcraft.jzlib; +import java.io.*; + +/** + * ZInputStream + * + * @deprecated use DeflaterOutputStream or InflaterInputStream + */ +@Deprecated +public class ZInputStream extends FilterInputStream { + + protected int flush=JZlib.Z_NO_FLUSH; + protected boolean compress; + protected InputStream in=null; + + protected Deflater deflater; + protected InflaterInputStream iis; + + public ZInputStream(InputStream in) throws IOException { + this(in, false); + } + public ZInputStream(InputStream in, boolean nowrap) throws IOException { + super(in); + iis = new InflaterInputStream(in, nowrap); + compress=false; + } + + public ZInputStream(InputStream in, int level) throws IOException { + super(in); + this.in=in; + deflater = new Deflater(); + deflater.init(level); + compress=true; + } + + private byte[] buf1 = new byte[1]; + public int read() throws IOException { + if(read(buf1, 0, 1)==-1) return -1; + return(buf1[0]&0xFF); + } + + private byte[] buf = new byte[512]; + + public int read(byte[] b, int off, int len) throws IOException { + if(compress){ + deflater.setOutput(b, off, len); + while(true){ + int datalen = in.read(buf, 0, buf.length); + if(datalen == -1) return -1; + deflater.setInput(buf, 0, datalen, true); + int err = deflater.deflate(flush); + if(deflater.next_out_index>0) + return deflater.next_out_index; + if(err == JZlib.Z_STREAM_END) + return 0; + if(err == JZlib.Z_STREAM_ERROR || + err == JZlib.Z_DATA_ERROR){ + throw new ZStreamException("deflating: "+deflater.msg); + } + } + } + else{ + return iis.read(b, off, len); + } + } + + public long skip(long n) throws IOException { + int len=512; + if(n0){ + inflater.setOutput(buf, 0, buf.length); + err = inflater.inflate(flush); + if(inflater.next_out_index>0) + out.write(buf, 0, inflater.next_out_index); + if(err != JZlib.Z_OK) + break; + } + if(err != JZlib.Z_OK) + throw new ZStreamException("inflating: "+inflater.msg); + return; + } + } + + public int getFlushMode() { + return flush; + } + + public void setFlushMode(int flush) { + this.flush=flush; + } + + public void finish() throws IOException { + int err; + if(compress){ + int tmp = flush; + int flush = JZlib.Z_FINISH; + try{ + write("".getBytes(), 0, 0); + } + finally { flush = tmp; } + } + else{ + dos.finish(); + } + flush(); + } + public synchronized void end() { + if(end) return; + if(compress){ + try { dos.finish(); } catch(Exception e){} + } + else{ + inflater.end(); + } + end=true; + } + public void close() throws IOException { + try{ + try{finish();} + catch (IOException ignored) {} + } + finally{ + end(); + out.close(); + out=null; + } + } + + public long getTotalIn() { + if(compress) return dos.getTotalIn(); + else return inflater.total_in; + } + + public long getTotalOut() { + if(compress) return dos.getTotalOut(); + else return inflater.total_out; + } + + public void flush() throws IOException { + out.flush(); + } + +} diff --git a/epkcompiler/src/com/jcraft/jzlib/ZStream.java b/epkcompiler/src/com/jcraft/jzlib/ZStream.java new file mode 100644 index 0000000..0afa4fd --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/ZStream.java @@ -0,0 +1,377 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +/** + * ZStream + * + * @deprecated Not for public use in the future. + */ +@Deprecated +public class ZStream{ + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_WBITS=MAX_WBITS; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + public byte[] next_in; // next input byte + public int next_in_index; + public int avail_in; // number of bytes available at next_in + public long total_in; // total nb of input bytes read so far + + public byte[] next_out; // next output byte should be put there + public int next_out_index; + public int avail_out; // remaining free space at next_out + public long total_out; // total nb of bytes output so far + + public String msg; + + Deflate dstate; + Inflate istate; + + int data_type; // best guess about the data type: ascii or binary + + Checksum adler; + + public ZStream(){ + this(new Adler32()); + } + + public ZStream(Checksum adler){ + this.adler=adler; + } + + public int inflateInit(){ + return inflateInit(DEF_WBITS); + } + public int inflateInit(boolean nowrap){ + return inflateInit(DEF_WBITS, nowrap); + } + public int inflateInit(int w){ + return inflateInit(w, false); + } + public int inflateInit(JZlib.WrapperType wrapperType) { + return inflateInit(DEF_WBITS, wrapperType); + } + public int inflateInit(int w, JZlib.WrapperType wrapperType) { + boolean nowrap = false; + if(wrapperType == JZlib.W_NONE){ + nowrap = true; + } + else if(wrapperType == JZlib.W_GZIP) { + w += 16; + } + else if(wrapperType == JZlib.W_ANY) { + w |= Inflate.INFLATE_ANY; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return inflateInit(w, nowrap); + } + public int inflateInit(int w, boolean nowrap){ + istate=new Inflate(this); + return istate.inflateInit(nowrap?-w:w); + } + + public int inflate(int f){ + if(istate==null) return Z_STREAM_ERROR; + return istate.inflate(f); + } + public int inflateEnd(){ + if(istate==null) return Z_STREAM_ERROR; + int ret=istate.inflateEnd(); +// istate = null; + return ret; + } + public int inflateSync(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSync(); + } + public int inflateSyncPoint(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSyncPoint(); + } + public int inflateSetDictionary(byte[] dictionary, int dictLength){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSetDictionary(dictionary, dictLength); + } + public boolean inflateFinished(){ + return istate.mode==12 /*DONE*/; + } + + public int deflateInit(int level){ + return deflateInit(level, MAX_WBITS); + } + public int deflateInit(int level, boolean nowrap){ + return deflateInit(level, MAX_WBITS, nowrap); + } + public int deflateInit(int level, int bits){ + return deflateInit(level, bits, false); + } + public int deflateInit(int level, int bits, int memlevel, JZlib.WrapperType wrapperType){ + if(bits < 9 || bits > 15){ + return Z_STREAM_ERROR; + } + if(wrapperType == JZlib.W_NONE) { + bits *= -1; + } + else if(wrapperType == JZlib.W_GZIP) { + bits += 16; + } + else if(wrapperType == JZlib.W_ANY) { + return Z_STREAM_ERROR; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return this.deflateInit(level, bits, memlevel); + } + public int deflateInit(int level, int bits, int memlevel){ + dstate=new Deflate(this); + return dstate.deflateInit(level, bits, memlevel); + } + public int deflateInit(int level, int bits, boolean nowrap){ + dstate=new Deflate(this); + return dstate.deflateInit(level, nowrap?-bits:bits); + } + public int deflate(int flush){ + if(dstate==null){ + return Z_STREAM_ERROR; + } + return dstate.deflate(flush); + } + public int deflateEnd(){ + if(dstate==null) return Z_STREAM_ERROR; + int ret=dstate.deflateEnd(); + dstate=null; + return ret; + } + public int deflateParams(int level, int strategy){ + if(dstate==null) return Z_STREAM_ERROR; + return dstate.deflateParams(level, strategy); + } + public int deflateSetDictionary (byte[] dictionary, int dictLength){ + if(dstate == null) + return Z_STREAM_ERROR; + return dstate.deflateSetDictionary(dictionary, dictLength); + } + + // Flush as much pending output as possible. All deflate() output goes + // through this function so some applications may wish to modify it + // to avoid allocating a large strm->next_out buffer and copying into it. + // (See also read_buf()). + void flush_pending(){ + int len=dstate.pending; + + if(len>avail_out) len=avail_out; + if(len==0) return; + + if(dstate.pending_buf.length<=dstate.pending_out || + next_out.length<=next_out_index || + dstate.pending_buf.length<(dstate.pending_out+len) || + next_out.length<(next_out_index+len)){ + //System.out.println(dstate.pending_buf.length+", "+dstate.pending_out+ + // ", "+next_out.length+", "+next_out_index+", "+len); + //System.out.println("avail_out="+avail_out); + } + + System.arraycopy(dstate.pending_buf, dstate.pending_out, + next_out, next_out_index, len); + + next_out_index+=len; + dstate.pending_out+=len; + total_out+=len; + avail_out-=len; + dstate.pending-=len; + if(dstate.pending==0){ + dstate.pending_out=0; + } + } + + // Read a new buffer from the current input stream, update the adler32 + // and total number of bytes read. All deflate() input goes through + // this function so some applications may wish to modify it to avoid + // allocating a large strm->next_in buffer and copying from it. + // (See also flush_pending()). + int read_buf(byte[] buf, int start, int size) { + int len=avail_in; + + if(len>size) len=size; + if(len==0) return 0; + + avail_in-=len; + + if(dstate.wrap!=0) { + adler.update(next_in, next_in_index, len); + } + System.arraycopy(next_in, next_in_index, buf, start, len); + next_in_index += len; + total_in += len; + return len; + } + + public long getAdler(){ + return adler.getValue(); + } + + public void free(){ + next_in=null; + next_out=null; + msg=null; + } + + public void setOutput(byte[] buf){ + setOutput(buf, 0, buf.length); + } + + public void setOutput(byte[] buf, int off, int len){ + next_out = buf; + next_out_index = off; + avail_out = len; + } + + public void setInput(byte[] buf){ + setInput(buf, 0, buf.length, false); + } + + public void setInput(byte[] buf, boolean append){ + setInput(buf, 0, buf.length, append); + } + + public void setInput(byte[] buf, int off, int len, boolean append){ + if(len<=0 && append && next_in!=null) return; + + if(avail_in>0 && append){ + byte[] tmp = new byte[avail_in+len]; + System.arraycopy(next_in, next_in_index, tmp, 0, avail_in); + System.arraycopy(buf, off, tmp, avail_in, len); + next_in=tmp; + next_in_index=0; + avail_in+=len; + } + else{ + next_in=buf; + next_in_index=off; + avail_in=len; + } + } + + public byte[] getNextIn(){ + return next_in; + } + + public void setNextIn(byte[] next_in){ + this.next_in = next_in; + } + + public int getNextInIndex(){ + return next_in_index; + } + + public void setNextInIndex(int next_in_index){ + this.next_in_index = next_in_index; + } + + public int getAvailIn(){ + return avail_in; + } + + public void setAvailIn(int avail_in){ + this.avail_in = avail_in; + } + + public byte[] getNextOut(){ + return next_out; + } + + public void setNextOut(byte[] next_out){ + this.next_out = next_out; + } + + public int getNextOutIndex(){ + return next_out_index; + } + + public void setNextOutIndex(int next_out_index){ + this.next_out_index = next_out_index; + } + + public int getAvailOut(){ + return avail_out; + + } + + public void setAvailOut(int avail_out){ + this.avail_out = avail_out; + } + + public long getTotalOut(){ + return total_out; + } + + public long getTotalIn(){ + return total_in; + } + + public String getMessage(){ + return msg; + } + + /** + * Those methods are expected to be override by Inflater and Deflater. + * In the future, they will become abstract methods. + */ + public int end(){ return Z_OK; } + public boolean finished(){ return false; } +} diff --git a/epkcompiler/src/com/jcraft/jzlib/ZStreamException.java b/epkcompiler/src/com/jcraft/jzlib/ZStreamException.java new file mode 100644 index 0000000..424b74b --- /dev/null +++ b/epkcompiler/src/com/jcraft/jzlib/ZStreamException.java @@ -0,0 +1,44 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +public class ZStreamException extends java.io.IOException { + public ZStreamException() { + super(); + } + public ZStreamException(String s) { + super(s); + } +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..cc4fdc2 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..6ce793f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.0-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..2fe81a7 --- /dev/null +++ b/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..9618d8d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/lwjgl-rundir/Java-WebSocket-1.5.1-with-dependencies.jar b/lwjgl-rundir/Java-WebSocket-1.5.1-with-dependencies.jar new file mode 100644 index 0000000..8fb33ad Binary files /dev/null and b/lwjgl-rundir/Java-WebSocket-1.5.1-with-dependencies.jar differ diff --git a/lwjgl-rundir/_eagstorage.a.dat b/lwjgl-rundir/_eagstorage.a.dat new file mode 100644 index 0000000..72f052d Binary files /dev/null and b/lwjgl-rundir/_eagstorage.a.dat differ diff --git a/lwjgl-rundir/_eagstorage.forced.dat b/lwjgl-rundir/_eagstorage.forced.dat new file mode 100644 index 0000000..3d90e9d Binary files /dev/null and b/lwjgl-rundir/_eagstorage.forced.dat differ diff --git a/lwjgl-rundir/_eagstorage.g.dat b/lwjgl-rundir/_eagstorage.g.dat new file mode 100644 index 0000000..b84a86b Binary files /dev/null and b/lwjgl-rundir/_eagstorage.g.dat differ diff --git a/lwjgl-rundir/_eagstorage.p.dat b/lwjgl-rundir/_eagstorage.p.dat new file mode 100644 index 0000000..b190f94 Binary files /dev/null and b/lwjgl-rundir/_eagstorage.p.dat differ diff --git a/lwjgl-rundir/lwjgl.jar b/lwjgl-rundir/lwjgl.jar new file mode 100644 index 0000000..4cb7cda Binary files /dev/null and b/lwjgl-rundir/lwjgl.jar differ diff --git a/lwjgl-rundir/lwjgl_util.jar b/lwjgl-rundir/lwjgl_util.jar new file mode 100644 index 0000000..c055bff Binary files /dev/null and b/lwjgl-rundir/lwjgl_util.jar differ diff --git a/lwjgl-rundir/natives/OpenAL32.dll b/lwjgl-rundir/natives/OpenAL32.dll new file mode 100644 index 0000000..1f69e94 Binary files /dev/null and b/lwjgl-rundir/natives/OpenAL32.dll differ diff --git a/lwjgl-rundir/natives/OpenAL64.dll b/lwjgl-rundir/natives/OpenAL64.dll new file mode 100644 index 0000000..6f2a2fe Binary files /dev/null and b/lwjgl-rundir/natives/OpenAL64.dll differ diff --git a/lwjgl-rundir/natives/liblwjgl.jnilib b/lwjgl-rundir/natives/liblwjgl.jnilib new file mode 100644 index 0000000..227ccf5 Binary files /dev/null and b/lwjgl-rundir/natives/liblwjgl.jnilib differ diff --git a/lwjgl-rundir/natives/liblwjgl.so b/lwjgl-rundir/natives/liblwjgl.so new file mode 100644 index 0000000..4beea98 Binary files /dev/null and b/lwjgl-rundir/natives/liblwjgl.so differ diff --git a/lwjgl-rundir/natives/liblwjgl64.so b/lwjgl-rundir/natives/liblwjgl64.so new file mode 100644 index 0000000..314b892 Binary files /dev/null and b/lwjgl-rundir/natives/liblwjgl64.so differ diff --git a/lwjgl-rundir/natives/libopenal.so b/lwjgl-rundir/natives/libopenal.so new file mode 100644 index 0000000..0a3a619 Binary files /dev/null and b/lwjgl-rundir/natives/libopenal.so differ diff --git a/lwjgl-rundir/natives/libopenal64.so b/lwjgl-rundir/natives/libopenal64.so new file mode 100644 index 0000000..e0693c0 Binary files /dev/null and b/lwjgl-rundir/natives/libopenal64.so differ diff --git a/lwjgl-rundir/natives/lwjgl.dll b/lwjgl-rundir/natives/lwjgl.dll new file mode 100644 index 0000000..f095831 Binary files /dev/null and b/lwjgl-rundir/natives/lwjgl.dll differ diff --git a/lwjgl-rundir/natives/lwjgl64.dll b/lwjgl-rundir/natives/lwjgl64.dll new file mode 100644 index 0000000..240dd2c Binary files /dev/null and b/lwjgl-rundir/natives/lwjgl64.dll differ diff --git a/lwjgl-rundir/natives/openal.dylib b/lwjgl-rundir/natives/openal.dylib new file mode 100644 index 0000000..3c6d0f7 Binary files /dev/null and b/lwjgl-rundir/natives/openal.dylib differ diff --git a/lwjgl-rundir/resources/achievement/bg.png b/lwjgl-rundir/resources/achievement/bg.png new file mode 100644 index 0000000..d4ecac2 Binary files /dev/null and b/lwjgl-rundir/resources/achievement/bg.png differ diff --git a/lwjgl-rundir/resources/achievement/icons.png b/lwjgl-rundir/resources/achievement/icons.png new file mode 100644 index 0000000..f966c28 Binary files /dev/null and b/lwjgl-rundir/resources/achievement/icons.png differ diff --git a/lwjgl-rundir/resources/achievement/map.txt b/lwjgl-rundir/resources/achievement/map.txt new file mode 100644 index 0000000..aaf280a --- /dev/null +++ b/lwjgl-rundir/resources/achievement/map.txt @@ -0,0 +1,446 @@ +1000,43ddd8b48469d9a8c011718aa846facb +1001,aaed8c669f583cf35300f7c5d5396fce +1002,d517ae73160fd8576d7687ead1c1a973 +1003,ac37df168bae3c69a24d7fd5bae913c7 +1004,6d2591e94464b8327afadbdba44978d +1100,8b1df73e012e2ae34cd2d84a72a7898b +2000,c9ee0d494e0524c86a577cf684f5816d +2001,cd7a2836ea0b77b23a6131222f5be354 +2002,381aeedb2c5c5a7a9a01333e0eebc839 +2003,229048d1bb9e928831734cb2e5000286 +2004,b2c088c3c6928bfe29684a75ae1b127c +2005,1ce3491a1021a5aed07c687e3f6133e6 +2006,6c3d114caffd8160f7d56fc8757419a +2007,bcb501cfac8f7e73b455563bddbcb417 +2008,e1aa93d7bba48898a32810c43c6ff5c3 +2010,d0818779df1b967cc2f8ffc3ada631ec +2011,ecf0dbe93240e84edf6bd263645e634f +2020,b4a67353e11c3039ad755a3e96b4a046 +2021,1bb21f7731a5b3ffc6a1e2b586dae3f5 +2022,e58162e284df8fe339f05626eb46d835 +2023,739948643f5f6f685aea81c42883a480 +2024,799b0d35362a9574d3226c2d762b53c6 +2025,5ec18fbb462516a1e1a3427e0595a7d6 +16908544,12512904b67d2091dd516dc8eeb0cfa0 +16908545,a5c35cc01a263f91419d3e8e981708f1 +16908546,f6bdebf227e42c204066cede8cb5928c +16908547,9c44e6d3ab80afa2bb52fe3499559d5e +16908548,2e1799ddfdab14417c2a8e24d8c0c731 +16908549,3f4169a181feb5d2532efc6aa91f2ee5 +16908550,895725d3432cbf374b1cce4f7db28e9 +16908551,12892864f18d30521b6f4a6c45b65ece +16908552,146f6c3458adde8e0bca04d976275f85 +16908553,7c40dbd9451129b4762f3ab04ce7ffb9 +16908554,56d763eeb6a0107c2146d7dccd686d2a +16908555,9a4fff004ae419711c2a876b57cba69f +16908556,170ff67dd90d8d3d8dae393037da5e9b +16908557,3e65d657af8611cb3578cd8713419d4c +16908558,f3cb95383f698c4e9721b5aaa5fac3a7 +16908559,65bd006dc163a186f2dbb127f8ec0b27 +16908560,8c6479d786f9117e04910153a4f47d86 +16908561,75a25bd69f36250789d914ac01da34c1 +16908562,87a28b2bf2fad838af72ce00e2fb1937 +16908563,249ff32d605c5ba0a07694ff4fbbf15a +16908564,ba3b355eb9134bcd7522a1fc203c4c58 +16908565,321e1cb3657d2aca73fb9a8083d9c3bf +16908566,adb182051fab2c2269df89b4f75e505e +16908567,3d9ae8982f01fb6a6c56cffbe2fa074e +16908568,1efffb054b2c864f5ebe180ae46891c3 +16908569,25c73629d0b6b46690d222cecf331ba2 +16908570,6a46694c996e5721b14c9da1f00fe62c +16908571,5efc1c291eef23fe33f5209388b8cc33 +16908572,f71fc7deef6835c8efc305a00f1e8b8f +16908573,15484a373254c6024d90edf3b7a82947 +16908574,8253f1aaa2205dcaf828903cfce46e4 +16908575,ab778410d1fb2c0e55fec0c7d764b17c +16908576,19ad61c04ff3ae082955f72fc8771866 +16908577,b5d3eeff40086643a03f034b5345504d +16908578,3d647bf5562e743263cbd90be36b6a1c +16908579,5a9d2fb7050009785421257d5ef24416 +16908580,909b03e2d2eeee2e868b5aaf446e81ea +16908581,e603a4cbfdfcbf4d0bfe25efb753b424 +16908582,e355f481f99220e50e4b2b2eb45dcc56 +16908583,73a25e59c2d18ae77db02928b0a70e3 +16908584,8f81a2fb647f817422a299829994de7b +16908585,128e9978380ee9ef981d2e12d008255e +16908586,fd1453f3e2a3125e7d16cfe6fd2d4722 +16908587,8e27b6f750bec22333a5d4108ce1e094 +16908588,b2169f6190bdf95236037bed2301712b +16908589,536e6340e5328075ede672428d94d921 +16908590,cb9eede8b783b4a5d7ff7529e3fb1f44 +16908591,267d51d891c3c32b3a02577d38f4e242 +16908592,3f31e8ab260f02acca218c720fafc7b8 +16908593,552869a63aa3151e79e875596f31e505 +16908594,c5b0399e7fc64f0561a82063773e1282 +16908595,cfd61cdbf22133caeca528da9b53474e +16908596,8d3802169313f270d5adcda790170ca2 +16908597,a82c4f31d6d3f5bef9aa3062945c02d6 +16908598,85eca649072752e9ffafdefa1287470f +16908599,98ffd259abbe2e4794c00716a9d2da7 +16908600,263f8fab89ae0f9d695a74512443070b +16908601,b4ae28e8babe7bd09b2a392780565dbe +16908602,dfd84b5b35231267a47891cc8c8f48ba +16908603,f6990bbd57862a238aaf68b0c2f4c998 +16908604,9dca837e109ae977a89ed64dd17fab10 +16908605,ebdb407fd6e4d5c450f73173487c3162 +16908606,fdf869946d814f4f2aeebe269db06e31 +16908607,f9ea1fa393862a86e79ffade6a2662e7 +16908608,60491b4f5956534afd5959e7c2411cda +16908609,b78fc6d8b8b8ecb1266eb9c04c5129b +16908610,add241f6dcfe6af3f096a45b96fb04e1 +16908611,38760b28c0d26204b1e0383ca318947a +16908612,d3d8076b8b7a911b7cbbf5099f8ffd48 +16908613,fc78be6fb5735b715325ac499990550e +16908614,a7504fcd85d6696a8880f32b97b34a60 +16908615,f0821b6fdc8ebbf8a6fcb37c75086b1d +16908616,88b0e1b842fc88f0cbc5f38e95d68417 +16908617,d977f8453c349a44baa7e05c3dd81cb8 +16908618,26184c3c1edfa7623d5620433c0ff36 +16908619,8edbf7f3996852add4fcb18008cb722f +16908620,39e5881696ed1141fb934593dd6bab70 +16908621,1e0d787240ea16af6edbbdb1ab372fe7 +16908622,af6ec83a0b072b4abd4194d8d43f7f02 +16908623,658b5f77ff892a455a7fce5dc93268ac +16908624,6474336f089d541c9cec4a1df0c3b6cf +16908625,72cfc6fe503df207d53119aa7d5b84b4 +16908626,3070c2283ca5fd0fe00f7880a4bcdf18 +16908627,340cef5b043dceb7073ede0be69d700d +16908628,24dda1839a72d6707ed1932f6f32bd8e +16908629,1c50c7d94cec18710417d513708094d1 +16908630,2b1f11fed636bf7892650b9adc9b8e94 +16908631,afd9ba61c39fa742a840fe6ab2cfb490 +16908632,b709157ffabe225e820218b020508173 +16908633,3e9f7b867952f7b2df48e156402d558 +16908634,ab9f22a1fbc265d19a4dd7f84f3a4585 +16908635,c89cf9510108d63d7d181b3f7c546094 +16908636,c7af3251ce44f2dafb2c192d817e9c52 +16908637,796f607d214012447b7c552673f95b4a +16908638,ea796bd83dd7689d322085c74d0957a7 +16908639,ce2f6f842d68418baad5fc2ecefcb879 +16908640,6b3016429a5f814f3cccaff484a46831 +16908641,7dea9bdb69c9c5965609eab99af9f9d9 +16908642,3add5c50b3427182fcb7dd04fe953945 +16908643,4175965cd5cee134d43038ac54858b0f +16908644,feae27a32b6cc95860ec46da6d37c4b0 +16908645,5898813ee0b2785afc9dad2524f56162 +16910544,adb04e128238341b88a18532f3448d13 +16910545,8e274d3a14b5cb87cbce019d0a3b9a23 +16974080,cfed396d9f54d3c04bc390a004916c52 +16974081,64f1b3409c0937114f77f9933a4e2b82 +16974082,5a6e9dc254405a6cb066472172fa09b1 +16974083,b23adf8b24d9a42637977c3322f02b75 +16974091,df1b76bca1e6a035d3e22e7c01f67bc6 +16974092,4bb3d702d36739ba62041c0c936cbfb6 +16974093,d02062bdb07f81100381ef87e6fc2922 +16974094,1a0d208f9f489b37b800c6eeaaa752c9 +16974095,34ee6807c2040168606740d0e3f46e30 +16974096,9b8bb8517841df03f1a894b238251068 +16974097,bb0b43349ffa6aa13b5d84ca70d25eb3 +16974098,b3b647da85fe51c6da997e28b66cb4c3 +16974099,d33c3d7d3fbc6880e0e03ce573644b1e +16974100,17d45fba9866349c133608e9d42e4ac9 +16974101,74205e9529729bd0ef51c3d544c1e372 +16974102,edf620106dc10c10a3357436a306400d +16974103,74b3a17953dca5a0cb9bb8c47b241eca +16974107,1938aff98985ef5e79c7003868c1e91 +16974108,14b782f5d9afda571ce6c8bad868e2bd +16974109,cb124718b4ecfb29a900e1e617c79544 +16974110,ae3c73a1546a058da74d4b8a588b59f2 +16974114,cbdefe9bd14088ad45141843474d2bb0 +16974115,641938697f84f6e7b59ebc08edc4648b +16974116,74ccb1de521aa54c65ffcb906ffd1d3b +16974117,fffed44e7bb844ad6c69f7eb4540cff3 +16974118,536b2d3a4009eed61300bf5f0af7419e +16974122,8a8ea889723fc0f8de50c53339819871 +16974123,768b65f8e24b1e042b75cf6f576cfcd1 +16974124,a4b5522486920acfc2ed97e105c7831 +16974125,6e9b513f3c219f4276556070b36a0339 +16974126,942450301cd8068c9a14352c1cecc2d0 +16974127,c98e2b8eb252d75a2a1f90144596ada4 +16974128,7b13a95332dac62ad73cddf33d3bba0f +16974129,1951adc5a346867490626a854788b9ad +16974130,b75636944eeba77a4ce3f254460e0d49 +16974131,bb5bc2285c0a2e24548533f59af76788 +16974132,929561410b14786db52aa89b675a9759 +16974133,6b07bd2605f311d8134a8170ba49fd73 +16974134,2f97923d891e3e8c1967d53f7734ff55 +16974135,dea0b11c8760d28eafbe76e25df7d301 +16974136,586e309c00ba6f3c2ada595b742bef23 +16974137,29e48d74dc5062eb900d376196fd4f23 +16974138,fa79e8b641b225166b17ea86a9ecb174 +16974139,7a66328b6b976337ff5bde5c7edccaa5 +16974140,95559b402657cf222a87248d1e6ce0f5 +16974141,52843420526ced65d57513afad342515 +16974170,56690bacbebf8107b83e80528f40740 +16908289,83cfae9a11032a88e08c95b7fcef84cc +16908291,39a4ea3b5ddf7f89b41faf675f7bfc0f +16908292,64ec21dc8495fb180cc94f59f873efb8 +16908293,fda16e9858404b9545649ba21a828a6a +16908294,a57157213ffc25d269ea46e45984eae0 +16908295,90f2ac6ac3005ad4cabcd248831f2205 +16908296,4adafcbbef5ace168ca03e173af10452 +16908298,bb2e0425d8b489fc856cab2c0828f2ff +16908300,76b80613789c553593097956002a392b +16908301,23bd5cc4fb97d25e432604be0958320d +16908302,7b129f5775b2d4997681338012130cad +16908303,4935425ac3ef59e71bca7c4c8bf7e2ea +16908304,564d5c2df622b99692929bedbcd7f4b1 +16908305,e06bb538b6b224ce1376b47804ee2bbb +16908306,f13b4a0fa66e65ed33dcbd7ead08ac46 +16908307,29710a54739e35ae0d34919fca091640 +16908308,8693b46ac89dd595f8e3efd4437e6e90 +16908309,3ebf10825c7d8f2e17deae70b37d1fbd +16908310,354d414b2a1f29494a80b3acedb72ae2 +16908311,de662954670ec00899809b916abe6c60 +16908312,831dd7a79cd7e5f3cad86690c6724902 +16908313,265f19645487a858e4f53b9706cdff03 +16908314,2ad06f9f7e24f920fb067e2f2cc7869c +16908315,99f3286cc36b9a4393b3e967878b01d4 +16908316,4fbc91a39f7f4814f8f79ba425e4f30a +16908318,ccb82be2278587dd637ac763a1087c7 +16908323,8e8a2f6a87c3701e76650680e7b2f6e6 +16908325,fcd992a9a44518d5de6bd09c409ea7de +16908326,e41e706456c10963824e032484992946 +16908327,662301d3344073cc69887a27a8c42f24 +16908329,313738e052612f868d55f47940080288 +16908330,79474b10f860f09be4e9183ad5f1c7b4 +16908332,60a3062d151151a2ff229a02d3221337 +16908333,833c8c420ce04aa18b9912ff05e5ced2 +16908334,6e0f4183ad7abbb63c5b6a1ead24214a +16908335,477292deea02d72acc1087b2425c570a +16908336,82cf44076f1a94ed31f3172433a80ef6 +16908337,84f64a9f8523d35a1cf8319f580dd578 +16908338,b6365376050089a025a1ed1d85a85dba +16908339,4e989db8b445f22b61bd4d30daee1a05 +16908340,50ec890e85029d44ea96bfa31d8ed16a +16908341,b4f23438454d39a742546dafd5d3cfc6 +16908342,5414035b686e0fb0a1ce0d535d0a0f82 +16908343,72d6218e86d3787422fa6b03f30ccaf3 +16908344,ddfe42c53aae03dd94c2d3163869ddc0 +16908345,b8b09ac7af1bb81e28715a3e0f0eeb17 +16908346,c53d28ac584d8053ec438f692a58cd1a +16908347,243cf7fb2bf36e60e3a25cde83b33a5e +16908349,2837ae3dabc00c4c5515bafa34a302dc +16908351,4973e12438ce4c870f6ba1c158873c43 +16908352,37678301896aa95cc358bcd73308232c +16908353,31c5e38768bda9a8a7cd1bbca7c9226d +16908354,5ff1e27f9ef25fcf0a3c51b0551f7fd2 +16908355,60a060ee3e51167f4d87cf6d923f9ca7 +16908356,b24aa4a609b3483b795c4f3bf89116b7 +16908357,7a17a96ff758cd4ff8c0ffd070230cc7 +16908358,c14586711c04239a174c192d24b8ce20 +16908359,1f0abe2925128be5191932a1cc4a3019 +16908360,a9c8343cf444aa7686d9dd2b40e90a47 +16908361,94a02b3ef18bb35970105bf276001fe0 +16908363,bfa45b4169d1944debabc84b04880837 +16908365,a3d0bb31ba7c30209129e4366e072b05 +16908366,de6d35451526c85c7c5907a0adcbeff7 +16908367,4a0d45a9aedaa06eb574f88f580c265b +16908368,56ab2510d3cb4787bdcfa9680aa7e757 +16908369,feef935305ae32e1972d3b017a4eb +16908370,41b270e7ecb39d0b81d1b60f32c3943 +16908371,b159339fc55e60000efee4c55d0e1d1c +16908372,74ca5387c7d373fc88e65e0623d5991f +16908373,8b8ae20ea681d47cd899f74f75bde08d +16908374,5cb926f4743f6ccdb4988c8b35dc97dd +16908375,947a02e037fe9d31c8eb4c4a22dba58c +16908376,2c2a7e8a269a770cc4afbe695e662601 +16908377,9a992e19651652de8b4f5ce07d1d2af0 +16908378,3e37efadc720d972ddc30ccae606ab00 +16908380,77b1802a2504a685bf8ff34a1f9de6c3 +16908381,45c0dbda39dca97dc634a6e89f037716 +16908383,ca404ded18b83fd872a5810c8a44517d +16843027,ecc0eb0ba51e2c14aaa006e168eacc8c +16842753,f6282e18f6f87e4cf68970579aac7219 +16843026,6f3d105b3e6d1624af4ce68b2a55362d +16843025,aa1c8e137823bf5245f0d27c980796e7 +16843024,ed65803a11251872c6cf659381d0aaaa +16843031,fa2f9de197813d8e32d78bd184603161 +16842757,1a13db89ae6fdbb152856edbe3688d95 +16843030,46bd8fadf2f12988d808e69dcfc138cb +16843029,bf398d8ec9fef1d04c67fbf474fda790 +16843028,69ee29bc3bd715b3203d888ca2a88cc0 +16843035,2f79ed9030fe0339dec2eb43f56fa369 +16843034,e2f097a36cdf87a1b211d27eb31dea32 +16843033,c02e9379a6624b40fef669494a7e7183 +16843032,af44f7fe9a4366c67479a44b24ae80b +16843038,501ead1cb03222808aa09b376c9d5cac +16843037,a2d01853631a9b52006ad32497ddc865 +16843036,6e381ac09bfc75ef7f71e02f3b99f279 +16843010,bcfe734d49949142a5073766188213dc +16843011,88ea7e11c57b09139afe92169c443e20 +16843008,91f14375672f1b2003202ec7682771cb +16843009,f5007e4886946d1eb603979a35726d69 +16843014,b0bde3daab8a1cc6354cd86c65db90e2 +16842772,b59c880de07e668eaba0888fc4de229a +16843015,7184233667abf34d2ee3eea20fb9f82b +16842775,bcc06ff4c56de9b4a1557d3c47ec1783 +16842774,6f2eab110a33c15cb17238708244db4d +16843013,3fe45d065187550d481cc745780c29c2 +16843018,7bddb0161d99059f0a6c1c09d0b35b34 +16842777,fdc779803765398f0c782a1fd55a9d86 +16842776,6b6c09ee89a933288c37f55d2187eddd +16843019,87545673867c5cf2f97ea6cc3e0d3595 +16843016,e2288c9f60d09d5f2882175abf161bd +16842779,9667a31366f5dcf740d64b775402c64 +16843017,e3108d8ee8530e50d7b425de217a4585 +16843022,847f1b6f38ebf442a1d34cac0fd6080e +16843023,5d01d19f8441e4d5dd5c41266f480ffc +16842780,b02509b360e6f14eac4fb03f55c11fed +16843020,90e2ab194dab9f482eca64c651ea41e9 +16843021,58d3e73bd29c14b6ec97d4187cee5500 +16843057,bf533b7d78ccc350cfd2f41a8e1f0822 +16842787,e49146643faf3308ca7246d82fc5b2bb +16843056,d8e023c15aa80df2445c782c6b2179da +16843059,c649596d99d96be696332cb08b4a33f2 +16843058,d129fce211dfb56e80195a11f39ab1e9 +16843061,441d86175b74884ef3f672066ae52c90 +16843060,cf6d7dfef99b200a4551cd65467fb9fc +16843063,f50f8b7fafde6d640ced3ec4d797f807 +16843062,d22de0ebc290280b2699b5cb77568fcb +16842794,d347d92a886b9d445d7d60b090a5bcda +16843065,a393477443f20a1a8a511c390024f963 +16843064,e6f28eea0ebbad0d18d23ea3c15f2102 +16843067,d6efe6a63f529d675417c2092546e144 +16842793,d5ac3bcc56cbc370ae3b172dd6ed5df4 +16843066,935aa84de286e8bced6a127b69347997 +16842798,377a21bcb39dcfcb4a0902a7555a984f +16843069,63cc6da6165cc068740827890b4460ed +16843068,6dda3129884399b67b935bb4e51ad34f +16842799,d4831a785c1c65ad2054bb1232babf0c +16842796,48be99a37d3a885d38657a50d6f77365 +16842797,8da03c2f611c7f0654aa71096832b5c +16842802,9b2a96570a99f6677e299d8215b1eecd +16843042,322d7c02f205806126f1529564ab3cd0 +16843043,660acf0ca76261ec49deb7a7bd072f8c +16843044,d8dd28acc9e4431ff8eb481c1d8d9832 +16842806,919bc6715eddf74c0517372ead95cdcb +16843045,72ae59db2ef5c472f671b31f1c6f07ce +16842805,9e359ce06b5603c820bd749592beb4a7 +16843046,cee09c2303e44dfbbaadbf167cdc503c +16842810,8ecd9ec7607c958cdf2e252f516fe3d8 +16843049,47171b2af8bb14c3816f52f79579b46d +16842809,fef5bbbc588422579bf3de8a49c73e18 +16843050,6b29998dbe690122afdf6da71e905009 +16843051,5f9f017aa89719c7a282aa222c65baf +16843052,216a61701714cb3f04e23a74a1336864 +16843053,e146704e3fe30e6821352ceb3b090184 +16842813,899942760d5a83d94cf58a536be6171e +16843054,5aa0a467c7451f88f9c6056e8c7427cc +16843055,6881fc74a0574433e9e0f05f7cae53f7 +16843095,50f6c2ffdc69bea12cd7b58c69824be1 +16842821,42b4814e4e61191b61a8d3f7c6041938 +16843094,356c3f0d5b88d0e2077d85168eac6306 +16842822,d69011621d777519c5ab6a68da8959 +16843092,d84a39f3d30a72b13640e3afb7ea2018 +16843091,37603e187bd7ad9dceccb8ef2b6b5335 +16842817,bad6f1072232c28353aabf42142cbd26 +16842818,bd0c4079c99e529e55abef5ac44dcdf8 +16843088,5e5d08b1780bfd69747216c24b7aee92 +16842819,ae608e1ca5ca083163d92974d7c66b06 +16843103,d4d1b946336039e515c3e4a392694223 +16842828,6a15bcf38bcf78021f9416ac395cac85 +16843102,603020acbbdc6e8765c2e2cd589f7933 +16842829,41cce73f9ce59993afa3517becd4bd3c +16842824,2368ffe803beb1d06772e96eeffd9cc9 +16843099,c373e78822d440c926edf7f1b700d4c5 +16843098,503a4fb49cbfebe1fb71ef185c8ced56 +16843097,4e72dc4d35b34147ce69d691aa2937e3 +16842837,4c903ddf3b9cd49a952a3889fc2c5573 +16842836,a304f875b846d65498366479fbf34568 +16843076,1b11a34d5c6cee280c727938ee96054b +16843077,ff170af78a0a674445f16e24394546c0 +16843074,ba8bd10757ab9a4446f024952bf3f1e3 +16843075,b34ec8f0f5f92acf230925c89eacec65 +16842832,3b10180dc99ab99568b51010d89c655c +16843072,d752bd5dd907feec915d036d76707ee5 +16843073,168e43895b105169862fa2e3c205529b +16842834,58efc828918aa006d5af09e32fe7799b +16843085,b30c099494e63d26f755d58ba109136a +16842841,2c471142bddf9a982a48e0ecb52cbb8 +16843082,5574b9699d71e02f3efb48f3712da8bf +16843080,4945e39d1260ff273c49d39dfc58c2a8 +16842843,bfc9dce4c1ccef959c57360fb9f70205 +16843108,4e225dd49c0231b617a15ded1ba6cb0a +16843109,35715377a038019c56925b2e661cfdab +16843105,3b91182484dc677a0bf27263e612d818 +16843106,affab7221afa03df4b7306b9ce50be7f +16843107,e3710bc197d17e0dc78ae3f607c46048 +16777217,9012132a1d0f770eca67e62a68247137 +16777219,58fc65723143afeb33f742c17e028c94 +16777220,1d5e2088f7137e304366873dd829ca98 +16777221,66a18fa3f554756edc12bf1a08586bc8 +16777222,4007295f7bdae0b78a6e47a9d64521 +16777228,c154160ce7b52d4bdc220fc954edf796 +16777229,2400808c6f442f2663b6869e4930c879 +16777230,7ae3b31e8e0f2f22f50fbf224e1fe4f7 +16777231,fe5698e183b10037e38f979a411489b8 +16777232,aeae00c7b4a95ff05423c1629bf3ad7e +16777233,72153ea3d60930cebf4c0d37fac89102 +16777235,f517ab768fbb35e275440b74b6631bfc +16777236,623df9298630687873579ea16bb97e7b +16777237,6984cb9e6a322728be736860b97b971a +16777238,6947378f4e2abb24b47e2b943945b16f +16777239,55a585682bf0569a60a71a66f031ca2 +16777240,f653295b0c48244dc2aa68fc5b94fa29 +16777241,c213fb7ee968403b24ff6ede98686add +16777243,afd641da6f3834b319b761ba6d72ff74 +16777244,8d822c710a221b8a407b2def97885470 +16777246,9c99187cc6fd9c958417b4736772e4d3 +16777251,6418210d69669c4a602148ed42ab2ecd +16777253,afe51ea56dc8c831f9b0b5ae02bac702 +16777254,95812c1d4021558b6a7f62521228c52a +16777255,3a1252acb6fe968751d2b61d57557e09 +16777257,fd7caeeb5d16756028f19ba016ed1970 +16777258,6339b8043c05d19c6b15135eade95f94 +16777260,aa1ed939a8b275df9dc5474bc0477a33 +16777261,b631dcf219d3add3560f243ff6cceb75 +16777262,91eca0c33ac53fb155feb15db48c43de +16777263,b681c19d7812c281b4b2feabb88697f4 +16777264,a2b07ae4f37a65fe1f5992826b578b02 +16777265,af5255a4dcb486e2ab11669fd3de8441 +16777266,8a4b2b706f219e52a261e342b47a3964 +16777269,921cb54cfb47ca9eca0edcf8e660e3cd +16777270,b79b3a522d1e2f865eb1e9aeb63dc66a +16777272,36e1c1dd8cbb267488e1669811319e7e +16777273,c84a7d710228024c2e100a79a2c30e55 +16777274,a1674e3020689bae5680f29f937e5424 +16777277,46b34dd723f7efeb38f670925ee3824f +16777281,da71e3e4f9a25c6621d2f0b40ffd1c72 +16777282,388109bb9b9b49c1f5bb604abee91671 +16777283,eb6912fd84b2d57ed3433acb3f85d3e6 +16777285,619967351702f1d570d4d0195bbbcc1e +16777286,ebff74d54387fb154d5b467e01d92b64 +16777288,f8154dd7c9c1d397dd64eeb6569d7d34 +16777289,971cc6f827398c6c4755b310c6795672 +16777291,bb952ff9523f248ddaae56317e91a509 +16777293,e5c24577cf35a31bd217d206b88a7499 +16777294,f4c170867c75982e604358da611b26e3 +16777295,922200512d058ecc0ef19a0efcdb51bf +16777296,39283c3dbafb10b2a732f9d6ef3e08b6 +16777297,3603ae881c41c957a89aaa30990c0040 +16777298,fbf9e47600457d091060b0f877458a83 +16777300,2b0d53bafa91c68bf59b5863354bd7ae +16777301,50b99fabae858e971eb02ed5146fd63a +16777302,7a32eac396b4cf3930ba9ca7b5d8dbae +16777303,115f1e956219026bb9cca0bcafb2b11b +16777304,afb2f032a96d859ca5f24d8ff129bd64 +16777305,372b3a0fd7c09f64f3cfcab89f03a9a0 +16777306,e4b6233ac91337dcc3940e309d21c3c +16777311,d290638555ce76ce3053c70fdacf7d55 +5242880,8099ff561e194072c9086dea38757a89 +5242881,90b3d9a90a8cf3e21527fc8fe3b43c49 +5242882,c9806dd45be8ebed3e4ab94f66e65212 +5242883,f382ded5f9a4299e3879dea4f7fe1c50 +5242884,27af08a994f76a2a08ec8671d14fdcc2 +5242885,9969ce4355ae7338470461f48f4e5ef5 +5242886,39208e0b0f070629cad494da5fb95f0d +5242887,678e63329d3d813f22e0f15006a93768 +5242888,694ffe9efa49193780d4b757115c9064 +5242889,9080a51ccefd23f9924bae9a854e7b49 +5242890,5f1d51ccd1b4adf141707907233f8379 +5242891,73df45f45e0b7484ef51441ad0e50604 +5242892,c9e52234c475354483dc3e9e6386af61 +5242893,3c3ee1df989ecf5de70a5673acfa33b8 +5242894,468cc8b546e1586406b78ad733976f5f +5242895,e546a7afaaa6c6729e3b062fc4ace4ae diff --git a/lwjgl-rundir/resources/armor/chain_1.png b/lwjgl-rundir/resources/armor/chain_1.png new file mode 100644 index 0000000..ae6c708 Binary files /dev/null and b/lwjgl-rundir/resources/armor/chain_1.png differ diff --git a/lwjgl-rundir/resources/armor/chain_2.png b/lwjgl-rundir/resources/armor/chain_2.png new file mode 100644 index 0000000..642a41a Binary files /dev/null and b/lwjgl-rundir/resources/armor/chain_2.png differ diff --git a/lwjgl-rundir/resources/armor/cloth_1.png b/lwjgl-rundir/resources/armor/cloth_1.png new file mode 100644 index 0000000..078c3f7 Binary files /dev/null and b/lwjgl-rundir/resources/armor/cloth_1.png differ diff --git a/lwjgl-rundir/resources/armor/cloth_1_b.png b/lwjgl-rundir/resources/armor/cloth_1_b.png new file mode 100644 index 0000000..442cfa3 Binary files /dev/null and b/lwjgl-rundir/resources/armor/cloth_1_b.png differ diff --git a/lwjgl-rundir/resources/armor/cloth_2.png b/lwjgl-rundir/resources/armor/cloth_2.png new file mode 100644 index 0000000..f276b65 Binary files /dev/null and b/lwjgl-rundir/resources/armor/cloth_2.png differ diff --git a/lwjgl-rundir/resources/armor/cloth_2_b.png b/lwjgl-rundir/resources/armor/cloth_2_b.png new file mode 100644 index 0000000..4150bc1 Binary files /dev/null and b/lwjgl-rundir/resources/armor/cloth_2_b.png differ diff --git a/lwjgl-rundir/resources/armor/diamond_1.png b/lwjgl-rundir/resources/armor/diamond_1.png new file mode 100644 index 0000000..315a7c4 Binary files /dev/null and b/lwjgl-rundir/resources/armor/diamond_1.png differ diff --git a/lwjgl-rundir/resources/armor/diamond_2.png b/lwjgl-rundir/resources/armor/diamond_2.png new file mode 100644 index 0000000..0a9f655 Binary files /dev/null and b/lwjgl-rundir/resources/armor/diamond_2.png differ diff --git a/lwjgl-rundir/resources/armor/gold_1.png b/lwjgl-rundir/resources/armor/gold_1.png new file mode 100644 index 0000000..d9e505d Binary files /dev/null and b/lwjgl-rundir/resources/armor/gold_1.png differ diff --git a/lwjgl-rundir/resources/armor/gold_2.png b/lwjgl-rundir/resources/armor/gold_2.png new file mode 100644 index 0000000..85aea24 Binary files /dev/null and b/lwjgl-rundir/resources/armor/gold_2.png differ diff --git a/lwjgl-rundir/resources/armor/iron_1.png b/lwjgl-rundir/resources/armor/iron_1.png new file mode 100644 index 0000000..fa91769 Binary files /dev/null and b/lwjgl-rundir/resources/armor/iron_1.png differ diff --git a/lwjgl-rundir/resources/armor/iron_2.png b/lwjgl-rundir/resources/armor/iron_2.png new file mode 100644 index 0000000..8b77f13 Binary files /dev/null and b/lwjgl-rundir/resources/armor/iron_2.png differ diff --git a/lwjgl-rundir/resources/armor/power.png b/lwjgl-rundir/resources/armor/power.png new file mode 100644 index 0000000..d1bd38d Binary files /dev/null and b/lwjgl-rundir/resources/armor/power.png differ diff --git a/lwjgl-rundir/resources/armor/witherarmor.png b/lwjgl-rundir/resources/armor/witherarmor.png new file mode 100644 index 0000000..3ed7757 Binary files /dev/null and b/lwjgl-rundir/resources/armor/witherarmor.png differ diff --git a/lwjgl-rundir/resources/art/kz.png b/lwjgl-rundir/resources/art/kz.png new file mode 100644 index 0000000..c273ea1 Binary files /dev/null and b/lwjgl-rundir/resources/art/kz.png differ diff --git a/lwjgl-rundir/resources/credits.txt b/lwjgl-rundir/resources/credits.txt new file mode 100644 index 0000000..28abd0c --- /dev/null +++ b/lwjgl-rundir/resources/credits.txt @@ -0,0 +1,74 @@ +eaglercraft is an AOT compiled port of mojang's minecraft 1.5.2 designed to run in an html5/javascript environment, using TeaVM and my opengl 1.3 emulator to simulate a desktop java enviroment fully compatible with minecraft java edition + +§1this §1mess §1was §1created §1by §1calder §1young §1(LAX1DUDE), §1submit §1complaints §1and §1bug §1reports §1to §1cgiacun@gmail.com §1or §1hmu §1on §1discord §1at §1LAX1DUDE#6306 §1or §1on §1instagram §1@eagler.69§r + +title music: Rockstar Games / Tangerine Dream - GTA V loading theme (Mona Da Vinc) + +compiling the javascript and emulating the JRE is largely made possible by the TeaVM project, created by Alexey Andreev and is available for free at §nhttp://teavm.org/§r under Apache License 2.0 + +eaglercraft makes use of baislsl's java PNG decoder, which is available at §nhttp://github.com/baislsl/PNG§r under MIT License. eaglercraft also makes use of jCraft's jzlib port, available at §nhttp://www.jcraft.com/jzlib/§r under BSD-style licensing. + +all graphical assets in this project were ripped from mojang's official minecraft.jar for minecraft version 1.5.2 and they are mojang's intellectual property. assets ommitted include the minecraft soundtrack and music disks and all software references to the mojang/minecraft api. + +eaglercraft servers are powered by md_5's BungeeCord and the Spigot project available at §nhttp://www.spigotmc.org/§r. BungeeCord has been modified to accept eaglercraft's unorthodox login packets and to include a websocket server to translate browser connections to a format that vanilla Spigot can understand. All plugins designed for Spigot/CraftBukkit 1.5.2 are still compatible with this configuration. + +voice chat is powered by google's WebRTC protocol built into all modern web browsers. more information available at §nhttp://webrtc.org/§r. + +scroll down for the detailed license statements + +======================================== + +Copyright (c) 2020 Calder Young. + +This work is licensed uner a Creative Commons +Attribution-NonCommercial 4.0 International License +§nhttp://creativecommons.org/licenses/by-nc/4.0/§r + +======================================== + +MIT License + +Copyright (c) 2017 baislsl. + +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. + +======================================== + +Copyright 2016 Alexey Andreev. + +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 + +§nhttp://www.apache.org/licenses/LICENSE-2.0§r + +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. + +======================================== + +NVIDIA FXAA 3.11 by TIMOTHY LOTTES + +Copyright (c) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED. + +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +======================================== + +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +======================================== + +|> + diff --git a/lwjgl-rundir/resources/environment/clouds.png b/lwjgl-rundir/resources/environment/clouds.png new file mode 100644 index 0000000..b0dc574 Binary files /dev/null and b/lwjgl-rundir/resources/environment/clouds.png differ diff --git a/lwjgl-rundir/resources/environment/light_normal.png b/lwjgl-rundir/resources/environment/light_normal.png new file mode 100644 index 0000000..21ca94b Binary files /dev/null and b/lwjgl-rundir/resources/environment/light_normal.png differ diff --git a/lwjgl-rundir/resources/environment/moon.png b/lwjgl-rundir/resources/environment/moon.png new file mode 100644 index 0000000..7777b93 Binary files /dev/null and b/lwjgl-rundir/resources/environment/moon.png differ diff --git a/lwjgl-rundir/resources/environment/moon_phases.png b/lwjgl-rundir/resources/environment/moon_phases.png new file mode 100644 index 0000000..5916c65 Binary files /dev/null and b/lwjgl-rundir/resources/environment/moon_phases.png differ diff --git a/lwjgl-rundir/resources/environment/rain.png b/lwjgl-rundir/resources/environment/rain.png new file mode 100644 index 0000000..19cd93d Binary files /dev/null and b/lwjgl-rundir/resources/environment/rain.png differ diff --git a/lwjgl-rundir/resources/environment/snow.png b/lwjgl-rundir/resources/environment/snow.png new file mode 100644 index 0000000..7a32c3c Binary files /dev/null and b/lwjgl-rundir/resources/environment/snow.png differ diff --git a/lwjgl-rundir/resources/environment/sun.png b/lwjgl-rundir/resources/environment/sun.png new file mode 100644 index 0000000..706614d Binary files /dev/null and b/lwjgl-rundir/resources/environment/sun.png differ diff --git a/lwjgl-rundir/resources/font.txt b/lwjgl-rundir/resources/font.txt new file mode 100644 index 0000000..59c1d31 --- /dev/null +++ b/lwjgl-rundir/resources/font.txt @@ -0,0 +1,10 @@ +# This file NEEDS to be in UTF-8 format! + !"#$%&'()*+,-./ +0123456789:;<=>? +@ABCDEFGHIJKLMNO +PQRSTUVWXYZ[\]^_ +'abcdefghijklmno +pqrstuvwxyz{|}~⌂ +ÇüéâäàåçêëèïîìÄÅ +ÉæÆôöòûùÿÖÜø£Ø׃ +áíóúñѪº¿®¬½¼¡«» \ No newline at end of file diff --git a/lwjgl-rundir/resources/font/alternate.png b/lwjgl-rundir/resources/font/alternate.png new file mode 100644 index 0000000..1d32a19 Binary files /dev/null and b/lwjgl-rundir/resources/font/alternate.png differ diff --git a/lwjgl-rundir/resources/font/default.png b/lwjgl-rundir/resources/font/default.png new file mode 100644 index 0000000..0b5144d Binary files /dev/null and b/lwjgl-rundir/resources/font/default.png differ diff --git a/lwjgl-rundir/resources/font/glyph_00.png b/lwjgl-rundir/resources/font/glyph_00.png new file mode 100644 index 0000000..2f39fd4 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_00.png differ diff --git a/lwjgl-rundir/resources/font/glyph_01.png b/lwjgl-rundir/resources/font/glyph_01.png new file mode 100644 index 0000000..ae61f58 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_01.png differ diff --git a/lwjgl-rundir/resources/font/glyph_02.png b/lwjgl-rundir/resources/font/glyph_02.png new file mode 100644 index 0000000..5b82601 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_02.png differ diff --git a/lwjgl-rundir/resources/font/glyph_03.png b/lwjgl-rundir/resources/font/glyph_03.png new file mode 100644 index 0000000..100d3f2 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_03.png differ diff --git a/lwjgl-rundir/resources/font/glyph_04.png b/lwjgl-rundir/resources/font/glyph_04.png new file mode 100644 index 0000000..140817c Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_04.png differ diff --git a/lwjgl-rundir/resources/font/glyph_05.png b/lwjgl-rundir/resources/font/glyph_05.png new file mode 100644 index 0000000..dc036df Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_05.png differ diff --git a/lwjgl-rundir/resources/font/glyph_06.png b/lwjgl-rundir/resources/font/glyph_06.png new file mode 100644 index 0000000..f2a3c3c Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_06.png differ diff --git a/lwjgl-rundir/resources/font/glyph_07.png b/lwjgl-rundir/resources/font/glyph_07.png new file mode 100644 index 0000000..179740f Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_07.png differ diff --git a/lwjgl-rundir/resources/font/glyph_09.png b/lwjgl-rundir/resources/font/glyph_09.png new file mode 100644 index 0000000..124c973 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_09.png differ diff --git a/lwjgl-rundir/resources/font/glyph_0A.png b/lwjgl-rundir/resources/font/glyph_0A.png new file mode 100644 index 0000000..cf8b46a Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_0A.png differ diff --git a/lwjgl-rundir/resources/font/glyph_0B.png b/lwjgl-rundir/resources/font/glyph_0B.png new file mode 100644 index 0000000..a58feca Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_0B.png differ diff --git a/lwjgl-rundir/resources/font/glyph_0C.png b/lwjgl-rundir/resources/font/glyph_0C.png new file mode 100644 index 0000000..36a61dc Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_0C.png differ diff --git a/lwjgl-rundir/resources/font/glyph_0D.png b/lwjgl-rundir/resources/font/glyph_0D.png new file mode 100644 index 0000000..67b4bcb Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_0D.png differ diff --git a/lwjgl-rundir/resources/font/glyph_0E.png b/lwjgl-rundir/resources/font/glyph_0E.png new file mode 100644 index 0000000..b959dc2 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_0E.png differ diff --git a/lwjgl-rundir/resources/font/glyph_0F.png b/lwjgl-rundir/resources/font/glyph_0F.png new file mode 100644 index 0000000..99c1fab Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_0F.png differ diff --git a/lwjgl-rundir/resources/font/glyph_10.png b/lwjgl-rundir/resources/font/glyph_10.png new file mode 100644 index 0000000..a11b731 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_10.png differ diff --git a/lwjgl-rundir/resources/font/glyph_11.png b/lwjgl-rundir/resources/font/glyph_11.png new file mode 100644 index 0000000..f399379 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_11.png differ diff --git a/lwjgl-rundir/resources/font/glyph_12.png b/lwjgl-rundir/resources/font/glyph_12.png new file mode 100644 index 0000000..f239767 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_12.png differ diff --git a/lwjgl-rundir/resources/font/glyph_13.png b/lwjgl-rundir/resources/font/glyph_13.png new file mode 100644 index 0000000..ed5dc4c Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_13.png differ diff --git a/lwjgl-rundir/resources/font/glyph_14.png b/lwjgl-rundir/resources/font/glyph_14.png new file mode 100644 index 0000000..dbc383d Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_14.png differ diff --git a/lwjgl-rundir/resources/font/glyph_15.png b/lwjgl-rundir/resources/font/glyph_15.png new file mode 100644 index 0000000..27d321b Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_15.png differ diff --git a/lwjgl-rundir/resources/font/glyph_16.png b/lwjgl-rundir/resources/font/glyph_16.png new file mode 100644 index 0000000..2821f2b Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_16.png differ diff --git a/lwjgl-rundir/resources/font/glyph_17.png b/lwjgl-rundir/resources/font/glyph_17.png new file mode 100644 index 0000000..f72396d Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_17.png differ diff --git a/lwjgl-rundir/resources/font/glyph_18.png b/lwjgl-rundir/resources/font/glyph_18.png new file mode 100644 index 0000000..0bd1d53 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_18.png differ diff --git a/lwjgl-rundir/resources/font/glyph_19.png b/lwjgl-rundir/resources/font/glyph_19.png new file mode 100644 index 0000000..d4e2ea5 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_19.png differ diff --git a/lwjgl-rundir/resources/font/glyph_1A.png b/lwjgl-rundir/resources/font/glyph_1A.png new file mode 100644 index 0000000..b302b86 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_1A.png differ diff --git a/lwjgl-rundir/resources/font/glyph_1B.png b/lwjgl-rundir/resources/font/glyph_1B.png new file mode 100644 index 0000000..5aa3983 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_1B.png differ diff --git a/lwjgl-rundir/resources/font/glyph_1C.png b/lwjgl-rundir/resources/font/glyph_1C.png new file mode 100644 index 0000000..f0b60ab Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_1C.png differ diff --git a/lwjgl-rundir/resources/font/glyph_1D.png b/lwjgl-rundir/resources/font/glyph_1D.png new file mode 100644 index 0000000..df8cfcc Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_1D.png differ diff --git a/lwjgl-rundir/resources/font/glyph_1E.png b/lwjgl-rundir/resources/font/glyph_1E.png new file mode 100644 index 0000000..b348b8e Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_1E.png differ diff --git a/lwjgl-rundir/resources/font/glyph_1F.png b/lwjgl-rundir/resources/font/glyph_1F.png new file mode 100644 index 0000000..0a05ba5 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_1F.png differ diff --git a/lwjgl-rundir/resources/font/glyph_20.png b/lwjgl-rundir/resources/font/glyph_20.png new file mode 100644 index 0000000..4f374bb Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_20.png differ diff --git a/lwjgl-rundir/resources/font/glyph_21.png b/lwjgl-rundir/resources/font/glyph_21.png new file mode 100644 index 0000000..f52eb0c Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_21.png differ diff --git a/lwjgl-rundir/resources/font/glyph_22.png b/lwjgl-rundir/resources/font/glyph_22.png new file mode 100644 index 0000000..3e69a7a Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_22.png differ diff --git a/lwjgl-rundir/resources/font/glyph_23.png b/lwjgl-rundir/resources/font/glyph_23.png new file mode 100644 index 0000000..7a12c99 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_23.png differ diff --git a/lwjgl-rundir/resources/font/glyph_24.png b/lwjgl-rundir/resources/font/glyph_24.png new file mode 100644 index 0000000..0e3f774 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_24.png differ diff --git a/lwjgl-rundir/resources/font/glyph_25.png b/lwjgl-rundir/resources/font/glyph_25.png new file mode 100644 index 0000000..f3f72a2 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_25.png differ diff --git a/lwjgl-rundir/resources/font/glyph_26.png b/lwjgl-rundir/resources/font/glyph_26.png new file mode 100644 index 0000000..db291dd Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_26.png differ diff --git a/lwjgl-rundir/resources/font/glyph_27.png b/lwjgl-rundir/resources/font/glyph_27.png new file mode 100644 index 0000000..be9e6c9 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_27.png differ diff --git a/lwjgl-rundir/resources/font/glyph_28.png b/lwjgl-rundir/resources/font/glyph_28.png new file mode 100644 index 0000000..97d3c5d Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_28.png differ diff --git a/lwjgl-rundir/resources/font/glyph_29.png b/lwjgl-rundir/resources/font/glyph_29.png new file mode 100644 index 0000000..84bea67 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_29.png differ diff --git a/lwjgl-rundir/resources/font/glyph_2A.png b/lwjgl-rundir/resources/font/glyph_2A.png new file mode 100644 index 0000000..76e66d6 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_2A.png differ diff --git a/lwjgl-rundir/resources/font/glyph_2B.png b/lwjgl-rundir/resources/font/glyph_2B.png new file mode 100644 index 0000000..f97bc28 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_2B.png differ diff --git a/lwjgl-rundir/resources/font/glyph_2C.png b/lwjgl-rundir/resources/font/glyph_2C.png new file mode 100644 index 0000000..4c002d2 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_2C.png differ diff --git a/lwjgl-rundir/resources/font/glyph_2D.png b/lwjgl-rundir/resources/font/glyph_2D.png new file mode 100644 index 0000000..b88b45b Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_2D.png differ diff --git a/lwjgl-rundir/resources/font/glyph_2E.png b/lwjgl-rundir/resources/font/glyph_2E.png new file mode 100644 index 0000000..c9b145b Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_2E.png differ diff --git a/lwjgl-rundir/resources/font/glyph_2F.png b/lwjgl-rundir/resources/font/glyph_2F.png new file mode 100644 index 0000000..aa989c1 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_2F.png differ diff --git a/lwjgl-rundir/resources/font/glyph_30.png b/lwjgl-rundir/resources/font/glyph_30.png new file mode 100644 index 0000000..6590db9 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_30.png differ diff --git a/lwjgl-rundir/resources/font/glyph_31.png b/lwjgl-rundir/resources/font/glyph_31.png new file mode 100644 index 0000000..baf62d8 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_31.png differ diff --git a/lwjgl-rundir/resources/font/glyph_32.png b/lwjgl-rundir/resources/font/glyph_32.png new file mode 100644 index 0000000..b3b2cca Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_32.png differ diff --git a/lwjgl-rundir/resources/font/glyph_33.png b/lwjgl-rundir/resources/font/glyph_33.png new file mode 100644 index 0000000..0da1956 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_33.png differ diff --git a/lwjgl-rundir/resources/font/glyph_34.png b/lwjgl-rundir/resources/font/glyph_34.png new file mode 100644 index 0000000..156689f Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_34.png differ diff --git a/lwjgl-rundir/resources/font/glyph_35.png b/lwjgl-rundir/resources/font/glyph_35.png new file mode 100644 index 0000000..8de7678 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_35.png differ diff --git a/lwjgl-rundir/resources/font/glyph_36.png b/lwjgl-rundir/resources/font/glyph_36.png new file mode 100644 index 0000000..f60a213 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_36.png differ diff --git a/lwjgl-rundir/resources/font/glyph_37.png b/lwjgl-rundir/resources/font/glyph_37.png new file mode 100644 index 0000000..c1e7189 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_37.png differ diff --git a/lwjgl-rundir/resources/font/glyph_38.png b/lwjgl-rundir/resources/font/glyph_38.png new file mode 100644 index 0000000..8f12d40 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_38.png differ diff --git a/lwjgl-rundir/resources/font/glyph_39.png b/lwjgl-rundir/resources/font/glyph_39.png new file mode 100644 index 0000000..6684a8a Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_39.png differ diff --git a/lwjgl-rundir/resources/font/glyph_3A.png b/lwjgl-rundir/resources/font/glyph_3A.png new file mode 100644 index 0000000..c9dcb6f Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_3A.png differ diff --git a/lwjgl-rundir/resources/font/glyph_3B.png b/lwjgl-rundir/resources/font/glyph_3B.png new file mode 100644 index 0000000..0501bb5 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_3B.png differ diff --git a/lwjgl-rundir/resources/font/glyph_3C.png b/lwjgl-rundir/resources/font/glyph_3C.png new file mode 100644 index 0000000..c8e198b Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_3C.png differ diff --git a/lwjgl-rundir/resources/font/glyph_3D.png b/lwjgl-rundir/resources/font/glyph_3D.png new file mode 100644 index 0000000..e9ec05b Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_3D.png differ diff --git a/lwjgl-rundir/resources/font/glyph_3E.png b/lwjgl-rundir/resources/font/glyph_3E.png new file mode 100644 index 0000000..af7b112 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_3E.png differ diff --git a/lwjgl-rundir/resources/font/glyph_3F.png b/lwjgl-rundir/resources/font/glyph_3F.png new file mode 100644 index 0000000..4c637d8 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_3F.png differ diff --git a/lwjgl-rundir/resources/font/glyph_40.png b/lwjgl-rundir/resources/font/glyph_40.png new file mode 100644 index 0000000..4e17621 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_40.png differ diff --git a/lwjgl-rundir/resources/font/glyph_41.png b/lwjgl-rundir/resources/font/glyph_41.png new file mode 100644 index 0000000..63574a7 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_41.png differ diff --git a/lwjgl-rundir/resources/font/glyph_42.png b/lwjgl-rundir/resources/font/glyph_42.png new file mode 100644 index 0000000..efdcbfe Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_42.png differ diff --git a/lwjgl-rundir/resources/font/glyph_43.png b/lwjgl-rundir/resources/font/glyph_43.png new file mode 100644 index 0000000..9d04609 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_43.png differ diff --git a/lwjgl-rundir/resources/font/glyph_44.png b/lwjgl-rundir/resources/font/glyph_44.png new file mode 100644 index 0000000..6583690 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_44.png differ diff --git a/lwjgl-rundir/resources/font/glyph_45.png b/lwjgl-rundir/resources/font/glyph_45.png new file mode 100644 index 0000000..e5a2ac6 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_45.png differ diff --git a/lwjgl-rundir/resources/font/glyph_46.png b/lwjgl-rundir/resources/font/glyph_46.png new file mode 100644 index 0000000..d65bcc7 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_46.png differ diff --git a/lwjgl-rundir/resources/font/glyph_47.png b/lwjgl-rundir/resources/font/glyph_47.png new file mode 100644 index 0000000..c101322 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_47.png differ diff --git a/lwjgl-rundir/resources/font/glyph_48.png b/lwjgl-rundir/resources/font/glyph_48.png new file mode 100644 index 0000000..838181c Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_48.png differ diff --git a/lwjgl-rundir/resources/font/glyph_49.png b/lwjgl-rundir/resources/font/glyph_49.png new file mode 100644 index 0000000..76cb33b Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_49.png differ diff --git a/lwjgl-rundir/resources/font/glyph_4A.png b/lwjgl-rundir/resources/font/glyph_4A.png new file mode 100644 index 0000000..a8cb916 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_4A.png differ diff --git a/lwjgl-rundir/resources/font/glyph_4B.png b/lwjgl-rundir/resources/font/glyph_4B.png new file mode 100644 index 0000000..1628ba4 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_4B.png differ diff --git a/lwjgl-rundir/resources/font/glyph_4C.png b/lwjgl-rundir/resources/font/glyph_4C.png new file mode 100644 index 0000000..0f136c3 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_4C.png differ diff --git a/lwjgl-rundir/resources/font/glyph_4D.png b/lwjgl-rundir/resources/font/glyph_4D.png new file mode 100644 index 0000000..a452f3f Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_4D.png differ diff --git a/lwjgl-rundir/resources/font/glyph_4E.png b/lwjgl-rundir/resources/font/glyph_4E.png new file mode 100644 index 0000000..eaf2d79 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_4E.png differ diff --git a/lwjgl-rundir/resources/font/glyph_4F.png b/lwjgl-rundir/resources/font/glyph_4F.png new file mode 100644 index 0000000..e4e1a0d Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_4F.png differ diff --git a/lwjgl-rundir/resources/font/glyph_50.png b/lwjgl-rundir/resources/font/glyph_50.png new file mode 100644 index 0000000..3282f42 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_50.png differ diff --git a/lwjgl-rundir/resources/font/glyph_51.png b/lwjgl-rundir/resources/font/glyph_51.png new file mode 100644 index 0000000..d89a606 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_51.png differ diff --git a/lwjgl-rundir/resources/font/glyph_52.png b/lwjgl-rundir/resources/font/glyph_52.png new file mode 100644 index 0000000..a1263ff Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_52.png differ diff --git a/lwjgl-rundir/resources/font/glyph_53.png b/lwjgl-rundir/resources/font/glyph_53.png new file mode 100644 index 0000000..565036f Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_53.png differ diff --git a/lwjgl-rundir/resources/font/glyph_54.png b/lwjgl-rundir/resources/font/glyph_54.png new file mode 100644 index 0000000..fa263ae Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_54.png differ diff --git a/lwjgl-rundir/resources/font/glyph_55.png b/lwjgl-rundir/resources/font/glyph_55.png new file mode 100644 index 0000000..7b1c5cf Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_55.png differ diff --git a/lwjgl-rundir/resources/font/glyph_56.png b/lwjgl-rundir/resources/font/glyph_56.png new file mode 100644 index 0000000..96606a4 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_56.png differ diff --git a/lwjgl-rundir/resources/font/glyph_57.png b/lwjgl-rundir/resources/font/glyph_57.png new file mode 100644 index 0000000..401a1bd Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_57.png differ diff --git a/lwjgl-rundir/resources/font/glyph_58.png b/lwjgl-rundir/resources/font/glyph_58.png new file mode 100644 index 0000000..61b7c9b Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_58.png differ diff --git a/lwjgl-rundir/resources/font/glyph_59.png b/lwjgl-rundir/resources/font/glyph_59.png new file mode 100644 index 0000000..2ebd5d4 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_59.png differ diff --git a/lwjgl-rundir/resources/font/glyph_5A.png b/lwjgl-rundir/resources/font/glyph_5A.png new file mode 100644 index 0000000..5a5c053 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_5A.png differ diff --git a/lwjgl-rundir/resources/font/glyph_5B.png b/lwjgl-rundir/resources/font/glyph_5B.png new file mode 100644 index 0000000..d328e35 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_5B.png differ diff --git a/lwjgl-rundir/resources/font/glyph_5C.png b/lwjgl-rundir/resources/font/glyph_5C.png new file mode 100644 index 0000000..e589483 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_5C.png differ diff --git a/lwjgl-rundir/resources/font/glyph_5D.png b/lwjgl-rundir/resources/font/glyph_5D.png new file mode 100644 index 0000000..b864552 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_5D.png differ diff --git a/lwjgl-rundir/resources/font/glyph_5E.png b/lwjgl-rundir/resources/font/glyph_5E.png new file mode 100644 index 0000000..9adbf9d Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_5E.png differ diff --git a/lwjgl-rundir/resources/font/glyph_5F.png b/lwjgl-rundir/resources/font/glyph_5F.png new file mode 100644 index 0000000..dbb299f Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_5F.png differ diff --git a/lwjgl-rundir/resources/font/glyph_60.png b/lwjgl-rundir/resources/font/glyph_60.png new file mode 100644 index 0000000..d7006d3 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_60.png differ diff --git a/lwjgl-rundir/resources/font/glyph_61.png b/lwjgl-rundir/resources/font/glyph_61.png new file mode 100644 index 0000000..48dec58 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_61.png differ diff --git a/lwjgl-rundir/resources/font/glyph_62.png b/lwjgl-rundir/resources/font/glyph_62.png new file mode 100644 index 0000000..5cade89 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_62.png differ diff --git a/lwjgl-rundir/resources/font/glyph_63.png b/lwjgl-rundir/resources/font/glyph_63.png new file mode 100644 index 0000000..4b66cdc Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_63.png differ diff --git a/lwjgl-rundir/resources/font/glyph_64.png b/lwjgl-rundir/resources/font/glyph_64.png new file mode 100644 index 0000000..8208e07 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_64.png differ diff --git a/lwjgl-rundir/resources/font/glyph_65.png b/lwjgl-rundir/resources/font/glyph_65.png new file mode 100644 index 0000000..c7f2b3c Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_65.png differ diff --git a/lwjgl-rundir/resources/font/glyph_66.png b/lwjgl-rundir/resources/font/glyph_66.png new file mode 100644 index 0000000..6fd0e86 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_66.png differ diff --git a/lwjgl-rundir/resources/font/glyph_67.png b/lwjgl-rundir/resources/font/glyph_67.png new file mode 100644 index 0000000..3ba6513 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_67.png differ diff --git a/lwjgl-rundir/resources/font/glyph_68.png b/lwjgl-rundir/resources/font/glyph_68.png new file mode 100644 index 0000000..6b6963a Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_68.png differ diff --git a/lwjgl-rundir/resources/font/glyph_69.png b/lwjgl-rundir/resources/font/glyph_69.png new file mode 100644 index 0000000..d6b455c Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_69.png differ diff --git a/lwjgl-rundir/resources/font/glyph_6A.png b/lwjgl-rundir/resources/font/glyph_6A.png new file mode 100644 index 0000000..48a56e6 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_6A.png differ diff --git a/lwjgl-rundir/resources/font/glyph_6B.png b/lwjgl-rundir/resources/font/glyph_6B.png new file mode 100644 index 0000000..95e1ecd Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_6B.png differ diff --git a/lwjgl-rundir/resources/font/glyph_6C.png b/lwjgl-rundir/resources/font/glyph_6C.png new file mode 100644 index 0000000..e539b26 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_6C.png differ diff --git a/lwjgl-rundir/resources/font/glyph_6D.png b/lwjgl-rundir/resources/font/glyph_6D.png new file mode 100644 index 0000000..784b6d2 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_6D.png differ diff --git a/lwjgl-rundir/resources/font/glyph_6E.png b/lwjgl-rundir/resources/font/glyph_6E.png new file mode 100644 index 0000000..357f7f8 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_6E.png differ diff --git a/lwjgl-rundir/resources/font/glyph_6F.png b/lwjgl-rundir/resources/font/glyph_6F.png new file mode 100644 index 0000000..b20483a Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_6F.png differ diff --git a/lwjgl-rundir/resources/font/glyph_70.png b/lwjgl-rundir/resources/font/glyph_70.png new file mode 100644 index 0000000..46f65b0 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_70.png differ diff --git a/lwjgl-rundir/resources/font/glyph_71.png b/lwjgl-rundir/resources/font/glyph_71.png new file mode 100644 index 0000000..51409d9 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_71.png differ diff --git a/lwjgl-rundir/resources/font/glyph_72.png b/lwjgl-rundir/resources/font/glyph_72.png new file mode 100644 index 0000000..2b962ca Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_72.png differ diff --git a/lwjgl-rundir/resources/font/glyph_73.png b/lwjgl-rundir/resources/font/glyph_73.png new file mode 100644 index 0000000..9b148c1 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_73.png differ diff --git a/lwjgl-rundir/resources/font/glyph_74.png b/lwjgl-rundir/resources/font/glyph_74.png new file mode 100644 index 0000000..40b56a9 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_74.png differ diff --git a/lwjgl-rundir/resources/font/glyph_75.png b/lwjgl-rundir/resources/font/glyph_75.png new file mode 100644 index 0000000..82c3cf6 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_75.png differ diff --git a/lwjgl-rundir/resources/font/glyph_76.png b/lwjgl-rundir/resources/font/glyph_76.png new file mode 100644 index 0000000..42544b2 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_76.png differ diff --git a/lwjgl-rundir/resources/font/glyph_77.png b/lwjgl-rundir/resources/font/glyph_77.png new file mode 100644 index 0000000..ca6010e Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_77.png differ diff --git a/lwjgl-rundir/resources/font/glyph_78.png b/lwjgl-rundir/resources/font/glyph_78.png new file mode 100644 index 0000000..2d8720e Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_78.png differ diff --git a/lwjgl-rundir/resources/font/glyph_79.png b/lwjgl-rundir/resources/font/glyph_79.png new file mode 100644 index 0000000..8b7cdfc Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_79.png differ diff --git a/lwjgl-rundir/resources/font/glyph_7A.png b/lwjgl-rundir/resources/font/glyph_7A.png new file mode 100644 index 0000000..7509bf2 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_7A.png differ diff --git a/lwjgl-rundir/resources/font/glyph_7B.png b/lwjgl-rundir/resources/font/glyph_7B.png new file mode 100644 index 0000000..fadf89a Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_7B.png differ diff --git a/lwjgl-rundir/resources/font/glyph_7C.png b/lwjgl-rundir/resources/font/glyph_7C.png new file mode 100644 index 0000000..f1e5196 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_7C.png differ diff --git a/lwjgl-rundir/resources/font/glyph_7D.png b/lwjgl-rundir/resources/font/glyph_7D.png new file mode 100644 index 0000000..97a46c4 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_7D.png differ diff --git a/lwjgl-rundir/resources/font/glyph_7E.png b/lwjgl-rundir/resources/font/glyph_7E.png new file mode 100644 index 0000000..a641a50 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_7E.png differ diff --git a/lwjgl-rundir/resources/font/glyph_7F.png b/lwjgl-rundir/resources/font/glyph_7F.png new file mode 100644 index 0000000..eb0e7b9 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_7F.png differ diff --git a/lwjgl-rundir/resources/font/glyph_80.png b/lwjgl-rundir/resources/font/glyph_80.png new file mode 100644 index 0000000..a06533f Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_80.png differ diff --git a/lwjgl-rundir/resources/font/glyph_81.png b/lwjgl-rundir/resources/font/glyph_81.png new file mode 100644 index 0000000..354103a Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_81.png differ diff --git a/lwjgl-rundir/resources/font/glyph_82.png b/lwjgl-rundir/resources/font/glyph_82.png new file mode 100644 index 0000000..e66ad43 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_82.png differ diff --git a/lwjgl-rundir/resources/font/glyph_83.png b/lwjgl-rundir/resources/font/glyph_83.png new file mode 100644 index 0000000..8284dd8 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_83.png differ diff --git a/lwjgl-rundir/resources/font/glyph_84.png b/lwjgl-rundir/resources/font/glyph_84.png new file mode 100644 index 0000000..a4ea6d9 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_84.png differ diff --git a/lwjgl-rundir/resources/font/glyph_85.png b/lwjgl-rundir/resources/font/glyph_85.png new file mode 100644 index 0000000..428dc05 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_85.png differ diff --git a/lwjgl-rundir/resources/font/glyph_86.png b/lwjgl-rundir/resources/font/glyph_86.png new file mode 100644 index 0000000..ebb7503 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_86.png differ diff --git a/lwjgl-rundir/resources/font/glyph_87.png b/lwjgl-rundir/resources/font/glyph_87.png new file mode 100644 index 0000000..26bd75d Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_87.png differ diff --git a/lwjgl-rundir/resources/font/glyph_88.png b/lwjgl-rundir/resources/font/glyph_88.png new file mode 100644 index 0000000..76533ba Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_88.png differ diff --git a/lwjgl-rundir/resources/font/glyph_89.png b/lwjgl-rundir/resources/font/glyph_89.png new file mode 100644 index 0000000..5664c55 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_89.png differ diff --git a/lwjgl-rundir/resources/font/glyph_8A.png b/lwjgl-rundir/resources/font/glyph_8A.png new file mode 100644 index 0000000..a0c09c5 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_8A.png differ diff --git a/lwjgl-rundir/resources/font/glyph_8B.png b/lwjgl-rundir/resources/font/glyph_8B.png new file mode 100644 index 0000000..9b7ad06 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_8B.png differ diff --git a/lwjgl-rundir/resources/font/glyph_8C.png b/lwjgl-rundir/resources/font/glyph_8C.png new file mode 100644 index 0000000..a8f5027 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_8C.png differ diff --git a/lwjgl-rundir/resources/font/glyph_8D.png b/lwjgl-rundir/resources/font/glyph_8D.png new file mode 100644 index 0000000..adc93bc Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_8D.png differ diff --git a/lwjgl-rundir/resources/font/glyph_8E.png b/lwjgl-rundir/resources/font/glyph_8E.png new file mode 100644 index 0000000..1bc1d19 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_8E.png differ diff --git a/lwjgl-rundir/resources/font/glyph_8F.png b/lwjgl-rundir/resources/font/glyph_8F.png new file mode 100644 index 0000000..bb2bd59 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_8F.png differ diff --git a/lwjgl-rundir/resources/font/glyph_90.png b/lwjgl-rundir/resources/font/glyph_90.png new file mode 100644 index 0000000..7100032 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_90.png differ diff --git a/lwjgl-rundir/resources/font/glyph_91.png b/lwjgl-rundir/resources/font/glyph_91.png new file mode 100644 index 0000000..e539ff8 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_91.png differ diff --git a/lwjgl-rundir/resources/font/glyph_92.png b/lwjgl-rundir/resources/font/glyph_92.png new file mode 100644 index 0000000..7180f3e Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_92.png differ diff --git a/lwjgl-rundir/resources/font/glyph_93.png b/lwjgl-rundir/resources/font/glyph_93.png new file mode 100644 index 0000000..d71b17b Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_93.png differ diff --git a/lwjgl-rundir/resources/font/glyph_94.png b/lwjgl-rundir/resources/font/glyph_94.png new file mode 100644 index 0000000..e7be74f Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_94.png differ diff --git a/lwjgl-rundir/resources/font/glyph_95.png b/lwjgl-rundir/resources/font/glyph_95.png new file mode 100644 index 0000000..a734a89 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_95.png differ diff --git a/lwjgl-rundir/resources/font/glyph_96.png b/lwjgl-rundir/resources/font/glyph_96.png new file mode 100644 index 0000000..5cdb08c Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_96.png differ diff --git a/lwjgl-rundir/resources/font/glyph_97.png b/lwjgl-rundir/resources/font/glyph_97.png new file mode 100644 index 0000000..f12bd7a Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_97.png differ diff --git a/lwjgl-rundir/resources/font/glyph_98.png b/lwjgl-rundir/resources/font/glyph_98.png new file mode 100644 index 0000000..224bf6f Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_98.png differ diff --git a/lwjgl-rundir/resources/font/glyph_99.png b/lwjgl-rundir/resources/font/glyph_99.png new file mode 100644 index 0000000..8ff4c99 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_99.png differ diff --git a/lwjgl-rundir/resources/font/glyph_9A.png b/lwjgl-rundir/resources/font/glyph_9A.png new file mode 100644 index 0000000..4457af1 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_9A.png differ diff --git a/lwjgl-rundir/resources/font/glyph_9B.png b/lwjgl-rundir/resources/font/glyph_9B.png new file mode 100644 index 0000000..216de5a Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_9B.png differ diff --git a/lwjgl-rundir/resources/font/glyph_9C.png b/lwjgl-rundir/resources/font/glyph_9C.png new file mode 100644 index 0000000..260623b Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_9C.png differ diff --git a/lwjgl-rundir/resources/font/glyph_9D.png b/lwjgl-rundir/resources/font/glyph_9D.png new file mode 100644 index 0000000..f18b044 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_9D.png differ diff --git a/lwjgl-rundir/resources/font/glyph_9E.png b/lwjgl-rundir/resources/font/glyph_9E.png new file mode 100644 index 0000000..a98a8dc Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_9E.png differ diff --git a/lwjgl-rundir/resources/font/glyph_9F.png b/lwjgl-rundir/resources/font/glyph_9F.png new file mode 100644 index 0000000..dc4fa99 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_9F.png differ diff --git a/lwjgl-rundir/resources/font/glyph_A0.png b/lwjgl-rundir/resources/font/glyph_A0.png new file mode 100644 index 0000000..04e3e70 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_A0.png differ diff --git a/lwjgl-rundir/resources/font/glyph_A1.png b/lwjgl-rundir/resources/font/glyph_A1.png new file mode 100644 index 0000000..52b0a4b Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_A1.png differ diff --git a/lwjgl-rundir/resources/font/glyph_A2.png b/lwjgl-rundir/resources/font/glyph_A2.png new file mode 100644 index 0000000..8a96025 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_A2.png differ diff --git a/lwjgl-rundir/resources/font/glyph_A3.png b/lwjgl-rundir/resources/font/glyph_A3.png new file mode 100644 index 0000000..c3fb499 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_A3.png differ diff --git a/lwjgl-rundir/resources/font/glyph_A4.png b/lwjgl-rundir/resources/font/glyph_A4.png new file mode 100644 index 0000000..c57601d Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_A4.png differ diff --git a/lwjgl-rundir/resources/font/glyph_A5.png b/lwjgl-rundir/resources/font/glyph_A5.png new file mode 100644 index 0000000..a0b0e37 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_A5.png differ diff --git a/lwjgl-rundir/resources/font/glyph_A6.png b/lwjgl-rundir/resources/font/glyph_A6.png new file mode 100644 index 0000000..92f821c Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_A6.png differ diff --git a/lwjgl-rundir/resources/font/glyph_A7.png b/lwjgl-rundir/resources/font/glyph_A7.png new file mode 100644 index 0000000..b61f933 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_A7.png differ diff --git a/lwjgl-rundir/resources/font/glyph_A8.png b/lwjgl-rundir/resources/font/glyph_A8.png new file mode 100644 index 0000000..24f1004 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_A8.png differ diff --git a/lwjgl-rundir/resources/font/glyph_A9.png b/lwjgl-rundir/resources/font/glyph_A9.png new file mode 100644 index 0000000..c17194f Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_A9.png differ diff --git a/lwjgl-rundir/resources/font/glyph_AA.png b/lwjgl-rundir/resources/font/glyph_AA.png new file mode 100644 index 0000000..a95dc87 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_AA.png differ diff --git a/lwjgl-rundir/resources/font/glyph_AB.png b/lwjgl-rundir/resources/font/glyph_AB.png new file mode 100644 index 0000000..fa56e85 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_AB.png differ diff --git a/lwjgl-rundir/resources/font/glyph_AC.png b/lwjgl-rundir/resources/font/glyph_AC.png new file mode 100644 index 0000000..6292942 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_AC.png differ diff --git a/lwjgl-rundir/resources/font/glyph_AD.png b/lwjgl-rundir/resources/font/glyph_AD.png new file mode 100644 index 0000000..a4b093d Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_AD.png differ diff --git a/lwjgl-rundir/resources/font/glyph_AE.png b/lwjgl-rundir/resources/font/glyph_AE.png new file mode 100644 index 0000000..4e6aff5 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_AE.png differ diff --git a/lwjgl-rundir/resources/font/glyph_AF.png b/lwjgl-rundir/resources/font/glyph_AF.png new file mode 100644 index 0000000..07a5665 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_AF.png differ diff --git a/lwjgl-rundir/resources/font/glyph_B0.png b/lwjgl-rundir/resources/font/glyph_B0.png new file mode 100644 index 0000000..f4952a0 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_B0.png differ diff --git a/lwjgl-rundir/resources/font/glyph_B1.png b/lwjgl-rundir/resources/font/glyph_B1.png new file mode 100644 index 0000000..4c05c53 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_B1.png differ diff --git a/lwjgl-rundir/resources/font/glyph_B2.png b/lwjgl-rundir/resources/font/glyph_B2.png new file mode 100644 index 0000000..e592c6d Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_B2.png differ diff --git a/lwjgl-rundir/resources/font/glyph_B3.png b/lwjgl-rundir/resources/font/glyph_B3.png new file mode 100644 index 0000000..dd428b3 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_B3.png differ diff --git a/lwjgl-rundir/resources/font/glyph_B4.png b/lwjgl-rundir/resources/font/glyph_B4.png new file mode 100644 index 0000000..c2fb1f1 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_B4.png differ diff --git a/lwjgl-rundir/resources/font/glyph_B5.png b/lwjgl-rundir/resources/font/glyph_B5.png new file mode 100644 index 0000000..3e0808f Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_B5.png differ diff --git a/lwjgl-rundir/resources/font/glyph_B6.png b/lwjgl-rundir/resources/font/glyph_B6.png new file mode 100644 index 0000000..969f19f Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_B6.png differ diff --git a/lwjgl-rundir/resources/font/glyph_B7.png b/lwjgl-rundir/resources/font/glyph_B7.png new file mode 100644 index 0000000..4eec3d7 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_B7.png differ diff --git a/lwjgl-rundir/resources/font/glyph_B8.png b/lwjgl-rundir/resources/font/glyph_B8.png new file mode 100644 index 0000000..247da2a Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_B8.png differ diff --git a/lwjgl-rundir/resources/font/glyph_B9.png b/lwjgl-rundir/resources/font/glyph_B9.png new file mode 100644 index 0000000..30b35ff Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_B9.png differ diff --git a/lwjgl-rundir/resources/font/glyph_BA.png b/lwjgl-rundir/resources/font/glyph_BA.png new file mode 100644 index 0000000..bf557f5 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_BA.png differ diff --git a/lwjgl-rundir/resources/font/glyph_BB.png b/lwjgl-rundir/resources/font/glyph_BB.png new file mode 100644 index 0000000..f712545 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_BB.png differ diff --git a/lwjgl-rundir/resources/font/glyph_BC.png b/lwjgl-rundir/resources/font/glyph_BC.png new file mode 100644 index 0000000..69ba241 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_BC.png differ diff --git a/lwjgl-rundir/resources/font/glyph_BD.png b/lwjgl-rundir/resources/font/glyph_BD.png new file mode 100644 index 0000000..1f8f13f Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_BD.png differ diff --git a/lwjgl-rundir/resources/font/glyph_BE.png b/lwjgl-rundir/resources/font/glyph_BE.png new file mode 100644 index 0000000..332f83c Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_BE.png differ diff --git a/lwjgl-rundir/resources/font/glyph_BF.png b/lwjgl-rundir/resources/font/glyph_BF.png new file mode 100644 index 0000000..a2de5fa Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_BF.png differ diff --git a/lwjgl-rundir/resources/font/glyph_C0.png b/lwjgl-rundir/resources/font/glyph_C0.png new file mode 100644 index 0000000..5b49168 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_C0.png differ diff --git a/lwjgl-rundir/resources/font/glyph_C1.png b/lwjgl-rundir/resources/font/glyph_C1.png new file mode 100644 index 0000000..3ecfe61 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_C1.png differ diff --git a/lwjgl-rundir/resources/font/glyph_C2.png b/lwjgl-rundir/resources/font/glyph_C2.png new file mode 100644 index 0000000..038d1a9 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_C2.png differ diff --git a/lwjgl-rundir/resources/font/glyph_C3.png b/lwjgl-rundir/resources/font/glyph_C3.png new file mode 100644 index 0000000..0149e0e Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_C3.png differ diff --git a/lwjgl-rundir/resources/font/glyph_C4.png b/lwjgl-rundir/resources/font/glyph_C4.png new file mode 100644 index 0000000..2f46eee Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_C4.png differ diff --git a/lwjgl-rundir/resources/font/glyph_C5.png b/lwjgl-rundir/resources/font/glyph_C5.png new file mode 100644 index 0000000..5fd808a Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_C5.png differ diff --git a/lwjgl-rundir/resources/font/glyph_C6.png b/lwjgl-rundir/resources/font/glyph_C6.png new file mode 100644 index 0000000..60c6e41 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_C6.png differ diff --git a/lwjgl-rundir/resources/font/glyph_C7.png b/lwjgl-rundir/resources/font/glyph_C7.png new file mode 100644 index 0000000..8886ecd Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_C7.png differ diff --git a/lwjgl-rundir/resources/font/glyph_C8.png b/lwjgl-rundir/resources/font/glyph_C8.png new file mode 100644 index 0000000..2e8fb53 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_C8.png differ diff --git a/lwjgl-rundir/resources/font/glyph_C9.png b/lwjgl-rundir/resources/font/glyph_C9.png new file mode 100644 index 0000000..6b9e3ab Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_C9.png differ diff --git a/lwjgl-rundir/resources/font/glyph_CA.png b/lwjgl-rundir/resources/font/glyph_CA.png new file mode 100644 index 0000000..8ab04e9 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_CA.png differ diff --git a/lwjgl-rundir/resources/font/glyph_CB.png b/lwjgl-rundir/resources/font/glyph_CB.png new file mode 100644 index 0000000..4c8feed Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_CB.png differ diff --git a/lwjgl-rundir/resources/font/glyph_CC.png b/lwjgl-rundir/resources/font/glyph_CC.png new file mode 100644 index 0000000..d4ec20b Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_CC.png differ diff --git a/lwjgl-rundir/resources/font/glyph_CD.png b/lwjgl-rundir/resources/font/glyph_CD.png new file mode 100644 index 0000000..09012b5 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_CD.png differ diff --git a/lwjgl-rundir/resources/font/glyph_CE.png b/lwjgl-rundir/resources/font/glyph_CE.png new file mode 100644 index 0000000..24c1be4 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_CE.png differ diff --git a/lwjgl-rundir/resources/font/glyph_CF.png b/lwjgl-rundir/resources/font/glyph_CF.png new file mode 100644 index 0000000..c433dab Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_CF.png differ diff --git a/lwjgl-rundir/resources/font/glyph_D0.png b/lwjgl-rundir/resources/font/glyph_D0.png new file mode 100644 index 0000000..cef12e4 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_D0.png differ diff --git a/lwjgl-rundir/resources/font/glyph_D1.png b/lwjgl-rundir/resources/font/glyph_D1.png new file mode 100644 index 0000000..2d51e09 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_D1.png differ diff --git a/lwjgl-rundir/resources/font/glyph_D2.png b/lwjgl-rundir/resources/font/glyph_D2.png new file mode 100644 index 0000000..13c2a68 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_D2.png differ diff --git a/lwjgl-rundir/resources/font/glyph_D3.png b/lwjgl-rundir/resources/font/glyph_D3.png new file mode 100644 index 0000000..9f79365 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_D3.png differ diff --git a/lwjgl-rundir/resources/font/glyph_D4.png b/lwjgl-rundir/resources/font/glyph_D4.png new file mode 100644 index 0000000..2d16fa1 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_D4.png differ diff --git a/lwjgl-rundir/resources/font/glyph_D5.png b/lwjgl-rundir/resources/font/glyph_D5.png new file mode 100644 index 0000000..978d6c7 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_D5.png differ diff --git a/lwjgl-rundir/resources/font/glyph_D6.png b/lwjgl-rundir/resources/font/glyph_D6.png new file mode 100644 index 0000000..6143f53 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_D6.png differ diff --git a/lwjgl-rundir/resources/font/glyph_D7.png b/lwjgl-rundir/resources/font/glyph_D7.png new file mode 100644 index 0000000..71a0fdb Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_D7.png differ diff --git a/lwjgl-rundir/resources/font/glyph_F9.png b/lwjgl-rundir/resources/font/glyph_F9.png new file mode 100644 index 0000000..e9292ef Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_F9.png differ diff --git a/lwjgl-rundir/resources/font/glyph_FA.png b/lwjgl-rundir/resources/font/glyph_FA.png new file mode 100644 index 0000000..fec6651 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_FA.png differ diff --git a/lwjgl-rundir/resources/font/glyph_FB.png b/lwjgl-rundir/resources/font/glyph_FB.png new file mode 100644 index 0000000..27775ec Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_FB.png differ diff --git a/lwjgl-rundir/resources/font/glyph_FC.png b/lwjgl-rundir/resources/font/glyph_FC.png new file mode 100644 index 0000000..e588d33 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_FC.png differ diff --git a/lwjgl-rundir/resources/font/glyph_FD.png b/lwjgl-rundir/resources/font/glyph_FD.png new file mode 100644 index 0000000..92ee667 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_FD.png differ diff --git a/lwjgl-rundir/resources/font/glyph_FE.png b/lwjgl-rundir/resources/font/glyph_FE.png new file mode 100644 index 0000000..24d3587 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_FE.png differ diff --git a/lwjgl-rundir/resources/font/glyph_FF.png b/lwjgl-rundir/resources/font/glyph_FF.png new file mode 100644 index 0000000..ebbe426 Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_FF.png differ diff --git a/lwjgl-rundir/resources/font/glyph_sizes.bin b/lwjgl-rundir/resources/font/glyph_sizes.bin new file mode 100644 index 0000000..69c857e Binary files /dev/null and b/lwjgl-rundir/resources/font/glyph_sizes.bin differ diff --git a/lwjgl-rundir/resources/glsl/bloom.glsl b/lwjgl-rundir/resources/glsl/bloom.glsl new file mode 100644 index 0000000..3e7d8d7 --- /dev/null +++ b/lwjgl-rundir/resources/glsl/bloom.glsl @@ -0,0 +1,15 @@ +#line 0 +precision lowp float; + +varying lowp vec2 pos; + +uniform sampler2D f_color; +uniform sampler2D f_depth; +uniform sampler2D f_bloom; + +uniform ivec2 screenSize; + +void main(){ + vec3 cc = texture2D(f_color, pos).rgb; + gl_FragColor = vec4(max(cc, cc * vec3(0.5) + texture2D(f_bloom, pos).rgb), 1.0); +} diff --git a/lwjgl-rundir/resources/glsl/bloom_a.glsl b/lwjgl-rundir/resources/glsl/bloom_a.glsl new file mode 100644 index 0000000..064b9c3 --- /dev/null +++ b/lwjgl-rundir/resources/glsl/bloom_a.glsl @@ -0,0 +1,18 @@ +#line 0 +precision lowp float; + +varying lowp vec2 pos; + +uniform sampler2D f_color; +uniform sampler2D f_depth; + +uniform ivec2 screenSize; + +vec3 ramp(vec3 v){ + return (v * vec3(0.5)) * (1.0 + pow(v.r*2.5+v.g-(v.b*v.g*3.0), 3.0)*0.06); +} + +void main(){ + vec2 offset = 1.0 / screenSize; + gl_FragColor = vec4((ramp(texture2D(f_color, pos).rgb) + ramp(texture2D(f_color, pos + vec2(offset.x, 0.0)).rgb) + ramp(texture2D(f_color, pos + vec2(0.0, offset.y)).rgb) + ramp(texture2D(f_color, pos + offset).rgb)) * 0.2, 1.0); +} diff --git a/lwjgl-rundir/resources/glsl/bloom_b.glsl b/lwjgl-rundir/resources/glsl/bloom_b.glsl new file mode 100644 index 0000000..30cc4b5 --- /dev/null +++ b/lwjgl-rundir/resources/glsl/bloom_b.glsl @@ -0,0 +1,37 @@ +#line 0 +precision lowp float; + +varying lowp vec2 pos; + +uniform sampler2D f_color; +uniform sampler2D f_depth; + +uniform ivec2 direction; +uniform ivec2 screenSize; + +void main(){ + vec3 color = vec3(0.0); + vec2 pix = direction * vec2(1.0 / screenSize); + color += texture2D(f_color, pos - pix * 10.0).rgb * 0.011090; + color += texture2D(f_color, pos - pix * 9.0).rgb * 0.016196; + color += texture2D(f_color, pos - pix * 8.0).rgb * 0.022729; + color += texture2D(f_color, pos - pix * 7.0).rgb * 0.030651; + color += texture2D(f_color, pos - pix * 6.0).rgb * 0.039717; + color += texture2D(f_color, pos - pix * 5.0).rgb * 0.049455; + color += texture2D(f_color, pos - pix * 4.0).rgb * 0.059173; + color += texture2D(f_color, pos - pix * 3.0).rgb * 0.068033; + color += texture2D(f_color, pos - pix * 2.0).rgb * 0.075163; + color += texture2D(f_color, pos - pix * 1.0).rgb * 0.079795; + color += texture2D(f_color, pos).rgb * 0.081402; + color += texture2D(f_color, pos + pix * 1.0).rgb * 0.079795; + color += texture2D(f_color, pos + pix * 2.0).rgb * 0.075163; + color += texture2D(f_color, pos + pix * 3.0).rgb * 0.068033; + color += texture2D(f_color, pos + pix * 4.0).rgb * 0.059173; + color += texture2D(f_color, pos + pix * 5.0).rgb * 0.049455; + color += texture2D(f_color, pos + pix * 6.0).rgb * 0.039717; + color += texture2D(f_color, pos + pix * 7.0).rgb * 0.030651; + color += texture2D(f_color, pos + pix * 8.0).rgb * 0.022729; + color += texture2D(f_color, pos + pix * 9.0).rgb * 0.016196; + color += texture2D(f_color, pos + pix * 10.0).rgb * 0.011090; + gl_FragColor = vec4(color, 1.0); +} diff --git a/lwjgl-rundir/resources/glsl/core.glsl b/lwjgl-rundir/resources/glsl/core.glsl new file mode 100644 index 0000000..18002c5 --- /dev/null +++ b/lwjgl-rundir/resources/glsl/core.glsl @@ -0,0 +1,228 @@ + +// eaglercraft opengl 1.3 emulation +// copyright (c) 2020 calder young +// creative commons BY-NC 4.0 + +#line 7 + +precision highp int; +precision highp sampler2D; +precision highp float; + +uniform mat4 matrix_m; +uniform mat4 matrix_p; +uniform mat3 matrix_mn; +uniform mat4 matrix_t; + +#ifdef CC_VERT + +in vec3 a_position; +#ifdef CC_a_texture0 +in vec2 a_texture0; +#endif +#ifdef CC_a_color +in vec4 a_color; +#endif +#ifdef CC_a_normal +in vec4 a_normal; +#endif +#ifdef CC_a_texture1 +in vec2 a_texture1; +#endif + +#ifdef CC_TEX_GEN_STRQ +out vec4 v_object_pos; +#endif +out vec4 v_position; +#ifdef CC_a_color +out vec4 v_color; +#endif +#ifdef CC_a_normal +out vec4 v_normal; +#endif +#ifdef CC_a_texture0 +out vec2 v_texture0; +#endif +#ifdef CC_a_texture1 +out vec2 v_texture1; +#endif + +#endif + + +#ifdef CC_VERT + +void main(){ + vec4 pos = matrix_m * vec4(a_position, 1.0); + v_position = pos; +#ifdef CC_TEX_GEN_STRQ + v_object_pos = vec4(a_position, 1.0); +#endif +#ifdef CC_a_color + v_color = a_color; +#endif +#ifdef CC_a_normal + v_normal = a_normal; +#endif +#ifdef CC_a_texture0 + v_texture0 = a_texture0; +#endif +#ifdef CC_a_texture1 + v_texture1 = a_texture1; +#endif + gl_Position = matrix_p * pos; +} + +#endif + +#ifdef CC_FRAG + +uniform sampler2D tex0; +uniform sampler2D tex1; +uniform vec2 texCoordV0; +uniform vec2 texCoordV1; +#ifdef CC_lighting +uniform vec3 light0Pos; +uniform vec3 light1Pos; +#endif +#ifdef CC_fog +uniform vec4 fogColor; +uniform int fogMode; +uniform float fogStart; +uniform float fogEnd; +uniform float fogDensity; +uniform float fogPremultiply; +#endif +uniform vec4 colorUniform; +uniform vec3 normalUniform; +#ifdef CC_alphatest +uniform float alphaTestF; +#endif +#ifdef CC_TEX_GEN_STRQ +uniform int textureGenS_M; +uniform int textureGenT_M; +uniform int textureGenR_M; +uniform int textureGenQ_M; +uniform vec4 textureGenS_V; +uniform vec4 textureGenT_V; +uniform vec4 textureGenR_V; +uniform vec4 textureGenQ_V; +uniform mat4 matrix_inverse_m; +#endif + +#ifdef CC_TEX_GEN_STRQ +in vec4 v_object_pos; +#endif +in vec4 v_position; +#ifdef CC_a_color +in vec4 v_color; +#endif +#ifdef CC_a_normal +in vec4 v_normal; +#endif +#ifdef CC_a_texture0 +in vec2 v_texture0; +#endif +#ifdef CC_a_texture1 +in vec2 v_texture1; +#endif + +out vec4 fragColor; + +void main(){ +#ifdef CC_a_color + vec4 color = colorUniform * v_color; +#else + vec4 color = colorUniform; +#endif + +#ifdef CC_TEX_GEN_STRQ + vec4 texPos; + if(textureGenS_M == 1){ + texPos.x = dot(v_position, textureGenS_V * matrix_inverse_m); + }else{ + texPos.x = dot(v_object_pos, textureGenS_V); + } + if(textureGenT_M == 1){ + texPos.y = dot(v_position, textureGenT_V * matrix_inverse_m); + }else{ + texPos.y = dot(v_object_pos, textureGenT_V); + } + if(textureGenR_M == 1){ + texPos.z = dot(v_position, textureGenR_V * matrix_inverse_m); + }else{ + texPos.z = dot(v_object_pos, textureGenR_V); + } + if(textureGenQ_M == 1){ + texPos.w = dot(v_position, textureGenQ_V * matrix_inverse_m); + }else{ + texPos.w = dot(v_object_pos, textureGenQ_V); + } + texPos = matrix_t * texPos; + texPos.x /= texPos.w; + texPos.y /= texPos.w; + texPos.z /= texPos.w; + texPos.w = 1.0; + color *= texture(tex0, texPos.xy).bgra; +#ifdef CC_alphatest + if(color.a < alphaTestF){ + discard; + } +#endif +#else +#ifdef CC_unit0 +#ifdef CC_a_texture0 + +#if (defined(CC_patch_anisotropic) && defined(CC_a_texture1) && defined(CC_a_color)) + vec2 uv = (matrix_t * vec4(v_texture0, 0.0, 1.0)).xy ; + + /* https://bugs.chromium.org/p/angleproject/issues/detail?id=4994 */ + float x = 1024.0 * 63.0 / 64.0; + uv = ((uv * x) - fract(uv * x) + 0.5) / x; + + color *= texture(tex0, uv).bgra; +#else + color *= texture(tex0, (matrix_t * vec4(v_texture0, 0.0, 1.0)).xy).bgra; +#endif + +#else + color *= texture(tex0, (matrix_t * vec4(texCoordV0, 0.0, 1.0)).xy).bgra; +#endif +#endif + +#ifdef CC_alphatest + if(color.a < alphaTestF){ + discard; + } +#endif + +#ifdef CC_unit1 +#ifdef CC_a_texture1 + color.rgb *= texture(tex1, (v_texture1 + 8.0) * 0.00390625).bgr; +#else + color.rgb *= texture(tex1, (texCoordV1 + 8.0) * 0.00390625).bgr; +#endif +#endif +#endif + +#ifdef CC_lighting +#ifdef CC_a_normal + vec3 normal = normalize(matrix_mn * ((v_normal.xyz - 0.5) * 2.0)); +#else + vec3 normal = normalize(matrix_mn * normalUniform); +#endif + float ins = abs(dot(normal, light0Pos) + dot(normal, light1Pos)); + color.rgb *= sqrt(0.4 + ins * 0.6); +#endif + +#ifdef CC_fog + float dist = sqrt(v_position.x * v_position.x + v_position.y * v_position.y + v_position.z * v_position.z); + float i = (fogMode == 1) ? clamp((dist - fogStart) / (fogEnd - fogStart), 0.0, 1.0) : clamp(1.0 - pow(2.718, -(fogDensity * dist)), 0.0, 1.0); + color.rgb = mix(color.rgb, fogColor.xyz, i * fogColor.a); +#endif + + fragColor = color; +} + +#endif + diff --git a/lwjgl-rundir/resources/glsl/fxaa.glsl b/lwjgl-rundir/resources/glsl/fxaa.glsl new file mode 100644 index 0000000..19e2811 --- /dev/null +++ b/lwjgl-rundir/resources/glsl/fxaa.glsl @@ -0,0 +1,255 @@ +#line 0 + +precision lowp int; +precision lowp sampler2D; +precision lowp float; + +in vec2 pos; + +out vec4 fragColor; + +#define FXAA_PC 1 +#define FXAA_GLSL_130 1 +#define FXAA_FAST_PIXEL_OFFSET 0 +#define FXAA_GATHER4_ALPHA 0 + +#ifndef FXAA_GREEN_AS_LUMA + // For those using non-linear color, + // and either not able to get luma in alpha, or not wanting to, + // this enables FXAA to run using green as a proxy for luma. + // So with this enabled, no need to pack luma in alpha. + // + // This will turn off AA on anything which lacks some amount of green. + // Pure red and blue or combination of only R and B, will get no AA. + // + // Might want to lower the settings for both, + // fxaaConsoleEdgeThresholdMin + // fxaaQualityEdgeThresholdMin + // In order to insure AA does not get turned off on colors + // which contain a minor amount of green. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_GREEN_AS_LUMA 1 +#endif + +#ifndef FXAA_DISCARD + // 1 = Use discard on pixels which don't need AA. + // 0 = Return unchanged color on pixels which don't need AA. + #define FXAA_DISCARD 0 +#endif + +/*============================================================================ + API PORTING +============================================================================*/ + #define FxaaBool bool + #define FxaaDiscard discard + #define FxaaFloat float + #define FxaaFloat2 vec2 + #define FxaaFloat3 vec3 + #define FxaaFloat4 vec4 + #define FxaaHalf float + #define FxaaHalf2 vec2 + #define FxaaHalf3 vec3 + #define FxaaHalf4 vec4 + #define FxaaInt2 ivec2 + #define FxaaSat(x) clamp(x, 0.0, 1.0) + #define FxaaTex sampler2D +/*--------------------------------------------------------------------------*/ + + #define FxaaTexTop(t, p) texture(t, p) + +/*============================================================================ + GREEN AS LUMA OPTION SUPPORT FUNCTION +============================================================================*/ +#if (FXAA_GREEN_AS_LUMA == 0) + // TODO Luma + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return dot(rgba.xyz, vec3(0.299, 0.587, 0.114)); } +#else + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; } +#endif + +/*============================================================================ + FXAA3 CONSOLE - PC VERSION +============================================================================*/ +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + // + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy} = center of pixel + FxaaFloat2 pos, + // + // Used only for FXAA Console, and not used on the 360 version. + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + // + // Input color texture. + // {rgb_} = color in linear or perceptual color space + // if (FXAA_GREEN_AS_LUMA == 0) + // {___a} = luma in perceptual color space (not linear) + FxaaTex tex, + // + // Only used on FXAA Console. + // This must be from a constant/uniform. + // This effects sub-pixel AA quality and inversely sharpness. + // Where N ranges between, + // N = 0.50 (default) + // N = 0.33 (sharper) + // {x___} = -N/screenWidthInPixels + // {_y__} = -N/screenHeightInPixels + // {__z_} = N/screenWidthInPixels + // {___w} = N/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt, + // + // Only used on FXAA Console. + // Not used on 360, but used on PS3 and PC. + // This must be from a constant/uniform. + // {x___} = -2.0/screenWidthInPixels + // {_y__} = -2.0/screenHeightInPixels + // {__z_} = 2.0/screenWidthInPixels + // {___w} = 2.0/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. + // Due to the PS3 being ALU bound, + // there are only three safe values here: 2 and 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // For all other platforms can be a non-power of two. + // 8.0 is sharper (default!!!) + // 4.0 is softer + // 2.0 is really soft (good only for vector graphics inputs) + FxaaFloat fxaaConsoleEdgeSharpness, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3. + // Due to the PS3 being ALU bound, + // there are only two safe values here: 1/4 and 1/8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // The console setting has a different mapping than the quality setting. + // Other platforms can use other values. + // 0.125 leaves less aliasing, but is softer (default!!!) + // 0.25 leaves more aliasing, and is sharper + FxaaFloat fxaaConsoleEdgeThreshold, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // The console setting has a different mapping than the quality setting. + // This does not apply to PS3, + // PS3 was simplified to avoid more shader instructions. + // 0.06 - faster but more aliasing in darks + // 0.05 - default + // 0.04 - slower and less aliasing in darks + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaConsoleEdgeThresholdMin +) { +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy)); + FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw)); + FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy)); + FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw)); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy); + #if (FXAA_GREEN_AS_LUMA == 0) + // TODO Luma + FxaaFloat lumaM = FxaaLuma(rgbyM); + #else + FxaaFloat lumaM = rgbyM.y; + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw); + lumaNe += 1.0/384.0; + FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe); + FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw); + FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMinM = min(lumaMin, lumaM); + FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled); + FxaaFloat lumaMaxM = max(lumaMax, lumaM); + FxaaFloat dirSwMinusNe = lumaSw - lumaNe; + FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM; + FxaaFloat dirSeMinusNw = lumaSe - lumaNw; + if(lumaMaxSubMinM < lumaMaxScaledClamped) + { + #if (FXAA_DISCARD == 1) + FxaaDiscard; + #else + return rgbyM; + #endif + } +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir; + dir.x = dirSwMinusNe + dirSeMinusNw; + dir.y = dirSwMinusNe - dirSeMinusNw; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir1 = normalize(dir.xy); + FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw); + FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw); +/*--------------------------------------------------------------------------*/ + FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness; + FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0); +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir2x = dir2 * fxaaConsoleRcpFrameOpt2.zw; + FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2x); + FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2x); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyA = rgbyN1 + rgbyP1; + FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25); +/*--------------------------------------------------------------------------*/ + #if (FXAA_GREEN_AS_LUMA == 0) + // TODO Luma + float lumaB = FxaaLuma(rgbyB); + #else + float lumaB = rgbyB.y; + #endif + if((lumaB < lumaMin) || (lumaB > lumaMax)) + rgbyB.xyz = rgbyA.xyz * 0.5; + // + return rgbyB; +} +/*==========================================================================*/ + +uniform sampler2D f_color; + +uniform vec2 screenSize; + +#define edgeSharpness 7.0 +#define edgeThreshold 0.1 +#define edgeThresholdMin 0.005 + +void main(){ + vec4 posPos; + posPos.xy = pos - (0.6 / screenSize); + posPos.zw = pos + (0.6 / screenSize); + vec4 rcpFrameOpt; + rcpFrameOpt.xy = vec2(-0.50, -0.50) / screenSize; + rcpFrameOpt.zw = vec2( 0.50, 0.50) / screenSize; + vec4 rcpFrameOpt2; + rcpFrameOpt2.xy = vec2(-2.0, -2.0) / screenSize; + rcpFrameOpt2.zw = vec2( 2.0, 2.0) / screenSize; + + fragColor = vec4(FxaaPixelShader(pos, posPos, f_color, rcpFrameOpt, rcpFrameOpt2, edgeSharpness, edgeThreshold, edgeThresholdMin).rgb, 1.0); +} diff --git a/lwjgl-rundir/resources/glsl/lens.glsl b/lwjgl-rundir/resources/glsl/lens.glsl new file mode 100644 index 0000000..2be5ff1 --- /dev/null +++ b/lwjgl-rundir/resources/glsl/lens.glsl @@ -0,0 +1,40 @@ +#line 0 +precision lowp float; + +varying lowp vec2 pos; + +uniform sampler2D f_color; +uniform sampler2D f_depth; + +uniform vec2 screenSize; +uniform vec2 randomInter; +uniform float randomInterF; + +vec2 barrelDistortion(vec2 coord, float amt){ + vec2 cc = coord - 0.5; + float dist = dot(cc, cc); + return coord + cc * dist * amt; +} + +#define amount 0.1 +#define abberation 0.015 + +float noise(vec2 seed){ + float r = sin(dot(seed, vec2(12.10482130, 4.32894663)) * 763.345734); + float r1 = fract(r * (1.0 + randomInter.x*34735.49057645)); + float r2 = fract(r * (1.0 + randomInter.y*74764.63566345)); + return (r1*r1*r1)*(randomInterF) + (r2*r2*r2)*(1.0 - randomInterF); +} + +void main(){ + vec2 yeer = screenSize * 0.3; + vec2 pos2 = pos * 0.93 + 0.035; + vec3 color = vec3(0.0); + color += vec3(0.8, 0.0, 0.0) * texture2D(f_color, barrelDistortion(pos2, (amount + abberation + abberation))).rgb; + color += vec3(0.0, 1.0, 0.1) * texture2D(f_color, barrelDistortion(pos2, (amount + abberation))).rgb; + color += vec3(0.2, 0.0, 0.9) * texture2D(f_color, barrelDistortion(pos2, (amount))).rgb; + color *= 0.8; + color += 0.2 * texture2D(f_color, barrelDistortion(pos2, (amount * 1.5))).rgb; + float r = noise(floor(pos * yeer) / yeer); + gl_FragColor = vec4(color.rgb + ((0.08 + color.rgb) * (r * 0.07 / (0.06+color.r+color.g*4.0+color.b))), 1.0); +} diff --git a/lwjgl-rundir/resources/glsl/occl.glsl b/lwjgl-rundir/resources/glsl/occl.glsl new file mode 100644 index 0000000..5f6df32 --- /dev/null +++ b/lwjgl-rundir/resources/glsl/occl.glsl @@ -0,0 +1,25 @@ +#line 2 + +precision highp int; +precision highp sampler2D; +precision highp float; + +#ifdef CC_VERT +uniform mat4 matrix_m; +uniform mat4 matrix_p; + +in vec3 a_vert; + +void main(){ + gl_Position = (matrix_p * (matrix_m * vec4(a_vert, 1.0))); +} +#endif + +#ifdef CC_FRAG + +out vec4 fragColor; + +void main(){ + fragColor = vec4(1.0); +} +#endif diff --git a/lwjgl-rundir/resources/glsl/pvert.glsl b/lwjgl-rundir/resources/glsl/pvert.glsl new file mode 100644 index 0000000..350ff6d --- /dev/null +++ b/lwjgl-rundir/resources/glsl/pvert.glsl @@ -0,0 +1,13 @@ +#line 0 + +precision lowp int; +precision lowp sampler2D; +precision lowp float; + +in vec2 a_pos; + +out vec2 pos; + +void main(){ + gl_Position = vec4((pos = a_pos) * 2.0 - 1.0, 0.0, 1.0); +} diff --git a/lwjgl-rundir/resources/glsl/ssao.glsl b/lwjgl-rundir/resources/glsl/ssao.glsl new file mode 100644 index 0000000..6b8aeb9 --- /dev/null +++ b/lwjgl-rundir/resources/glsl/ssao.glsl @@ -0,0 +1,13 @@ +#line 0 +precision lowp float; + +varying lowp vec2 pos; + +uniform sampler2D f_color; +uniform sampler2D f_depth; +uniform sampler2D f_ssao; +uniform ivec2 screenSize; +void main(){ + vec2 a_pixel = (1.0 / screenSize) * 3.0; + gl_FragColor = vec4((texture2D(f_ssao, pos).r) * texture2D(f_color, pos).rgb, 1.0); +} diff --git a/lwjgl-rundir/resources/glsl/ssao_a.glsl b/lwjgl-rundir/resources/glsl/ssao_a.glsl new file mode 100644 index 0000000..703aa42 --- /dev/null +++ b/lwjgl-rundir/resources/glsl/ssao_a.glsl @@ -0,0 +1,37 @@ +#line 0 +precision highp float; + +varying lowp vec2 pos; + +uniform sampler2D f_color; +uniform sampler2D f_depth; + +uniform mat4 matrix_p; +uniform mat4 matrix_p_inv; + +uniform vec3 ssao_kernel[24]; + +float LinearizeDepth(float zoverw){ + return (2.0 * 0.001) / (4000.0 + 0.001 - zoverw * (4000.0 - 0.001)); +} + +void main(){ + float r1 = sin(dot(pos,vec2(4.245693,3.24942))); + + vec4 posW = matrix_p_inv * vec4(pos * 2.0 - 1.0, texture2D(f_depth, pos).r, 1.0); + posW.xyz /= posW.w; + + //int samples = int(clamp(32.0 - posW.z * -0.5, 8.0, 24.0)); + + float f = 0.0; + for(int i = 0; i < 24; ++i){ + vec4 trans = matrix_p * vec4(posW.xyz + (ssao_kernel[i] * 2.0) * (0.5 + vec3((fract(r1 * (2434.64775 * i)) - 0.5), (fract(r1 * (4365.76945 * i)) - 0.5), (fract(r1 * (2354.95634 * i)) - 0.5)) * 0.5), 1.0); + trans.xyz /= trans.w; + float A = LinearizeDepth(trans.z); + float B = LinearizeDepth(texture2D(f_depth, trans.xy * 0.5 + 0.5).r); + + f += ((A < B && B - A < 0.02) ? 0.0 : (2.2 / 24.0)); + } + + gl_FragColor = vec4(clamp(f, 0.0, 1.0), 0.0, 0.0, 1.0); +} diff --git a/lwjgl-rundir/resources/gui/alchemy.png b/lwjgl-rundir/resources/gui/alchemy.png new file mode 100644 index 0000000..ec9f914 Binary files /dev/null and b/lwjgl-rundir/resources/gui/alchemy.png differ diff --git a/lwjgl-rundir/resources/gui/allitems.png b/lwjgl-rundir/resources/gui/allitems.png new file mode 100644 index 0000000..69fa242 Binary files /dev/null and b/lwjgl-rundir/resources/gui/allitems.png differ diff --git a/lwjgl-rundir/resources/gui/background.png b/lwjgl-rundir/resources/gui/background.png new file mode 100644 index 0000000..929d3db Binary files /dev/null and b/lwjgl-rundir/resources/gui/background.png differ diff --git a/lwjgl-rundir/resources/gui/beacon.png b/lwjgl-rundir/resources/gui/beacon.png new file mode 100644 index 0000000..2ed24e6 Binary files /dev/null and b/lwjgl-rundir/resources/gui/beacon.png differ diff --git a/lwjgl-rundir/resources/gui/book.png b/lwjgl-rundir/resources/gui/book.png new file mode 100644 index 0000000..3bcd49d Binary files /dev/null and b/lwjgl-rundir/resources/gui/book.png differ diff --git a/lwjgl-rundir/resources/gui/container.png b/lwjgl-rundir/resources/gui/container.png new file mode 100644 index 0000000..46dcc7e Binary files /dev/null and b/lwjgl-rundir/resources/gui/container.png differ diff --git a/lwjgl-rundir/resources/gui/crafting.png b/lwjgl-rundir/resources/gui/crafting.png new file mode 100644 index 0000000..fbaf272 Binary files /dev/null and b/lwjgl-rundir/resources/gui/crafting.png differ diff --git a/lwjgl-rundir/resources/gui/crash_logo.png b/lwjgl-rundir/resources/gui/crash_logo.png new file mode 100644 index 0000000..bd86c9e Binary files /dev/null and b/lwjgl-rundir/resources/gui/crash_logo.png differ diff --git a/lwjgl-rundir/resources/gui/creative_inv/list_items.png b/lwjgl-rundir/resources/gui/creative_inv/list_items.png new file mode 100644 index 0000000..a36d541 Binary files /dev/null and b/lwjgl-rundir/resources/gui/creative_inv/list_items.png differ diff --git a/lwjgl-rundir/resources/gui/creative_inv/search.png b/lwjgl-rundir/resources/gui/creative_inv/search.png new file mode 100644 index 0000000..28253cc Binary files /dev/null and b/lwjgl-rundir/resources/gui/creative_inv/search.png differ diff --git a/lwjgl-rundir/resources/gui/creative_inv/survival_inv.png b/lwjgl-rundir/resources/gui/creative_inv/survival_inv.png new file mode 100644 index 0000000..89b83c0 Binary files /dev/null and b/lwjgl-rundir/resources/gui/creative_inv/survival_inv.png differ diff --git a/lwjgl-rundir/resources/gui/demo_bg.png b/lwjgl-rundir/resources/gui/demo_bg.png new file mode 100644 index 0000000..f44e4b8 Binary files /dev/null and b/lwjgl-rundir/resources/gui/demo_bg.png differ diff --git a/lwjgl-rundir/resources/gui/enchant.png b/lwjgl-rundir/resources/gui/enchant.png new file mode 100644 index 0000000..4498698 Binary files /dev/null and b/lwjgl-rundir/resources/gui/enchant.png differ diff --git a/lwjgl-rundir/resources/gui/furnace.png b/lwjgl-rundir/resources/gui/furnace.png new file mode 100644 index 0000000..5b73688 Binary files /dev/null and b/lwjgl-rundir/resources/gui/furnace.png differ diff --git a/lwjgl-rundir/resources/gui/gui.png b/lwjgl-rundir/resources/gui/gui.png new file mode 100644 index 0000000..e035bcd Binary files /dev/null and b/lwjgl-rundir/resources/gui/gui.png differ diff --git a/lwjgl-rundir/resources/gui/hopper.png b/lwjgl-rundir/resources/gui/hopper.png new file mode 100644 index 0000000..9bd8c74 Binary files /dev/null and b/lwjgl-rundir/resources/gui/hopper.png differ diff --git a/lwjgl-rundir/resources/gui/icons.png b/lwjgl-rundir/resources/gui/icons.png new file mode 100644 index 0000000..10f4373 Binary files /dev/null and b/lwjgl-rundir/resources/gui/icons.png differ diff --git a/lwjgl-rundir/resources/gui/inventory.png b/lwjgl-rundir/resources/gui/inventory.png new file mode 100644 index 0000000..b37b096 Binary files /dev/null and b/lwjgl-rundir/resources/gui/inventory.png differ diff --git a/lwjgl-rundir/resources/gui/particles.png b/lwjgl-rundir/resources/gui/particles.png new file mode 100644 index 0000000..7b90059 Binary files /dev/null and b/lwjgl-rundir/resources/gui/particles.png differ diff --git a/lwjgl-rundir/resources/gui/repair.png b/lwjgl-rundir/resources/gui/repair.png new file mode 100644 index 0000000..8486628 Binary files /dev/null and b/lwjgl-rundir/resources/gui/repair.png differ diff --git a/lwjgl-rundir/resources/gui/slot.png b/lwjgl-rundir/resources/gui/slot.png new file mode 100644 index 0000000..458dbd0 Binary files /dev/null and b/lwjgl-rundir/resources/gui/slot.png differ diff --git a/lwjgl-rundir/resources/gui/trading.png b/lwjgl-rundir/resources/gui/trading.png new file mode 100644 index 0000000..baf53f6 Binary files /dev/null and b/lwjgl-rundir/resources/gui/trading.png differ diff --git a/lwjgl-rundir/resources/gui/trap.png b/lwjgl-rundir/resources/gui/trap.png new file mode 100644 index 0000000..b6ffb0d Binary files /dev/null and b/lwjgl-rundir/resources/gui/trap.png differ diff --git a/lwjgl-rundir/resources/gui/unknown_pack.png b/lwjgl-rundir/resources/gui/unknown_pack.png new file mode 100644 index 0000000..1d41f30 Binary files /dev/null and b/lwjgl-rundir/resources/gui/unknown_pack.png differ diff --git a/lwjgl-rundir/resources/item/arrows.png b/lwjgl-rundir/resources/item/arrows.png new file mode 100644 index 0000000..30071d2 Binary files /dev/null and b/lwjgl-rundir/resources/item/arrows.png differ diff --git a/lwjgl-rundir/resources/item/boat.png b/lwjgl-rundir/resources/item/boat.png new file mode 100644 index 0000000..2bbb155 Binary files /dev/null and b/lwjgl-rundir/resources/item/boat.png differ diff --git a/lwjgl-rundir/resources/item/book.png b/lwjgl-rundir/resources/item/book.png new file mode 100644 index 0000000..7edecec Binary files /dev/null and b/lwjgl-rundir/resources/item/book.png differ diff --git a/lwjgl-rundir/resources/item/cart.png b/lwjgl-rundir/resources/item/cart.png new file mode 100644 index 0000000..523718b Binary files /dev/null and b/lwjgl-rundir/resources/item/cart.png differ diff --git a/lwjgl-rundir/resources/item/chest.png b/lwjgl-rundir/resources/item/chest.png new file mode 100644 index 0000000..b6b50da Binary files /dev/null and b/lwjgl-rundir/resources/item/chest.png differ diff --git a/lwjgl-rundir/resources/item/chests/trap_large.png b/lwjgl-rundir/resources/item/chests/trap_large.png new file mode 100644 index 0000000..104db7e Binary files /dev/null and b/lwjgl-rundir/resources/item/chests/trap_large.png differ diff --git a/lwjgl-rundir/resources/item/chests/trap_small.png b/lwjgl-rundir/resources/item/chests/trap_small.png new file mode 100644 index 0000000..db0dbaf Binary files /dev/null and b/lwjgl-rundir/resources/item/chests/trap_small.png differ diff --git a/lwjgl-rundir/resources/item/door.png b/lwjgl-rundir/resources/item/door.png new file mode 100644 index 0000000..6cc8e8d Binary files /dev/null and b/lwjgl-rundir/resources/item/door.png differ diff --git a/lwjgl-rundir/resources/item/enderchest.png b/lwjgl-rundir/resources/item/enderchest.png new file mode 100644 index 0000000..4eed9d8 Binary files /dev/null and b/lwjgl-rundir/resources/item/enderchest.png differ diff --git a/lwjgl-rundir/resources/item/largechest.png b/lwjgl-rundir/resources/item/largechest.png new file mode 100644 index 0000000..13356c3 Binary files /dev/null and b/lwjgl-rundir/resources/item/largechest.png differ diff --git a/lwjgl-rundir/resources/item/largexmaschest.png b/lwjgl-rundir/resources/item/largexmaschest.png new file mode 100644 index 0000000..4952f9d Binary files /dev/null and b/lwjgl-rundir/resources/item/largexmaschest.png differ diff --git a/lwjgl-rundir/resources/item/sign.png b/lwjgl-rundir/resources/item/sign.png new file mode 100644 index 0000000..657e620 Binary files /dev/null and b/lwjgl-rundir/resources/item/sign.png differ diff --git a/lwjgl-rundir/resources/item/skis.png b/lwjgl-rundir/resources/item/skis.png new file mode 100644 index 0000000..d6cb3ba Binary files /dev/null and b/lwjgl-rundir/resources/item/skis.png differ diff --git a/lwjgl-rundir/resources/item/xmaschest.png b/lwjgl-rundir/resources/item/xmaschest.png new file mode 100644 index 0000000..985470d Binary files /dev/null and b/lwjgl-rundir/resources/item/xmaschest.png differ diff --git a/lwjgl-rundir/resources/item/xporb.png b/lwjgl-rundir/resources/item/xporb.png new file mode 100644 index 0000000..1d5a71c Binary files /dev/null and b/lwjgl-rundir/resources/item/xporb.png differ diff --git a/lwjgl-rundir/resources/lang/en_US.lang b/lwjgl-rundir/resources/lang/en_US.lang new file mode 100644 index 0000000..6170e31 --- /dev/null +++ b/lwjgl-rundir/resources/lang/en_US.lang @@ -0,0 +1,1339 @@ + +language.name=English +language.region=US +language.code=en_US + +gui.done=Done +gui.cancel=Cancel +gui.back=Back +gui.toMenu=Back to title screen +gui.up=Up +gui.down=Down +gui.yes=Yes +gui.no=No + +menu.singleplayer=Singleplayer +menu.multiplayer=Multiplayer +menu.online=Minecraft Realms +menu.options=Options... +menu.editprofile=Edit Profile +menu.voicechannel=Voice Channel +menu.quit=Quit Game +menu.returnToMenu=Save and Quit to Title +menu.disconnect=Disconnect +menu.returnToGame=Back to Game +menu.switchingLevel=Switching worlds +menu.generatingLevel=Generating world +menu.loadingLevel=Loading world +menu.generatingTerrain=Building terrain +menu.convertingLevel=Converting world +menu.simulating=Simulating the world for a bit +menu.respawning=Respawning +menu.shareToLan=Open to LAN + +profile.title=Edit Profile +profile.screenname=Screenname +profile.playerSkin=Player Skin +profile.addSkin=Add Skin +profile.clearSkin=Clear List + +voice.title=Voice Channel +voice.addr=Channel Address +voice.connect=Connect +voice.disconnect=Disconnect +voice.volume=Channel Volume +voice.warning1=§cWarning:§r your network does not support the STUN +voice.warning2=connection procedure, a TURN relay will be used as +voice.warning3=fallback, which will greatly impact the audio quality + +selectWorld.title=Select World +selectWorld.empty=empty +selectWorld.world=World +selectWorld.select=Play Selected World +selectWorld.create=Create New World +selectWorld.recreate=Re-Create +selectWorld.createDemo=Play New Demo World +selectWorld.delete=Delete +selectWorld.rename=Rename +selectWorld.deleteQuestion=Are you sure you want to delete this world? +selectWorld.deleteWarning=will be lost forever! (A long time!) +selectWorld.deleteButton=Delete +selectWorld.renameButton=Rename +selectWorld.renameTitle=Rename World +selectWorld.conversion=Must be converted! +selectWorld.newWorld=New World +selectWorld.newWorld.copyOf=Copy of %s +selectWorld.enterName=World Name +selectWorld.resultFolder=Will be saved in: +selectWorld.enterSeed=Seed for the World Generator +selectWorld.seedInfo=Leave blank for a random seed +selectWorld.cheats=Cheats +selectWorld.customizeType=Customize + +createWorld.customize.presets=Presets +createWorld.customize.presets.title=Select a Preset +createWorld.customize.presets.select=Use Preset +createWorld.customize.presets.share=Want to share your preset with someone? Use the below box! +createWorld.customize.presets.list=Alternatively, here's some we made earlier! +createWorld.customize.flat.title=Superflat Customization +createWorld.customize.flat.tile=Layer Material +createWorld.customize.flat.height=Height +createWorld.customize.flat.addLayer=Add Layer +createWorld.customize.flat.editLayer=Edit Layer +createWorld.customize.flat.removeLayer=Remove Layer +createWorld.customize.flat.layer.top=Top - %d +createWorld.customize.flat.layer=%d +createWorld.customize.flat.layer.bottom=Bottom - %d + +gameMode.survival=Survival Mode +gameMode.creative=Creative Mode +gameMode.adventure=Adventure Mode +gameMode.hardcore=Hardcore Mode! +gameMode.changed=Your game mode has been updated + +selectWorld.gameMode=Game Mode: +selectWorld.gameMode.survival=Survival +selectWorld.gameMode.survival.line1=Search for resources, crafting, gain +selectWorld.gameMode.survival.line2=levels, health and hunger +selectWorld.gameMode.creative=Creative +selectWorld.gameMode.creative.line1=Unlimited resources, free flying and +selectWorld.gameMode.creative.line2=destroy blocks instantly +selectWorld.gameMode.hardcore=Hardcore +selectWorld.gameMode.hardcore.line1=Same as survival mode, locked at hardest +selectWorld.gameMode.hardcore.line2=difficulty, and one life only +selectWorld.gameMode.adventure=Adventure +selectWorld.gameMode.adventure.line1=Same as survival mode, but blocks can't +selectWorld.gameMode.adventure.line2=be added or removed +selectWorld.moreWorldOptions=More World Options... +selectWorld.mapFeatures=Generate Structures: +selectWorld.mapFeatures.info=Villages, dungeons etc +selectWorld.mapType=World Type: +selectWorld.mapType.normal=Normal +selectWorld.allowCommands=Allow Cheats: +selectWorld.allowCommands.info=Commands like /gamemode, /xp +selectWorld.hardcoreMode=Hardcore: +selectWorld.hardcoreMode.info=World is deleted upon death +selectWorld.bonusItems=Bonus Chest: + +generator.default=Default +generator.flat=Superflat +generator.largeBiomes=Large Biomes + +selectServer.title=Select Server +selectServer.empty=empty +selectServer.select=Join Server +selectServer.direct=Direct Connect +selectServer.edit=Edit +selectServer.delete=Delete +selectServer.add=Add server +selectServer.defaultName=Minecraft Server +selectServer.deleteQuestion=Are you sure you want to remove this server? +selectServer.deleteWarning=will be lost forever! (A long time!) +selectServer.deleteButton=Delete +selectServer.refresh=Refresh +selectServer.hiddenAddress=(Hidden) +addServer.title=Edit Server Info +addServer.enterName=Server Name +addServer.enterIp=Server Address +addServer.add=Done +addServer.hideAddress=Hide Address +lanServer.title=LAN World +lanServer.scanning=Scanning for games on your local network +lanServer.start=Start LAN World +lanServer.otherPlayers=Settings for Other Players +mcoServer.title=Minecraft Online World + +multiplayer.title=Play Multiplayer +multiplayer.connect=Connect +multiplayer.info1=Minecraft Multiplayer is currently not finished, but there +multiplayer.info2=is some buggy early testing going on. +multiplayer.ipinfo=Enter the IP of a server to connect to it: + +multiplayer.texturePrompt.line1=This server recommends the use of a custom texture pack. +multiplayer.texturePrompt.line2=Would you like to download and install it automagically? + +multiplayer.downloadingTerrain=Downloading terrain + +multiplayer.stopSleeping=Leave Bed + +chat.link.confirm=Are you sure you want to open the following website? +chat.link.confirmTrusted=Do you want to open this link or copy it to your clipboard? +chat.link.warning=Never open links from people that you don't trust! +chat.link.open=Open in browser +chat.copy=Copy to Clipboard + +menu.playdemo=Play Demo World +menu.resetdemo=Reset Demo World +demo.day.1=This demo will last five game days, do your best! +demo.day.2=Day Two +demo.day.3=Day Three +demo.day.4=Day Four +demo.day.5=This is your last day! +demo.day.warning=Your time is almost up! +demo.day.6=You have passed your fifth day, use F2 to save a screenshot of your creation +demo.reminder=The demo time has expired, buy the game to continue or start a new world! +demo.remainingTime=Remaining time: %s +demo.demoExpired=Demo time's up! +demo.help.movement=Use %1$s, %2$s, %3$s, %4$s and the mouse to move around +demo.help.movementShort=Move by pressing %1$s, %2$s, %3$s, %4$s +demo.help.movementMouse=Look around using the mouse +demo.help.jump=Jump by pressing %1$s +demo.help.inventory=Use %1$s to open your inventory +demo.help.title=Minecraft Demo Mode +demo.help.fullWrapped=This demo will last 5 ingame days (about 1 hour and 40 minutes of real time). Check the achievements for hints! Have fun! +demo.help.buy=Purchase Now! +demo.help.later=Continue Playing! + +connect.connecting=Connecting to the server... +connect.authorizing=Logging in... +connect.failed=Failed to connect to the server + +disconnect.genericReason=%s +disconnect.disconnected=Disconnected by Server +disconnect.lost=Connection Lost +disconnect.kicked=Was kicked from the game +disconnect.timeout=Timed out +disconnect.closed=Connection closed +disconnect.loginFailed=Failed to login +disconnect.loginFailedInfo=Failed to login: %s +disconnect.quitting=Quitting +disconnect.endOfStream=End of stream +disconnect.overflow=Buffer overflow +disconnect.spam=Kicked for spamming + +options.off=OFF +options.on=ON +options.visible=Shown +options.hidden=Hidden +options.title=Options +options.controls=Controls... +options.video=Video Settings... +options.language=Language... +options.languageWarning=Language translations may not be 100% accurate +options.videoTitle=Video Settings +options.music=Music +options.sound=Sound +options.invertMouse=Invert Mouse +options.fov=FOV +options.fov.min=Normal +options.fov.max=Quake Pro +options.gamma=Brightness +options.gamma.min=Moody +options.gamma.max=Bright +options.sensitivity=Sensitivity +options.sensitivity.min=*yawn* +options.sensitivity.max=HYPERSPEED!!! +options.renderDistance=Render Distance +options.renderDistance.tiny=Tiny +options.renderDistance.short=Short +options.renderDistance.normal=Normal +options.renderDistance.far=Far +options.viewBobbing=View Bobbing +options.ao=Smooth Lighting +options.ao.off=Off +options.ao.min=Minimum +options.ao.max=Maximum +options.anaglyph=3D Anaglyph +options.framerateLimit=Performance +options.difficulty=Difficulty +options.difficulty.peaceful=Peaceful +options.difficulty.easy=Easy +options.difficulty.normal=Normal +options.difficulty.hard=Hard +options.difficulty.hardcore=Hardcore +options.graphics=Graphics +options.graphics.fancy=Fancy +options.graphics.fast=Fast +options.guiScale=GUI Scale +options.guiScale.auto=Auto +options.guiScale.small=Small +options.guiScale.normal=Normal +options.guiScale.large=Large +options.advancedOpengl=Advanced OpenGL +options.renderClouds=Clouds +options.fog=Fog +options.farWarning1=A 64 bit Java installation is recommended +options.farWarning2=for 'Far' render distance (you have 32 bit) +options.particles=Particles +options.particles.all=All +options.particles.decreased=Decreased +options.particles.minimal=Minimal +options.multiplayer.title=Multiplayer Settings... +options.chat.title=Chat Settings... +options.chat.visibility=Chat +options.chat.visibility.full=Shown +options.chat.visibility.system=Commands Only +options.chat.visibility.hidden=Hidden +options.chat.color=Colors +options.chat.opacity=Opacity +options.chat.links=Web Links +options.chat.links.prompt=Prompt on Links +options.chat.scale=Scale +options.chat.width=Width +options.chat.height.focused=Focused Height +options.chat.height.unfocused=Unfocused Height +options.showCape=Show Cape +options.serverTextures=Server Textures +options.snooper=Allow Snooper +options.snooper.view=Snooper Settings... +options.snooper.title=Machine Specs Collection +options.snooper.desc=We want to collect information about your machine to help improve Minecraft by knowing what we can support and where the biggest problems are. All of this information is completely anonymous and viewable below. We promise we won't do anything bad with this data, but if you want to opt out then feel free to toggle it off! +options.texture.pack=Texture Packs +options.fullscreen=Fullscreen +options.vsync=Use VSync +options.touchscreen=Touchscreen Mode +options.framebufferAntialias=Buffer Antialiasing +options.framebufferAntialias.none=None +options.framebufferAntialias.auto=Auto +options.framebufferAntialias.fxaa=FXAA +options.framebufferAntialias.msaa4=MSAA4 +options.framebufferAntialias.msaa8=MSAA8 +performance.max=Max FPS +performance.balanced=Balanced +performance.powersaver=Power saver + +controls.title=Controls + +key.forward=Forward +key.left=Left +key.back=Back +key.right=Right +key.jump=Jump +key.inventory=Inventory +key.drop=Drop +key.chat=Chat +key.fog=Toggle Fog +key.sneak=Sneak +key.playerlist=List Players +key.attack=Attack +key.use=Use Item +key.pickItem=Pick Block +key.mouseButton=Button %1$s +key.sprint=Sprint +key.zoom=Zoom +key.function=Function + +texturePack.openFolder=Open texture pack folder +texturePack.title=Select Texture Pack +texturePack.folderInfo=(Place texture pack files here) +texturePack.incompatible=Incompatible + +book.pageIndicator=Page %1$s of %2$s +book.byAuthor=by %1$s +book.signButton=Sign +book.editTitle=Enter Book Title: +book.finalizeButton=Sign and Close +book.finalizeWarning=Note! When you sign the book, it will no longer be editable. + +tile.stone.name=Stone + +tile.grass.name=Grass Block +tile.dirt.name=Dirt +tile.stonebrick.name=Cobblestone +tile.wood.name=Wooden Planks +tile.wood.oak.name=Oak Wood Planks +tile.wood.spruce.name=Spruce Wood Planks +tile.wood.birch.name=Birch Wood Planks +tile.wood.jungle.name=Jungle Wood Planks +tile.sapling.oak.name=Oak Sapling +tile.sapling.spruce.name=Spruce Sapling +tile.sapling.birch.name=Birch Sapling +tile.sapling.jungle.name=Jungle Sapling +tile.deadbush.name=Dead Bush +tile.bedrock.name=Bedrock +tile.water.name=Water +tile.lava.name=Lava +tile.sand.name=Sand +tile.sandStone.name=Sandstone +tile.sandStone.default.name=Sandstone +tile.sandStone.chiseled.name=Chiseled Sandstone +tile.sandStone.smooth.name=Smooth Sandstone +tile.gravel.name=Gravel +tile.oreGold.name=Gold Ore +tile.oreIron.name=Iron Ore +tile.oreCoal.name=Coal Ore +tile.log.name=Wood +tile.log.oak.name=Oak Wood +tile.log.spruce.name=Spruce Wood +tile.log.birch.name=Birch Wood +tile.log.jungle.name=Jungle Wood +tile.leaves.name=Leaves +tile.leaves.oak.name=Oak Leaves +tile.leaves.spruce.name=Spruce Leaves +tile.leaves.birch.name=Birch Leaves +tile.leaves.jungle.name=Jungle Leaves +tile.tallgrass.name=Grass +tile.tallgrass.shrub.name=Shrub +tile.tallgrass.grass.name=Grass +tile.tallgrass.fern.name=Fern +tile.sponge.name=Sponge +tile.glass.name=Glass +tile.thinGlass.name=Glass Pane +tile.cloth.name=Wool +tile.flower.name=Flower +tile.rose.name=Rose +tile.mushroom.name=Mushroom +tile.blockGold.name=Block of Gold +tile.blockIron.name=Block of Iron +tile.stoneSlab.stone.name=Stone Slab +tile.stoneSlab.sand.name=Sandstone Slab +tile.stoneSlab.wood.name=Wooden Slab +tile.stoneSlab.cobble.name=Cobblestone Slab +tile.stoneSlab.brick.name=Bricks Slab +tile.stoneSlab.smoothStoneBrick.name=Stone Bricks Slab +tile.stoneSlab.netherBrick.name=Nether Brick Slab +tile.stoneSlab.quartz.name=Quartz Slab +tile.woodSlab.oak.name=Oak Wood Slab +tile.woodSlab.spruce.name=Spruce Wood Slab +tile.woodSlab.birch.name=Birch Wood Slab +tile.woodSlab.jungle.name=Jungle Wood Slab +tile.brick.name=Bricks +tile.tnt.name=TNT +tile.bookshelf.name=Bookshelf +tile.stoneMoss.name=Moss Stone +tile.obsidian.name=Obsidian +tile.torch.name=Torch +tile.fire.name=Fire +tile.mobSpawner.name=Monster Spawner +tile.stairsWood.name=Oak Wood Stairs +tile.stairsWoodSpruce.name=Spruce Wood Stairs +tile.stairsWoodBirch.name=Birch Wood Stairs +tile.stairsWoodJungle.name=Jungle Wood Stairs +tile.chest.name=Chest +tile.chestTrap.name=Trapped Chest +tile.redstoneDust.name=Redstone Dust +tile.oreDiamond.name=Diamond Ore +tile.blockDiamond.name=Block of Diamond +tile.workbench.name=Crafting Table +tile.crops.name=Crops +tile.farmland.name=Farmland +tile.furnace.name=Furnace +tile.sign.name=Sign +tile.doorWood.name=Wooden Door +tile.ladder.name=Ladder +tile.rail.name=Rail +tile.goldenRail.name=Powered Rail +tile.activatorRail.name=Activator Rail +tile.detectorRail.name=Detector Rail +tile.stairsStone.name=Stone Stairs +tile.stairsSandStone.name=Sandstone Stairs +tile.lever.name=Lever +tile.pressurePlate.name=Pressure Plate +tile.weightedPlate_light.name=Weighted Pressure Plate (Light) +tile.weightedPlate_heavy.name=Weighted Pressure Plate (Heavy) +tile.doorIron.name=Iron Door +tile.oreRedstone.name=Redstone Ore +tile.notGate.name=Redstone Torch +tile.button.name=Button +tile.snow.name=Snow +tile.ice.name=Ice +tile.cactus.name=Cactus +tile.clay.name=Clay +tile.reeds.name=Sugar cane +tile.jukebox.name=Jukebox +tile.fence.name=Fence +tile.fenceGate.name=Fence Gate +tile.pumpkin.name=Pumpkin +tile.litpumpkin.name=Jack 'o' Lantern +tile.hellrock.name=Netherrack +tile.hellsand.name=Soul Sand +tile.lightgem.name=Glowstone +tile.portal.name=Portal +tile.cloth.black.name=Black Wool +tile.cloth.red.name=Red Wool +tile.cloth.green.name=Green Wool +tile.cloth.brown.name=Brown Wool +tile.cloth.blue.name=Blue Wool +tile.cloth.purple.name=Purple Wool +tile.cloth.cyan.name=Cyan Wool +tile.cloth.silver.name=Light Gray Wool +tile.cloth.gray.name=Gray Wool +tile.cloth.pink.name=Pink Wool +tile.cloth.lime.name=Lime Wool +tile.cloth.yellow.name=Yellow Wool +tile.cloth.lightBlue.name=Light Blue Wool +tile.cloth.magenta.name=Magenta Wool +tile.cloth.orange.name=Orange Wool +tile.cloth.white.name=Wool +tile.oreLapis.name=Lapis Lazuli Ore +tile.blockLapis.name=Lapis Lazuli Block +tile.dispenser.name=Dispenser +tile.dropper.name=Dropper +tile.musicBlock.name=Note Block +tile.cake.name=Cake +tile.bed.name=Bed +tile.bed.occupied=This bed is occupied +tile.bed.noSleep=You can only sleep at night +tile.bed.notSafe=You may not rest now, there are monsters nearby +tile.bed.notValid=Your home bed was missing or obstructed +tile.lockedchest.name=Locked chest +tile.trapdoor.name=Trapdoor +tile.web.name=Cobweb +tile.stonebricksmooth.name=Stone Bricks +tile.stonebricksmooth.default.name=Stone Bricks +tile.stonebricksmooth.mossy.name=Mossy Stone Bricks +tile.stonebricksmooth.cracked.name=Cracked Stone Bricks +tile.stonebricksmooth.chiseled.name=Chiseled Stone Bricks +tile.monsterStoneEgg.stone.name=Stone Monster Egg +tile.monsterStoneEgg.cobble.name=Cobblestone Monster Egg +tile.monsterStoneEgg.brick.name=Stone Brick Monster Egg +tile.pistonBase.name=Piston +tile.pistonStickyBase.name=Sticky Piston +tile.fenceIron.name=Iron Bars +tile.melon.name=Melon +tile.stairsBrick.name=Brick Stairs +tile.stairsStoneBrickSmooth.name=Stone Brick Stairs +tile.vine.name=Vines +tile.netherBrick.name=Nether Brick +tile.netherFence.name=Nether Brick Fence +tile.stairsNetherBrick.name=Nether Brick Stairs +tile.netherStalk.name=Nether Wart +tile.cauldron.name=Cauldron +tile.enchantmentTable.name=Enchantment Table +tile.anvil.name=Anvil +tile.anvil.intact.name=Anvil +tile.anvil.slightlyDamaged.name=Slightly Damaged Anvil +tile.anvil.veryDamaged.name=Very Damaged Anvil +tile.whiteStone.name=End Stone +tile.endPortalFrame.name=End Portal +tile.mycel.name=Mycelium +tile.waterlily.name=Lily Pad +tile.dragonEgg.name=Dragon Egg +tile.redstoneLight.name=Redstone Lamp +tile.cocoa.name=Cocoa +tile.enderChest.name=Ender Chest +tile.oreRuby.name=Ruby Ore +tile.oreEmerald.name=Emerald Ore +tile.blockEmerald.name=Block of Emerald +tile.blockRedstone.name=Block of Redstone +tile.tripWire.name=Tripwire +tile.tripWireSource.name=Tripwire Hook +tile.commandBlock.name=Command Block +tile.beacon.name=Beacon +tile.beacon.primary=Primary Power +tile.beacon.secondary=Secondary Power +tile.cobbleWall.normal.name=Cobblestone Wall +tile.cobbleWall.mossy.name=Mossy Cobblestone Wall +tile.carrots.name=Carrots +tile.potatoes.name=Potatoes +tile.daylightDetector.name=Daylight Sensor +tile.netherquartz.name=Nether Quartz Ore +tile.hopper.name=Hopper +tile.quartzBlock.default.name=Block of Quartz +tile.quartzBlock.chiseled.name=Chiseled Quartz Block +tile.quartzBlock.lines.name=Pillar Quartz Block +tile.stairsQuartz.name=Quartz Stairs + +item.shovelIron.name=Iron Shovel +item.pickaxeIron.name=Iron Pickaxe +item.hatchetIron.name=Iron Axe +item.flintAndSteel.name=Flint and Steel +item.apple.name=Apple +item.cookie.name=Cookie +item.bow.name=Bow +item.arrow.name=Arrow +item.coal.name=Coal +item.charcoal.name=Charcoal +item.diamond.name=Diamond +item.emerald.name=Emerald +item.ingotIron.name=Iron Ingot +item.ingotGold.name=Gold Ingot +item.swordIron.name=Iron Sword +item.swordWood.name=Wooden Sword +item.shovelWood.name=Wooden Shovel +item.pickaxeWood.name=Wooden Pickaxe +item.hatchetWood.name=Wooden Axe +item.swordStone.name=Stone Sword +item.shovelStone.name=Stone Shovel +item.pickaxeStone.name=Stone Pickaxe +item.hatchetStone.name=Stone Axe +item.swordDiamond.name=Diamond Sword +item.shovelDiamond.name=Diamond Shovel +item.pickaxeDiamond.name=Diamond Pickaxe +item.hatchetDiamond.name=Diamond Axe +item.stick.name=Stick +item.bowl.name=Bowl +item.mushroomStew.name=Mushroom Stew +item.swordGold.name=Golden Sword +item.shovelGold.name=Golden Shovel +item.pickaxeGold.name=Golden Pickaxe +item.hatchetGold.name=Golden Axe +item.string.name=String +item.feather.name=Feather +item.sulphur.name=Gunpowder +item.hoeWood.name=Wooden Hoe +item.hoeStone.name=Stone Hoe +item.hoeIron.name=Iron Hoe +item.hoeDiamond.name=Diamond Hoe +item.hoeGold.name=Golden Hoe +item.seeds.name=Seeds +item.seeds_pumpkin.name=Pumpkin Seeds +item.seeds_melon.name=Melon Seeds +item.melon.name=Melon +item.wheat.name=Wheat +item.bread.name=Bread +item.helmetCloth.name=Leather Cap +item.chestplateCloth.name=Leather Tunic +item.leggingsCloth.name=Leather Pants +item.bootsCloth.name=Leather Boots +item.helmetChain.name=Chain Helmet +item.chestplateChain.name=Chain Chestplate +item.leggingsChain.name=Chain Leggings +item.bootsChain.name=Chain Boots +item.helmetIron.name=Iron Helmet +item.chestplateIron.name=Iron Chestplate +item.leggingsIron.name=Iron Leggings +item.bootsIron.name=Iron Boots +item.helmetDiamond.name=Diamond Helmet +item.chestplateDiamond.name=Diamond Chestplate +item.leggingsDiamond.name=Diamond Leggings +item.bootsDiamond.name=Diamond Boots +item.helmetGold.name=Golden Helmet +item.chestplateGold.name=Golden Chestplate +item.leggingsGold.name=Golden Leggings +item.bootsGold.name=Golden Boots +item.flint.name=Flint +item.porkchopRaw.name=Raw Porkchop +item.porkchopCooked.name=Cooked Porkchop +item.chickenRaw.name=Raw Chicken +item.chickenCooked.name=Cooked Chicken +item.beefRaw.name=Raw Beef +item.beefCooked.name=Steak +item.painting.name=Painting +item.frame.name=Item Frame +item.appleGold.name=Golden Apple +item.sign.name=Sign +item.doorWood.name=Wooden Door +item.bucket.name=Bucket +item.bucketWater.name=Water Bucket +item.bucketLava.name=Lava Bucket +item.minecart.name=Minecart +item.saddle.name=Saddle +item.doorIron.name=Iron Door +item.redstone.name=Redstone +item.snowball.name=Snowball +item.boat.name=Boat +item.leather.name=Leather +item.milk.name=Milk +item.brick.name=Brick +item.clay.name=Clay +item.reeds.name=Sugar Canes +item.paper.name=Paper +item.book.name=Book +item.slimeball.name=Slimeball +item.minecartChest.name=Minecart with Chest +item.minecartFurnace.name=Minecart with Furnace +item.minecartTnt.name=Minecart with TNT +item.minecartHopper.name=Minecart with Hopper +item.egg.name=Egg +item.compass.name=Compass +item.fishingRod.name=Fishing Rod +item.clock.name=Clock +item.yellowDust.name=Glowstone Dust +item.fishRaw.name=Raw Fish +item.fishCooked.name=Cooked Fish +item.record.name=Music Disc +item.bone.name=Bone +item.dyePowder.black.name=Ink Sac +item.dyePowder.red.name=Rose Red +item.dyePowder.green.name=Cactus Green +item.dyePowder.brown.name=Cocoa Beans +item.dyePowder.blue.name=Lapis Lazuli +item.dyePowder.purple.name=Purple Dye +item.dyePowder.cyan.name=Cyan Dye +item.dyePowder.silver.name=Light Gray Dye +item.dyePowder.gray.name=Gray Dye +item.dyePowder.pink.name=Pink Dye +item.dyePowder.lime.name=Lime Dye +item.dyePowder.yellow.name=Dandelion Yellow +item.dyePowder.lightBlue.name=Light Blue Dye +item.dyePowder.magenta.name=Magenta Dye +item.dyePowder.orange.name=Orange Dye +item.dyePowder.white.name=Bone Meal +item.sugar.name=Sugar +item.cake.name=Cake +item.bed.name=Bed +item.diode.name=Redstone Repeater +item.comparator.name=Redstone Comparator +item.map.name=Map +item.leaves.name=Leaves +item.shears.name=Shears +item.rottenFlesh.name=Rotten Flesh +item.enderPearl.name=Ender Pearl +item.blazeRod.name=Blaze Rod +item.ghastTear.name=Ghast Tear +item.netherStalkSeeds.name=Nether Wart +item.potion.name=Potion +item.emptyPotion.name=Water Bottle +item.goldNugget.name=Gold Nugget +item.glassBottle.name=Glass Bottle +item.spiderEye.name=Spider Eye +item.fermentedSpiderEye.name=Fermented Spider Eye +item.blazePowder.name=Blaze Powder +item.magmaCream.name=Magma Cream +item.cauldron.name=Cauldron +item.brewingStand.name=Brewing Stand +item.eyeOfEnder.name=Eye of Ender +item.speckledMelon.name=Glistering Melon +item.monsterPlacer.name=Spawn +item.expBottle.name=Bottle o' Enchanting +item.fireball.name=Fire Charge +item.writingBook.name=Book and Quill +item.writtenBook.name=Written Book +item.ruby.name=Ruby +item.flowerPot.name=Flower Pot +item.emptyMap.name=Empty Map +item.carrots.name=Carrot +item.carrotGolden.name=Golden Carrot +item.potato.name=Potato +item.potatoBaked.name=Baked Potato +item.potatoPoisonous.name=Poisonous Potato +item.skull.skeleton.name=Skeleton Skull +item.skull.wither.name=Wither Skeleton Skull +item.skull.zombie.name=Zombie Head +item.skull.char.name=Head +item.skull.player.name=%s's Head +item.skull.creeper.name=Creeper Head +item.carrotOnAStick.name=Carrot on a Stick +item.netherStar.name=Nether Star +item.pumpkinPie.name=Pumpkin Pie +item.enchantedBook.name=Enchanted Book +item.fireworks.name=Firework Rocket +item.fireworks.flight=Flight Duration: +item.fireworksCharge.name=Firework Star +item.fireworksCharge.black=Black +item.fireworksCharge.red=Red +item.fireworksCharge.green=Green +item.fireworksCharge.brown=Brown +item.fireworksCharge.blue=Blue +item.fireworksCharge.purple=Purple +item.fireworksCharge.cyan=Cyan +item.fireworksCharge.silver=Light Gray +item.fireworksCharge.gray=Gray +item.fireworksCharge.pink=Pink +item.fireworksCharge.lime=Lime +item.fireworksCharge.yellow=Yellow +item.fireworksCharge.lightBlue=Light Blue +item.fireworksCharge.magenta=Magenta +item.fireworksCharge.orange=Orange +item.fireworksCharge.white=White +item.fireworksCharge.customColor=Custom +item.fireworksCharge.fadeTo=Fade to +item.fireworksCharge.flicker=Twinkle +item.fireworksCharge.trail=Trail +item.fireworksCharge.type.0=Small Ball +item.fireworksCharge.type.1=Large Ball +item.fireworksCharge.type.2=Star-shaped +item.fireworksCharge.type.3=Creeper-shaped +item.fireworksCharge.type.4=Burst +item.fireworksCharge.type=Unknown Shape +item.netherbrick.name=Nether Brick +item.netherquartz.name=Nether Quartz + +container.inventory=Inventory +container.hopper=Item Hopper +container.crafting=Crafting +container.dispenser=Dispenser +container.dropper=Dropper +container.furnace=Furnace +container.enchant=Enchant +container.repair=Repair & Name +container.repair.cost=Enchantment Cost: %1$d +container.repair.expensive=Too Expensive! +container.creative=Item Selection +container.brewing=Brewing Stand +container.chest=Chest +container.chestDouble=Large Chest +container.minecart=Minecart +container.enderchest=Ender Chest + +item.dyed=Dyed + +entity.Item.name=Item +entity.XPOrb.name=Experience Orb +entity.SmallFireball.name=Small Fireball +entity.Fireball.name=Fireball + +entity.Arrow.name=Arrow +entity.Snowball.name=Snowball +entity.Painting.name=Painting + +entity.Mob.name=Mob +entity.Monster.name=Monster + +entity.Creeper.name=Creeper +entity.Skeleton.name=Skeleton +entity.Spider.name=Spider +entity.Giant.name=Giant +entity.Zombie.name=Zombie +entity.Slime.name=Slime +entity.Ghast.name=Ghast +entity.PigZombie.name=Zombie Pigman +entity.Enderman.name=Enderman +entity.Silverfish.name=Silverfish +entity.CaveSpider.name=Cave Spider +entity.Blaze.name=Blaze +entity.LavaSlime.name=Magma Cube +entity.MushroomCow.name=Mooshroom +entity.Villager.name=Villager +entity.VillagerGolem.name=Iron Golem +entity.SnowMan.name=Snow Golem +entity.EnderDragon.name=Ender Dragon +entity.WitherBoss.name=Wither +entity.Witch.name=Witch + +entity.Pig.name=Pig +entity.Sheep.name=Sheep +entity.Cow.name=Cow +entity.Chicken.name=Chicken +entity.Squid.name=Squid +entity.Wolf.name=Wolf +entity.Ozelot.name=Ocelot +entity.Cat.name=Cat +entity.Bat.name=Bat + +entity.PrimedTnt.name=Block of TNT +entity.FallingSand.name=Falling Block + +entity.Minecart.name=Minecart +entity.Boat.name=Boat + +entity.Arrow.name=arrow +entity.generic.name=unknown + +death.fell.accident.ladder=%1$s fell off a ladder +death.fell.accident.vines=%1$s fell off some vines +death.fell.accident.water=%1$s fell out of the water +death.fell.accident.generic=%1$s fell from a high place +death.fell.killer=%1$s was doomed to fall +death.fell.assist=%1$s was doomed to fall by %2$s +death.fell.assist.item=%1$s was doomed to fall by %2$s using %3$s +death.fell.finish=%1$s was fell too far and was finished by %2$s +death.fell.finish.item=%1$s was fell too far and was finished by %2$s using %3$s + +death.attack.inFire=%1$s went up in flames +death.attack.inFire.player=%1$s walked into fire whilst fighting %2$s +death.attack.onFire=%1$s burned to death +death.attack.onFire.player=%1$s was burnt to a crisp whilst fighting %2$s +death.attack.lava=%1$s tried to swim in lava +death.attack.lava.player=%1$s tried to swim in lava to escape %2$s +death.attack.inWall=%1$s suffocated in a wall +death.attack.drown=%1$s drowned +death.attack.drown.player=%1$s drowned whilst trying to escape %2$s +death.attack.starve=%1$s starved to death +death.attack.cactus=%1$s was pricked to death +death.attack.cactus.player=%1$s walked into a cactus whilst trying to escape %2$s +death.attack.generic=%1$s died +death.attack.explosion=%1$s blew up +death.attack.explosion.player=%1$s was blown up by %2$s +death.attack.magic=%1$s was killed by magic +death.attack.wither=%1$s withered away +death.attack.anvil=%1$s was squashed by a falling anvil +death.attack.fallingBlock=%1$s was squashed by a falling block +death.attack.mob=%1$s was slain by %2$s +death.attack.player=%1$s was slain by %2$s +death.attack.player.item=%1$s was slain by %2$s using %3$s +death.attack.arrow=%1$s was shot by %2$s +death.attack.arrow.item=%1$s was shot by %2$s using %3$s +death.attack.fireball=%1$s was fireballed by %2$s +death.attack.fireball.item=%1$s was fireballed by %2$s using %3$s +death.attack.thrown=%1$s was pummeled by %2$s +death.attack.thrown.item=%1$s was pummeled by %2$s using %3$s +death.attack.indirectMagic=%1$s was killed by %2$s using magic +death.attack.indirectMagic.item=%1$s was killed by %2$s using %3$s +death.attack.thorns=%1$s was killed trying to hurt %2$s +death.attack.fall=%1$s hit the ground too hard +death.attack.outOfWorld=%1$s fell out of the world + +deathScreen.respawn=Respawn +deathScreen.deleteWorld=Delete world +deathScreen.titleScreen=Title screen +deathScreen.score=Score +deathScreen.title.hardcore=Game over! +deathScreen.hardcoreInfo=You cannot respawn in hardcore mode! +deathScreen.title=You died! +deathScreen.leaveServer=Leave server + +potion.empty=No Effects +potion.moveSpeed=Speed +potion.moveSlowdown=Slowness +potion.digSpeed=Haste +potion.digSlowDown=Mining Fatigue +potion.damageBoost=Strength +potion.weakness=Weakness +potion.heal=Instant Health +potion.harm=Instant Damage +potion.jump=Jump Boost +potion.confusion=Nausea +potion.regeneration=Regeneration +potion.resistance=Resistance +potion.fireResistance=Fire Resistance +potion.waterBreathing=Water Breathing +potion.invisibility=Invisibility +potion.blindness=Blindness +potion.nightVision=Night Vision +potion.hunger=Hunger +potion.poison=Poison +potion.wither=Wither + +potion.moveSpeed.postfix=Potion of Swiftness +potion.moveSlowdown.postfix=Potion of Slowness +potion.digSpeed.postfix=Potion of Haste +potion.digSlowDown.postfix=Potion of Dullness +potion.damageBoost.postfix=Potion of Strength +potion.weakness.postfix=Potion of Weakness +potion.heal.postfix=Potion of Healing +potion.harm.postfix=Potion of Harming +potion.jump.postfix=Potion of Leaping +potion.confusion.postfix=Potion of Nausea +potion.regeneration.postfix=Potion of Regeneration +potion.resistance.postfix=Potion of Resistance +potion.fireResistance.postfix=Potion of Fire Resistance +potion.waterBreathing.postfix=Potion of Water Breathing +potion.invisibility.postfix=Potion of Invisibility +potion.blindness.postfix=Potion of Blindness +potion.nightVision.postfix=Potion of Night Vision +potion.hunger.postfix=Potion of Hunger +potion.poison.postfix=Potion of Poison +potion.wither.postfix=Potion of Decay + +potion.potency.0= +potion.potency.1=II +potion.potency.2=III +potion.potency.3=IV + +potion.prefix.grenade=Splash +potion.prefix.mundane=Mundane +potion.prefix.uninteresting=Uninteresting +potion.prefix.bland=Bland +potion.prefix.clear=Clear +potion.prefix.milky=Milky +potion.prefix.diffuse=Diffuse +potion.prefix.artless=Artless +potion.prefix.thin=Thin +potion.prefix.awkward=Awkward +potion.prefix.flat=Flat +potion.prefix.bulky=Bulky +potion.prefix.bungling=Bungling +potion.prefix.buttered=Buttered +potion.prefix.smooth=Smooth +potion.prefix.suave=Suave +potion.prefix.debonair=Debonair +potion.prefix.thick=Thick +potion.prefix.elegant=Elegant +potion.prefix.fancy=Fancy +potion.prefix.charming=Charming +potion.prefix.dashing=Dashing +potion.prefix.refined=Refined +potion.prefix.cordial=Cordial +potion.prefix.sparkling=Sparkling +potion.prefix.potent=Potent +potion.prefix.foul=Foul +potion.prefix.odorless=Odorless +potion.prefix.rank=Rank +potion.prefix.harsh=Harsh +potion.prefix.acrid=Acrid +potion.prefix.gross=Gross +potion.prefix.stinky=Stinky + +enchantment.damage.all=Sharpness +enchantment.damage.undead=Smite +enchantment.damage.arthropods=Bane of Arthropods +enchantment.knockback=Knockback +enchantment.fire=Fire Aspect +enchantment.protect.all=Protection +enchantment.protect.fire=Fire Protection +enchantment.protect.fall=Feather Falling +enchantment.protect.explosion=Blast Protection +enchantment.protect.projectile=Projectile Protection +enchantment.oxygen=Respiration +enchantment.waterWorker=Aqua Affinity +enchantment.digging=Efficiency +enchantment.untouching=Silk Touch +enchantment.durability=Unbreaking +enchantment.lootBonus=Looting +enchantment.lootBonusDigger=Fortune +enchantment.arrowDamage=Power +enchantment.arrowFire=Flame +enchantment.arrowKnockback=Punch +enchantment.arrowInfinite=Infinity +enchantment.thorns=Thorns + +enchantment.level.1=I +enchantment.level.2=II +enchantment.level.3=III +enchantment.level.4=IV +enchantment.level.5=V +enchantment.level.6=VI +enchantment.level.7=VII +enchantment.level.8=VIII +enchantment.level.9=IX +enchantment.level.10=X + +gui.achievements=Achievements +gui.stats=Statistics + +stat.generalButton=General +stat.blocksButton=Blocks +stat.itemsButton=Items + +stat.used=Times Used +stat.mined=Times Mined +stat.depleted=Times Depleted +stat.crafted=Times Crafted + +stat.startGame=Times played +stat.createWorld=Worlds played +stat.loadWorld=Saves loaded +stat.joinMultiplayer=Multiplayer joins +stat.leaveGame=Games quit + +stat.playOneMinute=Minutes Played + +stat.walkOneCm=Distance Walked +stat.fallOneCm=Distance Fallen +stat.swimOneCm=Distance Swum +stat.flyOneCm=Distance Flown +stat.climbOneCm=Distance Climbed +stat.diveOneCm=Distance Dove +stat.minecartOneCm=Distance by Minecart +stat.boatOneCm=Distance by Boat +stat.pigOneCm=Distance by Pig +stat.jump=Jumps +stat.drop=Items Dropped + +stat.damageDealt=Damage Dealt +stat.damageTaken=Damage Taken +stat.deaths=Number of Deaths +stat.mobKills=Mob Kills +stat.playerKills=Player Kills +stat.fishCaught=Fish Caught + +stat.mineBlock=%1$s Mined +stat.craftItem=%1$s Crafted +stat.useItem=%1$s Used +stat.breakItem=%1$s Depleted + +achievement.get=Achievement get! + +achievement.taken=Taken! + +achievement.requires=Requires '%1$s' +achievement.openInventory=Taking Inventory +achievement.openInventory.desc=Press '%1$s' to open your inventory. +achievement.mineWood=Getting Wood +achievement.mineWood.desc=Attack a tree until a block of wood pops out +achievement.buildWorkBench=Benchmarking +achievement.buildWorkBench.desc=Craft a workbench with four blocks of planks +achievement.buildPickaxe=Time to Mine! +achievement.buildPickaxe.desc=Use planks and sticks to make a pickaxe +achievement.buildFurnace=Hot Topic +achievement.buildFurnace.desc=Construct a furnace out of eight stone blocks +achievement.acquireIron=Acquire Hardware +achievement.acquireIron.desc=Smelt an iron ingot +achievement.buildHoe=Time to Farm! +achievement.buildHoe.desc=Use planks and sticks to make a hoe +achievement.makeBread=Bake Bread +achievement.makeBread.desc=Turn wheat into bread +achievement.bakeCake=The Lie +achievement.bakeCake.desc=Wheat, sugar, milk and eggs! +achievement.buildBetterPickaxe=Getting an Upgrade +achievement.buildBetterPickaxe.desc=Construct a better pickaxe +achievement.cookFish=Delicious Fish +achievement.cookFish.desc=Catch and cook fish! +achievement.onARail=On A Rail +achievement.onARail.desc=Travel by minecart at least 1 km from where you started +achievement.buildSword=Time to Strike! +achievement.buildSword.desc=Use planks and sticks to make a sword +achievement.killEnemy=Monster Hunter +achievement.killEnemy.desc=Attack and destroy a monster +achievement.killCow=Cow Tipper +achievement.killCow.desc=Harvest some leather +achievement.flyPig=When Pigs Fly +achievement.flyPig.desc=Fly a pig off a cliff +achievement.snipeSkeleton=Sniper Duel +achievement.snipeSkeleton.desc=Kill a skeleton with an arrow from more than 50 meters +achievement.diamonds=DIAMONDS! +achievement.diamonds.desc=Acquire diamonds with your iron tools +achievement.portal=We Need to Go Deeper +achievement.portal.desc=Build a portal to the Nether +achievement.ghast=Return to Sender +achievement.ghast.desc=Destroy a Ghast with a fireball +achievement.blazeRod=Into Fire +achievement.blazeRod.desc=Relieve a Blaze of its rod +achievement.potion=Local Brewery +achievement.potion.desc=Brew a potion +achievement.theEnd=The End? +achievement.theEnd.desc=Locate the End +achievement.theEnd2=The End. +achievement.theEnd2.desc=Defeat the Ender Dragon +achievement.enchantments=Enchanter +achievement.enchantments.desc=Use a book, obsidian and diamonds to construct an enchantment table +achievement.overkill=Overkill +achievement.overkill.desc=Deal eight hearts of damage in a single hit +achievement.bookcase=Librarian +achievement.bookcase.desc=Build some bookshelves to improve your enchantment table + +commands.generic.exception=An unknown error occurred while attempting to perform this command +commands.generic.syntax=Invalid command syntax +commands.generic.player.notFound=That player cannot be found +commands.generic.notFound=Unknown command. Try /help for a list of commands. +commands.generic.num.invalid='%s' is not a valid number +commands.generic.num.tooSmall=The number you have entered (%d) is too small, it must be at least %d +commands.generic.num.tooBig=The number you have entered (%d) is too big, it must be at most %d +commands.generic.double.tooSmall=The number you have entered (%.2f) is too small, it must be at least %.2f +commands.generic.double.tooBig=The number you have entered (%.2f) is too big, it must be at most %.2f +commands.generic.usage=Usage: %s + +commands.xp.failure.widthdrawXp=Cannot give player negative experience points +commands.xp.success=Given %d experience to %s +commands.xp.success.levels=Given %d levels to %s +commands.xp.success.negative.levels=Taken %d levels from %s +commands.xp.usage=/xp [player] OR /xp L [player] +commands.give.usage=/give [amount] [data] +commands.give.notFound=There is no such item with ID %d +commands.give.success=Given %s (ID %d) * %d to %s +commands.effect.usage=/effect [seconds] [amplifier] +commands.effect.notFound=There is no such mob effect with ID %d +commands.effect.success=Given %1$s (ID %2$d) * %3$d to %4$s for %5$d seconds +commands.effect.success.removed=Took %1$s from %2$s +commands.effect.failure.notActive=Couldn't take %1$s from %2$s as they do not have the effect +commands.enchant.usage=/enchant [level] +commands.enchant.notFound=There is no such enchantment with ID %d +commands.enchant.noItem=The target doesn't hold an item +commands.enchant.cantEnchant=The selected enchantment can't be added to the target item +commands.enchant.cantCombine=%1$s can't be combined with %2$s +commands.enchant.success=Enchanting succeeded +commands.clear.usage=/clear [item] [data] +commands.clear.success=Cleared the inventory of %s, removing %d items +commands.clear.failure=Could not clear the inventory of %s, no items to remove +commands.downfall.success=Toggled downfall +commands.time.usage=/time +commands.time.added=Added %d to the time +commands.time.set=Set the time to %d +commands.players.list=There are %d/%d players online: +commands.banlist.ips=There are %d total banned IP addresses: +commands.banlist.players=There are %d total banned players: +commands.banlist.usage=/banlist [ips|players] +commands.kick.success=Kicked %s from the game +commands.kick.success.reason=Kicked %s from the game: '%s' +commands.kick.usage=/kick [reason ...] +commands.op.success=Opped %s +commands.op.usage=/op +commands.deop.success=De-opped %s +commands.deop.usage=/deop +commands.say.usage=/say +commands.ban.success=Banned player %s +commands.ban.usage=/ban [reason ...] +commands.unban.success=Unbanned player %s +commands.unban.usage=/pardon +commands.banip.invalid=You have entered an invalid IP address or a player that is not online +commands.banip.success=Banned IP address %s +commands.banip.success.players=Banned IP address %s belonging to %s +commands.banip.usage=/ban-ip [reason ...] +commands.unbanip.invalid=You have entered an invalid IP address +commands.unbanip.success=Unbanned IP address %s +commands.unbanip.usage=/pardon-ip
+commands.save.enabled=Turned on world auto-saving +commands.save.disabled=Turned off world auto-saving +commands.save.start=Saving... +commands.save.success=Saved the world +commands.save.failed=Saving failed: %s +commands.save.flushStart=Flushing all saves... +commands.save.flushEnd=Flushing completed +commands.stop.start=Stopping the server +commands.tp.success=Teleported %s to %s +commands.tp.success.coordinates=Teleported %s to %.2f,%.2f,%.2f +commands.tp.usage=/tp [target player] OR /tp [target player] +commands.tp.notSameDimension=Unable to teleport because players are not in the same dimension +commands.whitelist.list=There are %d (out of %d seen) whitelisted players: +commands.whitelist.enabled=Turned on the whitelist +commands.whitelist.disabled=Turned off the whitelist +commands.whitelist.reloaded=Reloaded the whitelist +commands.whitelist.add.success=Added %s to the whitelist +commands.whitelist.add.usage=/whitelist add +commands.whitelist.remove.success=Removed %s from the whitelist +commands.whitelist.remove.usage=/whitelist remove +commands.whitelist.usage=/whitelist +commands.scoreboard.usage=/scoreboard +commands.scoreboard.teamNotFound=No team was found by the name '%s' +commands.scoreboard.objectiveNotFound=No objective was found by the name '%s' +commands.scoreboard.objectiveReadOnly=The objective '%s' is read-only and cannot be set +commands.scoreboard.objectives.usage=/scoreboard objectives +commands.scoreboard.objectives.setdisplay.usage=/scoreboard objectives setdisplay [objective] +commands.scoreboard.objectives.setdisplay.invalidSlot=No such display slot '%s' +commands.scoreboard.objectives.setdisplay.successCleared=Cleared objective display slot '%s' +commands.scoreboard.objectives.setdisplay.successSet=Set the display objective in slot '%s' to '%s' +commands.scoreboard.objectives.add.usage=/scoreboard objectives add [display name ...] +commands.scoreboard.objectives.add.wrongType=Invalid objective criteria type. Valid types are: %s +commands.scoreboard.objectives.add.alreadyExists=An objective with the name '%s' already exists +commands.scoreboard.objectives.add.tooLong=The name '%s' is too long for an objective, it can be at most %d characters long +commands.scoreboard.objectives.add.displayTooLong=The display name '%s' is too long for an objective, it can be at most %d characters long +commands.scoreboard.objectives.add.success=Added new objective '%s' successfully +commands.scoreboard.objectives.remove.usage=/scoreboard objectives remove +commands.scoreboard.objectives.remove.success=Removed objective '%s' successfully +commands.scoreboard.objectives.list.count=Showing %d objective(s) on scoreboard +commands.scoreboard.objectives.list.entry=- %s: displays as '%s' and is type '%s' +commands.scoreboard.objectives.list.empty=There are no objectives on the scoreboard +commands.scoreboard.players.usage=/scoreboard players +commands.scoreboard.players.set.success=Set score of %s for player %s to %d +commands.scoreboard.players.set.usage=/scoreboard players set +commands.scoreboard.players.add.usage=/scoreboard players add +commands.scoreboard.players.remove.usage=/scoreboard players remove +commands.scoreboard.players.reset.usage=/scoreboard players reset +commands.scoreboard.players.reset.success=Reset all scores of player %s +commands.scoreboard.players.list.count=Showing %d tracked players on the scoreboard +commands.scoreboard.players.list.empty=There are no tracked players on the scoreboard +commands.scoreboard.players.list.player.count=Showing %d tracked objective(s) for %s +commands.scoreboard.players.list.player.entry=- %2$s: %1$d (%3$s) +commands.scoreboard.players.list.player.empty=Player %s has no scores recorded +commands.scoreboard.teams.usage=/scoreboard teams +commands.scoreboard.teams.add.usage=/scoreboard teams add [display name ...] +commands.scoreboard.teams.add.alreadyExists=A team with the name '%s' already exists +commands.scoreboard.teams.add.tooLong=The name '%s' is too long for a team, it can be at most %d characters long +commands.scoreboard.teams.add.displayTooLong=The display name '%s' is too long for a team, it can be at most %d characters long +commands.scoreboard.teams.add.success=Added new team '%s' successfully +commands.scoreboard.teams.list.usage=/scoreboard teams list [name] +commands.scoreboard.teams.list.count=Showing %d teams on the scoreboard +commands.scoreboard.teams.list.entry=- %1$s: '%2$s' has %3$d players +commands.scoreboard.teams.list.empty=There are no teams registered on the scoreboard +commands.scoreboard.teams.list.player.count=Showing %d player(s) in team %s +commands.scoreboard.teams.list.player.entry=- %2$s: %1$d (%3$s) +commands.scoreboard.teams.list.player.empty=Team %s has no players +commands.scoreboard.teams.empty.usage=/scoreboard teams clear +commands.scoreboard.teams.empty.alreadyEmpty=Team %s is already empty, cannot remove nonexistant players +commands.scoreboard.teams.empty.success=Removed all %d player(s) from team %s +commands.scoreboard.teams.remove.usage=/scoreboard teams remove +commands.scoreboard.teams.remove.success=Removed team %s +commands.scoreboard.teams.join.usage=/scoreboard teams join [player] +commands.scoreboard.teams.join.success=Added %d player(s) to team %s: %s +commands.scoreboard.teams.join.failure=Could not add %d player(s) to team %s: %s +commands.scoreboard.teams.leave.usage=/scoreboard teams leave [player] +commands.scoreboard.teams.leave.success=Removed %d player(s) from their teams: %s +commands.scoreboard.teams.leave.failure=Could not remove %d player(s) from their teams: %s +commands.scoreboard.teams.leave.noTeam=You are not in a team +commands.scoreboard.teams.option.usage=/scoreboard teams option +commands.scoreboard.teams.option.noValue=Valid values for option %s are: %s +commands.scoreboard.teams.option.success=Set option %s for team %s to %s +commands.gamemode.success.self=Set own game mode to %s +commands.gamemode.success.other=Set %s's game mode to %s +commands.gamemode.usage=/gamemode [player] +commands.defaultgamemode.usage=/defaultgamemode +commands.defaultgamemode.success=The world's default game mode is now %s +commands.me.usage=/me +commands.help.header=--- Showing help page %d of %d (/help ) --- +commands.help.footer=Tip: Use the key while typing a command to auto-complete the command or its arguments +commands.help.usage=/help [page|command name] +commands.publish.started=Local game hosted on %s +commands.publish.failed=Unable to host local game +commands.debug.start=Started debug profiling +commands.debug.stop=Stopped debug profiling after %.2f seconds (%d ticks) +commands.debug.notStarted=Can't stop profiling when we haven't started yet! +commands.debug.usage=/debug +commands.message.usage=/tell +commands.message.sameTarget=You can't send a private message to yourself! +commands.message.display.outgoing=You whisper to %s: %s +commands.message.display.incoming=%s whispers to you: %s +commands.difficulty.usage=/difficulty +commands.difficulty.success=Set game difficulty to %s +commands.spawnpoint.usage=/spawnpoint OR /spawnpoint OR /spawnpoint +commands.spawnpoint.success=Set %s's spawn point to (%d, %d, %d) +commands.gamerule.usage=/gamerule OR /gamerule +commands.gamerule.success=Game rule has been updated +commands.gamerule.norule=No game rule called '%s' is available +commands.weather.usage=/weather [duration in seconds] +commands.weather.clear=Changing to clear weather +commands.weather.rain=Changing to rainy weather +commands.weather.thunder=Changing to rain and thunder +commands.testfor.usage=/testfor +commands.testfor.failed=/testfor is only usable by commandblocks with analog output + +itemGroup.buildingBlocks=Building Blocks +itemGroup.decorations=Decoration Blocks +itemGroup.redstone=Redstone +itemGroup.transportation=Transportation +itemGroup.misc=Miscellaneous +itemGroup.search=Search Items +itemGroup.food=Foodstuffs +itemGroup.tools=Tools +itemGroup.combat=Combat +itemGroup.brewing=Brewing +itemGroup.materials=Materials +itemGroup.inventory=Survival Inventory + +inventory.binSlot=Destroy Item + +advMode.setCommand=Set Console Command for Block +advMode.command=Console Command +advMode.nearestPlayer=Use "@p" to target nearest player +advMode.randomPlayer=Use "@r" to target random player +advMode.allPlayers=Use "@a" to target all players + +advMode.notEnabled=Command blocks are not enabled on this server +advMode.notAllowed=Must be an opped player in creative mode + +mco.title=Minecraft Realms +mco.selectServer.select=Join World +mco.selectServer.configure=Configure +mco.selectServer.create=Create World +mco.selectServer.moreinfo=More Info + +mco.configure.world.edit.title=Edit World + +mco.configure.world.title=Configure World +mco.configure.world.name=Name +mco.configure.world.seed=World Seed (Optional) +mco.configure.world.description=Description +mco.configure.world.owner=Owner +mco.configure.world.status=Status +mco.configure.world.location=Location +mco.configure.world.invited=Invited +mco.configure.world.buttons.edit=Edit +mco.configure.world.buttons.reset=Reset World +mco.configure.world.buttons.done=Done +mco.configure.world.buttons.delete=Delete +mco.configure.world.buttons.open=Open World +mco.configure.world.buttons.close=Close World +mco.configure.world.buttons.invite=Invite +mco.configure.world.buttons.uninvite=Uninvite +mco.configure.world.buttons.subscription=Subscription +mco.configure.world.buttons.save=Save +mco.configure.world.buttons.settings=Settings... +mco.configure.world.invite.profile.name=Name +mco.configure.world.uninvite.question=Are you sure that you want to uninvite + +mco.configure.world.settings.title=Settings + +mco.configure.world.subscription.title=Subscription Info +mco.configure.world.subscription.daysleft=Days Left +mco.configure.world.subscription.start=Start Date +mco.configure.world.subscription.extend=Extend + +mco.create.world.location.title=Locations +mco.create.world.location.warning=You may not get the exact location you select +mco.create.world.wait=Creating the world... + +mco.reset.world.title=Reset World +mco.reset.world.warning=This will permanently delete your world! +mco.reset.world.seed=World Seed (Optional) +mco.reset.world.resetting.screen.title=Resetting World... + +mco.configure.world.close.question.line1=Your world will become unavailable. +mco.configure.world.close.question.line2=Are you sure you want to do that? + +mco.connect.connecting=Connecting to the online server... +mco.connect.authorizing=Logging in... +mco.connect.failed=Failed to connect to the online server + +mco.create.world=Create + +mco.gameMode=Game Mode +mco.gameMode.survival=Survival +mco.gameMode.survival.line1=Search for resources, crafting, gain +mco.gameMode.survival.line2=levels, health and hunger +mco.gameMode.creative=Creative +mco.gameMode.creative.line1=Unlimited resources, free flying and +mco.gameMode.creative.line2=destroy blocks instantly +mco.gameMode.adventure=Adventure +mco.gameMode.adventure.line1=Same as survival mode, but blocks can't +mco.gameMode.adventure.line2=be added or removed diff --git a/lwjgl-rundir/resources/misc/beacon.png b/lwjgl-rundir/resources/misc/beacon.png new file mode 100644 index 0000000..4b298c5 Binary files /dev/null and b/lwjgl-rundir/resources/misc/beacon.png differ diff --git a/lwjgl-rundir/resources/misc/beam.png b/lwjgl-rundir/resources/misc/beam.png new file mode 100644 index 0000000..2074211 Binary files /dev/null and b/lwjgl-rundir/resources/misc/beam.png differ diff --git a/lwjgl-rundir/resources/misc/dial.png b/lwjgl-rundir/resources/misc/dial.png new file mode 100644 index 0000000..56a4c01 Binary files /dev/null and b/lwjgl-rundir/resources/misc/dial.png differ diff --git a/lwjgl-rundir/resources/misc/explosion.png b/lwjgl-rundir/resources/misc/explosion.png new file mode 100644 index 0000000..3a368d6 Binary files /dev/null and b/lwjgl-rundir/resources/misc/explosion.png differ diff --git a/lwjgl-rundir/resources/misc/foliagecolor.png b/lwjgl-rundir/resources/misc/foliagecolor.png new file mode 100644 index 0000000..732f607 Binary files /dev/null and b/lwjgl-rundir/resources/misc/foliagecolor.png differ diff --git a/lwjgl-rundir/resources/misc/footprint.png b/lwjgl-rundir/resources/misc/footprint.png new file mode 100644 index 0000000..ebc17f6 Binary files /dev/null and b/lwjgl-rundir/resources/misc/footprint.png differ diff --git a/lwjgl-rundir/resources/misc/glint.png b/lwjgl-rundir/resources/misc/glint.png new file mode 100644 index 0000000..9e3782a Binary files /dev/null and b/lwjgl-rundir/resources/misc/glint.png differ diff --git a/lwjgl-rundir/resources/misc/grasscolor.png b/lwjgl-rundir/resources/misc/grasscolor.png new file mode 100644 index 0000000..6da0768 Binary files /dev/null and b/lwjgl-rundir/resources/misc/grasscolor.png differ diff --git a/lwjgl-rundir/resources/misc/laxcape.png b/lwjgl-rundir/resources/misc/laxcape.png new file mode 100644 index 0000000..78ff899 Binary files /dev/null and b/lwjgl-rundir/resources/misc/laxcape.png differ diff --git a/lwjgl-rundir/resources/misc/mapbg.png b/lwjgl-rundir/resources/misc/mapbg.png new file mode 100644 index 0000000..38dbccc Binary files /dev/null and b/lwjgl-rundir/resources/misc/mapbg.png differ diff --git a/lwjgl-rundir/resources/misc/mapicons.png b/lwjgl-rundir/resources/misc/mapicons.png new file mode 100644 index 0000000..8039e2e Binary files /dev/null and b/lwjgl-rundir/resources/misc/mapicons.png differ diff --git a/lwjgl-rundir/resources/misc/particlefield.png b/lwjgl-rundir/resources/misc/particlefield.png new file mode 100644 index 0000000..cee51eb Binary files /dev/null and b/lwjgl-rundir/resources/misc/particlefield.png differ diff --git a/lwjgl-rundir/resources/misc/pumpkinblur.png b/lwjgl-rundir/resources/misc/pumpkinblur.png new file mode 100644 index 0000000..63a8184 Binary files /dev/null and b/lwjgl-rundir/resources/misc/pumpkinblur.png differ diff --git a/lwjgl-rundir/resources/misc/shadow.png b/lwjgl-rundir/resources/misc/shadow.png new file mode 100644 index 0000000..d0c39e0 Binary files /dev/null and b/lwjgl-rundir/resources/misc/shadow.png differ diff --git a/lwjgl-rundir/resources/misc/tunnel.png b/lwjgl-rundir/resources/misc/tunnel.png new file mode 100644 index 0000000..53833da Binary files /dev/null and b/lwjgl-rundir/resources/misc/tunnel.png differ diff --git a/lwjgl-rundir/resources/misc/vignette.png b/lwjgl-rundir/resources/misc/vignette.png new file mode 100644 index 0000000..5371fda Binary files /dev/null and b/lwjgl-rundir/resources/misc/vignette.png differ diff --git a/lwjgl-rundir/resources/misc/water.png b/lwjgl-rundir/resources/misc/water.png new file mode 100644 index 0000000..0671a75 Binary files /dev/null and b/lwjgl-rundir/resources/misc/water.png differ diff --git a/lwjgl-rundir/resources/misc/watercolor.png b/lwjgl-rundir/resources/misc/watercolor.png new file mode 100644 index 0000000..3c83008 Binary files /dev/null and b/lwjgl-rundir/resources/misc/watercolor.png differ diff --git a/lwjgl-rundir/resources/mob/bat.png b/lwjgl-rundir/resources/mob/bat.png new file mode 100644 index 0000000..4c303e6 Binary files /dev/null and b/lwjgl-rundir/resources/mob/bat.png differ diff --git a/lwjgl-rundir/resources/mob/cat_black.png b/lwjgl-rundir/resources/mob/cat_black.png new file mode 100644 index 0000000..fc550dd Binary files /dev/null and b/lwjgl-rundir/resources/mob/cat_black.png differ diff --git a/lwjgl-rundir/resources/mob/cat_red.png b/lwjgl-rundir/resources/mob/cat_red.png new file mode 100644 index 0000000..db816ab Binary files /dev/null and b/lwjgl-rundir/resources/mob/cat_red.png differ diff --git a/lwjgl-rundir/resources/mob/cat_siamese.png b/lwjgl-rundir/resources/mob/cat_siamese.png new file mode 100644 index 0000000..d9b3fa3 Binary files /dev/null and b/lwjgl-rundir/resources/mob/cat_siamese.png differ diff --git a/lwjgl-rundir/resources/mob/cavespider.png b/lwjgl-rundir/resources/mob/cavespider.png new file mode 100644 index 0000000..4854846 Binary files /dev/null and b/lwjgl-rundir/resources/mob/cavespider.png differ diff --git a/lwjgl-rundir/resources/mob/char.png b/lwjgl-rundir/resources/mob/char.png new file mode 100644 index 0000000..1ffa3d1 Binary files /dev/null and b/lwjgl-rundir/resources/mob/char.png differ diff --git a/lwjgl-rundir/resources/mob/chicken.png b/lwjgl-rundir/resources/mob/chicken.png new file mode 100644 index 0000000..f320d27 Binary files /dev/null and b/lwjgl-rundir/resources/mob/chicken.png differ diff --git a/lwjgl-rundir/resources/mob/cow.png b/lwjgl-rundir/resources/mob/cow.png new file mode 100644 index 0000000..9b4bf2c Binary files /dev/null and b/lwjgl-rundir/resources/mob/cow.png differ diff --git a/lwjgl-rundir/resources/mob/creeper.png b/lwjgl-rundir/resources/mob/creeper.png new file mode 100644 index 0000000..6812afd Binary files /dev/null and b/lwjgl-rundir/resources/mob/creeper.png differ diff --git a/lwjgl-rundir/resources/mob/enderdragon/beam.png b/lwjgl-rundir/resources/mob/enderdragon/beam.png new file mode 100644 index 0000000..9fde0ff Binary files /dev/null and b/lwjgl-rundir/resources/mob/enderdragon/beam.png differ diff --git a/lwjgl-rundir/resources/mob/enderdragon/body.png b/lwjgl-rundir/resources/mob/enderdragon/body.png new file mode 100644 index 0000000..a5bd140 Binary files /dev/null and b/lwjgl-rundir/resources/mob/enderdragon/body.png differ diff --git a/lwjgl-rundir/resources/mob/enderdragon/crystal.png b/lwjgl-rundir/resources/mob/enderdragon/crystal.png new file mode 100644 index 0000000..2e1931d Binary files /dev/null and b/lwjgl-rundir/resources/mob/enderdragon/crystal.png differ diff --git a/lwjgl-rundir/resources/mob/enderdragon/dragon.png b/lwjgl-rundir/resources/mob/enderdragon/dragon.png new file mode 100644 index 0000000..d518de1 Binary files /dev/null and b/lwjgl-rundir/resources/mob/enderdragon/dragon.png differ diff --git a/lwjgl-rundir/resources/mob/enderdragon/ender.png b/lwjgl-rundir/resources/mob/enderdragon/ender.png new file mode 100644 index 0000000..8f79bb6 Binary files /dev/null and b/lwjgl-rundir/resources/mob/enderdragon/ender.png differ diff --git a/lwjgl-rundir/resources/mob/enderdragon/ender_eyes.png b/lwjgl-rundir/resources/mob/enderdragon/ender_eyes.png new file mode 100644 index 0000000..6104b6c Binary files /dev/null and b/lwjgl-rundir/resources/mob/enderdragon/ender_eyes.png differ diff --git a/lwjgl-rundir/resources/mob/enderdragon/shuffle.png b/lwjgl-rundir/resources/mob/enderdragon/shuffle.png new file mode 100644 index 0000000..5d32922 Binary files /dev/null and b/lwjgl-rundir/resources/mob/enderdragon/shuffle.png differ diff --git a/lwjgl-rundir/resources/mob/enderman.png b/lwjgl-rundir/resources/mob/enderman.png new file mode 100644 index 0000000..8ba482e Binary files /dev/null and b/lwjgl-rundir/resources/mob/enderman.png differ diff --git a/lwjgl-rundir/resources/mob/enderman_eyes.png b/lwjgl-rundir/resources/mob/enderman_eyes.png new file mode 100644 index 0000000..e0e78c0 Binary files /dev/null and b/lwjgl-rundir/resources/mob/enderman_eyes.png differ diff --git a/lwjgl-rundir/resources/mob/fire.png b/lwjgl-rundir/resources/mob/fire.png new file mode 100644 index 0000000..6e81f2a Binary files /dev/null and b/lwjgl-rundir/resources/mob/fire.png differ diff --git a/lwjgl-rundir/resources/mob/ghast.png b/lwjgl-rundir/resources/mob/ghast.png new file mode 100644 index 0000000..0f94446 Binary files /dev/null and b/lwjgl-rundir/resources/mob/ghast.png differ diff --git a/lwjgl-rundir/resources/mob/ghast_fire.png b/lwjgl-rundir/resources/mob/ghast_fire.png new file mode 100644 index 0000000..7771034 Binary files /dev/null and b/lwjgl-rundir/resources/mob/ghast_fire.png differ diff --git a/lwjgl-rundir/resources/mob/lava.png b/lwjgl-rundir/resources/mob/lava.png new file mode 100644 index 0000000..b3f646b Binary files /dev/null and b/lwjgl-rundir/resources/mob/lava.png differ diff --git a/lwjgl-rundir/resources/mob/ozelot.png b/lwjgl-rundir/resources/mob/ozelot.png new file mode 100644 index 0000000..3ea58db Binary files /dev/null and b/lwjgl-rundir/resources/mob/ozelot.png differ diff --git a/lwjgl-rundir/resources/mob/pig.png b/lwjgl-rundir/resources/mob/pig.png new file mode 100644 index 0000000..562c7bf Binary files /dev/null and b/lwjgl-rundir/resources/mob/pig.png differ diff --git a/lwjgl-rundir/resources/mob/pigman.png b/lwjgl-rundir/resources/mob/pigman.png new file mode 100644 index 0000000..e85e7d2 Binary files /dev/null and b/lwjgl-rundir/resources/mob/pigman.png differ diff --git a/lwjgl-rundir/resources/mob/pigzombie.png b/lwjgl-rundir/resources/mob/pigzombie.png new file mode 100644 index 0000000..d5dcf5c Binary files /dev/null and b/lwjgl-rundir/resources/mob/pigzombie.png differ diff --git a/lwjgl-rundir/resources/mob/redcow.png b/lwjgl-rundir/resources/mob/redcow.png new file mode 100644 index 0000000..0efc9bc Binary files /dev/null and b/lwjgl-rundir/resources/mob/redcow.png differ diff --git a/lwjgl-rundir/resources/mob/saddle.png b/lwjgl-rundir/resources/mob/saddle.png new file mode 100644 index 0000000..630d9a3 Binary files /dev/null and b/lwjgl-rundir/resources/mob/saddle.png differ diff --git a/lwjgl-rundir/resources/mob/sheep.png b/lwjgl-rundir/resources/mob/sheep.png new file mode 100644 index 0000000..24fd1d4 Binary files /dev/null and b/lwjgl-rundir/resources/mob/sheep.png differ diff --git a/lwjgl-rundir/resources/mob/sheep_fur.png b/lwjgl-rundir/resources/mob/sheep_fur.png new file mode 100644 index 0000000..2172afa Binary files /dev/null and b/lwjgl-rundir/resources/mob/sheep_fur.png differ diff --git a/lwjgl-rundir/resources/mob/silverfish.png b/lwjgl-rundir/resources/mob/silverfish.png new file mode 100644 index 0000000..1affbb1 Binary files /dev/null and b/lwjgl-rundir/resources/mob/silverfish.png differ diff --git a/lwjgl-rundir/resources/mob/skeleton.png b/lwjgl-rundir/resources/mob/skeleton.png new file mode 100644 index 0000000..88190f6 Binary files /dev/null and b/lwjgl-rundir/resources/mob/skeleton.png differ diff --git a/lwjgl-rundir/resources/mob/skeleton_wither.png b/lwjgl-rundir/resources/mob/skeleton_wither.png new file mode 100644 index 0000000..2b50af3 Binary files /dev/null and b/lwjgl-rundir/resources/mob/skeleton_wither.png differ diff --git a/lwjgl-rundir/resources/mob/slime.png b/lwjgl-rundir/resources/mob/slime.png new file mode 100644 index 0000000..a912163 Binary files /dev/null and b/lwjgl-rundir/resources/mob/slime.png differ diff --git a/lwjgl-rundir/resources/mob/snowman.png b/lwjgl-rundir/resources/mob/snowman.png new file mode 100644 index 0000000..6177178 Binary files /dev/null and b/lwjgl-rundir/resources/mob/snowman.png differ diff --git a/lwjgl-rundir/resources/mob/spider.png b/lwjgl-rundir/resources/mob/spider.png new file mode 100644 index 0000000..5311d91 Binary files /dev/null and b/lwjgl-rundir/resources/mob/spider.png differ diff --git a/lwjgl-rundir/resources/mob/spider_eyes.png b/lwjgl-rundir/resources/mob/spider_eyes.png new file mode 100644 index 0000000..d66dd7b Binary files /dev/null and b/lwjgl-rundir/resources/mob/spider_eyes.png differ diff --git a/lwjgl-rundir/resources/mob/squid.png b/lwjgl-rundir/resources/mob/squid.png new file mode 100644 index 0000000..f285388 Binary files /dev/null and b/lwjgl-rundir/resources/mob/squid.png differ diff --git a/lwjgl-rundir/resources/mob/villager.png b/lwjgl-rundir/resources/mob/villager.png new file mode 100644 index 0000000..b6c0a6d Binary files /dev/null and b/lwjgl-rundir/resources/mob/villager.png differ diff --git a/lwjgl-rundir/resources/mob/villager/butcher.png b/lwjgl-rundir/resources/mob/villager/butcher.png new file mode 100644 index 0000000..b85a302 Binary files /dev/null and b/lwjgl-rundir/resources/mob/villager/butcher.png differ diff --git a/lwjgl-rundir/resources/mob/villager/farmer.png b/lwjgl-rundir/resources/mob/villager/farmer.png new file mode 100644 index 0000000..221ee6c Binary files /dev/null and b/lwjgl-rundir/resources/mob/villager/farmer.png differ diff --git a/lwjgl-rundir/resources/mob/villager/librarian.png b/lwjgl-rundir/resources/mob/villager/librarian.png new file mode 100644 index 0000000..b6c4451 Binary files /dev/null and b/lwjgl-rundir/resources/mob/villager/librarian.png differ diff --git a/lwjgl-rundir/resources/mob/villager/priest.png b/lwjgl-rundir/resources/mob/villager/priest.png new file mode 100644 index 0000000..a072fd3 Binary files /dev/null and b/lwjgl-rundir/resources/mob/villager/priest.png differ diff --git a/lwjgl-rundir/resources/mob/villager/smith.png b/lwjgl-rundir/resources/mob/villager/smith.png new file mode 100644 index 0000000..ac86589 Binary files /dev/null and b/lwjgl-rundir/resources/mob/villager/smith.png differ diff --git a/lwjgl-rundir/resources/mob/villager/villager.png b/lwjgl-rundir/resources/mob/villager/villager.png new file mode 100644 index 0000000..2974ace Binary files /dev/null and b/lwjgl-rundir/resources/mob/villager/villager.png differ diff --git a/lwjgl-rundir/resources/mob/villager/witch.png b/lwjgl-rundir/resources/mob/villager/witch.png new file mode 100644 index 0000000..c8e0e93 Binary files /dev/null and b/lwjgl-rundir/resources/mob/villager/witch.png differ diff --git a/lwjgl-rundir/resources/mob/villager_golem.png b/lwjgl-rundir/resources/mob/villager_golem.png new file mode 100644 index 0000000..414fc9c Binary files /dev/null and b/lwjgl-rundir/resources/mob/villager_golem.png differ diff --git a/lwjgl-rundir/resources/mob/wither.png b/lwjgl-rundir/resources/mob/wither.png new file mode 100644 index 0000000..c9ccc0e Binary files /dev/null and b/lwjgl-rundir/resources/mob/wither.png differ diff --git a/lwjgl-rundir/resources/mob/wither_invul.png b/lwjgl-rundir/resources/mob/wither_invul.png new file mode 100644 index 0000000..c33fb79 Binary files /dev/null and b/lwjgl-rundir/resources/mob/wither_invul.png differ diff --git a/lwjgl-rundir/resources/mob/wolf.png b/lwjgl-rundir/resources/mob/wolf.png new file mode 100644 index 0000000..54b275e Binary files /dev/null and b/lwjgl-rundir/resources/mob/wolf.png differ diff --git a/lwjgl-rundir/resources/mob/wolf_angry.png b/lwjgl-rundir/resources/mob/wolf_angry.png new file mode 100644 index 0000000..87a95bd Binary files /dev/null and b/lwjgl-rundir/resources/mob/wolf_angry.png differ diff --git a/lwjgl-rundir/resources/mob/wolf_collar.png b/lwjgl-rundir/resources/mob/wolf_collar.png new file mode 100644 index 0000000..bbc7ce0 Binary files /dev/null and b/lwjgl-rundir/resources/mob/wolf_collar.png differ diff --git a/lwjgl-rundir/resources/mob/wolf_tame.png b/lwjgl-rundir/resources/mob/wolf_tame.png new file mode 100644 index 0000000..cef6321 Binary files /dev/null and b/lwjgl-rundir/resources/mob/wolf_tame.png differ diff --git a/lwjgl-rundir/resources/mob/zombie.png b/lwjgl-rundir/resources/mob/zombie.png new file mode 100644 index 0000000..b328902 Binary files /dev/null and b/lwjgl-rundir/resources/mob/zombie.png differ diff --git a/lwjgl-rundir/resources/mob/zombie_villager.png b/lwjgl-rundir/resources/mob/zombie_villager.png new file mode 100644 index 0000000..349f9c2 Binary files /dev/null and b/lwjgl-rundir/resources/mob/zombie_villager.png differ diff --git a/lwjgl-rundir/resources/pack.png b/lwjgl-rundir/resources/pack.png new file mode 100644 index 0000000..eb85750 Binary files /dev/null and b/lwjgl-rundir/resources/pack.png differ diff --git a/lwjgl-rundir/resources/pack.txt b/lwjgl-rundir/resources/pack.txt new file mode 100644 index 0000000..c14bb3b --- /dev/null +++ b/lwjgl-rundir/resources/pack.txt @@ -0,0 +1,2 @@ +The default look of Minecraft + diff --git a/lwjgl-rundir/resources/particles.png b/lwjgl-rundir/resources/particles.png new file mode 100644 index 0000000..19efa7c Binary files /dev/null and b/lwjgl-rundir/resources/particles.png differ diff --git a/lwjgl-rundir/resources/skins/01.default_steve.png b/lwjgl-rundir/resources/skins/01.default_steve.png new file mode 100644 index 0000000..7cfa08a Binary files /dev/null and b/lwjgl-rundir/resources/skins/01.default_steve.png differ diff --git a/lwjgl-rundir/resources/skins/02.default_alex.png b/lwjgl-rundir/resources/skins/02.default_alex.png new file mode 100644 index 0000000..b643fe2 Binary files /dev/null and b/lwjgl-rundir/resources/skins/02.default_alex.png differ diff --git a/lwjgl-rundir/resources/skins/03.tennis_steve.png b/lwjgl-rundir/resources/skins/03.tennis_steve.png new file mode 100644 index 0000000..41576e6 Binary files /dev/null and b/lwjgl-rundir/resources/skins/03.tennis_steve.png differ diff --git a/lwjgl-rundir/resources/skins/04.tennis_alex.png b/lwjgl-rundir/resources/skins/04.tennis_alex.png new file mode 100644 index 0000000..3f6abf7 Binary files /dev/null and b/lwjgl-rundir/resources/skins/04.tennis_alex.png differ diff --git a/lwjgl-rundir/resources/skins/05.tuxedo_steve.png b/lwjgl-rundir/resources/skins/05.tuxedo_steve.png new file mode 100644 index 0000000..b921f85 Binary files /dev/null and b/lwjgl-rundir/resources/skins/05.tuxedo_steve.png differ diff --git a/lwjgl-rundir/resources/skins/06.tuxedo_alex.png b/lwjgl-rundir/resources/skins/06.tuxedo_alex.png new file mode 100644 index 0000000..a0258ab Binary files /dev/null and b/lwjgl-rundir/resources/skins/06.tuxedo_alex.png differ diff --git a/lwjgl-rundir/resources/skins/07.athlete_steve.png b/lwjgl-rundir/resources/skins/07.athlete_steve.png new file mode 100644 index 0000000..c7a3986 Binary files /dev/null and b/lwjgl-rundir/resources/skins/07.athlete_steve.png differ diff --git a/lwjgl-rundir/resources/skins/08.athlete_alex.png b/lwjgl-rundir/resources/skins/08.athlete_alex.png new file mode 100644 index 0000000..a67a3c8 Binary files /dev/null and b/lwjgl-rundir/resources/skins/08.athlete_alex.png differ diff --git a/lwjgl-rundir/resources/skins/09.cyclist_steve.png b/lwjgl-rundir/resources/skins/09.cyclist_steve.png new file mode 100644 index 0000000..7da2003 Binary files /dev/null and b/lwjgl-rundir/resources/skins/09.cyclist_steve.png differ diff --git a/lwjgl-rundir/resources/skins/10.cyclist_alex.png b/lwjgl-rundir/resources/skins/10.cyclist_alex.png new file mode 100644 index 0000000..20461a7 Binary files /dev/null and b/lwjgl-rundir/resources/skins/10.cyclist_alex.png differ diff --git a/lwjgl-rundir/resources/skins/11.boxer_steve.png b/lwjgl-rundir/resources/skins/11.boxer_steve.png new file mode 100644 index 0000000..5018dc4 Binary files /dev/null and b/lwjgl-rundir/resources/skins/11.boxer_steve.png differ diff --git a/lwjgl-rundir/resources/skins/12.boxer_alex.png b/lwjgl-rundir/resources/skins/12.boxer_alex.png new file mode 100644 index 0000000..cb20ba3 Binary files /dev/null and b/lwjgl-rundir/resources/skins/12.boxer_alex.png differ diff --git a/lwjgl-rundir/resources/skins/13.prisoner_steve.png b/lwjgl-rundir/resources/skins/13.prisoner_steve.png new file mode 100644 index 0000000..4cc80ac Binary files /dev/null and b/lwjgl-rundir/resources/skins/13.prisoner_steve.png differ diff --git a/lwjgl-rundir/resources/skins/14.prisoner_alex.png b/lwjgl-rundir/resources/skins/14.prisoner_alex.png new file mode 100644 index 0000000..a81c05f Binary files /dev/null and b/lwjgl-rundir/resources/skins/14.prisoner_alex.png differ diff --git a/lwjgl-rundir/resources/skins/15.scottish_steve.png b/lwjgl-rundir/resources/skins/15.scottish_steve.png new file mode 100644 index 0000000..25dcfec Binary files /dev/null and b/lwjgl-rundir/resources/skins/15.scottish_steve.png differ diff --git a/lwjgl-rundir/resources/skins/16.scottish_alex.png b/lwjgl-rundir/resources/skins/16.scottish_alex.png new file mode 100644 index 0000000..a73a931 Binary files /dev/null and b/lwjgl-rundir/resources/skins/16.scottish_alex.png differ diff --git a/lwjgl-rundir/resources/skins/17.dev_steve.png b/lwjgl-rundir/resources/skins/17.dev_steve.png new file mode 100644 index 0000000..652a7c4 Binary files /dev/null and b/lwjgl-rundir/resources/skins/17.dev_steve.png differ diff --git a/lwjgl-rundir/resources/skins/18.dev_alex.png b/lwjgl-rundir/resources/skins/18.dev_alex.png new file mode 100644 index 0000000..9db32e3 Binary files /dev/null and b/lwjgl-rundir/resources/skins/18.dev_alex.png differ diff --git a/lwjgl-rundir/resources/skins/19.herobrine.png b/lwjgl-rundir/resources/skins/19.herobrine.png new file mode 100644 index 0000000..a449fc1 Binary files /dev/null and b/lwjgl-rundir/resources/skins/19.herobrine.png differ diff --git a/lwjgl-rundir/resources/skins/20.barney.png b/lwjgl-rundir/resources/skins/20.barney.png new file mode 100644 index 0000000..c209a62 Binary files /dev/null and b/lwjgl-rundir/resources/skins/20.barney.png differ diff --git a/lwjgl-rundir/resources/skins/21.slime.png b/lwjgl-rundir/resources/skins/21.slime.png new file mode 100644 index 0000000..3a89af2 Binary files /dev/null and b/lwjgl-rundir/resources/skins/21.slime.png differ diff --git a/lwjgl-rundir/resources/skins/22.noob.png b/lwjgl-rundir/resources/skins/22.noob.png new file mode 100644 index 0000000..f0c2c01 Binary files /dev/null and b/lwjgl-rundir/resources/skins/22.noob.png differ diff --git a/lwjgl-rundir/resources/skins/23.trump.png b/lwjgl-rundir/resources/skins/23.trump.png new file mode 100644 index 0000000..71a6c6b Binary files /dev/null and b/lwjgl-rundir/resources/skins/23.trump.png differ diff --git a/lwjgl-rundir/resources/skins/24.notch.png b/lwjgl-rundir/resources/skins/24.notch.png new file mode 100644 index 0000000..374923f Binary files /dev/null and b/lwjgl-rundir/resources/skins/24.notch.png differ diff --git a/lwjgl-rundir/resources/skins/25.creeper.png b/lwjgl-rundir/resources/skins/25.creeper.png new file mode 100644 index 0000000..a71add5 Binary files /dev/null and b/lwjgl-rundir/resources/skins/25.creeper.png differ diff --git a/lwjgl-rundir/resources/skins/26.zombie.png b/lwjgl-rundir/resources/skins/26.zombie.png new file mode 100644 index 0000000..9c57fb0 Binary files /dev/null and b/lwjgl-rundir/resources/skins/26.zombie.png differ diff --git a/lwjgl-rundir/resources/skins/27.pig.png b/lwjgl-rundir/resources/skins/27.pig.png new file mode 100644 index 0000000..ad08bb5 Binary files /dev/null and b/lwjgl-rundir/resources/skins/27.pig.png differ diff --git a/lwjgl-rundir/resources/skins/28.squid.png b/lwjgl-rundir/resources/skins/28.squid.png new file mode 100644 index 0000000..23f1b23 Binary files /dev/null and b/lwjgl-rundir/resources/skins/28.squid.png differ diff --git a/lwjgl-rundir/resources/skins/29.mooshroom.png b/lwjgl-rundir/resources/skins/29.mooshroom.png new file mode 100644 index 0000000..e32b9b0 Binary files /dev/null and b/lwjgl-rundir/resources/skins/29.mooshroom.png differ diff --git a/lwjgl-rundir/resources/sounds/ambient/cave/cave1.mp3 b/lwjgl-rundir/resources/sounds/ambient/cave/cave1.mp3 new file mode 100644 index 0000000..e3e9223 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/cave/cave1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/cave/cave10.mp3 b/lwjgl-rundir/resources/sounds/ambient/cave/cave10.mp3 new file mode 100644 index 0000000..61a79e8 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/cave/cave10.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/cave/cave11.mp3 b/lwjgl-rundir/resources/sounds/ambient/cave/cave11.mp3 new file mode 100644 index 0000000..a320b03 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/cave/cave11.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/cave/cave12.mp3 b/lwjgl-rundir/resources/sounds/ambient/cave/cave12.mp3 new file mode 100644 index 0000000..0ca27bf Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/cave/cave12.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/cave/cave13.mp3 b/lwjgl-rundir/resources/sounds/ambient/cave/cave13.mp3 new file mode 100644 index 0000000..a5cfb14 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/cave/cave13.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/cave/cave2.mp3 b/lwjgl-rundir/resources/sounds/ambient/cave/cave2.mp3 new file mode 100644 index 0000000..b2264bb Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/cave/cave2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/cave/cave3.mp3 b/lwjgl-rundir/resources/sounds/ambient/cave/cave3.mp3 new file mode 100644 index 0000000..cff05c3 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/cave/cave3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/cave/cave4.mp3 b/lwjgl-rundir/resources/sounds/ambient/cave/cave4.mp3 new file mode 100644 index 0000000..89901bf Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/cave/cave4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/cave/cave5.mp3 b/lwjgl-rundir/resources/sounds/ambient/cave/cave5.mp3 new file mode 100644 index 0000000..bede086 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/cave/cave5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/cave/cave6.mp3 b/lwjgl-rundir/resources/sounds/ambient/cave/cave6.mp3 new file mode 100644 index 0000000..f50d379 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/cave/cave6.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/cave/cave7.mp3 b/lwjgl-rundir/resources/sounds/ambient/cave/cave7.mp3 new file mode 100644 index 0000000..712f682 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/cave/cave7.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/cave/cave8.mp3 b/lwjgl-rundir/resources/sounds/ambient/cave/cave8.mp3 new file mode 100644 index 0000000..65f6ac8 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/cave/cave8.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/cave/cave9.mp3 b/lwjgl-rundir/resources/sounds/ambient/cave/cave9.mp3 new file mode 100644 index 0000000..7c2562e Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/cave/cave9.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/weather/rain1.mp3 b/lwjgl-rundir/resources/sounds/ambient/weather/rain1.mp3 new file mode 100644 index 0000000..128610d Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/weather/rain1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/weather/rain2.mp3 b/lwjgl-rundir/resources/sounds/ambient/weather/rain2.mp3 new file mode 100644 index 0000000..a8bc443 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/weather/rain2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/weather/rain3.mp3 b/lwjgl-rundir/resources/sounds/ambient/weather/rain3.mp3 new file mode 100644 index 0000000..1a7433e Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/weather/rain3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/weather/rain4.mp3 b/lwjgl-rundir/resources/sounds/ambient/weather/rain4.mp3 new file mode 100644 index 0000000..eda95ae Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/weather/rain4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/weather/thunder1.mp3 b/lwjgl-rundir/resources/sounds/ambient/weather/thunder1.mp3 new file mode 100644 index 0000000..0279802 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/weather/thunder1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/weather/thunder2.mp3 b/lwjgl-rundir/resources/sounds/ambient/weather/thunder2.mp3 new file mode 100644 index 0000000..94d1b13 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/weather/thunder2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/ambient/weather/thunder3.mp3 b/lwjgl-rundir/resources/sounds/ambient/weather/thunder3.mp3 new file mode 100644 index 0000000..051da57 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/ambient/weather/thunder3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/damage/fallbig.mp3 b/lwjgl-rundir/resources/sounds/damage/fallbig.mp3 new file mode 100644 index 0000000..4f7f15f Binary files /dev/null and b/lwjgl-rundir/resources/sounds/damage/fallbig.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/damage/fallbig1.mp3 b/lwjgl-rundir/resources/sounds/damage/fallbig1.mp3 new file mode 100644 index 0000000..b460fc0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/damage/fallbig1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/damage/fallbig2.mp3 b/lwjgl-rundir/resources/sounds/damage/fallbig2.mp3 new file mode 100644 index 0000000..0f64fa8 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/damage/fallbig2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/damage/fallsmall.mp3 b/lwjgl-rundir/resources/sounds/damage/fallsmall.mp3 new file mode 100644 index 0000000..209f596 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/damage/fallsmall.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/damage/hit1.mp3 b/lwjgl-rundir/resources/sounds/damage/hit1.mp3 new file mode 100644 index 0000000..1bbe8ce Binary files /dev/null and b/lwjgl-rundir/resources/sounds/damage/hit1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/damage/hit2.mp3 b/lwjgl-rundir/resources/sounds/damage/hit2.mp3 new file mode 100644 index 0000000..c2db1a0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/damage/hit2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/damage/hit3.mp3 b/lwjgl-rundir/resources/sounds/damage/hit3.mp3 new file mode 100644 index 0000000..f1491c1 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/damage/hit3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/damage/hurtflesh1.mp3 b/lwjgl-rundir/resources/sounds/damage/hurtflesh1.mp3 new file mode 100644 index 0000000..c419f98 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/damage/hurtflesh1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/damage/hurtflesh2.mp3 b/lwjgl-rundir/resources/sounds/damage/hurtflesh2.mp3 new file mode 100644 index 0000000..0354ff5 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/damage/hurtflesh2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/damage/hurtflesh3.mp3 b/lwjgl-rundir/resources/sounds/damage/hurtflesh3.mp3 new file mode 100644 index 0000000..b3e433f Binary files /dev/null and b/lwjgl-rundir/resources/sounds/damage/hurtflesh3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/cloth1.mp3 b/lwjgl-rundir/resources/sounds/dig/cloth1.mp3 new file mode 100644 index 0000000..3437e45 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/cloth1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/cloth2.mp3 b/lwjgl-rundir/resources/sounds/dig/cloth2.mp3 new file mode 100644 index 0000000..2e4afd6 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/cloth2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/cloth3.mp3 b/lwjgl-rundir/resources/sounds/dig/cloth3.mp3 new file mode 100644 index 0000000..0a67aa2 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/cloth3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/cloth4.mp3 b/lwjgl-rundir/resources/sounds/dig/cloth4.mp3 new file mode 100644 index 0000000..1d99a59 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/cloth4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/grass1.mp3 b/lwjgl-rundir/resources/sounds/dig/grass1.mp3 new file mode 100644 index 0000000..b86a155 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/grass1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/grass2.mp3 b/lwjgl-rundir/resources/sounds/dig/grass2.mp3 new file mode 100644 index 0000000..24256d9 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/grass2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/grass3.mp3 b/lwjgl-rundir/resources/sounds/dig/grass3.mp3 new file mode 100644 index 0000000..5c2485b Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/grass3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/grass4.mp3 b/lwjgl-rundir/resources/sounds/dig/grass4.mp3 new file mode 100644 index 0000000..bbd4e6f Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/grass4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/gravel1.mp3 b/lwjgl-rundir/resources/sounds/dig/gravel1.mp3 new file mode 100644 index 0000000..41c4cf9 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/gravel1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/gravel2.mp3 b/lwjgl-rundir/resources/sounds/dig/gravel2.mp3 new file mode 100644 index 0000000..313cd8b Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/gravel2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/gravel3.mp3 b/lwjgl-rundir/resources/sounds/dig/gravel3.mp3 new file mode 100644 index 0000000..3bc516d Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/gravel3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/gravel4.mp3 b/lwjgl-rundir/resources/sounds/dig/gravel4.mp3 new file mode 100644 index 0000000..bcf0243 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/gravel4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/sand1.mp3 b/lwjgl-rundir/resources/sounds/dig/sand1.mp3 new file mode 100644 index 0000000..76eb51f Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/sand1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/sand2.mp3 b/lwjgl-rundir/resources/sounds/dig/sand2.mp3 new file mode 100644 index 0000000..825e676 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/sand2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/sand3.mp3 b/lwjgl-rundir/resources/sounds/dig/sand3.mp3 new file mode 100644 index 0000000..dd961fd Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/sand3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/sand4.mp3 b/lwjgl-rundir/resources/sounds/dig/sand4.mp3 new file mode 100644 index 0000000..6237152 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/sand4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/snow1.mp3 b/lwjgl-rundir/resources/sounds/dig/snow1.mp3 new file mode 100644 index 0000000..64c4e92 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/snow1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/snow2.mp3 b/lwjgl-rundir/resources/sounds/dig/snow2.mp3 new file mode 100644 index 0000000..73e8415 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/snow2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/snow3.mp3 b/lwjgl-rundir/resources/sounds/dig/snow3.mp3 new file mode 100644 index 0000000..d1938c3 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/snow3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/snow4.mp3 b/lwjgl-rundir/resources/sounds/dig/snow4.mp3 new file mode 100644 index 0000000..fc93425 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/snow4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/stone1.mp3 b/lwjgl-rundir/resources/sounds/dig/stone1.mp3 new file mode 100644 index 0000000..f463f96 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/stone1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/stone2.mp3 b/lwjgl-rundir/resources/sounds/dig/stone2.mp3 new file mode 100644 index 0000000..c411fae Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/stone2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/stone3.mp3 b/lwjgl-rundir/resources/sounds/dig/stone3.mp3 new file mode 100644 index 0000000..565d611 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/stone3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/stone4.mp3 b/lwjgl-rundir/resources/sounds/dig/stone4.mp3 new file mode 100644 index 0000000..a702f9a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/stone4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/wood1.mp3 b/lwjgl-rundir/resources/sounds/dig/wood1.mp3 new file mode 100644 index 0000000..8d33c7e Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/wood1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/wood2.mp3 b/lwjgl-rundir/resources/sounds/dig/wood2.mp3 new file mode 100644 index 0000000..cf89ff0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/wood2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/wood3.mp3 b/lwjgl-rundir/resources/sounds/dig/wood3.mp3 new file mode 100644 index 0000000..69b0a63 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/wood3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/dig/wood4.mp3 b/lwjgl-rundir/resources/sounds/dig/wood4.mp3 new file mode 100644 index 0000000..4760697 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/dig/wood4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/fire/fire.mp3 b/lwjgl-rundir/resources/sounds/fire/fire.mp3 new file mode 100644 index 0000000..0120f09 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/fire/fire.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/fire/ignite.mp3 b/lwjgl-rundir/resources/sounds/fire/ignite.mp3 new file mode 100644 index 0000000..6987924 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/fire/ignite.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/fireworks/blast1.mp3 b/lwjgl-rundir/resources/sounds/fireworks/blast1.mp3 new file mode 100644 index 0000000..e530a50 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/fireworks/blast1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/fireworks/blast_far1.mp3 b/lwjgl-rundir/resources/sounds/fireworks/blast_far1.mp3 new file mode 100644 index 0000000..af4755e Binary files /dev/null and b/lwjgl-rundir/resources/sounds/fireworks/blast_far1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/fireworks/largeBlast1.mp3 b/lwjgl-rundir/resources/sounds/fireworks/largeBlast1.mp3 new file mode 100644 index 0000000..7907845 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/fireworks/largeBlast1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/fireworks/largeBlast_far1.mp3 b/lwjgl-rundir/resources/sounds/fireworks/largeBlast_far1.mp3 new file mode 100644 index 0000000..7ddf049 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/fireworks/largeBlast_far1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/fireworks/launch1.mp3 b/lwjgl-rundir/resources/sounds/fireworks/launch1.mp3 new file mode 100644 index 0000000..b7ebda9 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/fireworks/launch1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/fireworks/twinkle1.mp3 b/lwjgl-rundir/resources/sounds/fireworks/twinkle1.mp3 new file mode 100644 index 0000000..8e8bdad Binary files /dev/null and b/lwjgl-rundir/resources/sounds/fireworks/twinkle1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/fireworks/twinkle_far1.mp3 b/lwjgl-rundir/resources/sounds/fireworks/twinkle_far1.mp3 new file mode 100644 index 0000000..84c5878 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/fireworks/twinkle_far1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/gta.mp3 b/lwjgl-rundir/resources/sounds/gta.mp3 new file mode 100644 index 0000000..ce57335 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/gta.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/liquid/lava.mp3 b/lwjgl-rundir/resources/sounds/liquid/lava.mp3 new file mode 100644 index 0000000..3051f14 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/liquid/lava.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/liquid/lavapop.mp3 b/lwjgl-rundir/resources/sounds/liquid/lavapop.mp3 new file mode 100644 index 0000000..ab943e6 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/liquid/lavapop.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/liquid/splash1.mp3 b/lwjgl-rundir/resources/sounds/liquid/splash1.mp3 new file mode 100644 index 0000000..bc6c4ca Binary files /dev/null and b/lwjgl-rundir/resources/sounds/liquid/splash1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/liquid/splash2.mp3 b/lwjgl-rundir/resources/sounds/liquid/splash2.mp3 new file mode 100644 index 0000000..0dc932a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/liquid/splash2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/liquid/swim1.mp3 b/lwjgl-rundir/resources/sounds/liquid/swim1.mp3 new file mode 100644 index 0000000..4fdfccf Binary files /dev/null and b/lwjgl-rundir/resources/sounds/liquid/swim1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/liquid/swim2.mp3 b/lwjgl-rundir/resources/sounds/liquid/swim2.mp3 new file mode 100644 index 0000000..f910c2e Binary files /dev/null and b/lwjgl-rundir/resources/sounds/liquid/swim2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/liquid/swim3.mp3 b/lwjgl-rundir/resources/sounds/liquid/swim3.mp3 new file mode 100644 index 0000000..809ecd8 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/liquid/swim3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/liquid/swim4.mp3 b/lwjgl-rundir/resources/sounds/liquid/swim4.mp3 new file mode 100644 index 0000000..f054db0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/liquid/swim4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/liquid/water.mp3 b/lwjgl-rundir/resources/sounds/liquid/water.mp3 new file mode 100644 index 0000000..37a59c7 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/liquid/water.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/minecart/base.mp3 b/lwjgl-rundir/resources/sounds/minecart/base.mp3 new file mode 100644 index 0000000..bc029e3 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/minecart/base.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/minecart/inside.mp3 b/lwjgl-rundir/resources/sounds/minecart/inside.mp3 new file mode 100644 index 0000000..0aa7991 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/minecart/inside.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/bat/death.mp3 b/lwjgl-rundir/resources/sounds/mob/bat/death.mp3 new file mode 100644 index 0000000..2027d81 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/bat/death.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/bat/hurt1.mp3 b/lwjgl-rundir/resources/sounds/mob/bat/hurt1.mp3 new file mode 100644 index 0000000..a13db8d Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/bat/hurt1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/bat/hurt2.mp3 b/lwjgl-rundir/resources/sounds/mob/bat/hurt2.mp3 new file mode 100644 index 0000000..52f9a34 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/bat/hurt2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/bat/hurt3.mp3 b/lwjgl-rundir/resources/sounds/mob/bat/hurt3.mp3 new file mode 100644 index 0000000..216ed07 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/bat/hurt3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/bat/hurt4.mp3 b/lwjgl-rundir/resources/sounds/mob/bat/hurt4.mp3 new file mode 100644 index 0000000..a6013c6 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/bat/hurt4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/bat/idle1.mp3 b/lwjgl-rundir/resources/sounds/mob/bat/idle1.mp3 new file mode 100644 index 0000000..281ce6d Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/bat/idle1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/bat/idle2.mp3 b/lwjgl-rundir/resources/sounds/mob/bat/idle2.mp3 new file mode 100644 index 0000000..7236f31 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/bat/idle2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/bat/idle3.mp3 b/lwjgl-rundir/resources/sounds/mob/bat/idle3.mp3 new file mode 100644 index 0000000..18caafb Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/bat/idle3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/bat/idle4.mp3 b/lwjgl-rundir/resources/sounds/mob/bat/idle4.mp3 new file mode 100644 index 0000000..3bb1614 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/bat/idle4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/bat/loop.mp3 b/lwjgl-rundir/resources/sounds/mob/bat/loop.mp3 new file mode 100644 index 0000000..ad2efce Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/bat/loop.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/bat/takeoff.mp3 b/lwjgl-rundir/resources/sounds/mob/bat/takeoff.mp3 new file mode 100644 index 0000000..377126a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/bat/takeoff.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/blaze/breathe1.mp3 b/lwjgl-rundir/resources/sounds/mob/blaze/breathe1.mp3 new file mode 100644 index 0000000..395011c Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/blaze/breathe1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/blaze/breathe2.mp3 b/lwjgl-rundir/resources/sounds/mob/blaze/breathe2.mp3 new file mode 100644 index 0000000..5c2a9d6 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/blaze/breathe2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/blaze/breathe3.mp3 b/lwjgl-rundir/resources/sounds/mob/blaze/breathe3.mp3 new file mode 100644 index 0000000..54f0126 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/blaze/breathe3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/blaze/breathe4.mp3 b/lwjgl-rundir/resources/sounds/mob/blaze/breathe4.mp3 new file mode 100644 index 0000000..308c958 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/blaze/breathe4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/blaze/death.mp3 b/lwjgl-rundir/resources/sounds/mob/blaze/death.mp3 new file mode 100644 index 0000000..6be1d8f Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/blaze/death.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/blaze/hit1.mp3 b/lwjgl-rundir/resources/sounds/mob/blaze/hit1.mp3 new file mode 100644 index 0000000..68ceb94 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/blaze/hit1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/blaze/hit2.mp3 b/lwjgl-rundir/resources/sounds/mob/blaze/hit2.mp3 new file mode 100644 index 0000000..8dbf5df Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/blaze/hit2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/blaze/hit3.mp3 b/lwjgl-rundir/resources/sounds/mob/blaze/hit3.mp3 new file mode 100644 index 0000000..e43a803 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/blaze/hit3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/blaze/hit4.mp3 b/lwjgl-rundir/resources/sounds/mob/blaze/hit4.mp3 new file mode 100644 index 0000000..0e44565 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/blaze/hit4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cat/hiss1.mp3 b/lwjgl-rundir/resources/sounds/mob/cat/hiss1.mp3 new file mode 100644 index 0000000..fd6e8b7 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cat/hiss1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cat/hiss2.mp3 b/lwjgl-rundir/resources/sounds/mob/cat/hiss2.mp3 new file mode 100644 index 0000000..20aeab0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cat/hiss2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cat/hiss3.mp3 b/lwjgl-rundir/resources/sounds/mob/cat/hiss3.mp3 new file mode 100644 index 0000000..d113056 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cat/hiss3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cat/hitt1.mp3 b/lwjgl-rundir/resources/sounds/mob/cat/hitt1.mp3 new file mode 100644 index 0000000..6d49516 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cat/hitt1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cat/hitt2.mp3 b/lwjgl-rundir/resources/sounds/mob/cat/hitt2.mp3 new file mode 100644 index 0000000..7f3bf9a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cat/hitt2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cat/hitt3.mp3 b/lwjgl-rundir/resources/sounds/mob/cat/hitt3.mp3 new file mode 100644 index 0000000..bf89606 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cat/hitt3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cat/meow1.mp3 b/lwjgl-rundir/resources/sounds/mob/cat/meow1.mp3 new file mode 100644 index 0000000..f55e126 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cat/meow1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cat/meow2.mp3 b/lwjgl-rundir/resources/sounds/mob/cat/meow2.mp3 new file mode 100644 index 0000000..b97e5c9 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cat/meow2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cat/meow3.mp3 b/lwjgl-rundir/resources/sounds/mob/cat/meow3.mp3 new file mode 100644 index 0000000..b6305db Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cat/meow3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cat/meow4.mp3 b/lwjgl-rundir/resources/sounds/mob/cat/meow4.mp3 new file mode 100644 index 0000000..01e5da5 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cat/meow4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cat/purr1.mp3 b/lwjgl-rundir/resources/sounds/mob/cat/purr1.mp3 new file mode 100644 index 0000000..8c7aca8 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cat/purr1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cat/purr2.mp3 b/lwjgl-rundir/resources/sounds/mob/cat/purr2.mp3 new file mode 100644 index 0000000..51bc040 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cat/purr2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cat/purr3.mp3 b/lwjgl-rundir/resources/sounds/mob/cat/purr3.mp3 new file mode 100644 index 0000000..2f13ae8 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cat/purr3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cat/purreow1.mp3 b/lwjgl-rundir/resources/sounds/mob/cat/purreow1.mp3 new file mode 100644 index 0000000..b3e8d95 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cat/purreow1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cat/purreow2.mp3 b/lwjgl-rundir/resources/sounds/mob/cat/purreow2.mp3 new file mode 100644 index 0000000..82940d7 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cat/purreow2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/chicken/hurt1.mp3 b/lwjgl-rundir/resources/sounds/mob/chicken/hurt1.mp3 new file mode 100644 index 0000000..97f07c0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/chicken/hurt1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/chicken/hurt2.mp3 b/lwjgl-rundir/resources/sounds/mob/chicken/hurt2.mp3 new file mode 100644 index 0000000..ba0b2f7 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/chicken/hurt2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/chicken/plop.mp3 b/lwjgl-rundir/resources/sounds/mob/chicken/plop.mp3 new file mode 100644 index 0000000..ce61a5c Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/chicken/plop.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/chicken/say1.mp3 b/lwjgl-rundir/resources/sounds/mob/chicken/say1.mp3 new file mode 100644 index 0000000..5ee7850 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/chicken/say1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/chicken/say2.mp3 b/lwjgl-rundir/resources/sounds/mob/chicken/say2.mp3 new file mode 100644 index 0000000..8309bc9 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/chicken/say2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/chicken/say3.mp3 b/lwjgl-rundir/resources/sounds/mob/chicken/say3.mp3 new file mode 100644 index 0000000..67e9305 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/chicken/say3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/chicken/step1.mp3 b/lwjgl-rundir/resources/sounds/mob/chicken/step1.mp3 new file mode 100644 index 0000000..bc810f2 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/chicken/step1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/chicken/step2.mp3 b/lwjgl-rundir/resources/sounds/mob/chicken/step2.mp3 new file mode 100644 index 0000000..d52acad Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/chicken/step2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cow/hurt1.mp3 b/lwjgl-rundir/resources/sounds/mob/cow/hurt1.mp3 new file mode 100644 index 0000000..3230316 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cow/hurt1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cow/hurt2.mp3 b/lwjgl-rundir/resources/sounds/mob/cow/hurt2.mp3 new file mode 100644 index 0000000..f5203be Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cow/hurt2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cow/hurt3.mp3 b/lwjgl-rundir/resources/sounds/mob/cow/hurt3.mp3 new file mode 100644 index 0000000..14d6291 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cow/hurt3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cow/say1.mp3 b/lwjgl-rundir/resources/sounds/mob/cow/say1.mp3 new file mode 100644 index 0000000..eeb486f Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cow/say1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cow/say2.mp3 b/lwjgl-rundir/resources/sounds/mob/cow/say2.mp3 new file mode 100644 index 0000000..dadfb6c Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cow/say2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cow/say3.mp3 b/lwjgl-rundir/resources/sounds/mob/cow/say3.mp3 new file mode 100644 index 0000000..b43ade9 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cow/say3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cow/say4.mp3 b/lwjgl-rundir/resources/sounds/mob/cow/say4.mp3 new file mode 100644 index 0000000..18d1bf3 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cow/say4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cow/step1.mp3 b/lwjgl-rundir/resources/sounds/mob/cow/step1.mp3 new file mode 100644 index 0000000..7c5b9cd Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cow/step1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cow/step2.mp3 b/lwjgl-rundir/resources/sounds/mob/cow/step2.mp3 new file mode 100644 index 0000000..da4ce82 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cow/step2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cow/step3.mp3 b/lwjgl-rundir/resources/sounds/mob/cow/step3.mp3 new file mode 100644 index 0000000..86554dc Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cow/step3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/cow/step4.mp3 b/lwjgl-rundir/resources/sounds/mob/cow/step4.mp3 new file mode 100644 index 0000000..1a93b09 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/cow/step4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/creeper/death.mp3 b/lwjgl-rundir/resources/sounds/mob/creeper/death.mp3 new file mode 100644 index 0000000..a75902f Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/creeper/death.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/creeper/say1.mp3 b/lwjgl-rundir/resources/sounds/mob/creeper/say1.mp3 new file mode 100644 index 0000000..352fc46 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/creeper/say1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/creeper/say2.mp3 b/lwjgl-rundir/resources/sounds/mob/creeper/say2.mp3 new file mode 100644 index 0000000..78521b9 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/creeper/say2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/creeper/say3.mp3 b/lwjgl-rundir/resources/sounds/mob/creeper/say3.mp3 new file mode 100644 index 0000000..6bb29dd Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/creeper/say3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/creeper/say4.mp3 b/lwjgl-rundir/resources/sounds/mob/creeper/say4.mp3 new file mode 100644 index 0000000..b66d257 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/creeper/say4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/enderdragon/growl1.mp3 b/lwjgl-rundir/resources/sounds/mob/enderdragon/growl1.mp3 new file mode 100644 index 0000000..ea4221a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/enderdragon/growl1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/enderdragon/growl2.mp3 b/lwjgl-rundir/resources/sounds/mob/enderdragon/growl2.mp3 new file mode 100644 index 0000000..394b735 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/enderdragon/growl2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/enderdragon/growl3.mp3 b/lwjgl-rundir/resources/sounds/mob/enderdragon/growl3.mp3 new file mode 100644 index 0000000..b8318a6 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/enderdragon/growl3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/enderdragon/growl4.mp3 b/lwjgl-rundir/resources/sounds/mob/enderdragon/growl4.mp3 new file mode 100644 index 0000000..3ca9166 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/enderdragon/growl4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/enderdragon/hit1.mp3 b/lwjgl-rundir/resources/sounds/mob/enderdragon/hit1.mp3 new file mode 100644 index 0000000..f1f37f6 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/enderdragon/hit1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/enderdragon/hit2.mp3 b/lwjgl-rundir/resources/sounds/mob/enderdragon/hit2.mp3 new file mode 100644 index 0000000..ba148ef Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/enderdragon/hit2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/enderdragon/hit3.mp3 b/lwjgl-rundir/resources/sounds/mob/enderdragon/hit3.mp3 new file mode 100644 index 0000000..8e7ee45 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/enderdragon/hit3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/enderdragon/hit4.mp3 b/lwjgl-rundir/resources/sounds/mob/enderdragon/hit4.mp3 new file mode 100644 index 0000000..ebd15ed Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/enderdragon/hit4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/enderdragon/wings1.mp3 b/lwjgl-rundir/resources/sounds/mob/enderdragon/wings1.mp3 new file mode 100644 index 0000000..fdbf4e7 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/enderdragon/wings1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/enderdragon/wings2.mp3 b/lwjgl-rundir/resources/sounds/mob/enderdragon/wings2.mp3 new file mode 100644 index 0000000..f998f41 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/enderdragon/wings2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/enderdragon/wings3.mp3 b/lwjgl-rundir/resources/sounds/mob/enderdragon/wings3.mp3 new file mode 100644 index 0000000..b76307b Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/enderdragon/wings3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/enderdragon/wings4.mp3 b/lwjgl-rundir/resources/sounds/mob/enderdragon/wings4.mp3 new file mode 100644 index 0000000..faaec6c Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/enderdragon/wings4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/enderdragon/wings5.mp3 b/lwjgl-rundir/resources/sounds/mob/enderdragon/wings5.mp3 new file mode 100644 index 0000000..88f1623 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/enderdragon/wings5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/enderdragon/wings6.mp3 b/lwjgl-rundir/resources/sounds/mob/enderdragon/wings6.mp3 new file mode 100644 index 0000000..aa713a2 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/enderdragon/wings6.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/death.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/death.mp3 new file mode 100644 index 0000000..e8bd73d Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/death.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/hit1.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/hit1.mp3 new file mode 100644 index 0000000..d32735a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/hit1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/hit2.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/hit2.mp3 new file mode 100644 index 0000000..1fd3ad4 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/hit2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/hit3.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/hit3.mp3 new file mode 100644 index 0000000..ce9e825 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/hit3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/hit4.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/hit4.mp3 new file mode 100644 index 0000000..afefa1e Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/hit4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/idle1.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/idle1.mp3 new file mode 100644 index 0000000..087141d Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/idle1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/idle2.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/idle2.mp3 new file mode 100644 index 0000000..42c949b Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/idle2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/idle3.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/idle3.mp3 new file mode 100644 index 0000000..a910d9d Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/idle3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/idle4.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/idle4.mp3 new file mode 100644 index 0000000..92883b3 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/idle4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/idle5.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/idle5.mp3 new file mode 100644 index 0000000..50e0813 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/idle5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/portal1.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/portal1.mp3 new file mode 100644 index 0000000..98607ed Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/portal1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/portal2.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/portal2.mp3 new file mode 100644 index 0000000..df00269 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/portal2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/scream1.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/scream1.mp3 new file mode 100644 index 0000000..d905de6 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/scream1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/scream2.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/scream2.mp3 new file mode 100644 index 0000000..2781e1c Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/scream2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/scream3.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/scream3.mp3 new file mode 100644 index 0000000..9beaee0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/scream3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/scream4.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/scream4.mp3 new file mode 100644 index 0000000..128aab6 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/scream4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/endermen/stare.mp3 b/lwjgl-rundir/resources/sounds/mob/endermen/stare.mp3 new file mode 100644 index 0000000..62fd153 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/endermen/stare.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/affectionate scream.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/affectionate scream.mp3 new file mode 100644 index 0000000..e2e08f1 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/affectionate scream.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/charge.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/charge.mp3 new file mode 100644 index 0000000..d210f56 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/charge.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/death.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/death.mp3 new file mode 100644 index 0000000..12c996a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/death.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/fireball.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/fireball.mp3 new file mode 100644 index 0000000..8789156 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/fireball.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/moan1.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/moan1.mp3 new file mode 100644 index 0000000..c2741f8 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/moan1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/moan2.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/moan2.mp3 new file mode 100644 index 0000000..eb9f96a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/moan2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/moan3.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/moan3.mp3 new file mode 100644 index 0000000..d27e02a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/moan3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/moan4.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/moan4.mp3 new file mode 100644 index 0000000..3e33bca Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/moan4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/moan5.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/moan5.mp3 new file mode 100644 index 0000000..f63df19 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/moan5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/moan6.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/moan6.mp3 new file mode 100644 index 0000000..5a32b51 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/moan6.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/moan7.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/moan7.mp3 new file mode 100644 index 0000000..9081451 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/moan7.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/scream1.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/scream1.mp3 new file mode 100644 index 0000000..411c5c6 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/scream1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/scream2.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/scream2.mp3 new file mode 100644 index 0000000..630e0d5 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/scream2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/scream3.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/scream3.mp3 new file mode 100644 index 0000000..895523c Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/scream3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/scream4.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/scream4.mp3 new file mode 100644 index 0000000..e746c14 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/scream4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/ghast/scream5.mp3 b/lwjgl-rundir/resources/sounds/mob/ghast/scream5.mp3 new file mode 100644 index 0000000..3ed4b6a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/ghast/scream5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/irongolem/death.mp3 b/lwjgl-rundir/resources/sounds/mob/irongolem/death.mp3 new file mode 100644 index 0000000..7216fc7 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/irongolem/death.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/irongolem/hit1.mp3 b/lwjgl-rundir/resources/sounds/mob/irongolem/hit1.mp3 new file mode 100644 index 0000000..26d489c Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/irongolem/hit1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/irongolem/hit2.mp3 b/lwjgl-rundir/resources/sounds/mob/irongolem/hit2.mp3 new file mode 100644 index 0000000..b33b76c Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/irongolem/hit2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/irongolem/hit3.mp3 b/lwjgl-rundir/resources/sounds/mob/irongolem/hit3.mp3 new file mode 100644 index 0000000..2838961 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/irongolem/hit3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/irongolem/hit4.mp3 b/lwjgl-rundir/resources/sounds/mob/irongolem/hit4.mp3 new file mode 100644 index 0000000..6bd4455 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/irongolem/hit4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/irongolem/throw.mp3 b/lwjgl-rundir/resources/sounds/mob/irongolem/throw.mp3 new file mode 100644 index 0000000..4129439 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/irongolem/throw.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/irongolem/walk1.mp3 b/lwjgl-rundir/resources/sounds/mob/irongolem/walk1.mp3 new file mode 100644 index 0000000..cb64153 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/irongolem/walk1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/irongolem/walk2.mp3 b/lwjgl-rundir/resources/sounds/mob/irongolem/walk2.mp3 new file mode 100644 index 0000000..18576b2 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/irongolem/walk2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/irongolem/walk3.mp3 b/lwjgl-rundir/resources/sounds/mob/irongolem/walk3.mp3 new file mode 100644 index 0000000..ceda99a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/irongolem/walk3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/irongolem/walk4.mp3 b/lwjgl-rundir/resources/sounds/mob/irongolem/walk4.mp3 new file mode 100644 index 0000000..9ffecff Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/irongolem/walk4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/magmacube/big1.mp3 b/lwjgl-rundir/resources/sounds/mob/magmacube/big1.mp3 new file mode 100644 index 0000000..9bddc87 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/magmacube/big1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/magmacube/big2.mp3 b/lwjgl-rundir/resources/sounds/mob/magmacube/big2.mp3 new file mode 100644 index 0000000..cfb82a2 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/magmacube/big2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/magmacube/big3.mp3 b/lwjgl-rundir/resources/sounds/mob/magmacube/big3.mp3 new file mode 100644 index 0000000..f3ce820 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/magmacube/big3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/magmacube/big4.mp3 b/lwjgl-rundir/resources/sounds/mob/magmacube/big4.mp3 new file mode 100644 index 0000000..9d5c4b1 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/magmacube/big4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/magmacube/jump1.mp3 b/lwjgl-rundir/resources/sounds/mob/magmacube/jump1.mp3 new file mode 100644 index 0000000..8a3384b Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/magmacube/jump1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/magmacube/jump2.mp3 b/lwjgl-rundir/resources/sounds/mob/magmacube/jump2.mp3 new file mode 100644 index 0000000..aab2b83 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/magmacube/jump2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/magmacube/jump3.mp3 b/lwjgl-rundir/resources/sounds/mob/magmacube/jump3.mp3 new file mode 100644 index 0000000..e7fa459 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/magmacube/jump3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/magmacube/jump4.mp3 b/lwjgl-rundir/resources/sounds/mob/magmacube/jump4.mp3 new file mode 100644 index 0000000..0eecfda Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/magmacube/jump4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/magmacube/small1.mp3 b/lwjgl-rundir/resources/sounds/mob/magmacube/small1.mp3 new file mode 100644 index 0000000..f1df759 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/magmacube/small1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/magmacube/small2.mp3 b/lwjgl-rundir/resources/sounds/mob/magmacube/small2.mp3 new file mode 100644 index 0000000..ef3aee0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/magmacube/small2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/magmacube/small3.mp3 b/lwjgl-rundir/resources/sounds/mob/magmacube/small3.mp3 new file mode 100644 index 0000000..a9fa4c0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/magmacube/small3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/magmacube/small4.mp3 b/lwjgl-rundir/resources/sounds/mob/magmacube/small4.mp3 new file mode 100644 index 0000000..7dd4455 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/magmacube/small4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/magmacube/small5.mp3 b/lwjgl-rundir/resources/sounds/mob/magmacube/small5.mp3 new file mode 100644 index 0000000..07349d2 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/magmacube/small5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/pig/death.mp3 b/lwjgl-rundir/resources/sounds/mob/pig/death.mp3 new file mode 100644 index 0000000..f1e7568 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/pig/death.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/pig/say1.mp3 b/lwjgl-rundir/resources/sounds/mob/pig/say1.mp3 new file mode 100644 index 0000000..53f54ec Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/pig/say1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/pig/say2.mp3 b/lwjgl-rundir/resources/sounds/mob/pig/say2.mp3 new file mode 100644 index 0000000..c28e929 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/pig/say2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/pig/say3.mp3 b/lwjgl-rundir/resources/sounds/mob/pig/say3.mp3 new file mode 100644 index 0000000..2f9801c Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/pig/say3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/pig/step1.mp3 b/lwjgl-rundir/resources/sounds/mob/pig/step1.mp3 new file mode 100644 index 0000000..2ba8253 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/pig/step1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/pig/step2.mp3 b/lwjgl-rundir/resources/sounds/mob/pig/step2.mp3 new file mode 100644 index 0000000..628c64c Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/pig/step2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/pig/step3.mp3 b/lwjgl-rundir/resources/sounds/mob/pig/step3.mp3 new file mode 100644 index 0000000..f1fa142 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/pig/step3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/pig/step4.mp3 b/lwjgl-rundir/resources/sounds/mob/pig/step4.mp3 new file mode 100644 index 0000000..fbb8fa2 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/pig/step4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/pig/step5.mp3 b/lwjgl-rundir/resources/sounds/mob/pig/step5.mp3 new file mode 100644 index 0000000..8e3a26c Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/pig/step5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/sheep/say1.mp3 b/lwjgl-rundir/resources/sounds/mob/sheep/say1.mp3 new file mode 100644 index 0000000..817aa44 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/sheep/say1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/sheep/say2.mp3 b/lwjgl-rundir/resources/sounds/mob/sheep/say2.mp3 new file mode 100644 index 0000000..01ab24a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/sheep/say2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/sheep/say3.mp3 b/lwjgl-rundir/resources/sounds/mob/sheep/say3.mp3 new file mode 100644 index 0000000..936fd23 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/sheep/say3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/sheep/shear.mp3 b/lwjgl-rundir/resources/sounds/mob/sheep/shear.mp3 new file mode 100644 index 0000000..e13874f Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/sheep/shear.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/sheep/step1.mp3 b/lwjgl-rundir/resources/sounds/mob/sheep/step1.mp3 new file mode 100644 index 0000000..205e031 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/sheep/step1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/sheep/step2.mp3 b/lwjgl-rundir/resources/sounds/mob/sheep/step2.mp3 new file mode 100644 index 0000000..81159fa Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/sheep/step2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/sheep/step3.mp3 b/lwjgl-rundir/resources/sounds/mob/sheep/step3.mp3 new file mode 100644 index 0000000..badd2c4 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/sheep/step3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/sheep/step4.mp3 b/lwjgl-rundir/resources/sounds/mob/sheep/step4.mp3 new file mode 100644 index 0000000..d61b751 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/sheep/step4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/sheep/step5.mp3 b/lwjgl-rundir/resources/sounds/mob/sheep/step5.mp3 new file mode 100644 index 0000000..9baf4ba Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/sheep/step5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/silverfish/hit1.mp3 b/lwjgl-rundir/resources/sounds/mob/silverfish/hit1.mp3 new file mode 100644 index 0000000..be6825e Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/silverfish/hit1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/silverfish/hit2.mp3 b/lwjgl-rundir/resources/sounds/mob/silverfish/hit2.mp3 new file mode 100644 index 0000000..fbda2b8 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/silverfish/hit2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/silverfish/hit3.mp3 b/lwjgl-rundir/resources/sounds/mob/silverfish/hit3.mp3 new file mode 100644 index 0000000..b5fcf50 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/silverfish/hit3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/silverfish/kill.mp3 b/lwjgl-rundir/resources/sounds/mob/silverfish/kill.mp3 new file mode 100644 index 0000000..52a1c65 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/silverfish/kill.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/silverfish/say1.mp3 b/lwjgl-rundir/resources/sounds/mob/silverfish/say1.mp3 new file mode 100644 index 0000000..4a937f2 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/silverfish/say1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/silverfish/say2.mp3 b/lwjgl-rundir/resources/sounds/mob/silverfish/say2.mp3 new file mode 100644 index 0000000..53ecd5e Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/silverfish/say2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/silverfish/say3.mp3 b/lwjgl-rundir/resources/sounds/mob/silverfish/say3.mp3 new file mode 100644 index 0000000..5febd02 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/silverfish/say3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/silverfish/say4.mp3 b/lwjgl-rundir/resources/sounds/mob/silverfish/say4.mp3 new file mode 100644 index 0000000..e83f177 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/silverfish/say4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/silverfish/step1.mp3 b/lwjgl-rundir/resources/sounds/mob/silverfish/step1.mp3 new file mode 100644 index 0000000..72c9e00 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/silverfish/step1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/silverfish/step2.mp3 b/lwjgl-rundir/resources/sounds/mob/silverfish/step2.mp3 new file mode 100644 index 0000000..365c383 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/silverfish/step2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/silverfish/step3.mp3 b/lwjgl-rundir/resources/sounds/mob/silverfish/step3.mp3 new file mode 100644 index 0000000..7b35ac4 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/silverfish/step3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/silverfish/step4.mp3 b/lwjgl-rundir/resources/sounds/mob/silverfish/step4.mp3 new file mode 100644 index 0000000..19960df Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/silverfish/step4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/skeleton/death.mp3 b/lwjgl-rundir/resources/sounds/mob/skeleton/death.mp3 new file mode 100644 index 0000000..ef87489 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/skeleton/death.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/skeleton/hurt1.mp3 b/lwjgl-rundir/resources/sounds/mob/skeleton/hurt1.mp3 new file mode 100644 index 0000000..060c42d Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/skeleton/hurt1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/skeleton/hurt2.mp3 b/lwjgl-rundir/resources/sounds/mob/skeleton/hurt2.mp3 new file mode 100644 index 0000000..0431797 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/skeleton/hurt2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/skeleton/hurt3.mp3 b/lwjgl-rundir/resources/sounds/mob/skeleton/hurt3.mp3 new file mode 100644 index 0000000..aea8bff Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/skeleton/hurt3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/skeleton/hurt4.mp3 b/lwjgl-rundir/resources/sounds/mob/skeleton/hurt4.mp3 new file mode 100644 index 0000000..f51ccee Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/skeleton/hurt4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/skeleton/say1.mp3 b/lwjgl-rundir/resources/sounds/mob/skeleton/say1.mp3 new file mode 100644 index 0000000..305f52f Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/skeleton/say1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/skeleton/say2.mp3 b/lwjgl-rundir/resources/sounds/mob/skeleton/say2.mp3 new file mode 100644 index 0000000..eca5546 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/skeleton/say2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/skeleton/say3.mp3 b/lwjgl-rundir/resources/sounds/mob/skeleton/say3.mp3 new file mode 100644 index 0000000..d93b2b0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/skeleton/say3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/skeleton/step1.mp3 b/lwjgl-rundir/resources/sounds/mob/skeleton/step1.mp3 new file mode 100644 index 0000000..7bc2dda Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/skeleton/step1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/skeleton/step2.mp3 b/lwjgl-rundir/resources/sounds/mob/skeleton/step2.mp3 new file mode 100644 index 0000000..96bd50f Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/skeleton/step2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/skeleton/step3.mp3 b/lwjgl-rundir/resources/sounds/mob/skeleton/step3.mp3 new file mode 100644 index 0000000..4f19aee Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/skeleton/step3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/skeleton/step4.mp3 b/lwjgl-rundir/resources/sounds/mob/skeleton/step4.mp3 new file mode 100644 index 0000000..1986b93 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/skeleton/step4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/slime/attack1.mp3 b/lwjgl-rundir/resources/sounds/mob/slime/attack1.mp3 new file mode 100644 index 0000000..40d9f82 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/slime/attack1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/slime/attack2.mp3 b/lwjgl-rundir/resources/sounds/mob/slime/attack2.mp3 new file mode 100644 index 0000000..4b97ee2 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/slime/attack2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/slime/big1.mp3 b/lwjgl-rundir/resources/sounds/mob/slime/big1.mp3 new file mode 100644 index 0000000..9bddc87 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/slime/big1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/slime/big2.mp3 b/lwjgl-rundir/resources/sounds/mob/slime/big2.mp3 new file mode 100644 index 0000000..cfb82a2 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/slime/big2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/slime/big3.mp3 b/lwjgl-rundir/resources/sounds/mob/slime/big3.mp3 new file mode 100644 index 0000000..f3ce820 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/slime/big3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/slime/big4.mp3 b/lwjgl-rundir/resources/sounds/mob/slime/big4.mp3 new file mode 100644 index 0000000..9d5c4b1 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/slime/big4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/slime/small1.mp3 b/lwjgl-rundir/resources/sounds/mob/slime/small1.mp3 new file mode 100644 index 0000000..f1df759 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/slime/small1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/slime/small2.mp3 b/lwjgl-rundir/resources/sounds/mob/slime/small2.mp3 new file mode 100644 index 0000000..ef3aee0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/slime/small2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/slime/small3.mp3 b/lwjgl-rundir/resources/sounds/mob/slime/small3.mp3 new file mode 100644 index 0000000..a9fa4c0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/slime/small3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/slime/small4.mp3 b/lwjgl-rundir/resources/sounds/mob/slime/small4.mp3 new file mode 100644 index 0000000..7dd4455 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/slime/small4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/slime/small5.mp3 b/lwjgl-rundir/resources/sounds/mob/slime/small5.mp3 new file mode 100644 index 0000000..07349d2 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/slime/small5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/spider/death.mp3 b/lwjgl-rundir/resources/sounds/mob/spider/death.mp3 new file mode 100644 index 0000000..1a32e30 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/spider/death.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/spider/say1.mp3 b/lwjgl-rundir/resources/sounds/mob/spider/say1.mp3 new file mode 100644 index 0000000..993b970 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/spider/say1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/spider/say2.mp3 b/lwjgl-rundir/resources/sounds/mob/spider/say2.mp3 new file mode 100644 index 0000000..88620c5 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/spider/say2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/spider/say3.mp3 b/lwjgl-rundir/resources/sounds/mob/spider/say3.mp3 new file mode 100644 index 0000000..97ecf27 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/spider/say3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/spider/say4.mp3 b/lwjgl-rundir/resources/sounds/mob/spider/say4.mp3 new file mode 100644 index 0000000..fdfa807 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/spider/say4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/spider/step1.mp3 b/lwjgl-rundir/resources/sounds/mob/spider/step1.mp3 new file mode 100644 index 0000000..dd56225 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/spider/step1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/spider/step2.mp3 b/lwjgl-rundir/resources/sounds/mob/spider/step2.mp3 new file mode 100644 index 0000000..ff9b6ee Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/spider/step2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/spider/step3.mp3 b/lwjgl-rundir/resources/sounds/mob/spider/step3.mp3 new file mode 100644 index 0000000..1172ea4 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/spider/step3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/spider/step4.mp3 b/lwjgl-rundir/resources/sounds/mob/spider/step4.mp3 new file mode 100644 index 0000000..121291a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/spider/step4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wither/death.mp3 b/lwjgl-rundir/resources/sounds/mob/wither/death.mp3 new file mode 100644 index 0000000..14b3040 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wither/death.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wither/hurt1.mp3 b/lwjgl-rundir/resources/sounds/mob/wither/hurt1.mp3 new file mode 100644 index 0000000..066edb6 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wither/hurt1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wither/hurt2.mp3 b/lwjgl-rundir/resources/sounds/mob/wither/hurt2.mp3 new file mode 100644 index 0000000..0f0cfc0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wither/hurt2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wither/hurt3.mp3 b/lwjgl-rundir/resources/sounds/mob/wither/hurt3.mp3 new file mode 100644 index 0000000..478dbca Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wither/hurt3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wither/hurt4.mp3 b/lwjgl-rundir/resources/sounds/mob/wither/hurt4.mp3 new file mode 100644 index 0000000..9a45bbd Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wither/hurt4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wither/idle1.mp3 b/lwjgl-rundir/resources/sounds/mob/wither/idle1.mp3 new file mode 100644 index 0000000..574ca04 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wither/idle1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wither/idle2.mp3 b/lwjgl-rundir/resources/sounds/mob/wither/idle2.mp3 new file mode 100644 index 0000000..dcd2182 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wither/idle2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wither/idle3.mp3 b/lwjgl-rundir/resources/sounds/mob/wither/idle3.mp3 new file mode 100644 index 0000000..9e0d8a4 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wither/idle3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wither/idle4.mp3 b/lwjgl-rundir/resources/sounds/mob/wither/idle4.mp3 new file mode 100644 index 0000000..9aaaa65 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wither/idle4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wither/shoot.mp3 b/lwjgl-rundir/resources/sounds/mob/wither/shoot.mp3 new file mode 100644 index 0000000..fe5d6a8 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wither/shoot.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wither/spawn.mp3 b/lwjgl-rundir/resources/sounds/mob/wither/spawn.mp3 new file mode 100644 index 0000000..1c5889d Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wither/spawn.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/bark1.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/bark1.mp3 new file mode 100644 index 0000000..9c9c1ec Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/bark1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/bark2.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/bark2.mp3 new file mode 100644 index 0000000..d93c649 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/bark2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/bark3.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/bark3.mp3 new file mode 100644 index 0000000..a8d85fc Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/bark3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/death.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/death.mp3 new file mode 100644 index 0000000..18d2e1e Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/death.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/growl1.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/growl1.mp3 new file mode 100644 index 0000000..e4a2207 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/growl1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/growl2.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/growl2.mp3 new file mode 100644 index 0000000..d49b6ed Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/growl2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/growl3.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/growl3.mp3 new file mode 100644 index 0000000..ed2f74a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/growl3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/howl1.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/howl1.mp3 new file mode 100644 index 0000000..599c28d Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/howl1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/howl2.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/howl2.mp3 new file mode 100644 index 0000000..340ad47 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/howl2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/hurt1.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/hurt1.mp3 new file mode 100644 index 0000000..5f020f5 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/hurt1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/hurt2.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/hurt2.mp3 new file mode 100644 index 0000000..41285ce Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/hurt2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/hurt3.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/hurt3.mp3 new file mode 100644 index 0000000..807972d Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/hurt3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/panting.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/panting.mp3 new file mode 100644 index 0000000..35ccf8a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/panting.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/shake.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/shake.mp3 new file mode 100644 index 0000000..fde671a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/shake.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/step1.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/step1.mp3 new file mode 100644 index 0000000..5f77082 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/step1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/step2.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/step2.mp3 new file mode 100644 index 0000000..2f64e8f Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/step2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/step3.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/step3.mp3 new file mode 100644 index 0000000..da3e0e6 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/step3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/step4.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/step4.mp3 new file mode 100644 index 0000000..2e9064a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/step4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/step5.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/step5.mp3 new file mode 100644 index 0000000..9a320c3 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/step5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/wolf/whine.mp3 b/lwjgl-rundir/resources/sounds/mob/wolf/whine.mp3 new file mode 100644 index 0000000..5fa6210 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/wolf/whine.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/death.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/death.mp3 new file mode 100644 index 0000000..81759dd Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/death.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/hurt1.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/hurt1.mp3 new file mode 100644 index 0000000..2188dd7 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/hurt1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/hurt2.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/hurt2.mp3 new file mode 100644 index 0000000..7c63406 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/hurt2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/infect.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/infect.mp3 new file mode 100644 index 0000000..bfffeef Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/infect.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/metal1.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/metal1.mp3 new file mode 100644 index 0000000..156a054 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/metal1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/metal2.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/metal2.mp3 new file mode 100644 index 0000000..e40cfc4 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/metal2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/metal3.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/metal3.mp3 new file mode 100644 index 0000000..272c95d Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/metal3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/remedy.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/remedy.mp3 new file mode 100644 index 0000000..bfbf831 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/remedy.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/say1.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/say1.mp3 new file mode 100644 index 0000000..148a292 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/say1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/say2.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/say2.mp3 new file mode 100644 index 0000000..f4a2801 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/say2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/say3.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/say3.mp3 new file mode 100644 index 0000000..2c5e5d1 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/say3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/step1.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/step1.mp3 new file mode 100644 index 0000000..d965009 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/step1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/step2.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/step2.mp3 new file mode 100644 index 0000000..14ec9bd Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/step2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/step3.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/step3.mp3 new file mode 100644 index 0000000..227f907 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/step3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/step4.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/step4.mp3 new file mode 100644 index 0000000..5b2e3fc Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/step4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/step5.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/step5.mp3 new file mode 100644 index 0000000..a847465 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/step5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/unfect.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/unfect.mp3 new file mode 100644 index 0000000..3435d26 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/unfect.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/wood1.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/wood1.mp3 new file mode 100644 index 0000000..4ff38ce Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/wood1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/wood2.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/wood2.mp3 new file mode 100644 index 0000000..c4031b0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/wood2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/wood3.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/wood3.mp3 new file mode 100644 index 0000000..1c40103 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/wood3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/wood4.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/wood4.mp3 new file mode 100644 index 0000000..116febd Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/wood4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombie/woodbreak.mp3 b/lwjgl-rundir/resources/sounds/mob/zombie/woodbreak.mp3 new file mode 100644 index 0000000..07e96b1 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombie/woodbreak.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombiepig/zpig1.mp3 b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpig1.mp3 new file mode 100644 index 0000000..398966b Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpig1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombiepig/zpig2.mp3 b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpig2.mp3 new file mode 100644 index 0000000..6e7b324 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpig2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombiepig/zpig3.mp3 b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpig3.mp3 new file mode 100644 index 0000000..5072cda Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpig3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombiepig/zpig4.mp3 b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpig4.mp3 new file mode 100644 index 0000000..012e0f4 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpig4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombiepig/zpigangry1.mp3 b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpigangry1.mp3 new file mode 100644 index 0000000..0f4feeb Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpigangry1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombiepig/zpigangry2.mp3 b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpigangry2.mp3 new file mode 100644 index 0000000..15e4182 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpigangry2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombiepig/zpigangry3.mp3 b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpigangry3.mp3 new file mode 100644 index 0000000..1910ed8 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpigangry3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombiepig/zpigangry4.mp3 b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpigangry4.mp3 new file mode 100644 index 0000000..be24602 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpigangry4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombiepig/zpigdeath.mp3 b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpigdeath.mp3 new file mode 100644 index 0000000..2c89ddf Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpigdeath.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombiepig/zpighurt1.mp3 b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpighurt1.mp3 new file mode 100644 index 0000000..d34ee55 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpighurt1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/mob/zombiepig/zpighurt2.mp3 b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpighurt2.mp3 new file mode 100644 index 0000000..d0e40aa Binary files /dev/null and b/lwjgl-rundir/resources/sounds/mob/zombiepig/zpighurt2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/note/bass.mp3 b/lwjgl-rundir/resources/sounds/note/bass.mp3 new file mode 100644 index 0000000..faee495 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/note/bass.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/note/bassattack.mp3 b/lwjgl-rundir/resources/sounds/note/bassattack.mp3 new file mode 100644 index 0000000..1c39be1 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/note/bassattack.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/note/bd.mp3 b/lwjgl-rundir/resources/sounds/note/bd.mp3 new file mode 100644 index 0000000..ec4d211 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/note/bd.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/note/harp.mp3 b/lwjgl-rundir/resources/sounds/note/harp.mp3 new file mode 100644 index 0000000..b4f6dcf Binary files /dev/null and b/lwjgl-rundir/resources/sounds/note/harp.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/note/hat.mp3 b/lwjgl-rundir/resources/sounds/note/hat.mp3 new file mode 100644 index 0000000..e43a183 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/note/hat.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/note/pling.mp3 b/lwjgl-rundir/resources/sounds/note/pling.mp3 new file mode 100644 index 0000000..296d507 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/note/pling.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/note/snare.mp3 b/lwjgl-rundir/resources/sounds/note/snare.mp3 new file mode 100644 index 0000000..7082d3b Binary files /dev/null and b/lwjgl-rundir/resources/sounds/note/snare.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/portal/portal.mp3 b/lwjgl-rundir/resources/sounds/portal/portal.mp3 new file mode 100644 index 0000000..3cd682c Binary files /dev/null and b/lwjgl-rundir/resources/sounds/portal/portal.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/portal/travel.mp3 b/lwjgl-rundir/resources/sounds/portal/travel.mp3 new file mode 100644 index 0000000..6446255 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/portal/travel.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/portal/trigger.mp3 b/lwjgl-rundir/resources/sounds/portal/trigger.mp3 new file mode 100644 index 0000000..98f91cb Binary files /dev/null and b/lwjgl-rundir/resources/sounds/portal/trigger.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/anvil_break.mp3 b/lwjgl-rundir/resources/sounds/random/anvil_break.mp3 new file mode 100644 index 0000000..591e217 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/anvil_break.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/anvil_land.mp3 b/lwjgl-rundir/resources/sounds/random/anvil_land.mp3 new file mode 100644 index 0000000..f7dbdac Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/anvil_land.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/anvil_use.mp3 b/lwjgl-rundir/resources/sounds/random/anvil_use.mp3 new file mode 100644 index 0000000..331b2aa Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/anvil_use.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/bow.mp3 b/lwjgl-rundir/resources/sounds/random/bow.mp3 new file mode 100644 index 0000000..93a3e00 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/bow.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/bowhit1.mp3 b/lwjgl-rundir/resources/sounds/random/bowhit1.mp3 new file mode 100644 index 0000000..bdd2d2a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/bowhit1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/bowhit2.mp3 b/lwjgl-rundir/resources/sounds/random/bowhit2.mp3 new file mode 100644 index 0000000..67c1452 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/bowhit2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/bowhit3.mp3 b/lwjgl-rundir/resources/sounds/random/bowhit3.mp3 new file mode 100644 index 0000000..c54eafb Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/bowhit3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/bowhit4.mp3 b/lwjgl-rundir/resources/sounds/random/bowhit4.mp3 new file mode 100644 index 0000000..65cf8fc Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/bowhit4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/break.mp3 b/lwjgl-rundir/resources/sounds/random/break.mp3 new file mode 100644 index 0000000..ee8fdb7 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/break.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/breath.mp3 b/lwjgl-rundir/resources/sounds/random/breath.mp3 new file mode 100644 index 0000000..1dac5da Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/breath.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/burp.mp3 b/lwjgl-rundir/resources/sounds/random/burp.mp3 new file mode 100644 index 0000000..420b2de Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/burp.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/chestclosed.mp3 b/lwjgl-rundir/resources/sounds/random/chestclosed.mp3 new file mode 100644 index 0000000..1110b16 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/chestclosed.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/chestopen.mp3 b/lwjgl-rundir/resources/sounds/random/chestopen.mp3 new file mode 100644 index 0000000..c1dc6d0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/chestopen.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/classic_hurt.mp3 b/lwjgl-rundir/resources/sounds/random/classic_hurt.mp3 new file mode 100644 index 0000000..77dff59 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/classic_hurt.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/click.mp3 b/lwjgl-rundir/resources/sounds/random/click.mp3 new file mode 100644 index 0000000..b9643be Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/click.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/door_close.mp3 b/lwjgl-rundir/resources/sounds/random/door_close.mp3 new file mode 100644 index 0000000..d414db0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/door_close.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/door_open.mp3 b/lwjgl-rundir/resources/sounds/random/door_open.mp3 new file mode 100644 index 0000000..95fe386 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/door_open.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/drink.mp3 b/lwjgl-rundir/resources/sounds/random/drink.mp3 new file mode 100644 index 0000000..054e413 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/drink.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/drr.mp3 b/lwjgl-rundir/resources/sounds/random/drr.mp3 new file mode 100644 index 0000000..28003b8 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/drr.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/eat1.mp3 b/lwjgl-rundir/resources/sounds/random/eat1.mp3 new file mode 100644 index 0000000..729b07f Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/eat1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/eat2.mp3 b/lwjgl-rundir/resources/sounds/random/eat2.mp3 new file mode 100644 index 0000000..bf5882b Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/eat2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/eat3.mp3 b/lwjgl-rundir/resources/sounds/random/eat3.mp3 new file mode 100644 index 0000000..a7f04b5 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/eat3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/explode1.mp3 b/lwjgl-rundir/resources/sounds/random/explode1.mp3 new file mode 100644 index 0000000..51f5989 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/explode1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/explode2.mp3 b/lwjgl-rundir/resources/sounds/random/explode2.mp3 new file mode 100644 index 0000000..250edf9 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/explode2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/explode3.mp3 b/lwjgl-rundir/resources/sounds/random/explode3.mp3 new file mode 100644 index 0000000..58752c5 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/explode3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/explode4.mp3 b/lwjgl-rundir/resources/sounds/random/explode4.mp3 new file mode 100644 index 0000000..4d39486 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/explode4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/fizz.mp3 b/lwjgl-rundir/resources/sounds/random/fizz.mp3 new file mode 100644 index 0000000..d331982 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/fizz.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/fuse.mp3 b/lwjgl-rundir/resources/sounds/random/fuse.mp3 new file mode 100644 index 0000000..d8bf484 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/fuse.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/glass1.mp3 b/lwjgl-rundir/resources/sounds/random/glass1.mp3 new file mode 100644 index 0000000..1568a08 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/glass1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/glass2.mp3 b/lwjgl-rundir/resources/sounds/random/glass2.mp3 new file mode 100644 index 0000000..e595045 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/glass2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/glass3.mp3 b/lwjgl-rundir/resources/sounds/random/glass3.mp3 new file mode 100644 index 0000000..9e75dd2 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/glass3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/hurt.mp3 b/lwjgl-rundir/resources/sounds/random/hurt.mp3 new file mode 100644 index 0000000..77dff59 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/hurt.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/levelup.mp3 b/lwjgl-rundir/resources/sounds/random/levelup.mp3 new file mode 100644 index 0000000..7975fe0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/levelup.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/old_explode.mp3 b/lwjgl-rundir/resources/sounds/random/old_explode.mp3 new file mode 100644 index 0000000..e4b3aa1 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/old_explode.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/orb.mp3 b/lwjgl-rundir/resources/sounds/random/orb.mp3 new file mode 100644 index 0000000..e64b127 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/orb.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/pop.mp3 b/lwjgl-rundir/resources/sounds/random/pop.mp3 new file mode 100644 index 0000000..827039e Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/pop.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/splash.mp3 b/lwjgl-rundir/resources/sounds/random/splash.mp3 new file mode 100644 index 0000000..978f393 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/splash.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/successful_hit.mp3 b/lwjgl-rundir/resources/sounds/random/successful_hit.mp3 new file mode 100644 index 0000000..e64b127 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/successful_hit.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/random/wood click.mp3 b/lwjgl-rundir/resources/sounds/random/wood click.mp3 new file mode 100644 index 0000000..da35933 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/random/wood click.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/sounds.dat b/lwjgl-rundir/resources/sounds/sounds.dat new file mode 100644 index 0000000..196b93d Binary files /dev/null and b/lwjgl-rundir/resources/sounds/sounds.dat differ diff --git a/lwjgl-rundir/resources/sounds/step/cloth1.mp3 b/lwjgl-rundir/resources/sounds/step/cloth1.mp3 new file mode 100644 index 0000000..8212bd8 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/cloth1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/cloth2.mp3 b/lwjgl-rundir/resources/sounds/step/cloth2.mp3 new file mode 100644 index 0000000..b51def4 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/cloth2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/cloth3.mp3 b/lwjgl-rundir/resources/sounds/step/cloth3.mp3 new file mode 100644 index 0000000..f1a8edd Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/cloth3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/cloth4.mp3 b/lwjgl-rundir/resources/sounds/step/cloth4.mp3 new file mode 100644 index 0000000..df38fe0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/cloth4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/grass1.mp3 b/lwjgl-rundir/resources/sounds/step/grass1.mp3 new file mode 100644 index 0000000..8ff1017 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/grass1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/grass2.mp3 b/lwjgl-rundir/resources/sounds/step/grass2.mp3 new file mode 100644 index 0000000..a415d06 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/grass2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/grass3.mp3 b/lwjgl-rundir/resources/sounds/step/grass3.mp3 new file mode 100644 index 0000000..348dd1a Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/grass3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/grass4.mp3 b/lwjgl-rundir/resources/sounds/step/grass4.mp3 new file mode 100644 index 0000000..d184527 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/grass4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/grass5.mp3 b/lwjgl-rundir/resources/sounds/step/grass5.mp3 new file mode 100644 index 0000000..e2f297f Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/grass5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/grass6.mp3 b/lwjgl-rundir/resources/sounds/step/grass6.mp3 new file mode 100644 index 0000000..1da4d6e Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/grass6.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/gravel1.mp3 b/lwjgl-rundir/resources/sounds/step/gravel1.mp3 new file mode 100644 index 0000000..0aedae1 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/gravel1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/gravel2.mp3 b/lwjgl-rundir/resources/sounds/step/gravel2.mp3 new file mode 100644 index 0000000..77e7534 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/gravel2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/gravel3.mp3 b/lwjgl-rundir/resources/sounds/step/gravel3.mp3 new file mode 100644 index 0000000..f322aa0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/gravel3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/gravel4.mp3 b/lwjgl-rundir/resources/sounds/step/gravel4.mp3 new file mode 100644 index 0000000..2f6115e Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/gravel4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/ladder1.mp3 b/lwjgl-rundir/resources/sounds/step/ladder1.mp3 new file mode 100644 index 0000000..1b3d194 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/ladder1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/ladder2.mp3 b/lwjgl-rundir/resources/sounds/step/ladder2.mp3 new file mode 100644 index 0000000..a403a5d Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/ladder2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/ladder3.mp3 b/lwjgl-rundir/resources/sounds/step/ladder3.mp3 new file mode 100644 index 0000000..b036e6b Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/ladder3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/ladder4.mp3 b/lwjgl-rundir/resources/sounds/step/ladder4.mp3 new file mode 100644 index 0000000..9d0db68 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/ladder4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/ladder5.mp3 b/lwjgl-rundir/resources/sounds/step/ladder5.mp3 new file mode 100644 index 0000000..f638b11 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/ladder5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/sand1.mp3 b/lwjgl-rundir/resources/sounds/step/sand1.mp3 new file mode 100644 index 0000000..7083195 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/sand1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/sand2.mp3 b/lwjgl-rundir/resources/sounds/step/sand2.mp3 new file mode 100644 index 0000000..d24fe22 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/sand2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/sand3.mp3 b/lwjgl-rundir/resources/sounds/step/sand3.mp3 new file mode 100644 index 0000000..fe30113 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/sand3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/sand4.mp3 b/lwjgl-rundir/resources/sounds/step/sand4.mp3 new file mode 100644 index 0000000..2c6d542 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/sand4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/sand5.mp3 b/lwjgl-rundir/resources/sounds/step/sand5.mp3 new file mode 100644 index 0000000..fa67db4 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/sand5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/snow1.mp3 b/lwjgl-rundir/resources/sounds/step/snow1.mp3 new file mode 100644 index 0000000..89a4c69 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/snow1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/snow2.mp3 b/lwjgl-rundir/resources/sounds/step/snow2.mp3 new file mode 100644 index 0000000..ba469d0 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/snow2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/snow3.mp3 b/lwjgl-rundir/resources/sounds/step/snow3.mp3 new file mode 100644 index 0000000..86178ca Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/snow3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/snow4.mp3 b/lwjgl-rundir/resources/sounds/step/snow4.mp3 new file mode 100644 index 0000000..1d97fae Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/snow4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/stone1.mp3 b/lwjgl-rundir/resources/sounds/step/stone1.mp3 new file mode 100644 index 0000000..6467f23 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/stone1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/stone2.mp3 b/lwjgl-rundir/resources/sounds/step/stone2.mp3 new file mode 100644 index 0000000..f593808 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/stone2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/stone3.mp3 b/lwjgl-rundir/resources/sounds/step/stone3.mp3 new file mode 100644 index 0000000..0ffa4d2 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/stone3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/stone4.mp3 b/lwjgl-rundir/resources/sounds/step/stone4.mp3 new file mode 100644 index 0000000..9e94085 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/stone4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/stone5.mp3 b/lwjgl-rundir/resources/sounds/step/stone5.mp3 new file mode 100644 index 0000000..7d3e36b Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/stone5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/stone6.mp3 b/lwjgl-rundir/resources/sounds/step/stone6.mp3 new file mode 100644 index 0000000..3039231 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/stone6.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/wood1.mp3 b/lwjgl-rundir/resources/sounds/step/wood1.mp3 new file mode 100644 index 0000000..86d8cfc Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/wood1.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/wood2.mp3 b/lwjgl-rundir/resources/sounds/step/wood2.mp3 new file mode 100644 index 0000000..b7c6008 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/wood2.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/wood3.mp3 b/lwjgl-rundir/resources/sounds/step/wood3.mp3 new file mode 100644 index 0000000..e7446f7 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/wood3.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/wood4.mp3 b/lwjgl-rundir/resources/sounds/step/wood4.mp3 new file mode 100644 index 0000000..23b8f5c Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/wood4.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/wood5.mp3 b/lwjgl-rundir/resources/sounds/step/wood5.mp3 new file mode 100644 index 0000000..818109f Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/wood5.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/step/wood6.mp3 b/lwjgl-rundir/resources/sounds/step/wood6.mp3 new file mode 100644 index 0000000..e0a9ac3 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/step/wood6.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/tile/piston/in.mp3 b/lwjgl-rundir/resources/sounds/tile/piston/in.mp3 new file mode 100644 index 0000000..b457522 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/tile/piston/in.mp3 differ diff --git a/lwjgl-rundir/resources/sounds/tile/piston/out.mp3 b/lwjgl-rundir/resources/sounds/tile/piston/out.mp3 new file mode 100644 index 0000000..6381e95 Binary files /dev/null and b/lwjgl-rundir/resources/sounds/tile/piston/out.mp3 differ diff --git a/lwjgl-rundir/resources/textures/blocks/activatorRail.png b/lwjgl-rundir/resources/textures/blocks/activatorRail.png new file mode 100644 index 0000000..b765a51 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/activatorRail.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/activatorRail_powered.png b/lwjgl-rundir/resources/textures/blocks/activatorRail_powered.png new file mode 100644 index 0000000..999a0f7 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/activatorRail_powered.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/anvil_base.png b/lwjgl-rundir/resources/textures/blocks/anvil_base.png new file mode 100644 index 0000000..0107fdd Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/anvil_base.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/anvil_top.png b/lwjgl-rundir/resources/textures/blocks/anvil_top.png new file mode 100644 index 0000000..0fbbd85 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/anvil_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/anvil_top_damaged_1.png b/lwjgl-rundir/resources/textures/blocks/anvil_top_damaged_1.png new file mode 100644 index 0000000..77d8ff0 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/anvil_top_damaged_1.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/anvil_top_damaged_2.png b/lwjgl-rundir/resources/textures/blocks/anvil_top_damaged_2.png new file mode 100644 index 0000000..5c0e951 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/anvil_top_damaged_2.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/beacon.png b/lwjgl-rundir/resources/textures/blocks/beacon.png new file mode 100644 index 0000000..fbd3d80 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/beacon.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/bed_feet_end.png b/lwjgl-rundir/resources/textures/blocks/bed_feet_end.png new file mode 100644 index 0000000..791243c Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/bed_feet_end.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/bed_feet_side.png b/lwjgl-rundir/resources/textures/blocks/bed_feet_side.png new file mode 100644 index 0000000..03f5193 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/bed_feet_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/bed_feet_top.png b/lwjgl-rundir/resources/textures/blocks/bed_feet_top.png new file mode 100644 index 0000000..f0efc24 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/bed_feet_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/bed_head_end.png b/lwjgl-rundir/resources/textures/blocks/bed_head_end.png new file mode 100644 index 0000000..9f4770d Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/bed_head_end.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/bed_head_side.png b/lwjgl-rundir/resources/textures/blocks/bed_head_side.png new file mode 100644 index 0000000..7041b04 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/bed_head_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/bed_head_top.png b/lwjgl-rundir/resources/textures/blocks/bed_head_top.png new file mode 100644 index 0000000..934d7d2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/bed_head_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/bedrock.png b/lwjgl-rundir/resources/textures/blocks/bedrock.png new file mode 100644 index 0000000..94c2ebe Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/bedrock.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/blockDiamond.png b/lwjgl-rundir/resources/textures/blocks/blockDiamond.png new file mode 100644 index 0000000..a874e39 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/blockDiamond.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/blockEmerald.png b/lwjgl-rundir/resources/textures/blocks/blockEmerald.png new file mode 100644 index 0000000..e16f2dc Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/blockEmerald.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/blockGold.png b/lwjgl-rundir/resources/textures/blocks/blockGold.png new file mode 100644 index 0000000..73aca21 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/blockGold.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/blockIron.png b/lwjgl-rundir/resources/textures/blocks/blockIron.png new file mode 100644 index 0000000..80535c2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/blockIron.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/blockLapis.png b/lwjgl-rundir/resources/textures/blocks/blockLapis.png new file mode 100644 index 0000000..0a4c85d Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/blockLapis.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/blockRedstone.png b/lwjgl-rundir/resources/textures/blocks/blockRedstone.png new file mode 100644 index 0000000..f04b979 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/blockRedstone.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/bookshelf.png b/lwjgl-rundir/resources/textures/blocks/bookshelf.png new file mode 100644 index 0000000..c1d63d0 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/bookshelf.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/brewingStand.png b/lwjgl-rundir/resources/textures/blocks/brewingStand.png new file mode 100644 index 0000000..504d68e Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/brewingStand.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/brewingStand_base.png b/lwjgl-rundir/resources/textures/blocks/brewingStand_base.png new file mode 100644 index 0000000..8ed7c85 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/brewingStand_base.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/brick.png b/lwjgl-rundir/resources/textures/blocks/brick.png new file mode 100644 index 0000000..c30f517 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/brick.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cactus_bottom.png b/lwjgl-rundir/resources/textures/blocks/cactus_bottom.png new file mode 100644 index 0000000..43a565f Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cactus_bottom.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cactus_side.png b/lwjgl-rundir/resources/textures/blocks/cactus_side.png new file mode 100644 index 0000000..de32a84 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cactus_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cactus_top.png b/lwjgl-rundir/resources/textures/blocks/cactus_top.png new file mode 100644 index 0000000..24cac9d Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cactus_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cake_bottom.png b/lwjgl-rundir/resources/textures/blocks/cake_bottom.png new file mode 100644 index 0000000..b1e28b3 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cake_bottom.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cake_inner.png b/lwjgl-rundir/resources/textures/blocks/cake_inner.png new file mode 100644 index 0000000..12d0f13 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cake_inner.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cake_side.png b/lwjgl-rundir/resources/textures/blocks/cake_side.png new file mode 100644 index 0000000..ccec604 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cake_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cake_top.png b/lwjgl-rundir/resources/textures/blocks/cake_top.png new file mode 100644 index 0000000..aff03b3 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cake_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/carrots_0.png b/lwjgl-rundir/resources/textures/blocks/carrots_0.png new file mode 100644 index 0000000..2ad8904 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/carrots_0.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/carrots_1.png b/lwjgl-rundir/resources/textures/blocks/carrots_1.png new file mode 100644 index 0000000..86a1998 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/carrots_1.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/carrots_2.png b/lwjgl-rundir/resources/textures/blocks/carrots_2.png new file mode 100644 index 0000000..c6501b7 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/carrots_2.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/carrots_3.png b/lwjgl-rundir/resources/textures/blocks/carrots_3.png new file mode 100644 index 0000000..a9bf5af Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/carrots_3.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cauldron_bottom.png b/lwjgl-rundir/resources/textures/blocks/cauldron_bottom.png new file mode 100644 index 0000000..d7bc1ba Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cauldron_bottom.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cauldron_inner.png b/lwjgl-rundir/resources/textures/blocks/cauldron_inner.png new file mode 100644 index 0000000..5a7f667 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cauldron_inner.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cauldron_side.png b/lwjgl-rundir/resources/textures/blocks/cauldron_side.png new file mode 100644 index 0000000..008fac8 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cauldron_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cauldron_top.png b/lwjgl-rundir/resources/textures/blocks/cauldron_top.png new file mode 100644 index 0000000..550ffca Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cauldron_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/clay.png b/lwjgl-rundir/resources/textures/blocks/clay.png new file mode 100644 index 0000000..ff52b1a Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/clay.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_0.png b/lwjgl-rundir/resources/textures/blocks/cloth_0.png new file mode 100644 index 0000000..f5ab041 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_0.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_1.png b/lwjgl-rundir/resources/textures/blocks/cloth_1.png new file mode 100644 index 0000000..6d8420e Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_1.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_10.png b/lwjgl-rundir/resources/textures/blocks/cloth_10.png new file mode 100644 index 0000000..62b5f3a Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_10.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_11.png b/lwjgl-rundir/resources/textures/blocks/cloth_11.png new file mode 100644 index 0000000..ffd8272 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_11.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_12.png b/lwjgl-rundir/resources/textures/blocks/cloth_12.png new file mode 100644 index 0000000..93eafeb Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_12.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_13.png b/lwjgl-rundir/resources/textures/blocks/cloth_13.png new file mode 100644 index 0000000..252c3c2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_13.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_14.png b/lwjgl-rundir/resources/textures/blocks/cloth_14.png new file mode 100644 index 0000000..16582da Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_14.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_15.png b/lwjgl-rundir/resources/textures/blocks/cloth_15.png new file mode 100644 index 0000000..0dfd254 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_15.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_2.png b/lwjgl-rundir/resources/textures/blocks/cloth_2.png new file mode 100644 index 0000000..c34be07 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_2.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_3.png b/lwjgl-rundir/resources/textures/blocks/cloth_3.png new file mode 100644 index 0000000..c4433c1 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_3.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_4.png b/lwjgl-rundir/resources/textures/blocks/cloth_4.png new file mode 100644 index 0000000..b9da2b9 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_4.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_5.png b/lwjgl-rundir/resources/textures/blocks/cloth_5.png new file mode 100644 index 0000000..3e64090 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_5.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_6.png b/lwjgl-rundir/resources/textures/blocks/cloth_6.png new file mode 100644 index 0000000..498e6fd Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_6.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_7.png b/lwjgl-rundir/resources/textures/blocks/cloth_7.png new file mode 100644 index 0000000..48f1f6f Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_7.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_8.png b/lwjgl-rundir/resources/textures/blocks/cloth_8.png new file mode 100644 index 0000000..38d7ed5 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_8.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cloth_9.png b/lwjgl-rundir/resources/textures/blocks/cloth_9.png new file mode 100644 index 0000000..02ba25e Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cloth_9.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cocoa_0.png b/lwjgl-rundir/resources/textures/blocks/cocoa_0.png new file mode 100644 index 0000000..0c7ca44 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cocoa_0.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cocoa_1.png b/lwjgl-rundir/resources/textures/blocks/cocoa_1.png new file mode 100644 index 0000000..8e6ac1b Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cocoa_1.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/cocoa_2.png b/lwjgl-rundir/resources/textures/blocks/cocoa_2.png new file mode 100644 index 0000000..eeb88f7 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/cocoa_2.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/commandBlock.png b/lwjgl-rundir/resources/textures/blocks/commandBlock.png new file mode 100644 index 0000000..bfa38a6 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/commandBlock.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/comparator.png b/lwjgl-rundir/resources/textures/blocks/comparator.png new file mode 100644 index 0000000..bf4f5b4 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/comparator.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/comparator_lit.png b/lwjgl-rundir/resources/textures/blocks/comparator_lit.png new file mode 100644 index 0000000..cdf9fbe Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/comparator_lit.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/crops_0.png b/lwjgl-rundir/resources/textures/blocks/crops_0.png new file mode 100644 index 0000000..81a7fd1 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/crops_0.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/crops_1.png b/lwjgl-rundir/resources/textures/blocks/crops_1.png new file mode 100644 index 0000000..7ce1969 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/crops_1.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/crops_2.png b/lwjgl-rundir/resources/textures/blocks/crops_2.png new file mode 100644 index 0000000..aae8208 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/crops_2.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/crops_3.png b/lwjgl-rundir/resources/textures/blocks/crops_3.png new file mode 100644 index 0000000..d122400 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/crops_3.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/crops_4.png b/lwjgl-rundir/resources/textures/blocks/crops_4.png new file mode 100644 index 0000000..8557928 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/crops_4.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/crops_5.png b/lwjgl-rundir/resources/textures/blocks/crops_5.png new file mode 100644 index 0000000..2ea1ed5 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/crops_5.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/crops_6.png b/lwjgl-rundir/resources/textures/blocks/crops_6.png new file mode 100644 index 0000000..72960a7 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/crops_6.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/crops_7.png b/lwjgl-rundir/resources/textures/blocks/crops_7.png new file mode 100644 index 0000000..bc73d63 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/crops_7.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/daylightDetector_side.png b/lwjgl-rundir/resources/textures/blocks/daylightDetector_side.png new file mode 100644 index 0000000..ddd3af1 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/daylightDetector_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/daylightDetector_top.png b/lwjgl-rundir/resources/textures/blocks/daylightDetector_top.png new file mode 100644 index 0000000..cdac108 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/daylightDetector_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/deadbush.png b/lwjgl-rundir/resources/textures/blocks/deadbush.png new file mode 100644 index 0000000..f2d5e35 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/deadbush.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/destroy_0.png b/lwjgl-rundir/resources/textures/blocks/destroy_0.png new file mode 100644 index 0000000..7909a3e Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/destroy_0.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/destroy_1.png b/lwjgl-rundir/resources/textures/blocks/destroy_1.png new file mode 100644 index 0000000..c2a15ff Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/destroy_1.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/destroy_2.png b/lwjgl-rundir/resources/textures/blocks/destroy_2.png new file mode 100644 index 0000000..a1acb5a Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/destroy_2.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/destroy_3.png b/lwjgl-rundir/resources/textures/blocks/destroy_3.png new file mode 100644 index 0000000..44c8300 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/destroy_3.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/destroy_4.png b/lwjgl-rundir/resources/textures/blocks/destroy_4.png new file mode 100644 index 0000000..9242002 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/destroy_4.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/destroy_5.png b/lwjgl-rundir/resources/textures/blocks/destroy_5.png new file mode 100644 index 0000000..140d158 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/destroy_5.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/destroy_6.png b/lwjgl-rundir/resources/textures/blocks/destroy_6.png new file mode 100644 index 0000000..a2f31cb Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/destroy_6.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/destroy_7.png b/lwjgl-rundir/resources/textures/blocks/destroy_7.png new file mode 100644 index 0000000..12bbe6a Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/destroy_7.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/destroy_8.png b/lwjgl-rundir/resources/textures/blocks/destroy_8.png new file mode 100644 index 0000000..c1312ec Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/destroy_8.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/destroy_9.png b/lwjgl-rundir/resources/textures/blocks/destroy_9.png new file mode 100644 index 0000000..828ea15 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/destroy_9.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/detectorRail.png b/lwjgl-rundir/resources/textures/blocks/detectorRail.png new file mode 100644 index 0000000..dc126a5 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/detectorRail.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/detectorRail_on.png b/lwjgl-rundir/resources/textures/blocks/detectorRail_on.png new file mode 100644 index 0000000..ac06d26 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/detectorRail_on.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/dirt.png b/lwjgl-rundir/resources/textures/blocks/dirt.png new file mode 100644 index 0000000..e0ed2bc Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/dirt.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/dispenser_front.png b/lwjgl-rundir/resources/textures/blocks/dispenser_front.png new file mode 100644 index 0000000..af0c298 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/dispenser_front.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/dispenser_front_vertical.png b/lwjgl-rundir/resources/textures/blocks/dispenser_front_vertical.png new file mode 100644 index 0000000..7092af0 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/dispenser_front_vertical.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/doorIron_lower.png b/lwjgl-rundir/resources/textures/blocks/doorIron_lower.png new file mode 100644 index 0000000..6cea30e Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/doorIron_lower.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/doorIron_upper.png b/lwjgl-rundir/resources/textures/blocks/doorIron_upper.png new file mode 100644 index 0000000..f88eace Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/doorIron_upper.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/doorWood_lower.png b/lwjgl-rundir/resources/textures/blocks/doorWood_lower.png new file mode 100644 index 0000000..8f41b65 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/doorWood_lower.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/doorWood_upper.png b/lwjgl-rundir/resources/textures/blocks/doorWood_upper.png new file mode 100644 index 0000000..c086ca1 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/doorWood_upper.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/dragonEgg.png b/lwjgl-rundir/resources/textures/blocks/dragonEgg.png new file mode 100644 index 0000000..2cc61a2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/dragonEgg.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/dropper_front.png b/lwjgl-rundir/resources/textures/blocks/dropper_front.png new file mode 100644 index 0000000..e8c2ff9 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/dropper_front.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/dropper_front_vertical.png b/lwjgl-rundir/resources/textures/blocks/dropper_front_vertical.png new file mode 100644 index 0000000..2dda923 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/dropper_front_vertical.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/enchantment_bottom.png b/lwjgl-rundir/resources/textures/blocks/enchantment_bottom.png new file mode 100644 index 0000000..13f189a Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/enchantment_bottom.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/enchantment_side.png b/lwjgl-rundir/resources/textures/blocks/enchantment_side.png new file mode 100644 index 0000000..e92fa98 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/enchantment_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/enchantment_top.png b/lwjgl-rundir/resources/textures/blocks/enchantment_top.png new file mode 100644 index 0000000..8d63efd Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/enchantment_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/endframe_eye.png b/lwjgl-rundir/resources/textures/blocks/endframe_eye.png new file mode 100644 index 0000000..8ecd36a Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/endframe_eye.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/endframe_side.png b/lwjgl-rundir/resources/textures/blocks/endframe_side.png new file mode 100644 index 0000000..eb68587 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/endframe_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/endframe_top.png b/lwjgl-rundir/resources/textures/blocks/endframe_top.png new file mode 100644 index 0000000..80a94fd Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/endframe_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/farmland_dry.png b/lwjgl-rundir/resources/textures/blocks/farmland_dry.png new file mode 100644 index 0000000..dc4c502 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/farmland_dry.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/farmland_wet.png b/lwjgl-rundir/resources/textures/blocks/farmland_wet.png new file mode 100644 index 0000000..859504b Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/farmland_wet.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/fenceIron.png b/lwjgl-rundir/resources/textures/blocks/fenceIron.png new file mode 100644 index 0000000..82d18ab Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/fenceIron.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/fern.png b/lwjgl-rundir/resources/textures/blocks/fern.png new file mode 100644 index 0000000..d203956 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/fern.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/fire_0.png b/lwjgl-rundir/resources/textures/blocks/fire_0.png new file mode 100644 index 0000000..a7f0626 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/fire_0.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/fire_0.txt b/lwjgl-rundir/resources/textures/blocks/fire_0.txt new file mode 100644 index 0000000..0cd6d4b --- /dev/null +++ b/lwjgl-rundir/resources/textures/blocks/fire_0.txt @@ -0,0 +1 @@ +8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7 \ No newline at end of file diff --git a/lwjgl-rundir/resources/textures/blocks/fire_1.png b/lwjgl-rundir/resources/textures/blocks/fire_1.png new file mode 100644 index 0000000..183f263 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/fire_1.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/fire_1.txt b/lwjgl-rundir/resources/textures/blocks/fire_1.txt new file mode 100644 index 0000000..e69de29 diff --git a/lwjgl-rundir/resources/textures/blocks/flower.png b/lwjgl-rundir/resources/textures/blocks/flower.png new file mode 100644 index 0000000..66fcf8a Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/flower.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/flowerPot.png b/lwjgl-rundir/resources/textures/blocks/flowerPot.png new file mode 100644 index 0000000..925d6d1 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/flowerPot.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/furnace_front.png b/lwjgl-rundir/resources/textures/blocks/furnace_front.png new file mode 100644 index 0000000..ba8baf3 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/furnace_front.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/furnace_front_lit.png b/lwjgl-rundir/resources/textures/blocks/furnace_front_lit.png new file mode 100644 index 0000000..43e3d3c Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/furnace_front_lit.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/furnace_side.png b/lwjgl-rundir/resources/textures/blocks/furnace_side.png new file mode 100644 index 0000000..0dd8e43 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/furnace_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/furnace_top.png b/lwjgl-rundir/resources/textures/blocks/furnace_top.png new file mode 100644 index 0000000..acd96f8 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/furnace_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/glass.png b/lwjgl-rundir/resources/textures/blocks/glass.png new file mode 100644 index 0000000..eab5d25 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/glass.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/goldenRail.png b/lwjgl-rundir/resources/textures/blocks/goldenRail.png new file mode 100644 index 0000000..dab1420 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/goldenRail.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/goldenRail_powered.png b/lwjgl-rundir/resources/textures/blocks/goldenRail_powered.png new file mode 100644 index 0000000..b1131b2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/goldenRail_powered.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/grass_side.png b/lwjgl-rundir/resources/textures/blocks/grass_side.png new file mode 100644 index 0000000..10c9651 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/grass_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/grass_side_overlay.png b/lwjgl-rundir/resources/textures/blocks/grass_side_overlay.png new file mode 100644 index 0000000..6e8d487 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/grass_side_overlay.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/grass_top.png b/lwjgl-rundir/resources/textures/blocks/grass_top.png new file mode 100644 index 0000000..52b0c56 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/grass_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/gravel.png b/lwjgl-rundir/resources/textures/blocks/gravel.png new file mode 100644 index 0000000..2043314 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/gravel.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/hellrock.png b/lwjgl-rundir/resources/textures/blocks/hellrock.png new file mode 100644 index 0000000..d611a0e Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/hellrock.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/hellsand.png b/lwjgl-rundir/resources/textures/blocks/hellsand.png new file mode 100644 index 0000000..46314f3 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/hellsand.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/hopper.png b/lwjgl-rundir/resources/textures/blocks/hopper.png new file mode 100644 index 0000000..a7453b8 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/hopper.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/hopper_inside.png b/lwjgl-rundir/resources/textures/blocks/hopper_inside.png new file mode 100644 index 0000000..2e07be8 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/hopper_inside.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/hopper_top.png b/lwjgl-rundir/resources/textures/blocks/hopper_top.png new file mode 100644 index 0000000..550ffca Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/hopper_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/ice.png b/lwjgl-rundir/resources/textures/blocks/ice.png new file mode 100644 index 0000000..6ecd8bd Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/ice.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/itemframe_back.png b/lwjgl-rundir/resources/textures/blocks/itemframe_back.png new file mode 100644 index 0000000..7b787a2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/itemframe_back.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/jukebox_top.png b/lwjgl-rundir/resources/textures/blocks/jukebox_top.png new file mode 100644 index 0000000..1ecd301 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/jukebox_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/ladder.png b/lwjgl-rundir/resources/textures/blocks/ladder.png new file mode 100644 index 0000000..07ed735 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/ladder.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/lava.png b/lwjgl-rundir/resources/textures/blocks/lava.png new file mode 100644 index 0000000..6230b53 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/lava.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/lava.txt b/lwjgl-rundir/resources/textures/blocks/lava.txt new file mode 100644 index 0000000..82afa8d --- /dev/null +++ b/lwjgl-rundir/resources/textures/blocks/lava.txt @@ -0,0 +1 @@ +0*2,1*2,2*2,3*2,4*2,5*2,6*2,7*2,8*2,9*2,10*2,11*2,12*2,13*2,14*2,15*2,16*2,17*2,18*2,19*2,18*2,17*2,16*2,15*2,14*2,13*2,12*2,11*2,10*2,9*2,8*2,7*2,6*2,5*2,4*2,3*2,2*2,1*2 \ No newline at end of file diff --git a/lwjgl-rundir/resources/textures/blocks/lava_flow.png b/lwjgl-rundir/resources/textures/blocks/lava_flow.png new file mode 100644 index 0000000..78ca3c2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/lava_flow.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/lava_flow.txt b/lwjgl-rundir/resources/textures/blocks/lava_flow.txt new file mode 100644 index 0000000..af85f2f --- /dev/null +++ b/lwjgl-rundir/resources/textures/blocks/lava_flow.txt @@ -0,0 +1 @@ +0*3,1*3,2*3,3*3,4*3,5*3,6*3,7*3,8*3,9*3,10*3,11*3,12*3,13*3,14*3,15*3 \ No newline at end of file diff --git a/lwjgl-rundir/resources/textures/blocks/leaves.png b/lwjgl-rundir/resources/textures/blocks/leaves.png new file mode 100644 index 0000000..2f132f2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/leaves.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/leaves_jungle.png b/lwjgl-rundir/resources/textures/blocks/leaves_jungle.png new file mode 100644 index 0000000..70bce94 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/leaves_jungle.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/leaves_jungle_opaque.png b/lwjgl-rundir/resources/textures/blocks/leaves_jungle_opaque.png new file mode 100644 index 0000000..899e959 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/leaves_jungle_opaque.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/leaves_opaque.png b/lwjgl-rundir/resources/textures/blocks/leaves_opaque.png new file mode 100644 index 0000000..37331dd Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/leaves_opaque.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/leaves_spruce.png b/lwjgl-rundir/resources/textures/blocks/leaves_spruce.png new file mode 100644 index 0000000..c79033a Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/leaves_spruce.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/leaves_spruce_opaque.png b/lwjgl-rundir/resources/textures/blocks/leaves_spruce_opaque.png new file mode 100644 index 0000000..f2f83ba Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/leaves_spruce_opaque.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/lever.png b/lwjgl-rundir/resources/textures/blocks/lever.png new file mode 100644 index 0000000..916d9e6 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/lever.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/lightgem.png b/lwjgl-rundir/resources/textures/blocks/lightgem.png new file mode 100644 index 0000000..171002e Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/lightgem.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/melon_side.png b/lwjgl-rundir/resources/textures/blocks/melon_side.png new file mode 100644 index 0000000..7061cfe Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/melon_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/melon_top.png b/lwjgl-rundir/resources/textures/blocks/melon_top.png new file mode 100644 index 0000000..98d2463 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/melon_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/mobSpawner.png b/lwjgl-rundir/resources/textures/blocks/mobSpawner.png new file mode 100644 index 0000000..c6a13d5 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/mobSpawner.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/mushroom_brown.png b/lwjgl-rundir/resources/textures/blocks/mushroom_brown.png new file mode 100644 index 0000000..3349052 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/mushroom_brown.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/mushroom_inside.png b/lwjgl-rundir/resources/textures/blocks/mushroom_inside.png new file mode 100644 index 0000000..187740c Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/mushroom_inside.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/mushroom_red.png b/lwjgl-rundir/resources/textures/blocks/mushroom_red.png new file mode 100644 index 0000000..8341a7e Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/mushroom_red.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/mushroom_skin_brown.png b/lwjgl-rundir/resources/textures/blocks/mushroom_skin_brown.png new file mode 100644 index 0000000..530da05 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/mushroom_skin_brown.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/mushroom_skin_red.png b/lwjgl-rundir/resources/textures/blocks/mushroom_skin_red.png new file mode 100644 index 0000000..3767ab0 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/mushroom_skin_red.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/mushroom_skin_stem.png b/lwjgl-rundir/resources/textures/blocks/mushroom_skin_stem.png new file mode 100644 index 0000000..270d340 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/mushroom_skin_stem.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/musicBlock.png b/lwjgl-rundir/resources/textures/blocks/musicBlock.png new file mode 100644 index 0000000..db5c6fc Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/musicBlock.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/mycel_side.png b/lwjgl-rundir/resources/textures/blocks/mycel_side.png new file mode 100644 index 0000000..296da07 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/mycel_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/mycel_top.png b/lwjgl-rundir/resources/textures/blocks/mycel_top.png new file mode 100644 index 0000000..3ae6bbd Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/mycel_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/netherBrick.png b/lwjgl-rundir/resources/textures/blocks/netherBrick.png new file mode 100644 index 0000000..f9dc7ab Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/netherBrick.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/netherStalk_0.png b/lwjgl-rundir/resources/textures/blocks/netherStalk_0.png new file mode 100644 index 0000000..50d00e0 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/netherStalk_0.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/netherStalk_1.png b/lwjgl-rundir/resources/textures/blocks/netherStalk_1.png new file mode 100644 index 0000000..35f719e Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/netherStalk_1.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/netherStalk_2.png b/lwjgl-rundir/resources/textures/blocks/netherStalk_2.png new file mode 100644 index 0000000..fd4fb1a Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/netherStalk_2.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/netherquartz.png b/lwjgl-rundir/resources/textures/blocks/netherquartz.png new file mode 100644 index 0000000..dacf288 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/netherquartz.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/obsidian.png b/lwjgl-rundir/resources/textures/blocks/obsidian.png new file mode 100644 index 0000000..395e1b8 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/obsidian.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/oreCoal.png b/lwjgl-rundir/resources/textures/blocks/oreCoal.png new file mode 100644 index 0000000..e0d2d10 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/oreCoal.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/oreDiamond.png b/lwjgl-rundir/resources/textures/blocks/oreDiamond.png new file mode 100644 index 0000000..90ac839 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/oreDiamond.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/oreEmerald.png b/lwjgl-rundir/resources/textures/blocks/oreEmerald.png new file mode 100644 index 0000000..39cb86d Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/oreEmerald.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/oreGold.png b/lwjgl-rundir/resources/textures/blocks/oreGold.png new file mode 100644 index 0000000..48f9285 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/oreGold.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/oreIron.png b/lwjgl-rundir/resources/textures/blocks/oreIron.png new file mode 100644 index 0000000..74bd2b1 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/oreIron.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/oreLapis.png b/lwjgl-rundir/resources/textures/blocks/oreLapis.png new file mode 100644 index 0000000..3a62dee Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/oreLapis.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/oreRedstone.png b/lwjgl-rundir/resources/textures/blocks/oreRedstone.png new file mode 100644 index 0000000..7df7c3f Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/oreRedstone.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/piston_bottom.png b/lwjgl-rundir/resources/textures/blocks/piston_bottom.png new file mode 100644 index 0000000..acd96f8 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/piston_bottom.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/piston_inner_top.png b/lwjgl-rundir/resources/textures/blocks/piston_inner_top.png new file mode 100644 index 0000000..10fd3d6 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/piston_inner_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/piston_side.png b/lwjgl-rundir/resources/textures/blocks/piston_side.png new file mode 100644 index 0000000..40c3514 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/piston_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/piston_top.png b/lwjgl-rundir/resources/textures/blocks/piston_top.png new file mode 100644 index 0000000..b029a44 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/piston_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/piston_top_sticky.png b/lwjgl-rundir/resources/textures/blocks/piston_top_sticky.png new file mode 100644 index 0000000..a530c78 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/piston_top_sticky.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/portal.png b/lwjgl-rundir/resources/textures/blocks/portal.png new file mode 100644 index 0000000..93651ec Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/portal.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/portal.txt b/lwjgl-rundir/resources/textures/blocks/portal.txt new file mode 100644 index 0000000..e69de29 diff --git a/lwjgl-rundir/resources/textures/blocks/potatoes_0.png b/lwjgl-rundir/resources/textures/blocks/potatoes_0.png new file mode 100644 index 0000000..2ad8904 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/potatoes_0.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/potatoes_1.png b/lwjgl-rundir/resources/textures/blocks/potatoes_1.png new file mode 100644 index 0000000..86a1998 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/potatoes_1.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/potatoes_2.png b/lwjgl-rundir/resources/textures/blocks/potatoes_2.png new file mode 100644 index 0000000..c6501b7 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/potatoes_2.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/potatoes_3.png b/lwjgl-rundir/resources/textures/blocks/potatoes_3.png new file mode 100644 index 0000000..4c81c8d Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/potatoes_3.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/pumpkin_face.png b/lwjgl-rundir/resources/textures/blocks/pumpkin_face.png new file mode 100644 index 0000000..3dd769a Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/pumpkin_face.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/pumpkin_jack.png b/lwjgl-rundir/resources/textures/blocks/pumpkin_jack.png new file mode 100644 index 0000000..5adc2dd Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/pumpkin_jack.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/pumpkin_side.png b/lwjgl-rundir/resources/textures/blocks/pumpkin_side.png new file mode 100644 index 0000000..85b1dac Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/pumpkin_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/pumpkin_top.png b/lwjgl-rundir/resources/textures/blocks/pumpkin_top.png new file mode 100644 index 0000000..ab6c4ec Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/pumpkin_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/quartzblock_bottom.png b/lwjgl-rundir/resources/textures/blocks/quartzblock_bottom.png new file mode 100644 index 0000000..b6f5462 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/quartzblock_bottom.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/quartzblock_chiseled.png b/lwjgl-rundir/resources/textures/blocks/quartzblock_chiseled.png new file mode 100644 index 0000000..05a127f Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/quartzblock_chiseled.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/quartzblock_chiseled_top.png b/lwjgl-rundir/resources/textures/blocks/quartzblock_chiseled_top.png new file mode 100644 index 0000000..9107cbd Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/quartzblock_chiseled_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/quartzblock_lines.png b/lwjgl-rundir/resources/textures/blocks/quartzblock_lines.png new file mode 100644 index 0000000..b6dfccf Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/quartzblock_lines.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/quartzblock_lines_top.png b/lwjgl-rundir/resources/textures/blocks/quartzblock_lines_top.png new file mode 100644 index 0000000..95b66dc Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/quartzblock_lines_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/quartzblock_side.png b/lwjgl-rundir/resources/textures/blocks/quartzblock_side.png new file mode 100644 index 0000000..27f83e0 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/quartzblock_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/quartzblock_top.png b/lwjgl-rundir/resources/textures/blocks/quartzblock_top.png new file mode 100644 index 0000000..27f83e0 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/quartzblock_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/rail.png b/lwjgl-rundir/resources/textures/blocks/rail.png new file mode 100644 index 0000000..777dcec Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/rail.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/rail_turn.png b/lwjgl-rundir/resources/textures/blocks/rail_turn.png new file mode 100644 index 0000000..38fe6e2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/rail_turn.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/redstoneDust_cross.png b/lwjgl-rundir/resources/textures/blocks/redstoneDust_cross.png new file mode 100644 index 0000000..bb748ca Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/redstoneDust_cross.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/redstoneDust_cross_overlay.png b/lwjgl-rundir/resources/textures/blocks/redstoneDust_cross_overlay.png new file mode 100644 index 0000000..d187124 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/redstoneDust_cross_overlay.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/redstoneDust_line.png b/lwjgl-rundir/resources/textures/blocks/redstoneDust_line.png new file mode 100644 index 0000000..f8453de Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/redstoneDust_line.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/redstoneDust_line_overlay.png b/lwjgl-rundir/resources/textures/blocks/redstoneDust_line_overlay.png new file mode 100644 index 0000000..d187124 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/redstoneDust_line_overlay.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/redstoneLight.png b/lwjgl-rundir/resources/textures/blocks/redstoneLight.png new file mode 100644 index 0000000..0a28379 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/redstoneLight.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/redstoneLight_lit.png b/lwjgl-rundir/resources/textures/blocks/redstoneLight_lit.png new file mode 100644 index 0000000..7b787f0 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/redstoneLight_lit.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/redtorch.png b/lwjgl-rundir/resources/textures/blocks/redtorch.png new file mode 100644 index 0000000..e92063d Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/redtorch.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/redtorch_lit.png b/lwjgl-rundir/resources/textures/blocks/redtorch_lit.png new file mode 100644 index 0000000..970ec83 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/redtorch_lit.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/reeds.png b/lwjgl-rundir/resources/textures/blocks/reeds.png new file mode 100644 index 0000000..aeadd15 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/reeds.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/repeater.png b/lwjgl-rundir/resources/textures/blocks/repeater.png new file mode 100644 index 0000000..67b182e Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/repeater.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/repeater_lit.png b/lwjgl-rundir/resources/textures/blocks/repeater_lit.png new file mode 100644 index 0000000..1c1f9d4 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/repeater_lit.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/rose.png b/lwjgl-rundir/resources/textures/blocks/rose.png new file mode 100644 index 0000000..d54d226 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/rose.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/sand.png b/lwjgl-rundir/resources/textures/blocks/sand.png new file mode 100644 index 0000000..17b6f28 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/sand.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/sandstone_bottom.png b/lwjgl-rundir/resources/textures/blocks/sandstone_bottom.png new file mode 100644 index 0000000..0a528d7 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/sandstone_bottom.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/sandstone_carved.png b/lwjgl-rundir/resources/textures/blocks/sandstone_carved.png new file mode 100644 index 0000000..6fb022d Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/sandstone_carved.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/sandstone_side.png b/lwjgl-rundir/resources/textures/blocks/sandstone_side.png new file mode 100644 index 0000000..f74185d Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/sandstone_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/sandstone_smooth.png b/lwjgl-rundir/resources/textures/blocks/sandstone_smooth.png new file mode 100644 index 0000000..0eace1f Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/sandstone_smooth.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/sandstone_top.png b/lwjgl-rundir/resources/textures/blocks/sandstone_top.png new file mode 100644 index 0000000..bee77bd Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/sandstone_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/sapling.png b/lwjgl-rundir/resources/textures/blocks/sapling.png new file mode 100644 index 0000000..b38a4ff Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/sapling.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/sapling_birch.png b/lwjgl-rundir/resources/textures/blocks/sapling_birch.png new file mode 100644 index 0000000..596687d Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/sapling_birch.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/sapling_jungle.png b/lwjgl-rundir/resources/textures/blocks/sapling_jungle.png new file mode 100644 index 0000000..3d94a79 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/sapling_jungle.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/sapling_spruce.png b/lwjgl-rundir/resources/textures/blocks/sapling_spruce.png new file mode 100644 index 0000000..4ad0cf9 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/sapling_spruce.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/snow.png b/lwjgl-rundir/resources/textures/blocks/snow.png new file mode 100644 index 0000000..86b9df2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/snow.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/snow_side.png b/lwjgl-rundir/resources/textures/blocks/snow_side.png new file mode 100644 index 0000000..7972b42 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/snow_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/sponge.png b/lwjgl-rundir/resources/textures/blocks/sponge.png new file mode 100644 index 0000000..0a7fabc Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/sponge.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/stem_bent.png b/lwjgl-rundir/resources/textures/blocks/stem_bent.png new file mode 100644 index 0000000..8a2d9c6 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/stem_bent.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/stem_straight.png b/lwjgl-rundir/resources/textures/blocks/stem_straight.png new file mode 100644 index 0000000..48400c9 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/stem_straight.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/stone.png b/lwjgl-rundir/resources/textures/blocks/stone.png new file mode 100644 index 0000000..7ee01e8 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/stone.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/stoneMoss.png b/lwjgl-rundir/resources/textures/blocks/stoneMoss.png new file mode 100644 index 0000000..c4990fd Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/stoneMoss.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/stonebrick.png b/lwjgl-rundir/resources/textures/blocks/stonebrick.png new file mode 100644 index 0000000..628ba59 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/stonebrick.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/stonebricksmooth.png b/lwjgl-rundir/resources/textures/blocks/stonebricksmooth.png new file mode 100644 index 0000000..08948a8 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/stonebricksmooth.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/stonebricksmooth_carved.png b/lwjgl-rundir/resources/textures/blocks/stonebricksmooth_carved.png new file mode 100644 index 0000000..7407b30 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/stonebricksmooth_carved.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/stonebricksmooth_cracked.png b/lwjgl-rundir/resources/textures/blocks/stonebricksmooth_cracked.png new file mode 100644 index 0000000..97123c4 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/stonebricksmooth_cracked.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/stonebricksmooth_mossy.png b/lwjgl-rundir/resources/textures/blocks/stonebricksmooth_mossy.png new file mode 100644 index 0000000..afeadb2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/stonebricksmooth_mossy.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/stoneslab_side.png b/lwjgl-rundir/resources/textures/blocks/stoneslab_side.png new file mode 100644 index 0000000..0ce3ad1 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/stoneslab_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/stoneslab_top.png b/lwjgl-rundir/resources/textures/blocks/stoneslab_top.png new file mode 100644 index 0000000..2cf3d05 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/stoneslab_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/tallgrass.png b/lwjgl-rundir/resources/textures/blocks/tallgrass.png new file mode 100644 index 0000000..c62bbc6 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/tallgrass.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/thinglass_top.png b/lwjgl-rundir/resources/textures/blocks/thinglass_top.png new file mode 100644 index 0000000..d201f6e Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/thinglass_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/tnt_bottom.png b/lwjgl-rundir/resources/textures/blocks/tnt_bottom.png new file mode 100644 index 0000000..7238c51 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/tnt_bottom.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/tnt_side.png b/lwjgl-rundir/resources/textures/blocks/tnt_side.png new file mode 100644 index 0000000..5e119e3 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/tnt_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/tnt_top.png b/lwjgl-rundir/resources/textures/blocks/tnt_top.png new file mode 100644 index 0000000..5612bb8 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/tnt_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/torch.png b/lwjgl-rundir/resources/textures/blocks/torch.png new file mode 100644 index 0000000..9a7e20d Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/torch.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/trapdoor.png b/lwjgl-rundir/resources/textures/blocks/trapdoor.png new file mode 100644 index 0000000..64b83de Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/trapdoor.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/tree_birch.png b/lwjgl-rundir/resources/textures/blocks/tree_birch.png new file mode 100644 index 0000000..56920fb Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/tree_birch.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/tree_jungle.png b/lwjgl-rundir/resources/textures/blocks/tree_jungle.png new file mode 100644 index 0000000..fc298db Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/tree_jungle.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/tree_side.png b/lwjgl-rundir/resources/textures/blocks/tree_side.png new file mode 100644 index 0000000..ce5fb88 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/tree_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/tree_spruce.png b/lwjgl-rundir/resources/textures/blocks/tree_spruce.png new file mode 100644 index 0000000..a3197bb Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/tree_spruce.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/tree_top.png b/lwjgl-rundir/resources/textures/blocks/tree_top.png new file mode 100644 index 0000000..92dcad3 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/tree_top.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/tripWire.png b/lwjgl-rundir/resources/textures/blocks/tripWire.png new file mode 100644 index 0000000..fcaccd8 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/tripWire.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/tripWireSource.png b/lwjgl-rundir/resources/textures/blocks/tripWireSource.png new file mode 100644 index 0000000..fd113bc Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/tripWireSource.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/vine.png b/lwjgl-rundir/resources/textures/blocks/vine.png new file mode 100644 index 0000000..20edd62 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/vine.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/water.png b/lwjgl-rundir/resources/textures/blocks/water.png new file mode 100644 index 0000000..7775802 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/water.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/water.txt b/lwjgl-rundir/resources/textures/blocks/water.txt new file mode 100644 index 0000000..fc9eecf --- /dev/null +++ b/lwjgl-rundir/resources/textures/blocks/water.txt @@ -0,0 +1 @@ +0*2,1*2,2*2,3*2,4*2,5*2,6*2,7*2,8*2,9*2,10*2,11*2,12*2,13*2,14*2,15*2,16*2,17*2,18*2,19*2,20*2,21*2,22*2,23*2,24*2,25*2,26*2,27*2,28*2,29*2,30*2,31*2 \ No newline at end of file diff --git a/lwjgl-rundir/resources/textures/blocks/water_flow.png b/lwjgl-rundir/resources/textures/blocks/water_flow.png new file mode 100644 index 0000000..317e6cb Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/water_flow.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/water_flow.txt b/lwjgl-rundir/resources/textures/blocks/water_flow.txt new file mode 100644 index 0000000..e69de29 diff --git a/lwjgl-rundir/resources/textures/blocks/waterlily.png b/lwjgl-rundir/resources/textures/blocks/waterlily.png new file mode 100644 index 0000000..628f599 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/waterlily.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/web.png b/lwjgl-rundir/resources/textures/blocks/web.png new file mode 100644 index 0000000..9f66411 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/web.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/whiteStone.png b/lwjgl-rundir/resources/textures/blocks/whiteStone.png new file mode 100644 index 0000000..c6a0209 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/whiteStone.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/wood.png b/lwjgl-rundir/resources/textures/blocks/wood.png new file mode 100644 index 0000000..4093a74 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/wood.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/wood_birch.png b/lwjgl-rundir/resources/textures/blocks/wood_birch.png new file mode 100644 index 0000000..a0708e6 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/wood_birch.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/wood_jungle.png b/lwjgl-rundir/resources/textures/blocks/wood_jungle.png new file mode 100644 index 0000000..0d4be3e Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/wood_jungle.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/wood_spruce.png b/lwjgl-rundir/resources/textures/blocks/wood_spruce.png new file mode 100644 index 0000000..0b8f29d Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/wood_spruce.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/workbench_front.png b/lwjgl-rundir/resources/textures/blocks/workbench_front.png new file mode 100644 index 0000000..79efbd4 Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/workbench_front.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/workbench_side.png b/lwjgl-rundir/resources/textures/blocks/workbench_side.png new file mode 100644 index 0000000..42f1daa Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/workbench_side.png differ diff --git a/lwjgl-rundir/resources/textures/blocks/workbench_top.png b/lwjgl-rundir/resources/textures/blocks/workbench_top.png new file mode 100644 index 0000000..b97608b Binary files /dev/null and b/lwjgl-rundir/resources/textures/blocks/workbench_top.png differ diff --git a/lwjgl-rundir/resources/textures/items/apple.png b/lwjgl-rundir/resources/textures/items/apple.png new file mode 100644 index 0000000..3cefdec Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/apple.png differ diff --git a/lwjgl-rundir/resources/textures/items/appleGold.png b/lwjgl-rundir/resources/textures/items/appleGold.png new file mode 100644 index 0000000..be70371 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/appleGold.png differ diff --git a/lwjgl-rundir/resources/textures/items/arrow.png b/lwjgl-rundir/resources/textures/items/arrow.png new file mode 100644 index 0000000..571a123 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/arrow.png differ diff --git a/lwjgl-rundir/resources/textures/items/bed.png b/lwjgl-rundir/resources/textures/items/bed.png new file mode 100644 index 0000000..fa4e459 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bed.png differ diff --git a/lwjgl-rundir/resources/textures/items/beefCooked.png b/lwjgl-rundir/resources/textures/items/beefCooked.png new file mode 100644 index 0000000..e9c6433 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/beefCooked.png differ diff --git a/lwjgl-rundir/resources/textures/items/beefRaw.png b/lwjgl-rundir/resources/textures/items/beefRaw.png new file mode 100644 index 0000000..cca6de7 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/beefRaw.png differ diff --git a/lwjgl-rundir/resources/textures/items/blazePowder.png b/lwjgl-rundir/resources/textures/items/blazePowder.png new file mode 100644 index 0000000..b704953 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/blazePowder.png differ diff --git a/lwjgl-rundir/resources/textures/items/blazeRod.png b/lwjgl-rundir/resources/textures/items/blazeRod.png new file mode 100644 index 0000000..64e005f Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/blazeRod.png differ diff --git a/lwjgl-rundir/resources/textures/items/boat.png b/lwjgl-rundir/resources/textures/items/boat.png new file mode 100644 index 0000000..b2db405 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/boat.png differ diff --git a/lwjgl-rundir/resources/textures/items/bone.png b/lwjgl-rundir/resources/textures/items/bone.png new file mode 100644 index 0000000..0e88366 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bone.png differ diff --git a/lwjgl-rundir/resources/textures/items/book.png b/lwjgl-rundir/resources/textures/items/book.png new file mode 100644 index 0000000..114e7d0 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/book.png differ diff --git a/lwjgl-rundir/resources/textures/items/bootsChain.png b/lwjgl-rundir/resources/textures/items/bootsChain.png new file mode 100644 index 0000000..edc5f1c Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bootsChain.png differ diff --git a/lwjgl-rundir/resources/textures/items/bootsCloth.png b/lwjgl-rundir/resources/textures/items/bootsCloth.png new file mode 100644 index 0000000..d94d99f Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bootsCloth.png differ diff --git a/lwjgl-rundir/resources/textures/items/bootsCloth_overlay.png b/lwjgl-rundir/resources/textures/items/bootsCloth_overlay.png new file mode 100644 index 0000000..2502aad Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bootsCloth_overlay.png differ diff --git a/lwjgl-rundir/resources/textures/items/bootsDiamond.png b/lwjgl-rundir/resources/textures/items/bootsDiamond.png new file mode 100644 index 0000000..1ac390c Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bootsDiamond.png differ diff --git a/lwjgl-rundir/resources/textures/items/bootsGold.png b/lwjgl-rundir/resources/textures/items/bootsGold.png new file mode 100644 index 0000000..0e67de4 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bootsGold.png differ diff --git a/lwjgl-rundir/resources/textures/items/bootsIron.png b/lwjgl-rundir/resources/textures/items/bootsIron.png new file mode 100644 index 0000000..b8cac6f Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bootsIron.png differ diff --git a/lwjgl-rundir/resources/textures/items/bow.png b/lwjgl-rundir/resources/textures/items/bow.png new file mode 100644 index 0000000..1c40420 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bow.png differ diff --git a/lwjgl-rundir/resources/textures/items/bow_pull_0.png b/lwjgl-rundir/resources/textures/items/bow_pull_0.png new file mode 100644 index 0000000..c79ff6e Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bow_pull_0.png differ diff --git a/lwjgl-rundir/resources/textures/items/bow_pull_1.png b/lwjgl-rundir/resources/textures/items/bow_pull_1.png new file mode 100644 index 0000000..1bde6d4 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bow_pull_1.png differ diff --git a/lwjgl-rundir/resources/textures/items/bow_pull_2.png b/lwjgl-rundir/resources/textures/items/bow_pull_2.png new file mode 100644 index 0000000..0be0d0d Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bow_pull_2.png differ diff --git a/lwjgl-rundir/resources/textures/items/bowl.png b/lwjgl-rundir/resources/textures/items/bowl.png new file mode 100644 index 0000000..dac199a Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bowl.png differ diff --git a/lwjgl-rundir/resources/textures/items/bread.png b/lwjgl-rundir/resources/textures/items/bread.png new file mode 100644 index 0000000..5809735 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bread.png differ diff --git a/lwjgl-rundir/resources/textures/items/brewingStand.png b/lwjgl-rundir/resources/textures/items/brewingStand.png new file mode 100644 index 0000000..2633561 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/brewingStand.png differ diff --git a/lwjgl-rundir/resources/textures/items/brick.png b/lwjgl-rundir/resources/textures/items/brick.png new file mode 100644 index 0000000..b9214fb Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/brick.png differ diff --git a/lwjgl-rundir/resources/textures/items/bucket.png b/lwjgl-rundir/resources/textures/items/bucket.png new file mode 100644 index 0000000..b3c7b62 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bucket.png differ diff --git a/lwjgl-rundir/resources/textures/items/bucketLava.png b/lwjgl-rundir/resources/textures/items/bucketLava.png new file mode 100644 index 0000000..e3a9da8 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bucketLava.png differ diff --git a/lwjgl-rundir/resources/textures/items/bucketWater.png b/lwjgl-rundir/resources/textures/items/bucketWater.png new file mode 100644 index 0000000..6e1c6d6 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/bucketWater.png differ diff --git a/lwjgl-rundir/resources/textures/items/cake.png b/lwjgl-rundir/resources/textures/items/cake.png new file mode 100644 index 0000000..573636b Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/cake.png differ diff --git a/lwjgl-rundir/resources/textures/items/carrotGolden.png b/lwjgl-rundir/resources/textures/items/carrotGolden.png new file mode 100644 index 0000000..16cc464 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/carrotGolden.png differ diff --git a/lwjgl-rundir/resources/textures/items/carrotOnAStick.png b/lwjgl-rundir/resources/textures/items/carrotOnAStick.png new file mode 100644 index 0000000..fbaf5d5 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/carrotOnAStick.png differ diff --git a/lwjgl-rundir/resources/textures/items/carrots.png b/lwjgl-rundir/resources/textures/items/carrots.png new file mode 100644 index 0000000..afdc6db Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/carrots.png differ diff --git a/lwjgl-rundir/resources/textures/items/cauldron.png b/lwjgl-rundir/resources/textures/items/cauldron.png new file mode 100644 index 0000000..adce228 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/cauldron.png differ diff --git a/lwjgl-rundir/resources/textures/items/chestplateChain.png b/lwjgl-rundir/resources/textures/items/chestplateChain.png new file mode 100644 index 0000000..b8d1728 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/chestplateChain.png differ diff --git a/lwjgl-rundir/resources/textures/items/chestplateCloth.png b/lwjgl-rundir/resources/textures/items/chestplateCloth.png new file mode 100644 index 0000000..efa3ab9 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/chestplateCloth.png differ diff --git a/lwjgl-rundir/resources/textures/items/chestplateCloth_overlay.png b/lwjgl-rundir/resources/textures/items/chestplateCloth_overlay.png new file mode 100644 index 0000000..d187124 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/chestplateCloth_overlay.png differ diff --git a/lwjgl-rundir/resources/textures/items/chestplateDiamond.png b/lwjgl-rundir/resources/textures/items/chestplateDiamond.png new file mode 100644 index 0000000..c9c6d4a Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/chestplateDiamond.png differ diff --git a/lwjgl-rundir/resources/textures/items/chestplateGold.png b/lwjgl-rundir/resources/textures/items/chestplateGold.png new file mode 100644 index 0000000..3058fb3 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/chestplateGold.png differ diff --git a/lwjgl-rundir/resources/textures/items/chestplateIron.png b/lwjgl-rundir/resources/textures/items/chestplateIron.png new file mode 100644 index 0000000..21c6197 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/chestplateIron.png differ diff --git a/lwjgl-rundir/resources/textures/items/chickenCooked.png b/lwjgl-rundir/resources/textures/items/chickenCooked.png new file mode 100644 index 0000000..9087883 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/chickenCooked.png differ diff --git a/lwjgl-rundir/resources/textures/items/chickenRaw.png b/lwjgl-rundir/resources/textures/items/chickenRaw.png new file mode 100644 index 0000000..7dbabeb Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/chickenRaw.png differ diff --git a/lwjgl-rundir/resources/textures/items/clay.png b/lwjgl-rundir/resources/textures/items/clay.png new file mode 100644 index 0000000..82f4329 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/clay.png differ diff --git a/lwjgl-rundir/resources/textures/items/clock.png b/lwjgl-rundir/resources/textures/items/clock.png new file mode 100644 index 0000000..5bbcf5e Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/clock.png differ diff --git a/lwjgl-rundir/resources/textures/items/clock.txt b/lwjgl-rundir/resources/textures/items/clock.txt new file mode 100644 index 0000000..e69de29 diff --git a/lwjgl-rundir/resources/textures/items/coal.png b/lwjgl-rundir/resources/textures/items/coal.png new file mode 100644 index 0000000..c4bca21 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/coal.png differ diff --git a/lwjgl-rundir/resources/textures/items/comparator.png b/lwjgl-rundir/resources/textures/items/comparator.png new file mode 100644 index 0000000..d94439d Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/comparator.png differ diff --git a/lwjgl-rundir/resources/textures/items/compass.png b/lwjgl-rundir/resources/textures/items/compass.png new file mode 100644 index 0000000..d4c4d22 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/compass.png differ diff --git a/lwjgl-rundir/resources/textures/items/compass.txt b/lwjgl-rundir/resources/textures/items/compass.txt new file mode 100644 index 0000000..e69de29 diff --git a/lwjgl-rundir/resources/textures/items/cookie.png b/lwjgl-rundir/resources/textures/items/cookie.png new file mode 100644 index 0000000..aab73a4 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/cookie.png differ diff --git a/lwjgl-rundir/resources/textures/items/diamond.png b/lwjgl-rundir/resources/textures/items/diamond.png new file mode 100644 index 0000000..72c4d2c Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/diamond.png differ diff --git a/lwjgl-rundir/resources/textures/items/diode.png b/lwjgl-rundir/resources/textures/items/diode.png new file mode 100644 index 0000000..c9f3772 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/diode.png differ diff --git a/lwjgl-rundir/resources/textures/items/doorIron.png b/lwjgl-rundir/resources/textures/items/doorIron.png new file mode 100644 index 0000000..7cef62b Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/doorIron.png differ diff --git a/lwjgl-rundir/resources/textures/items/doorWood.png b/lwjgl-rundir/resources/textures/items/doorWood.png new file mode 100644 index 0000000..9cd1e9e Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/doorWood.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_black.png b/lwjgl-rundir/resources/textures/items/dyePowder_black.png new file mode 100644 index 0000000..ae92e98 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_black.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_blue.png b/lwjgl-rundir/resources/textures/items/dyePowder_blue.png new file mode 100644 index 0000000..988793d Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_blue.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_brown.png b/lwjgl-rundir/resources/textures/items/dyePowder_brown.png new file mode 100644 index 0000000..0b9585d Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_brown.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_cyan.png b/lwjgl-rundir/resources/textures/items/dyePowder_cyan.png new file mode 100644 index 0000000..ce115db Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_cyan.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_gray.png b/lwjgl-rundir/resources/textures/items/dyePowder_gray.png new file mode 100644 index 0000000..ef32b4f Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_gray.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_green.png b/lwjgl-rundir/resources/textures/items/dyePowder_green.png new file mode 100644 index 0000000..c5b9736 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_green.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_lightBlue.png b/lwjgl-rundir/resources/textures/items/dyePowder_lightBlue.png new file mode 100644 index 0000000..72ef065 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_lightBlue.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_lime.png b/lwjgl-rundir/resources/textures/items/dyePowder_lime.png new file mode 100644 index 0000000..e5d2eba Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_lime.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_magenta.png b/lwjgl-rundir/resources/textures/items/dyePowder_magenta.png new file mode 100644 index 0000000..825f277 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_magenta.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_orange.png b/lwjgl-rundir/resources/textures/items/dyePowder_orange.png new file mode 100644 index 0000000..814edf4 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_orange.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_pink.png b/lwjgl-rundir/resources/textures/items/dyePowder_pink.png new file mode 100644 index 0000000..28f1bbc Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_pink.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_purple.png b/lwjgl-rundir/resources/textures/items/dyePowder_purple.png new file mode 100644 index 0000000..7a0256c Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_purple.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_red.png b/lwjgl-rundir/resources/textures/items/dyePowder_red.png new file mode 100644 index 0000000..9d3de7e Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_red.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_silver.png b/lwjgl-rundir/resources/textures/items/dyePowder_silver.png new file mode 100644 index 0000000..31f0b0b Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_silver.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_white.png b/lwjgl-rundir/resources/textures/items/dyePowder_white.png new file mode 100644 index 0000000..23183a2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_white.png differ diff --git a/lwjgl-rundir/resources/textures/items/dyePowder_yellow.png b/lwjgl-rundir/resources/textures/items/dyePowder_yellow.png new file mode 100644 index 0000000..3e6af24 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/dyePowder_yellow.png differ diff --git a/lwjgl-rundir/resources/textures/items/egg.png b/lwjgl-rundir/resources/textures/items/egg.png new file mode 100644 index 0000000..047d0bb Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/egg.png differ diff --git a/lwjgl-rundir/resources/textures/items/emerald.png b/lwjgl-rundir/resources/textures/items/emerald.png new file mode 100644 index 0000000..17f577f Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/emerald.png differ diff --git a/lwjgl-rundir/resources/textures/items/emptyMap.png b/lwjgl-rundir/resources/textures/items/emptyMap.png new file mode 100644 index 0000000..558a462 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/emptyMap.png differ diff --git a/lwjgl-rundir/resources/textures/items/enchantedBook.png b/lwjgl-rundir/resources/textures/items/enchantedBook.png new file mode 100644 index 0000000..80c8af9 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/enchantedBook.png differ diff --git a/lwjgl-rundir/resources/textures/items/enderPearl.png b/lwjgl-rundir/resources/textures/items/enderPearl.png new file mode 100644 index 0000000..29db9fb Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/enderPearl.png differ diff --git a/lwjgl-rundir/resources/textures/items/expBottle.png b/lwjgl-rundir/resources/textures/items/expBottle.png new file mode 100644 index 0000000..ebb526c Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/expBottle.png differ diff --git a/lwjgl-rundir/resources/textures/items/eyeOfEnder.png b/lwjgl-rundir/resources/textures/items/eyeOfEnder.png new file mode 100644 index 0000000..36f7cf5 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/eyeOfEnder.png differ diff --git a/lwjgl-rundir/resources/textures/items/feather.png b/lwjgl-rundir/resources/textures/items/feather.png new file mode 100644 index 0000000..3872518 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/feather.png differ diff --git a/lwjgl-rundir/resources/textures/items/fermentedSpiderEye.png b/lwjgl-rundir/resources/textures/items/fermentedSpiderEye.png new file mode 100644 index 0000000..a66cc86 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/fermentedSpiderEye.png differ diff --git a/lwjgl-rundir/resources/textures/items/fireball.png b/lwjgl-rundir/resources/textures/items/fireball.png new file mode 100644 index 0000000..c6bf55a Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/fireball.png differ diff --git a/lwjgl-rundir/resources/textures/items/fireworks.png b/lwjgl-rundir/resources/textures/items/fireworks.png new file mode 100644 index 0000000..77b5822 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/fireworks.png differ diff --git a/lwjgl-rundir/resources/textures/items/fireworksCharge.png b/lwjgl-rundir/resources/textures/items/fireworksCharge.png new file mode 100644 index 0000000..865932e Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/fireworksCharge.png differ diff --git a/lwjgl-rundir/resources/textures/items/fireworksCharge_overlay.png b/lwjgl-rundir/resources/textures/items/fireworksCharge_overlay.png new file mode 100644 index 0000000..69fe67e Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/fireworksCharge_overlay.png differ diff --git a/lwjgl-rundir/resources/textures/items/fishCooked.png b/lwjgl-rundir/resources/textures/items/fishCooked.png new file mode 100644 index 0000000..98ba9d7 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/fishCooked.png differ diff --git a/lwjgl-rundir/resources/textures/items/fishRaw.png b/lwjgl-rundir/resources/textures/items/fishRaw.png new file mode 100644 index 0000000..73d1103 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/fishRaw.png differ diff --git a/lwjgl-rundir/resources/textures/items/fishingRod.png b/lwjgl-rundir/resources/textures/items/fishingRod.png new file mode 100644 index 0000000..fa483b1 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/fishingRod.png differ diff --git a/lwjgl-rundir/resources/textures/items/fishingRod_empty.png b/lwjgl-rundir/resources/textures/items/fishingRod_empty.png new file mode 100644 index 0000000..87f94f4 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/fishingRod_empty.png differ diff --git a/lwjgl-rundir/resources/textures/items/flint.png b/lwjgl-rundir/resources/textures/items/flint.png new file mode 100644 index 0000000..a6d9ce2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/flint.png differ diff --git a/lwjgl-rundir/resources/textures/items/flintAndSteel.png b/lwjgl-rundir/resources/textures/items/flintAndSteel.png new file mode 100644 index 0000000..24472bc Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/flintAndSteel.png differ diff --git a/lwjgl-rundir/resources/textures/items/flowerPot.png b/lwjgl-rundir/resources/textures/items/flowerPot.png new file mode 100644 index 0000000..4ae1022 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/flowerPot.png differ diff --git a/lwjgl-rundir/resources/textures/items/frame.png b/lwjgl-rundir/resources/textures/items/frame.png new file mode 100644 index 0000000..c553631 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/frame.png differ diff --git a/lwjgl-rundir/resources/textures/items/ghastTear.png b/lwjgl-rundir/resources/textures/items/ghastTear.png new file mode 100644 index 0000000..f7a3473 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/ghastTear.png differ diff --git a/lwjgl-rundir/resources/textures/items/glassBottle.png b/lwjgl-rundir/resources/textures/items/glassBottle.png new file mode 100644 index 0000000..55e0348 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/glassBottle.png differ diff --git a/lwjgl-rundir/resources/textures/items/goldNugget.png b/lwjgl-rundir/resources/textures/items/goldNugget.png new file mode 100644 index 0000000..6742153 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/goldNugget.png differ diff --git a/lwjgl-rundir/resources/textures/items/hatchetDiamond.png b/lwjgl-rundir/resources/textures/items/hatchetDiamond.png new file mode 100644 index 0000000..f66a3e7 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/hatchetDiamond.png differ diff --git a/lwjgl-rundir/resources/textures/items/hatchetGold.png b/lwjgl-rundir/resources/textures/items/hatchetGold.png new file mode 100644 index 0000000..c886732 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/hatchetGold.png differ diff --git a/lwjgl-rundir/resources/textures/items/hatchetIron.png b/lwjgl-rundir/resources/textures/items/hatchetIron.png new file mode 100644 index 0000000..430d26b Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/hatchetIron.png differ diff --git a/lwjgl-rundir/resources/textures/items/hatchetStone.png b/lwjgl-rundir/resources/textures/items/hatchetStone.png new file mode 100644 index 0000000..dc19607 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/hatchetStone.png differ diff --git a/lwjgl-rundir/resources/textures/items/hatchetWood.png b/lwjgl-rundir/resources/textures/items/hatchetWood.png new file mode 100644 index 0000000..a3fd06a Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/hatchetWood.png differ diff --git a/lwjgl-rundir/resources/textures/items/helmetChain.png b/lwjgl-rundir/resources/textures/items/helmetChain.png new file mode 100644 index 0000000..8f726af Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/helmetChain.png differ diff --git a/lwjgl-rundir/resources/textures/items/helmetCloth.png b/lwjgl-rundir/resources/textures/items/helmetCloth.png new file mode 100644 index 0000000..e0cc094 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/helmetCloth.png differ diff --git a/lwjgl-rundir/resources/textures/items/helmetCloth_overlay.png b/lwjgl-rundir/resources/textures/items/helmetCloth_overlay.png new file mode 100644 index 0000000..10f9c59 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/helmetCloth_overlay.png differ diff --git a/lwjgl-rundir/resources/textures/items/helmetDiamond.png b/lwjgl-rundir/resources/textures/items/helmetDiamond.png new file mode 100644 index 0000000..1b97eb3 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/helmetDiamond.png differ diff --git a/lwjgl-rundir/resources/textures/items/helmetGold.png b/lwjgl-rundir/resources/textures/items/helmetGold.png new file mode 100644 index 0000000..1956c33 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/helmetGold.png differ diff --git a/lwjgl-rundir/resources/textures/items/helmetIron.png b/lwjgl-rundir/resources/textures/items/helmetIron.png new file mode 100644 index 0000000..c33c476 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/helmetIron.png differ diff --git a/lwjgl-rundir/resources/textures/items/hoeDiamond.png b/lwjgl-rundir/resources/textures/items/hoeDiamond.png new file mode 100644 index 0000000..d327187 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/hoeDiamond.png differ diff --git a/lwjgl-rundir/resources/textures/items/hoeGold.png b/lwjgl-rundir/resources/textures/items/hoeGold.png new file mode 100644 index 0000000..1fa5165 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/hoeGold.png differ diff --git a/lwjgl-rundir/resources/textures/items/hoeIron.png b/lwjgl-rundir/resources/textures/items/hoeIron.png new file mode 100644 index 0000000..09f7e79 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/hoeIron.png differ diff --git a/lwjgl-rundir/resources/textures/items/hoeStone.png b/lwjgl-rundir/resources/textures/items/hoeStone.png new file mode 100644 index 0000000..f8cf7dd Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/hoeStone.png differ diff --git a/lwjgl-rundir/resources/textures/items/hoeWood.png b/lwjgl-rundir/resources/textures/items/hoeWood.png new file mode 100644 index 0000000..ce6a8a6 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/hoeWood.png differ diff --git a/lwjgl-rundir/resources/textures/items/hopper.png b/lwjgl-rundir/resources/textures/items/hopper.png new file mode 100644 index 0000000..c02db4a Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/hopper.png differ diff --git a/lwjgl-rundir/resources/textures/items/ingotGold.png b/lwjgl-rundir/resources/textures/items/ingotGold.png new file mode 100644 index 0000000..d8ccf8d Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/ingotGold.png differ diff --git a/lwjgl-rundir/resources/textures/items/ingotIron.png b/lwjgl-rundir/resources/textures/items/ingotIron.png new file mode 100644 index 0000000..71a2366 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/ingotIron.png differ diff --git a/lwjgl-rundir/resources/textures/items/leather.png b/lwjgl-rundir/resources/textures/items/leather.png new file mode 100644 index 0000000..7e424ea Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/leather.png differ diff --git a/lwjgl-rundir/resources/textures/items/leggingsChain.png b/lwjgl-rundir/resources/textures/items/leggingsChain.png new file mode 100644 index 0000000..0d0aa05 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/leggingsChain.png differ diff --git a/lwjgl-rundir/resources/textures/items/leggingsCloth.png b/lwjgl-rundir/resources/textures/items/leggingsCloth.png new file mode 100644 index 0000000..bbb0b8e Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/leggingsCloth.png differ diff --git a/lwjgl-rundir/resources/textures/items/leggingsCloth_overlay.png b/lwjgl-rundir/resources/textures/items/leggingsCloth_overlay.png new file mode 100644 index 0000000..883a51d Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/leggingsCloth_overlay.png differ diff --git a/lwjgl-rundir/resources/textures/items/leggingsDiamond.png b/lwjgl-rundir/resources/textures/items/leggingsDiamond.png new file mode 100644 index 0000000..e7762c4 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/leggingsDiamond.png differ diff --git a/lwjgl-rundir/resources/textures/items/leggingsGold.png b/lwjgl-rundir/resources/textures/items/leggingsGold.png new file mode 100644 index 0000000..cd8e9b3 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/leggingsGold.png differ diff --git a/lwjgl-rundir/resources/textures/items/leggingsIron.png b/lwjgl-rundir/resources/textures/items/leggingsIron.png new file mode 100644 index 0000000..3c2fa19 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/leggingsIron.png differ diff --git a/lwjgl-rundir/resources/textures/items/magmaCream.png b/lwjgl-rundir/resources/textures/items/magmaCream.png new file mode 100644 index 0000000..410be86 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/magmaCream.png differ diff --git a/lwjgl-rundir/resources/textures/items/map.png b/lwjgl-rundir/resources/textures/items/map.png new file mode 100644 index 0000000..9a6927b Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/map.png differ diff --git a/lwjgl-rundir/resources/textures/items/melon.png b/lwjgl-rundir/resources/textures/items/melon.png new file mode 100644 index 0000000..0636f9c Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/melon.png differ diff --git a/lwjgl-rundir/resources/textures/items/milk.png b/lwjgl-rundir/resources/textures/items/milk.png new file mode 100644 index 0000000..7672d58 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/milk.png differ diff --git a/lwjgl-rundir/resources/textures/items/minecart.png b/lwjgl-rundir/resources/textures/items/minecart.png new file mode 100644 index 0000000..8e69964 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/minecart.png differ diff --git a/lwjgl-rundir/resources/textures/items/minecartChest.png b/lwjgl-rundir/resources/textures/items/minecartChest.png new file mode 100644 index 0000000..c6e7918 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/minecartChest.png differ diff --git a/lwjgl-rundir/resources/textures/items/minecartFurnace.png b/lwjgl-rundir/resources/textures/items/minecartFurnace.png new file mode 100644 index 0000000..aab24a9 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/minecartFurnace.png differ diff --git a/lwjgl-rundir/resources/textures/items/minecartHopper.png b/lwjgl-rundir/resources/textures/items/minecartHopper.png new file mode 100644 index 0000000..1c8240e Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/minecartHopper.png differ diff --git a/lwjgl-rundir/resources/textures/items/minecartTnt.png b/lwjgl-rundir/resources/textures/items/minecartTnt.png new file mode 100644 index 0000000..193e240 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/minecartTnt.png differ diff --git a/lwjgl-rundir/resources/textures/items/monsterPlacer.png b/lwjgl-rundir/resources/textures/items/monsterPlacer.png new file mode 100644 index 0000000..0e479e0 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/monsterPlacer.png differ diff --git a/lwjgl-rundir/resources/textures/items/monsterPlacer_overlay.png b/lwjgl-rundir/resources/textures/items/monsterPlacer_overlay.png new file mode 100644 index 0000000..63af147 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/monsterPlacer_overlay.png differ diff --git a/lwjgl-rundir/resources/textures/items/mushroomStew.png b/lwjgl-rundir/resources/textures/items/mushroomStew.png new file mode 100644 index 0000000..0449832 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/mushroomStew.png differ diff --git a/lwjgl-rundir/resources/textures/items/netherStalkSeeds.png b/lwjgl-rundir/resources/textures/items/netherStalkSeeds.png new file mode 100644 index 0000000..3600c6b Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/netherStalkSeeds.png differ diff --git a/lwjgl-rundir/resources/textures/items/netherStar.png b/lwjgl-rundir/resources/textures/items/netherStar.png new file mode 100644 index 0000000..c514edc Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/netherStar.png differ diff --git a/lwjgl-rundir/resources/textures/items/netherbrick.png b/lwjgl-rundir/resources/textures/items/netherbrick.png new file mode 100644 index 0000000..9c7a1e4 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/netherbrick.png differ diff --git a/lwjgl-rundir/resources/textures/items/netherquartz.png b/lwjgl-rundir/resources/textures/items/netherquartz.png new file mode 100644 index 0000000..71ca91b Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/netherquartz.png differ diff --git a/lwjgl-rundir/resources/textures/items/painting.png b/lwjgl-rundir/resources/textures/items/painting.png new file mode 100644 index 0000000..236e9cb Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/painting.png differ diff --git a/lwjgl-rundir/resources/textures/items/paper.png b/lwjgl-rundir/resources/textures/items/paper.png new file mode 100644 index 0000000..550d942 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/paper.png differ diff --git a/lwjgl-rundir/resources/textures/items/pickaxeDiamond.png b/lwjgl-rundir/resources/textures/items/pickaxeDiamond.png new file mode 100644 index 0000000..e0cf0bd Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/pickaxeDiamond.png differ diff --git a/lwjgl-rundir/resources/textures/items/pickaxeGold.png b/lwjgl-rundir/resources/textures/items/pickaxeGold.png new file mode 100644 index 0000000..1018cd1 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/pickaxeGold.png differ diff --git a/lwjgl-rundir/resources/textures/items/pickaxeIron.png b/lwjgl-rundir/resources/textures/items/pickaxeIron.png new file mode 100644 index 0000000..ff3ca8d Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/pickaxeIron.png differ diff --git a/lwjgl-rundir/resources/textures/items/pickaxeStone.png b/lwjgl-rundir/resources/textures/items/pickaxeStone.png new file mode 100644 index 0000000..5d2389e Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/pickaxeStone.png differ diff --git a/lwjgl-rundir/resources/textures/items/pickaxeWood.png b/lwjgl-rundir/resources/textures/items/pickaxeWood.png new file mode 100644 index 0000000..47741e2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/pickaxeWood.png differ diff --git a/lwjgl-rundir/resources/textures/items/porkchopCooked.png b/lwjgl-rundir/resources/textures/items/porkchopCooked.png new file mode 100644 index 0000000..d2a583d Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/porkchopCooked.png differ diff --git a/lwjgl-rundir/resources/textures/items/porkchopRaw.png b/lwjgl-rundir/resources/textures/items/porkchopRaw.png new file mode 100644 index 0000000..58fd2d4 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/porkchopRaw.png differ diff --git a/lwjgl-rundir/resources/textures/items/potato.png b/lwjgl-rundir/resources/textures/items/potato.png new file mode 100644 index 0000000..3dcd023 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/potato.png differ diff --git a/lwjgl-rundir/resources/textures/items/potatoBaked.png b/lwjgl-rundir/resources/textures/items/potatoBaked.png new file mode 100644 index 0000000..acdff85 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/potatoBaked.png differ diff --git a/lwjgl-rundir/resources/textures/items/potatoPoisonous.png b/lwjgl-rundir/resources/textures/items/potatoPoisonous.png new file mode 100644 index 0000000..56b3795 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/potatoPoisonous.png differ diff --git a/lwjgl-rundir/resources/textures/items/potion.png b/lwjgl-rundir/resources/textures/items/potion.png new file mode 100644 index 0000000..55e0348 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/potion.png differ diff --git a/lwjgl-rundir/resources/textures/items/potion_contents.png b/lwjgl-rundir/resources/textures/items/potion_contents.png new file mode 100644 index 0000000..b2c3a7e Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/potion_contents.png differ diff --git a/lwjgl-rundir/resources/textures/items/potion_splash.png b/lwjgl-rundir/resources/textures/items/potion_splash.png new file mode 100644 index 0000000..8693314 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/potion_splash.png differ diff --git a/lwjgl-rundir/resources/textures/items/pumpkinPie.png b/lwjgl-rundir/resources/textures/items/pumpkinPie.png new file mode 100644 index 0000000..07ca242 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/pumpkinPie.png differ diff --git a/lwjgl-rundir/resources/textures/items/quiver.png b/lwjgl-rundir/resources/textures/items/quiver.png new file mode 100644 index 0000000..8cdcab9 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/quiver.png differ diff --git a/lwjgl-rundir/resources/textures/items/record_11.png b/lwjgl-rundir/resources/textures/items/record_11.png new file mode 100644 index 0000000..247f01f Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/record_11.png differ diff --git a/lwjgl-rundir/resources/textures/items/record_13.png b/lwjgl-rundir/resources/textures/items/record_13.png new file mode 100644 index 0000000..77bc3d4 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/record_13.png differ diff --git a/lwjgl-rundir/resources/textures/items/record_blocks.png b/lwjgl-rundir/resources/textures/items/record_blocks.png new file mode 100644 index 0000000..f665a46 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/record_blocks.png differ diff --git a/lwjgl-rundir/resources/textures/items/record_cat.png b/lwjgl-rundir/resources/textures/items/record_cat.png new file mode 100644 index 0000000..f2b75bf Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/record_cat.png differ diff --git a/lwjgl-rundir/resources/textures/items/record_chirp.png b/lwjgl-rundir/resources/textures/items/record_chirp.png new file mode 100644 index 0000000..896f953 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/record_chirp.png differ diff --git a/lwjgl-rundir/resources/textures/items/record_far.png b/lwjgl-rundir/resources/textures/items/record_far.png new file mode 100644 index 0000000..4d72d30 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/record_far.png differ diff --git a/lwjgl-rundir/resources/textures/items/record_mall.png b/lwjgl-rundir/resources/textures/items/record_mall.png new file mode 100644 index 0000000..d6aff0a Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/record_mall.png differ diff --git a/lwjgl-rundir/resources/textures/items/record_mellohi.png b/lwjgl-rundir/resources/textures/items/record_mellohi.png new file mode 100644 index 0000000..808ee10 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/record_mellohi.png differ diff --git a/lwjgl-rundir/resources/textures/items/record_stal.png b/lwjgl-rundir/resources/textures/items/record_stal.png new file mode 100644 index 0000000..d0152a5 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/record_stal.png differ diff --git a/lwjgl-rundir/resources/textures/items/record_strad.png b/lwjgl-rundir/resources/textures/items/record_strad.png new file mode 100644 index 0000000..5f3ac31 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/record_strad.png differ diff --git a/lwjgl-rundir/resources/textures/items/record_wait.png b/lwjgl-rundir/resources/textures/items/record_wait.png new file mode 100644 index 0000000..b8decd0 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/record_wait.png differ diff --git a/lwjgl-rundir/resources/textures/items/record_ward.png b/lwjgl-rundir/resources/textures/items/record_ward.png new file mode 100644 index 0000000..c181add Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/record_ward.png differ diff --git a/lwjgl-rundir/resources/textures/items/redstone.png b/lwjgl-rundir/resources/textures/items/redstone.png new file mode 100644 index 0000000..4c5c459 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/redstone.png differ diff --git a/lwjgl-rundir/resources/textures/items/reeds.png b/lwjgl-rundir/resources/textures/items/reeds.png new file mode 100644 index 0000000..c4189f4 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/reeds.png differ diff --git a/lwjgl-rundir/resources/textures/items/rottenFlesh.png b/lwjgl-rundir/resources/textures/items/rottenFlesh.png new file mode 100644 index 0000000..b0331f1 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/rottenFlesh.png differ diff --git a/lwjgl-rundir/resources/textures/items/ruby.png b/lwjgl-rundir/resources/textures/items/ruby.png new file mode 100644 index 0000000..db0bc13 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/ruby.png differ diff --git a/lwjgl-rundir/resources/textures/items/saddle.png b/lwjgl-rundir/resources/textures/items/saddle.png new file mode 100644 index 0000000..a1e55f5 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/saddle.png differ diff --git a/lwjgl-rundir/resources/textures/items/seeds.png b/lwjgl-rundir/resources/textures/items/seeds.png new file mode 100644 index 0000000..c1808c0 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/seeds.png differ diff --git a/lwjgl-rundir/resources/textures/items/seeds_melon.png b/lwjgl-rundir/resources/textures/items/seeds_melon.png new file mode 100644 index 0000000..9f78d75 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/seeds_melon.png differ diff --git a/lwjgl-rundir/resources/textures/items/seeds_pumpkin.png b/lwjgl-rundir/resources/textures/items/seeds_pumpkin.png new file mode 100644 index 0000000..93b0c69 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/seeds_pumpkin.png differ diff --git a/lwjgl-rundir/resources/textures/items/shears.png b/lwjgl-rundir/resources/textures/items/shears.png new file mode 100644 index 0000000..72ec0fe Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/shears.png differ diff --git a/lwjgl-rundir/resources/textures/items/shovelDiamond.png b/lwjgl-rundir/resources/textures/items/shovelDiamond.png new file mode 100644 index 0000000..dcf43b6 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/shovelDiamond.png differ diff --git a/lwjgl-rundir/resources/textures/items/shovelGold.png b/lwjgl-rundir/resources/textures/items/shovelGold.png new file mode 100644 index 0000000..19fe196 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/shovelGold.png differ diff --git a/lwjgl-rundir/resources/textures/items/shovelIron.png b/lwjgl-rundir/resources/textures/items/shovelIron.png new file mode 100644 index 0000000..db1c756 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/shovelIron.png differ diff --git a/lwjgl-rundir/resources/textures/items/shovelStone.png b/lwjgl-rundir/resources/textures/items/shovelStone.png new file mode 100644 index 0000000..4d44d80 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/shovelStone.png differ diff --git a/lwjgl-rundir/resources/textures/items/shovelWood.png b/lwjgl-rundir/resources/textures/items/shovelWood.png new file mode 100644 index 0000000..a005288 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/shovelWood.png differ diff --git a/lwjgl-rundir/resources/textures/items/sign.png b/lwjgl-rundir/resources/textures/items/sign.png new file mode 100644 index 0000000..62ec54d Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/sign.png differ diff --git a/lwjgl-rundir/resources/textures/items/skull_char.png b/lwjgl-rundir/resources/textures/items/skull_char.png new file mode 100644 index 0000000..799a588 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/skull_char.png differ diff --git a/lwjgl-rundir/resources/textures/items/skull_creeper.png b/lwjgl-rundir/resources/textures/items/skull_creeper.png new file mode 100644 index 0000000..5380587 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/skull_creeper.png differ diff --git a/lwjgl-rundir/resources/textures/items/skull_skeleton.png b/lwjgl-rundir/resources/textures/items/skull_skeleton.png new file mode 100644 index 0000000..4fd68a2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/skull_skeleton.png differ diff --git a/lwjgl-rundir/resources/textures/items/skull_wither.png b/lwjgl-rundir/resources/textures/items/skull_wither.png new file mode 100644 index 0000000..2d559f4 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/skull_wither.png differ diff --git a/lwjgl-rundir/resources/textures/items/skull_zombie.png b/lwjgl-rundir/resources/textures/items/skull_zombie.png new file mode 100644 index 0000000..356711d Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/skull_zombie.png differ diff --git a/lwjgl-rundir/resources/textures/items/slimeball.png b/lwjgl-rundir/resources/textures/items/slimeball.png new file mode 100644 index 0000000..a9be3bd Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/slimeball.png differ diff --git a/lwjgl-rundir/resources/textures/items/slot_empty_boots.png b/lwjgl-rundir/resources/textures/items/slot_empty_boots.png new file mode 100644 index 0000000..20e5caf Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/slot_empty_boots.png differ diff --git a/lwjgl-rundir/resources/textures/items/slot_empty_chestplate.png b/lwjgl-rundir/resources/textures/items/slot_empty_chestplate.png new file mode 100644 index 0000000..75daaaf Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/slot_empty_chestplate.png differ diff --git a/lwjgl-rundir/resources/textures/items/slot_empty_helmet.png b/lwjgl-rundir/resources/textures/items/slot_empty_helmet.png new file mode 100644 index 0000000..392e553 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/slot_empty_helmet.png differ diff --git a/lwjgl-rundir/resources/textures/items/slot_empty_leggings.png b/lwjgl-rundir/resources/textures/items/slot_empty_leggings.png new file mode 100644 index 0000000..cd5906d Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/slot_empty_leggings.png differ diff --git a/lwjgl-rundir/resources/textures/items/snowball.png b/lwjgl-rundir/resources/textures/items/snowball.png new file mode 100644 index 0000000..3ee480f Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/snowball.png differ diff --git a/lwjgl-rundir/resources/textures/items/speckledMelon.png b/lwjgl-rundir/resources/textures/items/speckledMelon.png new file mode 100644 index 0000000..c5be982 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/speckledMelon.png differ diff --git a/lwjgl-rundir/resources/textures/items/spiderEye.png b/lwjgl-rundir/resources/textures/items/spiderEye.png new file mode 100644 index 0000000..9eec4b0 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/spiderEye.png differ diff --git a/lwjgl-rundir/resources/textures/items/stick.png b/lwjgl-rundir/resources/textures/items/stick.png new file mode 100644 index 0000000..8056e2c Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/stick.png differ diff --git a/lwjgl-rundir/resources/textures/items/string.png b/lwjgl-rundir/resources/textures/items/string.png new file mode 100644 index 0000000..54c980c Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/string.png differ diff --git a/lwjgl-rundir/resources/textures/items/sugar.png b/lwjgl-rundir/resources/textures/items/sugar.png new file mode 100644 index 0000000..656cb6e Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/sugar.png differ diff --git a/lwjgl-rundir/resources/textures/items/sulphur.png b/lwjgl-rundir/resources/textures/items/sulphur.png new file mode 100644 index 0000000..13b53f3 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/sulphur.png differ diff --git a/lwjgl-rundir/resources/textures/items/swordDiamond.png b/lwjgl-rundir/resources/textures/items/swordDiamond.png new file mode 100644 index 0000000..e1d4300 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/swordDiamond.png differ diff --git a/lwjgl-rundir/resources/textures/items/swordGold.png b/lwjgl-rundir/resources/textures/items/swordGold.png new file mode 100644 index 0000000..05452c8 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/swordGold.png differ diff --git a/lwjgl-rundir/resources/textures/items/swordIron.png b/lwjgl-rundir/resources/textures/items/swordIron.png new file mode 100644 index 0000000..9b6bf83 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/swordIron.png differ diff --git a/lwjgl-rundir/resources/textures/items/swordStone.png b/lwjgl-rundir/resources/textures/items/swordStone.png new file mode 100644 index 0000000..1f7b95c Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/swordStone.png differ diff --git a/lwjgl-rundir/resources/textures/items/swordWood.png b/lwjgl-rundir/resources/textures/items/swordWood.png new file mode 100644 index 0000000..3dfd8a0 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/swordWood.png differ diff --git a/lwjgl-rundir/resources/textures/items/wheat.png b/lwjgl-rundir/resources/textures/items/wheat.png new file mode 100644 index 0000000..e0891c2 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/wheat.png differ diff --git a/lwjgl-rundir/resources/textures/items/writingBook.png b/lwjgl-rundir/resources/textures/items/writingBook.png new file mode 100644 index 0000000..0f75d8a Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/writingBook.png differ diff --git a/lwjgl-rundir/resources/textures/items/writtenBook.png b/lwjgl-rundir/resources/textures/items/writtenBook.png new file mode 100644 index 0000000..cfa6496 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/writtenBook.png differ diff --git a/lwjgl-rundir/resources/textures/items/yellowDust.png b/lwjgl-rundir/resources/textures/items/yellowDust.png new file mode 100644 index 0000000..aabe116 Binary files /dev/null and b/lwjgl-rundir/resources/textures/items/yellowDust.png differ diff --git a/lwjgl-rundir/resources/title/bg/panorama0.png b/lwjgl-rundir/resources/title/bg/panorama0.png new file mode 100644 index 0000000..b926096 Binary files /dev/null and b/lwjgl-rundir/resources/title/bg/panorama0.png differ diff --git a/lwjgl-rundir/resources/title/bg/panorama1.png b/lwjgl-rundir/resources/title/bg/panorama1.png new file mode 100644 index 0000000..61749a1 Binary files /dev/null and b/lwjgl-rundir/resources/title/bg/panorama1.png differ diff --git a/lwjgl-rundir/resources/title/bg/panorama2.png b/lwjgl-rundir/resources/title/bg/panorama2.png new file mode 100644 index 0000000..8452d13 Binary files /dev/null and b/lwjgl-rundir/resources/title/bg/panorama2.png differ diff --git a/lwjgl-rundir/resources/title/bg/panorama3.png b/lwjgl-rundir/resources/title/bg/panorama3.png new file mode 100644 index 0000000..156a02b Binary files /dev/null and b/lwjgl-rundir/resources/title/bg/panorama3.png differ diff --git a/lwjgl-rundir/resources/title/bg/panorama4.png b/lwjgl-rundir/resources/title/bg/panorama4.png new file mode 100644 index 0000000..d528f84 Binary files /dev/null and b/lwjgl-rundir/resources/title/bg/panorama4.png differ diff --git a/lwjgl-rundir/resources/title/bg/panorama5.png b/lwjgl-rundir/resources/title/bg/panorama5.png new file mode 100644 index 0000000..8a4605a Binary files /dev/null and b/lwjgl-rundir/resources/title/bg/panorama5.png differ diff --git a/lwjgl-rundir/resources/title/black.png b/lwjgl-rundir/resources/title/black.png new file mode 100644 index 0000000..b5d2eb6 Binary files /dev/null and b/lwjgl-rundir/resources/title/black.png differ diff --git a/lwjgl-rundir/resources/title/credits.txt b/lwjgl-rundir/resources/title/credits.txt new file mode 100644 index 0000000..60afe6b --- /dev/null +++ b/lwjgl-rundir/resources/title/credits.txt @@ -0,0 +1,57 @@ +[C]§f=============== +[C]§eMinecraft Credits +[C]§f=============== + +§7Created by: +§f Markus Persson + +§7Game design, programming and graphics: +§f Markus Persson +§f Jens Bergensten + +§7Music and sound: +§f Daniel Rosenfeld + +§7Ingame artwork and paintings: +§f Kristoffer Zetterstrand + +§7End game narrative: +§f Julian Gough + +§7Website development: +§f Tobias Möllstam +§f Daniel Frisk +§f Leonard Axelsson +§f Jens Bergensten +§f Markus Persson + +§7Logo and promotional artwork: +§f Markus Toivonen + +§7Business and administration: +§f Carl Manneh +§f Daniel Kaplan + +§7Director of fun: +§f Lydia Winters + +§7Number crunching and statistics: +§f Patrick Geuder + +§7Additional programming: +§f Paul Spooner +§f Ryan 'Scaevolus' Hitchman +§f Elliot 'Hippoplatimus' Segal + +§7Technologies used: +§f Java by Oracle +§f LWJGL by many talented people +§f "3d Sound System" by Paul Lamb +§f JOrbis by JCraft + + + + + + +§f"Twenty years from now you will be more disappointed by the things that you didn't do than by the ones you did do. So throw off the bowlines. Sail away from the safe harbor. Catch the trade winds in your sails. Explore. Dream. Discover." §7- Unknown \ No newline at end of file diff --git a/lwjgl-rundir/resources/title/eagtek.png b/lwjgl-rundir/resources/title/eagtek.png new file mode 100644 index 0000000..0aa32fc Binary files /dev/null and b/lwjgl-rundir/resources/title/eagtek.png differ diff --git a/lwjgl-rundir/resources/title/eagtek2.png b/lwjgl-rundir/resources/title/eagtek2.png new file mode 100644 index 0000000..dcd8edd Binary files /dev/null and b/lwjgl-rundir/resources/title/eagtek2.png differ diff --git a/lwjgl-rundir/resources/title/enable.png b/lwjgl-rundir/resources/title/enable.png new file mode 100644 index 0000000..6f62bec Binary files /dev/null and b/lwjgl-rundir/resources/title/enable.png differ diff --git a/lwjgl-rundir/resources/title/mclogo.png b/lwjgl-rundir/resources/title/mclogo.png new file mode 100644 index 0000000..0bf5c37 Binary files /dev/null and b/lwjgl-rundir/resources/title/mclogo.png differ diff --git a/lwjgl-rundir/resources/title/mojang.png b/lwjgl-rundir/resources/title/mojang.png new file mode 100644 index 0000000..237c638 Binary files /dev/null and b/lwjgl-rundir/resources/title/mojang.png differ diff --git a/lwjgl-rundir/resources/title/win.txt b/lwjgl-rundir/resources/title/win.txt new file mode 100644 index 0000000..7277524 --- /dev/null +++ b/lwjgl-rundir/resources/title/win.txt @@ -0,0 +1,151 @@ +§3I see the player you mean. + +§2PLAYERNAME? + +§3Yes. Take care. It has reached a higher level now. It can read our thoughts. + +§2That doesn't matter. It thinks we are part of the game. + +§3I like this player. It played well. It did not give up. + +§2It is reading our thoughts as though they were words on a screen. + +§3That is how it chooses to imagine many things, when it is deep in the dream of a game. + +§2Words make a wonderful interface. Very flexible. And less terrifying than staring at the reality behind the screen. + +§3They used to hear voices. Before players could read. Back in the days when those who did not play called the players witches, and warlocks. And players dreamed they flew through the air, on sticks powered by demons. + +§2What did this player dream? + +§3This player dreamed of sunlight and trees. Of fire and water. It dreamed it created. And it dreamed it destroyed. It dreamed it hunted, and was hunted. It dreamed of shelter. + +§2Hah, the original interface. A million years old, and it still works. But what true structure did this player create, in the reality behind the screen? + +§3It worked, with a million others, to sculpt a true world in a fold of the §f§k§a§b§3, and created a §f§k§a§b§3 for §f§k§a§b§3, in the §f§k§a§b§3. + +§2It cannot read that thought. + +§3No. It has not yet achieved the highest level. That, it must achieve in the long dream of life, not the short dream of a game. + +§2Does it know that we love it? That the universe is kind? + +§3Sometimes, through the noise of its thoughts, it hears the universe, yes. + +§2But there are times it is sad, in the long dream. It creates worlds that have no summer, and it shivers under a black sun, and it takes its sad creation for reality. + +§3To cure it of sorrow would destroy it. The sorrow is part of its own private task. We cannot interfere. + +§2Sometimes when they are deep in dreams, I want to tell them, they are building true worlds in reality. Sometimes I want to tell them of their importance to the universe. Sometimes, when they have not made a true connection in a while, I want to help them to speak the word they fear. + +§3It reads our thoughts. + +§2Sometimes I do not care. Sometimes I wish to tell them, this world you take for truth is merely §f§k§a§b§2 and §f§k§a§b§2, I wish to tell them that they are §f§k§a§b§2 in the §f§k§a§b§2. They see so little of reality, in their long dream. + +§3And yet they play the game. + +§2But it would be so easy to tell them... + +§3Too strong for this dream. To tell them how to live is to prevent them living. + +§2I will not tell the player how to live. + +§3The player is growing restless. + +§2I will tell the player a story. + +§3But not the truth. + +§2No. A story that contains the truth safely, in a cage of words. Not the naked truth that can burn over any distance. + +§3Give it a body, again. + +§2Yes. Player... + +§3Use its name. + +§2PLAYERNAME. Player of games. + +§3Good. + +§2Take a breath, now. Take another. Feel air in your lungs. Let your limbs return. Yes, move your fingers. Have a body again, under gravity, in air. Respawn in the long dream. There you are. Your body touching the universe again at every point, as though you were separate things. As though we were separate things. + +§3Who are we? Once we were called the spirit of the mountain. Father sun, mother moon. Ancestral spirits, animal spirits. Jinn. Ghosts. The green man. Then gods, demons. Angels. Poltergeists. Aliens, extraterrestrials. Leptons, quarks. The words change. We do not change. + +§2We are the universe. We are everything you think isn't you. You are looking at us now, through your skin and your eyes. And why does the universe touch your skin, and throw light on you? To see you, player. To know you. And to be known. I shall tell you a story. + +§2Once upon a time, there was a player. + +§3The player was you, PLAYERNAME. + +§2Sometimes it thought itself human, on the thin crust of a spinning globe of molten rock. The ball of molten rock circled a ball of blazing gas that was three hundred and thirty thousand times more massive than it. They were so far apart that light took eight minutes to cross the gap. The light was information from a star, and it could burn your skin from a hundred and fifty million kilometres away. + +§2Sometimes the player dreamed it was a miner, on the surface of a world that was flat, and infinite. The sun was a square of white. The days were short; there was much to do; and death was a temporary inconvenience. + +§3Sometimes the player dreamed it was lost in a story. + +§2Sometimes the player dreamed it was other things, in other places. Sometimes these dreams were disturbing. Sometimes very beautiful indeed. Sometimes the player woke from one dream into another, then woke from that into a third. + +§3Sometimes the player dreamed it watched words on a screen. + +§2Let's go back. + +§2The atoms of the player were scattered in the grass, in the rivers, in the air, in the ground. A woman gathered the atoms; she drank and ate and inhaled; and the woman assembled the player, in her body. + +§2And the player awoke, from the warm, dark world of its mother's body, into the long dream. + +§2And the player was a new story, never told before, written in letters of DNA. And the player was a new program, never run before, generated by a sourcecode a billion years old. And the player was a new human, never alive before, made from nothing but milk and love. + +§3You are the player. The story. The program. The human. Made from nothing but milk and love. + +§2Let's go further back. + +§2The seven billion billion billion atoms of the player's body were created, long before this game, in the heart of a star. So the player, too, is information from a star. And the player moves through a story, which is a forest of information planted by a man called Julian, on a flat, infinite world created by a man called Markus, that exists inside a small, private world created by the player, who inhabits a universe created by... + +§3Shush. Sometimes the player created a small, private world that was soft and warm and simple. Sometimes hard, and cold, and complicated. Sometimes it built a model of the universe in its head; flecks of energy, moving through vast empty spaces. Sometimes it called those flecks "electrons" and "protons". + +§2Sometimes it called them "planets" and "stars". + +§2Sometimes it believed it was in a universe that was made of energy that was made of offs and ons; zeros and ones; lines of code. Sometimes it believed it was playing a game. Sometimes it believed it was reading words on a screen. + +§3You are the player, reading words... + +§2Shush... Sometimes the player read lines of code on a screen. Decoded them into words; decoded words into meaning; decoded meaning into feelings, emotions, theories, ideas, and the player started to breathe faster and deeper and realised it was alive, it was alive, those thousand deaths had not been real, the player was alive + +§3You. You. You are alive. + +§2and sometimes the player believed the universe had spoken to it through the sunlight that came through the shuffling leaves of the summer trees + +§3and sometimes the player believed the universe had spoken to it through the light that fell from the crisp night sky of winter, where a fleck of light in the corner of the player's eye might be a star a million times as massive as the sun, boiling its planets to plasma in order to be visible for a moment to the player, walking home at the far side of the universe, suddenly smelling food, almost at the familiar door, about to dream again + +§2and sometimes the player believed the universe had spoken to it through the zeros and ones, through the electricity of the world, through the scrolling words on a screen at the end of a dream + +§3and the universe said I love you + +§2and the universe said you have played the game well + +§3and the universe said everything you need is within you + +§2and the universe said you are stronger than you know + +§3and the universe said you are the daylight + +§2and the universe said you are the night + +§3and the universe said the darkness you fight is within you + +§2and the universe said the light you seek is within you + +§3and the universe said you are not alone + +§2and the universe said you are not separate from every other thing + +§3and the universe said you are the universe tasting itself, talking to itself, reading its own code + +§2and the universe said I love you because you are love. + +§3And the game was over and the player woke up from the dream. And the player began a new dream. And the player dreamed again, dreamed better. And the player was the universe. And the player was love. + +§3You are the player. + +§2Wake up. diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..da923ef --- /dev/null +++ b/settings.gradle @@ -0,0 +1,10 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user manual at https://docs.gradle.org/6.0/userguide/multi_project_builds.html + */ + +rootProject.name = 'eaglercraft-unified' diff --git a/spigot-server/banned-ips.txt b/spigot-server/banned-ips.txt new file mode 100644 index 0000000..b6ece2f --- /dev/null +++ b/spigot-server/banned-ips.txt @@ -0,0 +1,3 @@ +# Updated 8/29/20 1:12 PM by Minecraft 1.5.2 +# victim name | ban date | banned by | banned until | reason + diff --git a/spigot-server/banned-players.txt b/spigot-server/banned-players.txt new file mode 100644 index 0000000..b6ece2f --- /dev/null +++ b/spigot-server/banned-players.txt @@ -0,0 +1,3 @@ +# Updated 8/29/20 1:12 PM by Minecraft 1.5.2 +# victim name | ban date | banned by | banned until | reason + diff --git a/spigot-server/bukkit.yml b/spigot-server/bukkit.yml new file mode 100644 index 0000000..a7a53a8 --- /dev/null +++ b/spigot-server/bukkit.yml @@ -0,0 +1,45 @@ +# This is the main configuration file for Bukkit. +# As you can see, there's actually not that much to configure without any plugins. +# For a reference for any variable inside this file, check out the bukkit wiki at +# http://wiki.bukkit.org/Bukkit.yml +settings: + allow-end: true + warn-on-overload: true + permissions-file: permissions.yml + update-folder: update + ping-packet-limit: 100 + use-exact-login-location: false + plugin-profiling: false + connection-throttle: 4000 + query-plugins: true + deprecated-verbose: default + shutdown-message: Server closed +spawn-limits: + monsters: 70 + animals: 15 + water-animals: 5 + ambient: 15 +chunk-gc: + period-in-ticks: 600 + load-threshold: 0 +ticks-per: + animal-spawns: 400 + monster-spawns: 1 + autosave: 0 +auto-updater: + enabled: true + on-broken: + - warn-console + - warn-ops + on-update: + - warn-console + - warn-ops + preferred-channel: rb + host: dl.bukkit.org + suggest-channels: true +database: + username: bukkit + isolation: SERIALIZABLE + driver: org.sqlite.JDBC + password: walrus + url: jdbc:sqlite:{DIR}{NAME}.db diff --git a/spigot-server/help.yml b/spigot-server/help.yml new file mode 100644 index 0000000..c0ac928 --- /dev/null +++ b/spigot-server/help.yml @@ -0,0 +1,56 @@ +# This is the help configuration file for Bukkit. +# +# By default you do not need to modify this file. Help topics for all plugin commands are automatically provided by +# or extracted from your installed plugins. You only need to modify this file if you wish to add new help pages to +# your server or override the help pages of existing plugin commands. +# +# This file is divided up into the following parts: +# -- general-topics: lists admin defined help topics +# -- index-topics: lists admin defined index topics +# -- amend-topics: lists topic amendments to apply to existing help topics +# -- ignore-plugins: lists any plugins that should be excluded from help +# +# Examples are given below. When amending command topic, the string will be replaced with the existing value +# in the help topic. Color codes can be used in topic text. The color code character is & followed by 0-F. +# ================================================================ +# +# Set this to true to list the individual command help topics in the master help. +# command-topics-in-master-index: true +# +# Each general topic will show up as a separate topic in the help index along with all the plugin command topics. +# general-topics: +# Rules: +# shortText: Rules of the server +# fullText: | +# &61. Be kind to your fellow players. +# &B2. No griefing. +# &D3. No swearing. +# permission: topics.rules +# +# Each index topic will show up as a separate sub-index in the help index along with all the plugin command topics. +# To override the default help index (displayed when the user executes /help), name the index topic "Default". +# index-topics: +# Ban Commands: +# shortText: Player banning commands +# preamble: Moderator - do not abuse these commands +# permission: op +# commands: +# - /ban +# - /ban-ip +# - /banlist +# +# Topic amendments are used to change the content of automatically generated plugin command topics. +# amended-topics: +# /stop: +# shortText: Stops the server cold....in its tracks! +# fullText: - This kills the server. +# permission: you.dont.have +# +# Any plugin in the ignored plugins list will be excluded from help. The name must match the name displayed by +# the /plugins command. Ignore "Bukkit" to remove the standard bukkit commands from the index. Ignore "All" +# to completely disable automatic help topic generation. +# ignore-plugins: +# - PluginNameOne +# - PluginNameTwo +# - PluginNameThree + diff --git a/spigot-server/ops.txt b/spigot-server/ops.txt new file mode 100644 index 0000000..0f98515 --- /dev/null +++ b/spigot-server/ops.txt @@ -0,0 +1,2 @@ +lax2dude +lax1dude diff --git a/spigot-server/permissions.yml b/spigot-server/permissions.yml new file mode 100644 index 0000000..e69de29 diff --git a/spigot-server/plugins/PluginMetrics/config.yml b/spigot-server/plugins/PluginMetrics/config.yml new file mode 100644 index 0000000..5c9df97 --- /dev/null +++ b/spigot-server/plugins/PluginMetrics/config.yml @@ -0,0 +1,4 @@ +# http://mcstats.org +opt-out: false +guid: c015ae6f-e6ca-48d6-b4af-6e1cb5825cb9 +debug: false diff --git a/spigot-server/run.bat b/spigot-server/run.bat new file mode 100644 index 0000000..8ad88af --- /dev/null +++ b/spigot-server/run.bat @@ -0,0 +1 @@ +java -Xmx512M -Xms512M -jar spigot-1.5.2-R1.1-SNAPSHOT.jar \ No newline at end of file diff --git a/spigot-server/server.log b/spigot-server/server.log new file mode 100644 index 0000000..020588d --- /dev/null +++ b/spigot-server/server.log @@ -0,0 +1,3343 @@ +2020-07-11 20:36:55 [INFO] Starting minecraft server version 1.5.2 +2020-07-11 20:36:55 [WARNING] To start the server with more ram, launch it as "java -Xmx1024M -Xms1024M -jar minecraft_server.jar" +2020-07-11 20:36:55 [INFO] Loading properties +2020-07-11 20:36:55 [WARNING] server.properties does not exist +2020-07-11 20:36:55 [INFO] Generating new properties file +2020-07-11 20:36:55 [INFO] Default game type: SURVIVAL +2020-07-11 20:36:56 [INFO] This server is running CraftBukkit version git-Spigot-959 (MC: 1.5.2) (Implementing API version 1.5.2-R1.1-SNAPSHOT) +2020-07-11 20:36:56 [WARNING] Failed to load operators list: java.io.FileNotFoundException: .\ops.txt (The system cannot find the file specified) +2020-07-11 20:36:56 [WARNING] Failed to load white-list: java.io.FileNotFoundException: .\white-list.txt (The system cannot find the file specified) +2020-07-11 20:36:56 [INFO] Generating keypair +2020-07-11 20:36:56 [INFO] Starting listener #0 on *:25565 +2020-07-11 20:36:57 [INFO] Preparing level "world" +2020-07-11 20:36:57 [INFO] -------- World Settings For [world] -------- +2020-07-11 20:36:57 [INFO] View Distance: 10 +2020-07-11 20:36:57 [INFO] Chunks to Grow per Tick: 650 +2020-07-11 20:36:57 [INFO] Experience Merge Radius: 3.0 +2020-07-11 20:36:57 [INFO] Item Merge Radius: 2.5 +2020-07-11 20:36:57 [INFO] Cactus Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Cane Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Melon Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Mushroom Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Pumpkin Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Sapling Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Wheat Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-07-11 20:36:57 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-07-11 20:36:57 [INFO] Mob Spawn Range: 4 +2020-07-11 20:36:57 [INFO] Anti X-Ray: true +2020-07-11 20:36:57 [INFO] Engine Mode: 1 +2020-07-11 20:36:57 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-07-11 20:36:57 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-07-11 20:36:57 [INFO] Random Lighting Updates: false +2020-07-11 20:36:57 [INFO] -------- World Settings For [world_nether] -------- +2020-07-11 20:36:57 [INFO] View Distance: 10 +2020-07-11 20:36:57 [INFO] Chunks to Grow per Tick: 650 +2020-07-11 20:36:57 [INFO] Experience Merge Radius: 3.0 +2020-07-11 20:36:57 [INFO] Item Merge Radius: 2.5 +2020-07-11 20:36:57 [INFO] Cactus Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Cane Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Melon Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Mushroom Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Pumpkin Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Sapling Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Wheat Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-07-11 20:36:57 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-07-11 20:36:57 [INFO] Mob Spawn Range: 4 +2020-07-11 20:36:57 [INFO] Anti X-Ray: true +2020-07-11 20:36:57 [INFO] Engine Mode: 1 +2020-07-11 20:36:57 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-07-11 20:36:57 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-07-11 20:36:57 [INFO] Random Lighting Updates: false +2020-07-11 20:36:57 [INFO] -------- World Settings For [world_the_end] -------- +2020-07-11 20:36:57 [INFO] View Distance: 10 +2020-07-11 20:36:57 [INFO] Chunks to Grow per Tick: 650 +2020-07-11 20:36:57 [INFO] Experience Merge Radius: 3.0 +2020-07-11 20:36:57 [INFO] Item Merge Radius: 2.5 +2020-07-11 20:36:57 [INFO] Cactus Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Cane Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Melon Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Mushroom Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Pumpkin Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Sapling Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Wheat Growth Modifier: 100% +2020-07-11 20:36:57 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-07-11 20:36:57 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-07-11 20:36:57 [INFO] Mob Spawn Range: 4 +2020-07-11 20:36:57 [INFO] Anti X-Ray: true +2020-07-11 20:36:57 [INFO] Engine Mode: 1 +2020-07-11 20:36:57 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-07-11 20:36:57 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-07-11 20:36:57 [INFO] Random Lighting Updates: false +2020-07-11 20:36:57 [INFO] Preparing start region for level 0 (Seed: 1317118761349661229) +2020-07-11 20:36:58 [INFO] Preparing spawn area: 16% +2020-07-11 20:36:59 [INFO] Preparing spawn area: 49% +2020-07-11 20:37:00 [INFO] Preparing spawn area: 83% +2020-07-11 20:37:00 [INFO] Preparing start region for level 1 (Seed: 1317118761349661229) +2020-07-11 20:37:01 [INFO] Preparing spawn area: 8% +2020-07-11 20:37:02 [INFO] Preparing spawn area: 49% +2020-07-11 20:37:03 [INFO] Preparing spawn area: 95% +2020-07-11 20:37:03 [INFO] Preparing start region for level 2 (Seed: 1317118761349661229) +2020-07-11 20:37:04 [INFO] Preparing spawn area: 54% +2020-07-11 20:37:04 [INFO] Done (8.017s)! For help, type "help" or "?" +2020-07-11 20:38:53 [INFO] CONSOLE: Stopping the server.. +2020-07-11 20:38:53 [INFO] Stopping server +2020-07-11 20:38:53 [INFO] Saving players +2020-07-11 20:38:53 [INFO] Saving worlds +2020-07-11 20:38:53 [INFO] Saving chunks for level 'world'/Overworld +2020-07-11 20:38:53 [INFO] Saving chunks for level 'world_nether'/Nether +2020-07-11 20:38:53 [INFO] Saving chunks for level 'world_the_end'/The End +2020-07-11 20:38:58 [INFO] Starting minecraft server version 1.5.2 +2020-07-11 20:38:58 [WARNING] To start the server with more ram, launch it as "java -Xmx1024M -Xms1024M -jar minecraft_server.jar" +2020-07-11 20:38:58 [INFO] Loading properties +2020-07-11 20:38:58 [INFO] Default game type: CREATIVE +2020-07-11 20:38:59 [INFO] This server is running CraftBukkit version git-Spigot-959 (MC: 1.5.2) (Implementing API version 1.5.2-R1.1-SNAPSHOT) +2020-07-11 20:38:59 [INFO] Generating keypair +2020-07-11 20:38:59 [INFO] Starting listener #0 on *:25501 +2020-07-11 20:38:59 [INFO] Preparing level "world" +2020-07-11 20:38:59 [INFO] -------- World Settings For [world] -------- +2020-07-11 20:38:59 [INFO] View Distance: 10 +2020-07-11 20:38:59 [INFO] Chunks to Grow per Tick: 650 +2020-07-11 20:38:59 [INFO] Experience Merge Radius: 3.0 +2020-07-11 20:38:59 [INFO] Item Merge Radius: 2.5 +2020-07-11 20:38:59 [INFO] Anti X-Ray: true +2020-07-11 20:38:59 [INFO] Engine Mode: 1 +2020-07-11 20:38:59 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-07-11 20:38:59 [INFO] Mob Spawn Range: 4 +2020-07-11 20:38:59 [INFO] Cactus Growth Modifier: 100% +2020-07-11 20:38:59 [INFO] Cane Growth Modifier: 100% +2020-07-11 20:38:59 [INFO] Melon Growth Modifier: 100% +2020-07-11 20:38:59 [INFO] Mushroom Growth Modifier: 100% +2020-07-11 20:38:59 [INFO] Pumpkin Growth Modifier: 100% +2020-07-11 20:38:59 [INFO] Sapling Growth Modifier: 100% +2020-07-11 20:38:59 [INFO] Wheat Growth Modifier: 100% +2020-07-11 20:38:59 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-07-11 20:38:59 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-07-11 20:38:59 [INFO] Random Lighting Updates: false +2020-07-11 20:38:59 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-07-11 20:38:59 [INFO] -------- World Settings For [world_nether] -------- +2020-07-11 20:38:59 [INFO] View Distance: 10 +2020-07-11 20:38:59 [INFO] Chunks to Grow per Tick: 650 +2020-07-11 20:38:59 [INFO] Experience Merge Radius: 3.0 +2020-07-11 20:38:59 [INFO] Item Merge Radius: 2.5 +2020-07-11 20:38:59 [INFO] Anti X-Ray: true +2020-07-11 20:38:59 [INFO] Engine Mode: 1 +2020-07-11 20:38:59 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-07-11 20:38:59 [INFO] Mob Spawn Range: 4 +2020-07-11 20:38:59 [INFO] Cactus Growth Modifier: 100% +2020-07-11 20:38:59 [INFO] Cane Growth Modifier: 100% +2020-07-11 20:38:59 [INFO] Melon Growth Modifier: 100% +2020-07-11 20:38:59 [INFO] Mushroom Growth Modifier: 100% +2020-07-11 20:38:59 [INFO] Pumpkin Growth Modifier: 100% +2020-07-11 20:38:59 [INFO] Sapling Growth Modifier: 100% +2020-07-11 20:38:59 [INFO] Wheat Growth Modifier: 100% +2020-07-11 20:38:59 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-07-11 20:38:59 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-07-11 20:38:59 [INFO] Random Lighting Updates: false +2020-07-11 20:38:59 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-07-11 20:39:00 [INFO] -------- World Settings For [world_the_end] -------- +2020-07-11 20:39:00 [INFO] View Distance: 10 +2020-07-11 20:39:00 [INFO] Chunks to Grow per Tick: 650 +2020-07-11 20:39:00 [INFO] Experience Merge Radius: 3.0 +2020-07-11 20:39:00 [INFO] Item Merge Radius: 2.5 +2020-07-11 20:39:00 [INFO] Anti X-Ray: true +2020-07-11 20:39:00 [INFO] Engine Mode: 1 +2020-07-11 20:39:00 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-07-11 20:39:00 [INFO] Mob Spawn Range: 4 +2020-07-11 20:39:00 [INFO] Cactus Growth Modifier: 100% +2020-07-11 20:39:00 [INFO] Cane Growth Modifier: 100% +2020-07-11 20:39:00 [INFO] Melon Growth Modifier: 100% +2020-07-11 20:39:00 [INFO] Mushroom Growth Modifier: 100% +2020-07-11 20:39:00 [INFO] Pumpkin Growth Modifier: 100% +2020-07-11 20:39:00 [INFO] Sapling Growth Modifier: 100% +2020-07-11 20:39:00 [INFO] Wheat Growth Modifier: 100% +2020-07-11 20:39:00 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-07-11 20:39:00 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-07-11 20:39:00 [INFO] Random Lighting Updates: false +2020-07-11 20:39:00 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-07-11 20:39:00 [INFO] Preparing start region for level 0 (Seed: 1317118761349661229) +2020-07-11 20:39:00 [INFO] Preparing start region for level 1 (Seed: 1317118761349661229) +2020-07-11 20:39:00 [INFO] Preparing start region for level 2 (Seed: 1317118761349661229) +2020-07-11 20:39:01 [INFO] Preparing spawn area: 49% +2020-07-11 20:39:01 [INFO] Server permissions file permissions.yml is empty, ignoring it +2020-07-11 20:39:01 [INFO] Done (1.417s)! For help, type "help" or "?" +2020-07-11 20:39:06 [INFO] Unknown command. Type "help" for help. +2020-07-11 20:47:10 [INFO] Disconnecting LAX1DUDE [/127.0.0.1:50112]: Failed to verify username! +2020-07-11 20:47:10 [WARNING] Exception verifying LAX1DUDE +java.lang.NullPointerException + at net.minecraft.server.v1_5_R3.MinecraftEncryption.a(SourceFile:65) + at net.minecraft.server.v1_5_R3.ThreadLoginVerifier.auth(ThreadLoginVerifier.java:31) + at net.minecraft.server.v1_5_R3.ThreadLoginVerifier.run(ThreadLoginVerifier.java:52) +2020-07-11 20:52:13 [INFO] Disconnecting LAX1DUDE [/127.0.0.1:50145]: Failed to verify username! +2020-07-11 20:52:13 [WARNING] Exception verifying LAX1DUDE +java.lang.NullPointerException + at net.minecraft.server.v1_5_R3.MinecraftEncryption.a(SourceFile:65) + at net.minecraft.server.v1_5_R3.ThreadLoginVerifier.auth(ThreadLoginVerifier.java:31) + at net.minecraft.server.v1_5_R3.ThreadLoginVerifier.run(ThreadLoginVerifier.java:52) +2020-07-11 20:53:30 [INFO] CONSOLE: Stopping the server.. +2020-07-11 20:53:30 [INFO] Stopping server +2020-07-11 20:53:30 [INFO] Saving players +2020-07-11 20:53:30 [INFO] Saving worlds +2020-07-11 20:53:30 [INFO] Saving chunks for level 'world'/Overworld +2020-07-11 20:53:30 [INFO] Saving chunks for level 'world_nether'/Nether +2020-07-11 20:53:30 [INFO] Saving chunks for level 'world_the_end'/The End +2020-07-11 20:53:35 [INFO] Starting minecraft server version 1.5.2 +2020-07-11 20:53:35 [WARNING] To start the server with more ram, launch it as "java -Xmx1024M -Xms1024M -jar minecraft_server.jar" +2020-07-11 20:53:35 [INFO] Loading properties +2020-07-11 20:53:35 [INFO] Default game type: CREATIVE +2020-07-11 20:53:35 [INFO] This server is running CraftBukkit version git-Spigot-959 (MC: 1.5.2) (Implementing API version 1.5.2-R1.1-SNAPSHOT) +2020-07-11 20:53:35 [INFO] Generating keypair +2020-07-11 20:53:35 [INFO] Starting listener #0 on *:25501 +2020-07-11 20:53:36 [WARNING] **** SERVER IS RUNNING IN OFFLINE/INSECURE MODE! +2020-07-11 20:53:36 [WARNING] The server will make no attempt to authenticate usernames. Beware. +2020-07-11 20:53:36 [WARNING] 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. +2020-07-11 20:53:36 [WARNING] To change this, set "online-mode" to "true" in the server.properties file. +2020-07-11 20:53:36 [INFO] Preparing level "world" +2020-07-11 20:53:36 [INFO] -------- World Settings For [world] -------- +2020-07-11 20:53:36 [INFO] View Distance: 10 +2020-07-11 20:53:36 [INFO] Chunks to Grow per Tick: 650 +2020-07-11 20:53:36 [INFO] Experience Merge Radius: 3.0 +2020-07-11 20:53:36 [INFO] Item Merge Radius: 2.5 +2020-07-11 20:53:36 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-07-11 20:53:36 [INFO] Random Lighting Updates: false +2020-07-11 20:53:36 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-07-11 20:53:36 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-07-11 20:53:36 [INFO] Cactus Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Cane Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Melon Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Mushroom Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Pumpkin Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Sapling Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Wheat Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Anti X-Ray: true +2020-07-11 20:53:36 [INFO] Engine Mode: 1 +2020-07-11 20:53:36 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-07-11 20:53:36 [INFO] Mob Spawn Range: 4 +2020-07-11 20:53:36 [INFO] -------- World Settings For [world_nether] -------- +2020-07-11 20:53:36 [INFO] View Distance: 10 +2020-07-11 20:53:36 [INFO] Chunks to Grow per Tick: 650 +2020-07-11 20:53:36 [INFO] Experience Merge Radius: 3.0 +2020-07-11 20:53:36 [INFO] Item Merge Radius: 2.5 +2020-07-11 20:53:36 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-07-11 20:53:36 [INFO] Random Lighting Updates: false +2020-07-11 20:53:36 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-07-11 20:53:36 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-07-11 20:53:36 [INFO] Cactus Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Cane Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Melon Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Mushroom Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Pumpkin Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Sapling Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Wheat Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Anti X-Ray: true +2020-07-11 20:53:36 [INFO] Engine Mode: 1 +2020-07-11 20:53:36 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-07-11 20:53:36 [INFO] Mob Spawn Range: 4 +2020-07-11 20:53:36 [INFO] -------- World Settings For [world_the_end] -------- +2020-07-11 20:53:36 [INFO] View Distance: 10 +2020-07-11 20:53:36 [INFO] Chunks to Grow per Tick: 650 +2020-07-11 20:53:36 [INFO] Experience Merge Radius: 3.0 +2020-07-11 20:53:36 [INFO] Item Merge Radius: 2.5 +2020-07-11 20:53:36 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-07-11 20:53:36 [INFO] Random Lighting Updates: false +2020-07-11 20:53:36 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-07-11 20:53:36 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-07-11 20:53:36 [INFO] Cactus Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Cane Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Melon Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Mushroom Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Pumpkin Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Sapling Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Wheat Growth Modifier: 100% +2020-07-11 20:53:36 [INFO] Anti X-Ray: true +2020-07-11 20:53:36 [INFO] Engine Mode: 1 +2020-07-11 20:53:36 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-07-11 20:53:36 [INFO] Mob Spawn Range: 4 +2020-07-11 20:53:36 [INFO] Preparing start region for level 0 (Seed: 1317118761349661229) +2020-07-11 20:53:37 [INFO] Preparing start region for level 1 (Seed: 1317118761349661229) +2020-07-11 20:53:37 [INFO] Preparing start region for level 2 (Seed: 1317118761349661229) +2020-07-11 20:53:37 [INFO] Preparing spawn area: 49% +2020-07-11 20:53:37 [INFO] Server permissions file permissions.yml is empty, ignoring it +2020-07-11 20:53:37 [INFO] Done (1.398s)! For help, type "help" or "?" +2020-07-11 20:54:00 [INFO] LAX1DUDE[/127.0.0.1:50159] logged in with entity id 155 at ([world] 194.5, 66.0, 240.5) +2020-07-11 21:07:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-11 21:19:25 [INFO] LAX1DUDE[/127.0.0.1:50213] logged in with entity id 2410 at ([world] 92.59731175678084, 63.0, 362.0763238868076) +2020-07-11 21:22:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-12 22:02:44 [INFO] LAX1DUDE[/127.0.0.1:55378] logged in with entity id 4342 at ([world] 188.96963910948548, 66.0, 414.72079193170146) +2020-07-12 22:02:45 [WARNING] LAX1DUDE had an illegal stance: 0.0 +2020-07-12 22:13:07 [INFO] LAX1DUDE[/127.0.0.1:55507] logged in with entity id 4566 at ([world] 188.96963910948548, 66.0, 414.72079193170146) +2020-07-12 22:13:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-12 22:17:24 [INFO] LAX1DUDE[/127.0.0.1:55573] logged in with entity id 4793 at ([world] 188.96963910948548, 66.0, 414.72079193170146) +2020-07-12 22:17:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-12 23:04:12 [INFO] LAX1DUDE[/127.0.0.1:55823] logged in with entity id 5018 at ([world] 188.96963910948548, 66.0, 414.72079193170146) +2020-07-12 23:04:16 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-13 21:56:27 [INFO] LAX1DUDE[/127.0.0.1:59204] logged in with entity id 5280 at ([world] 188.96963910948548, 66.0, 414.72079193170146) +2020-07-13 21:56:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-13 21:57:28 [INFO] LAX1DUDE[/127.0.0.1:59237] logged in with entity id 5505 at ([world] 188.96963910948548, 66.0, 414.72079193170146) +2020-07-13 21:57:39 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-13 22:06:15 [INFO] LAX1DUDE[/127.0.0.1:59346] logged in with entity id 5730 at ([world] 188.96963910948548, 66.0, 414.72079193170146) +2020-07-13 22:06:47 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-07-13 22:06:47 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-07-13 23:13:25 [INFO] LAX1DUDE[/127.0.0.1:59525] logged in with entity id 5963 at ([world] 188.96963910948548, 66.0, 414.72079193170146) +2020-07-13 23:19:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-13 23:19:27 [INFO] LAX1DUDE[/127.0.0.1:59539] logged in with entity id 6479 at ([world] 154.3816250735706, 85.11435596545441, 395.7799022083639) +2020-07-13 23:24:24 [SEVERE] java.io.IOException: An existing connection was forcibly closed by the remote host +2020-07-13 23:24:24 [SEVERE] at sun.nio.ch.SocketDispatcher.read0(Native Method) +2020-07-13 23:24:24 [SEVERE] at sun.nio.ch.SocketDispatcher.read(Unknown Source) +2020-07-13 23:24:24 [SEVERE] at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source) +2020-07-13 23:24:24 [SEVERE] at sun.nio.ch.IOUtil.read(Unknown Source) +2020-07-13 23:24:24 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-07-13 23:24:24 [SEVERE] at sun.nio.ch.SocketChannelImpl.read(Unknown Source) +2020-07-13 23:24:24 [SEVERE] at io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:274) +2020-07-13 23:24:24 [SEVERE] at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:887) +2020-07-13 23:24:24 [SEVERE] at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:247) +2020-07-13 23:24:24 [SEVERE] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:89) +2020-07-13 23:24:24 [SEVERE] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:489) +2020-07-13 23:24:24 [SEVERE] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:464) +2020-07-13 23:24:24 [SEVERE] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:358) +2020-07-13 23:24:24 [SEVERE] at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101) +2020-07-13 23:24:24 [SEVERE] at java.lang.Thread.run(Unknown Source) +2020-07-14 01:16:44 [INFO] LAX1DUDE[/127.0.0.1:60172] logged in with entity id 7408 at ([world] 115.94254225038, 64.0, 394.93079072351287) +2020-07-14 01:16:47 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-14 01:54:07 [INFO] Disconnecting LAX1DUDE [/127.0.0.1:60326]: Outdated server! +2020-07-14 01:55:01 [INFO] Disconnecting LAX1DUDE [/127.0.0.1:60331]: Outdated server! +2020-07-14 01:59:49 [INFO] LAX1DUDE[/127.0.0.1:60378] logged in with entity id 7610 at ([world] 115.94254225038, 64.0, 394.93079072351287) +2020-07-14 01:59:55 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-14 02:01:43 [INFO] LAX1DUDE[/127.0.0.1:60386] logged in with entity id 7811 at ([world] 115.94254225038, 64.0, 394.93079072351287) +2020-07-14 02:03:16 [INFO] LAX1DUDE issued server command: /gamemode 0 +2020-07-14 02:03:25 [INFO] Can't find player @a +2020-07-14 02:03:31 [INFO] CONSOLE: Set LAX1DUDE's game mode to SURVIVAL mode +2020-07-14 02:03:41 [INFO] CONSOLE: Opped LAX1DUDE +2020-07-14 02:03:48 [INFO] LAX1DUDE issued server command: /gamemode 1 +2020-07-14 02:03:48 [INFO] LAX1DUDE: Set own game mode to CREATIVE mode +2020-07-14 02:03:59 [INFO] LAX1DUDE issued server command: /gamemode 0 +2020-07-14 02:03:59 [INFO] LAX1DUDE: Set own game mode to SURVIVAL mode +2020-07-14 02:04:44 [INFO] LAX1DUDE issued server command: /summon Ozelot +2020-07-14 02:06:01 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-14 02:09:55 [INFO] LAX1DUDE[/127.0.0.1:60407] logged in with entity id 8481 at ([world] 91.49361617912987, 64.0, 414.1279101808871) +2020-07-14 02:10:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-14 02:17:49 [INFO] LAX2DUDE[/127.0.0.1:60429] logged in with entity id 8692 at ([world] 196.5, 66.0, 244.5) +2020-07-14 02:18:33 [INFO] yee +2020-07-14 02:21:42 [INFO] LAX1DUDE[/127.0.0.1:60446] logged in with entity id 9083 at ([world] 87.17192318902745, 64.0, 415.8322653227179) +2020-07-14 02:22:12 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-07-14 02:22:12 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-07-14 02:25:06 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-14 02:25:51 [INFO] /127.0.0.1:60482 lost connection +2020-07-14 02:27:43 [INFO] /127.0.0.1:60512 lost connection +2020-07-14 02:32:01 [INFO] LAX1DUDE[/127.0.0.1:60542] logged in with entity id 9308 at ([world] 87.17192318902745, 64.0, 415.8322653227179) +2020-07-14 02:33:32 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-14 02:34:08 [INFO] LAX2DUDE[/127.0.0.1:60561] logged in with entity id 10018 at ([world] 158.16852380858003, 85.99727989251731, 310.20116215253915) +2020-07-14 02:34:41 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-14 02:35:11 [INFO] LAX2DUDE[/127.0.0.1:60568] logged in with entity id 10385 at ([world] 95.38279669118012, 64.0, 430.6543685711954) +2020-07-14 02:46:53 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-14 02:47:31 [INFO] LAX2DUDE[/127.0.0.1:60600] logged in with entity id 12874 at ([world] 286.19941275884594, 63.0, 229.8562512467022) +2020-07-14 02:49:12 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-14 02:50:13 [INFO] LAX2DUDE[/127.0.0.1:60608] logged in with entity id 12949 at ([world] 320.6765720955426, 63.0, 169.90858996258683) +2020-07-14 03:00:29 [INFO] CONSOLE: Opped LAX2DUDE +2020-07-14 03:01:17 [INFO] LAX2DUDE issued server command: /gamemode 0 +2020-07-14 03:01:17 [INFO] LAX2DUDE: Set own game mode to SURVIVAL mode +2020-07-14 03:01:20 [INFO] LAX2DUDE issued server command: /gamemode 1 +2020-07-14 03:01:20 [INFO] LAX2DUDE: Set own game mode to CREATIVE mode +2020-07-14 03:01:25 [INFO] LAX2DUDE issued server command: /gamemode 0 +2020-07-14 03:01:25 [INFO] LAX2DUDE: Set own game mode to SURVIVAL mode +2020-07-14 03:02:23 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-14 03:05:18 [INFO] LAX2DUDE[/127.0.0.1:60659] logged in with entity id 18688 at ([world] 64.30931612206354, 65.0, 1676.4406318239242) +2020-07-14 03:07:43 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-21 16:27:05 [INFO] CONSOLE: Stopping the server.. +2020-07-21 16:27:05 [INFO] Stopping server +2020-07-21 16:27:05 [INFO] Saving players +2020-07-21 16:27:05 [INFO] Saving worlds +2020-07-21 16:27:05 [INFO] Saving chunks for level 'world'/Overworld +2020-07-21 16:27:05 [INFO] Saving chunks for level 'world_nether'/Nether +2020-07-21 16:27:05 [INFO] Saving chunks for level 'world_the_end'/The End +2020-07-21 16:27:05 [INFO] Stopping server +2020-07-21 16:28:20 [INFO] Starting minecraft server version 1.5.2 +2020-07-21 16:28:20 [WARNING] To start the server with more ram, launch it as "java -Xmx1024M -Xms1024M -jar minecraft_server.jar" +2020-07-21 16:28:20 [INFO] Loading properties +2020-07-21 16:28:20 [INFO] Default game type: CREATIVE +2020-07-21 16:28:20 [INFO] This server is running CraftBukkit version git-Spigot-959 (MC: 1.5.2) (Implementing API version 1.5.2-R1.1-SNAPSHOT) +2020-07-21 16:28:20 [INFO] Generating keypair +2020-07-21 16:28:21 [INFO] Starting listener #0 on *:25501 +2020-07-21 16:28:21 [WARNING] **** SERVER IS RUNNING IN OFFLINE/INSECURE MODE! +2020-07-21 16:28:21 [WARNING] The server will make no attempt to authenticate usernames. Beware. +2020-07-21 16:28:21 [WARNING] 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. +2020-07-21 16:28:21 [WARNING] To change this, set "online-mode" to "true" in the server.properties file. +2020-07-21 16:28:21 [INFO] Preparing level "world" +2020-07-21 16:28:21 [INFO] -------- World Settings For [world] -------- +2020-07-21 16:28:21 [INFO] View Distance: 10 +2020-07-21 16:28:21 [INFO] Experience Merge Radius: 3.0 +2020-07-21 16:28:21 [INFO] Chunks to Grow per Tick: 650 +2020-07-21 16:28:21 [INFO] Item Merge Radius: 2.5 +2020-07-21 16:28:21 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-07-21 16:28:21 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-07-21 16:28:21 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-07-21 16:28:21 [INFO] Random Lighting Updates: false +2020-07-21 16:28:21 [INFO] Mob Spawn Range: 4 +2020-07-21 16:28:21 [INFO] Anti X-Ray: true +2020-07-21 16:28:21 [INFO] Engine Mode: 1 +2020-07-21 16:28:21 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-07-21 16:28:21 [INFO] Cactus Growth Modifier: 100% +2020-07-21 16:28:21 [INFO] Cane Growth Modifier: 100% +2020-07-21 16:28:21 [INFO] Melon Growth Modifier: 100% +2020-07-21 16:28:21 [INFO] Mushroom Growth Modifier: 100% +2020-07-21 16:28:21 [INFO] Pumpkin Growth Modifier: 100% +2020-07-21 16:28:21 [INFO] Sapling Growth Modifier: 100% +2020-07-21 16:28:21 [INFO] Wheat Growth Modifier: 100% +2020-07-21 16:28:22 [INFO] -------- World Settings For [world_nether] -------- +2020-07-21 16:28:22 [INFO] View Distance: 10 +2020-07-21 16:28:22 [INFO] Experience Merge Radius: 3.0 +2020-07-21 16:28:22 [INFO] Chunks to Grow per Tick: 650 +2020-07-21 16:28:22 [INFO] Item Merge Radius: 2.5 +2020-07-21 16:28:22 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-07-21 16:28:22 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-07-21 16:28:22 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-07-21 16:28:22 [INFO] Random Lighting Updates: false +2020-07-21 16:28:22 [INFO] Mob Spawn Range: 4 +2020-07-21 16:28:22 [INFO] Anti X-Ray: true +2020-07-21 16:28:22 [INFO] Engine Mode: 1 +2020-07-21 16:28:22 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-07-21 16:28:22 [INFO] Cactus Growth Modifier: 100% +2020-07-21 16:28:22 [INFO] Cane Growth Modifier: 100% +2020-07-21 16:28:22 [INFO] Melon Growth Modifier: 100% +2020-07-21 16:28:22 [INFO] Mushroom Growth Modifier: 100% +2020-07-21 16:28:22 [INFO] Pumpkin Growth Modifier: 100% +2020-07-21 16:28:22 [INFO] Sapling Growth Modifier: 100% +2020-07-21 16:28:22 [INFO] Wheat Growth Modifier: 100% +2020-07-21 16:28:22 [INFO] -------- World Settings For [world_the_end] -------- +2020-07-21 16:28:22 [INFO] View Distance: 10 +2020-07-21 16:28:22 [INFO] Experience Merge Radius: 3.0 +2020-07-21 16:28:22 [INFO] Chunks to Grow per Tick: 650 +2020-07-21 16:28:22 [INFO] Item Merge Radius: 2.5 +2020-07-21 16:28:22 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-07-21 16:28:22 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-07-21 16:28:22 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-07-21 16:28:22 [INFO] Random Lighting Updates: false +2020-07-21 16:28:22 [INFO] Mob Spawn Range: 4 +2020-07-21 16:28:22 [INFO] Anti X-Ray: true +2020-07-21 16:28:22 [INFO] Engine Mode: 1 +2020-07-21 16:28:22 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-07-21 16:28:22 [INFO] Cactus Growth Modifier: 100% +2020-07-21 16:28:22 [INFO] Cane Growth Modifier: 100% +2020-07-21 16:28:22 [INFO] Melon Growth Modifier: 100% +2020-07-21 16:28:22 [INFO] Mushroom Growth Modifier: 100% +2020-07-21 16:28:22 [INFO] Pumpkin Growth Modifier: 100% +2020-07-21 16:28:22 [INFO] Sapling Growth Modifier: 100% +2020-07-21 16:28:22 [INFO] Wheat Growth Modifier: 100% +2020-07-21 16:28:22 [INFO] Preparing start region for level 0 (Seed: 4810582216495008642) +2020-07-21 16:28:23 [INFO] Preparing spawn area: 20% +2020-07-21 16:28:24 [INFO] Preparing spawn area: 49% +2020-07-21 16:28:25 [INFO] Preparing spawn area: 83% +2020-07-21 16:28:25 [INFO] Preparing start region for level 1 (Seed: 4810582216495008642) +2020-07-21 16:28:26 [INFO] Preparing spawn area: 8% +2020-07-21 16:28:27 [INFO] Preparing spawn area: 49% +2020-07-21 16:28:28 [INFO] Preparing spawn area: 91% +2020-07-21 16:28:28 [INFO] Preparing start region for level 2 (Seed: 4810582216495008642) +2020-07-21 16:28:29 [INFO] Preparing spawn area: 49% +2020-07-21 16:28:29 [INFO] Server permissions file permissions.yml is empty, ignoring it +2020-07-21 16:28:30 [INFO] Done (8.366s)! For help, type "help" or "?" +2020-07-21 16:28:34 [INFO] LAX2DUDE[/127.0.0.1:57178] logged in with entity id 6167 at ([world] 91.5, 71.0, 230.5) +2020-07-21 16:28:56 [INFO] LAX2DUDE issued server command: /gamemode 0 +2020-07-21 16:28:56 [INFO] LAX2DUDE: Set own game mode to SURVIVAL mode +2020-07-21 16:29:43 [INFO] LAX2DUDE issued server command: /gamemode 1 +2020-07-21 16:29:43 [INFO] LAX2DUDE: Set own game mode to CREATIVE mode +2020-07-21 16:30:03 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-21 16:41:33 [INFO] LAX2DUDE[/127.0.0.1:57350] logged in with entity id 6686 at ([world] 88.48555490047195, 78.0, 304.4524404811821) +2020-07-21 16:42:14 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-21 16:45:38 [INFO] LAX2DUDE[/127.0.0.1:57419] logged in with entity id 6788 at ([world] 85.70147330965871, 75.0, 272.89188035976434) +2020-07-21 16:45:51 [INFO] LAX2DUDE issued server command: /gamemode 0 +2020-07-21 16:45:51 [INFO] LAX2DUDE: Set own game mode to SURVIVAL mode +2020-07-21 16:46:09 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-22 01:03:07 [INFO] LAX2DUDE[/127.0.0.1:51345] logged in with entity id 6890 at ([world] 105.18181110799705, 79.0, 296.2958744713105) +2020-07-22 01:03:32 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-22 01:04:24 [INFO] LAX2DUDE[/127.0.0.1:51358] logged in with entity id 6979 at ([world] 80.69999998807907, 71.0, 274.03045767027766) +2020-07-22 01:05:08 [INFO] LAX2DUDE issued server command: /time set day +2020-07-22 01:05:08 [INFO] LAX2DUDE: Set time to 0 +2020-07-22 01:05:24 [INFO] LAX2DUDE issued server command: /gamemode 0 +2020-07-22 01:05:24 [INFO] LAX2DUDE: Set own game mode to SURVIVAL mode +2020-07-22 01:05:58 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-22 01:17:56 [INFO] LAX2DUDE[/127.0.0.1:51546] logged in with entity id 7202 at ([world] 71.77735015266435, 65.0, 215.80508489915147) +2020-07-22 01:18:22 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-22 01:29:49 [INFO] LAX2DUDE[/127.0.0.1:51732] logged in with entity id 7249 at ([world] 71.77735015266435, 65.0, 215.80508489915147) +2020-07-22 01:30:01 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-22 01:30:38 [INFO] LAX2DUDE[/127.0.0.1:51742] logged in with entity id 7293 at ([world] 71.77735015266435, 65.0, 215.80508489915147) +2020-07-22 01:31:21 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-22 01:40:39 [INFO] LAX2DUDE[/127.0.0.1:51906] logged in with entity id 7380 at ([world] 66.27568319209132, 65.0, 216.50800530349113) +2020-07-22 01:43:01 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-22 01:46:59 [INFO] LAX2DUDE[/127.0.0.1:51997] logged in with entity id 7552 at ([world] 94.48191841890825, 64.0, 218.92158948460204) +2020-07-22 01:51:31 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-22 01:52:14 [INFO] LAX2DUDE[/127.0.0.1:52088] logged in with entity id 7854 at ([world] 112.95182416516462, 64.0, 208.05056351699528) +2020-07-22 01:55:54 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-22 02:10:36 [INFO] LAX2DUDE[/127.0.0.1:52276] logged in with entity id 8987 at ([world] 94.11017514420939, 75.0, 382.54716039290304) +2020-07-22 02:16:12 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-22 02:17:56 [INFO] LAX2DUDE[/127.0.0.1:52308] logged in with entity id 9590 at ([world] 43.17718525408283, 91.80478881041977, 396.4858972464837) +2020-07-22 02:18:12 [INFO] LAX2DUDE issued server command: /time set day +2020-07-22 02:18:12 [INFO] LAX2DUDE: Set time to 0 +2020-07-22 02:18:47 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-22 02:28:06 [INFO] LAX2DUDE[/127.0.0.1:52345] logged in with entity id 9686 at ([world] 51.23216183339508, 86.2378331347265, 365.46546828472617) +2020-07-22 02:28:38 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-22 02:34:45 [INFO] LAX2DUDE[/127.0.0.1:52365] logged in with entity id 9913 at ([world] 18.030159397585326, 71.39115788257902, 400.9467062367714) +2020-07-22 02:35:12 [INFO] LAX2DUDE issued server command: /time set day +2020-07-22 02:35:12 [INFO] LAX2DUDE: Set time to 0 +2020-07-22 02:36:45 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-22 02:47:30 [INFO] LAX2DUDE[/127.0.0.1:52448] logged in with entity id 10453 at ([world] 155.79374320887803, 67.0, 338.97731563105526) +2020-07-22 02:47:38 [INFO] LAX2DUDE lost connection: disconnect.quitting +2020-07-22 02:48:16 [INFO] LAX1DUDE[/127.0.0.1:52454] logged in with entity id 10512 at ([world] 84.5, 63.0, 214.5) +2020-07-22 02:50:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-22 16:20:00 [INFO] LAX1DUDE[/127.0.0.1:53737] logged in with entity id 10748 at ([world] 25.337216844073353, 66.0, 222.91936486509636) +2020-07-22 16:21:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-22 17:17:52 [INFO] LAX1DUDE[/127.0.0.1:53865] logged in with entity id 11457 at ([world] 253.95000211302565, 71.0, 193.7715532165113) +2020-07-22 17:20:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-22 17:20:44 [INFO] LAX1DUDE[/127.0.0.1:53876] logged in with entity id 12312 at ([world] 275.29533063852796, 64.0, 222.13106918534896) +2020-07-22 17:25:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-22 17:26:13 [INFO] LAX1DUDE[/127.0.0.1:53891] logged in with entity id 14242 at ([world] 320.5170454421012, 68.51513417583163, 629.2349932654886) +2020-07-22 17:26:25 [INFO] LAX1DUDE issued server command: /gamemode 0 +2020-07-22 17:26:25 [INFO] LAX1DUDE: Set own game mode to SURVIVAL mode +2020-07-22 17:26:42 [INFO] LAX1DUDE was doomed to fall by Ghast +2020-07-22 17:26:46 [INFO] LAX1DUDE issued server command: /gamemode 1 +2020-07-22 17:26:46 [INFO] LAX1DUDE: Set own game mode to CREATIVE mode +2020-07-22 17:28:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-22 17:29:17 [INFO] LAX1DUDE[/127.0.0.1:53911] logged in with entity id 14610 at ([world] 100.68218708964326, 72.0, 253.02839695371065) +2020-07-22 17:37:32 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-23 00:03:18 [INFO] LAX1DUDE[/127.0.0.1:53574] logged in with entity id 15623 at ([world] 78.3309436234477, 73.0, 326.7315309561078) +2020-07-23 00:03:21 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-23 20:35:23 [INFO] LAX1DUDE[/127.0.0.1:60715] logged in with entity id 15733 at ([world] 78.3309436234477, 73.0, 326.7315309561078) +2020-07-23 20:36:58 [INFO] LAX1DUDE issued server command: /give @p 52 +2020-07-23 20:37:04 [INFO] LAX1DUDE issued server command: /give LAX1DUDE 52 +2020-07-23 20:37:04 [INFO] LAX1DUDE: Gave LAX1DUDE some 52 (MOB_SPAWNER) +2020-07-23 20:57:12 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-23 20:57:14 [INFO] LAX1DUDE[/127.0.0.1:61331] logged in with entity id 26442 at ([world] 1159.9433503442685, 65.0, -94.37361884007947) +2020-07-23 21:17:21 [INFO] LAX1DUDE issued server command: /weather rain +2020-07-23 21:17:21 [INFO] LAX1DUDE: Changed weather to rainy for 855 seconds. +2020-07-23 21:17:24 [INFO] LAX1DUDE issued server command: /weather rain +2020-07-23 21:17:24 [INFO] LAX1DUDE: Changed weather to rainy for 551 seconds. +2020-07-23 21:17:25 [INFO] LAX1DUDE issued server command: /weather rain +2020-07-23 21:17:25 [INFO] LAX1DUDE: Changed weather to rainy for 308 seconds. +2020-07-23 21:17:27 [INFO] LAX1DUDE issued server command: /weather rain +2020-07-23 21:17:27 [INFO] LAX1DUDE: Changed weather to rainy for 740 seconds. +2020-07-23 21:22:07 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-23 21:22:32 [INFO] LAX1DUDE[/127.0.0.1:61548] logged in with entity id 35135 at ([world] 986.9840071668984, 63.0, 159.6881905347542) +2020-07-23 21:36:50 [INFO] LAX1DUDE issued server command: /kill +2020-07-23 21:36:50 [INFO] LAX1DUDE died +2020-07-23 21:41:23 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 01:26:14 [INFO] EagDeev58[/127.0.0.1:64441] logged in with entity id 40578 at ([world] 89.5, 69.0, 223.5) +2020-07-24 01:27:24 [INFO] EagDeev58 lost connection: disconnect.quitting +2020-07-24 02:06:15 [INFO] YeetGroon60[/127.0.0.1:64496] logged in with entity id 40693 at ([world] 88.5, 72.0, 228.5) +2020-07-24 02:06:21 [INFO] YeetGroon60 lost connection: disconnect.quitting +2020-07-24 02:21:15 [INFO] DeevYee8[/127.0.0.1:64533] logged in with entity id 40719 at ([world] 80.5, 74.0, 231.5) +2020-07-24 02:21:33 [INFO] https://x-games.nx-eags.tk/ +2020-07-24 19:59:46 [INFO] DeevYee8 lost connection: disconnect.quitting +2020-07-24 20:58:57 [INFO] LAX1DUDE[/127.0.0.1:50244] logged in with entity id 56967 at ([world] 71.98390489343886, 36.0, 230.97234027932817) +2020-07-24 21:02:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 21:03:42 [INFO] LAX1DUDE[/127.0.0.1:50250] logged in with entity id 57121 at ([world] 57.74681981392361, 36.0, 228.26471449705568) +2020-07-24 21:03:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 21:34:11 [INFO] LAX1DUDE[/127.0.0.1:50296] logged in with entity id 57150 at ([world] 57.30000001192093, 36.0, 227.363020217855) +2020-07-24 21:35:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 21:35:26 [INFO] LAX1DUDE[/127.0.0.1:50301] logged in with entity id 57232 at ([world] 59.280036008301096, 36.0, 233.2836529809649) +2020-07-24 21:36:23 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 21:36:50 [INFO] LAX1DUDE[/127.0.0.1:50307] logged in with entity id 57260 at ([world] 66.47165075251075, 36.0, 228.95598304515306) +2020-07-24 21:37:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 21:37:55 [INFO] LAX1DUDE[/127.0.0.1:50310] logged in with entity id 57300 at ([world] 62.874339902432084, 36.0, 229.593206572717) +2020-07-24 21:47:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 22:33:00 [INFO] EaglerYee45[/127.0.0.1:50378] logged in with entity id 57468 at ([world] 87.5, 63.0, 217.5) +2020-07-24 22:34:01 [INFO] EaglerYee45 lost connection: disconnect.quitting +2020-07-24 22:46:01 [INFO] LAX1DUDE[/127.0.0.1:50402] logged in with entity id 57541 at ([world] 62.874339902432084, 36.0, 229.593206572717) +2020-07-24 22:46:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 22:46:54 [INFO] LAX1DUDE[/127.0.0.1:50412] logged in with entity id 57566 at ([world] 68.00947085631373, 36.0, 232.07112530211393) +2020-07-24 22:55:13 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 22:55:59 [INFO] LAX1DUDE[/127.0.0.1:50427] logged in with entity id 57789 at ([world] 60.69659207147055, 36.0, 231.8859494078515) +2020-07-24 22:57:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 22:58:14 [INFO] LAX1DUDE[/127.0.0.1:50436] logged in with entity id 57872 at ([world] 64.36023971939153, 36.0, 228.8002363053274) +2020-07-24 23:00:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 23:00:42 [INFO] LAX1DUDE[/127.0.0.1:50442] logged in with entity id 57958 at ([world] 58.33476364580764, 36.0, 234.5777759206793) +2020-07-24 23:00:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 23:01:23 [INFO] LAX1DUDE[/127.0.0.1:50445] logged in with entity id 57981 at ([world] 70.69999998807907, 36.0, 230.35999667308994) +2020-07-24 23:09:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 23:09:38 [INFO] LAX1DUDE[/127.0.0.1:50466] logged in with entity id 58118 at ([world] 61.23326894932336, 36.0, 230.5355321188415) +2020-07-24 23:09:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 23:09:55 [INFO] LAX1DUDE[/127.0.0.1:50469] logged in with entity id 58144 at ([world] 62.55079716093677, 36.0, 230.30702054151521) +2020-07-24 23:24:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 23:25:22 [INFO] LAX1DUDE[/127.0.0.1:50490] logged in with entity id 58468 at ([world] 64.49892221639985, 36.0, 229.94084176698044) +2020-07-24 23:54:57 [WARNING] LAX1DUDE moved too quickly! -654.1161908195154,-87.8711286227121,-826.6366098572078 (654.1161908195154, 87.8711286227121, 826.6366098572078) +2020-07-24 23:55:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-24 23:55:16 [INFO] LAX1DUDE[/127.0.0.1:50552] logged in with entity id 63621 at ([world] 654.1161908195154, 86.25112861794373, 826.6366098572078) +2020-07-24 23:56:40 [INFO] LAX1DUDE fell out of the world +2020-07-24 23:58:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-25 00:03:59 [INFO] LAX1DUDE[/127.0.0.1:50576] logged in with entity id 65540 at ([world] 653.5472877199284, 12.0, 827.3000000119209) +2020-07-25 00:08:40 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-25 00:09:03 [INFO] LAX1DUDE[/127.0.0.1:50590] logged in with entity id 65804 at ([world] 647.3000000119209, 12.341840111248104, 829.4218092124868) +2020-07-25 00:16:15 [WARNING] LAX1DUDE moved too quickly! 0.38060449795508955,0.0,0.2279248249982222 (12.987591684926235, 0.40416000602245333, 27.053711281257897) +2020-07-25 00:16:15 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (2.108794423522281, 0.7224960107660293, 20.350796335884194) +2020-07-25 00:16:16 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (1.9190029807106104, 0.4334976064596176, 18.51922519937549) +2020-07-25 00:16:16 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (1.7462927627745115, 0.26009856387577057, 16.852495417117705) +2020-07-25 00:16:39 [INFO] LAX1DUDE fell out of the world +2020-07-25 00:30:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-25 00:30:21 [INFO] LAX1DUDE[/127.0.0.1:50618] logged in with entity id 67069 at ([world] 101.17928319528575, 72.0, 252.2169779688156) +2020-07-25 00:30:33 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-25 00:31:06 [INFO] LAX1DUDE[/127.0.0.1:50621] logged in with entity id 67089 at ([world] 101.61153525810984, 72.0, 251.267550214706) +2020-07-25 00:42:12 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-25 00:42:25 [INFO] LAX1DUDE[/127.0.0.1:50641] logged in with entity id 67408 at ([world] 101.61153525810984, 72.0, 251.267550214706) +2020-07-25 00:42:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-25 00:42:50 [INFO] LAX1DUDE[/127.0.0.1:50644] logged in with entity id 67443 at ([world] 94.73917963226349, 72.0, 247.06502730634068) +2020-07-25 00:45:56 [WARNING] LAX1DUDE had an illegal stance: -3.5 +2020-07-25 00:46:22 [INFO] LAX1DUDE[/127.0.0.1:50651] logged in with entity id 67560 at ([world] 95.98512725260946, 72.0, 249.90553868683267) +2020-07-25 00:56:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-25 00:56:41 [INFO] LAX1DUDE[/127.0.0.1:50671] logged in with entity id 67804 at ([world] 110.49378575187983, 71.0, 241.50724221427686) +2020-07-25 00:56:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-25 01:00:18 [INFO] YeerDeev61[/127.0.0.1:50681] logged in with entity id 67842 at ([world] 87.5, 62.0, 216.5) +2020-07-25 01:01:25 [INFO] YeerDeev61 lost connection: disconnect.quitting +2020-07-25 01:01:31 [INFO] YeerDeev61[/127.0.0.1:50684] logged in with entity id 67947 at ([world] 62.53228641345231, 36.0, 229.97575128436554) +2020-07-25 01:01:35 [INFO] YeerDeev61 lost connection: disconnect.quitting +2020-07-25 01:01:49 [INFO] YeerDeev61[/127.0.0.1:50687] logged in with entity id 67968 at ([world] 63.77587994230592, 36.0, 229.76038168366824) +2020-07-25 01:02:50 [INFO] YeerDeev61 lost connection: disconnect.quitting +2020-07-25 20:13:27 [INFO] FudgliDarvig55[/127.0.0.1:52158] logged in with entity id 68067 at ([world] 86.5, 70.0, 222.5) +2020-07-25 20:13:48 [INFO] FudglerEagler50[/127.0.0.1:52164] logged in with entity id 68107 at ([world] 76.5, 74.0, 229.5) +2020-07-25 20:13:51 [INFO] FudglerEagler50 lost connection: disconnect.quitting +2020-07-25 20:15:21 [INFO] FudgliDarvig55 lost connection: disconnect.quitting +2020-07-25 20:15:33 [INFO] EggYee6[/127.0.0.1:52171] logged in with entity id 68172 at ([world] 92.5, 70.0, 226.5) +2020-07-25 20:15:38 [INFO] DumpsterYee82[/127.0.0.1:52174] logged in with entity id 68195 at ([world] 77.5, 75.0, 233.5) +2020-07-25 20:15:41 [INFO] DumpsterYee82 lost connection: disconnect.quitting +2020-07-25 20:15:49 [INFO] EggYee6 lost connection: disconnect.quitting +2020-07-25 20:22:03 [INFO] ChadDeev70[/127.0.0.1:52190] logged in with entity id 68243 at ([world] 88.5, 61.0, 215.5) +2020-07-25 20:22:11 [INFO] ViggDeev55[/127.0.0.1:52193] logged in with entity id 68266 at ([world] 80.5, 66.0, 219.5) +2020-07-25 20:22:11 [INFO] ChadDeev70 lost connection: disconnect.quitting +2020-07-25 20:22:29 [INFO] ViggDeev55 lost connection: disconnect.quitting +2020-07-25 20:22:46 [INFO] DarvigEagler8[/127.0.0.1:52196] logged in with entity id 68268 at ([world] 91.5, 63.0, 217.5) +2020-07-25 20:22:50 [INFO] DeevYeet83[/127.0.0.1:52199] logged in with entity id 68291 at ([world] 77.5, 80.0, 230.5) +2020-07-25 20:23:01 [INFO] DeevYeet83 lost connection: disconnect.quitting +2020-07-25 20:23:05 [INFO] DarvigEagler8 lost connection: disconnect.quitting +2020-07-25 20:25:05 [INFO] DarvigCum97[/127.0.0.1:52206] logged in with entity id 68307 at ([world] 75.5, 72.0, 230.5) +2020-07-25 20:25:20 [INFO] DarverEagler16[/127.0.0.1:52209] logged in with entity id 68330 at ([world] 84.5, 72.0, 230.5) +2020-07-25 20:25:35 [INFO] DarvigCum97 lost connection: disconnect.quitting +2020-07-25 20:25:39 [INFO] DarverEagler16 lost connection: disconnect.quitting +2020-07-25 20:30:38 [INFO] DarverDarver70[/127.0.0.1:52250] logged in with entity id 68351 at ([world] 76.5, 75.0, 227.5) +2020-07-25 20:30:59 [INFO] DarvigDeev45[/127.0.0.1:52253] logged in with entity id 68388 at ([world] 76.5, 79.0, 231.5) +2020-07-25 20:31:10 [INFO] DarvigDeev45 lost connection: disconnect.quitting +2020-07-25 20:31:14 [INFO] DarverDarver70 lost connection: disconnect.quitting +2020-07-25 20:37:27 [INFO] GroonDarver84[/127.0.0.1:52299] logged in with entity id 68394 at ([world] 91.5, 68.0, 223.5) +2020-07-25 20:37:32 [INFO] EaglerChode28[/127.0.0.1:52302] logged in with entity id 68417 at ([world] 88.5, 63.0, 218.5) +2020-07-25 20:37:58 [INFO] GroonDarver84 lost connection: disconnect.quitting +2020-07-25 20:37:59 [INFO] EaglerChode28 lost connection: disconnect.quitting +2020-07-25 20:58:05 [INFO] DeevisVigg63[/127.0.0.1:52468] logged in with entity id 68451 at ([world] 82.5, 73.0, 229.5) +2020-07-25 20:58:13 [INFO] EaglerGroon50[/127.0.0.1:52471] logged in with entity id 68474 at ([world] 77.5, 64.0, 215.5) +2020-07-25 20:58:26 [INFO] EaglerGroon50 lost connection: disconnect.quitting +2020-07-25 20:58:32 [INFO] DeevisVigg63 lost connection: disconnect.quitting +2020-07-25 21:00:51 [INFO] DarvigDarvy74[/127.0.0.1:52479] logged in with entity id 68504 at ([world] 78.5, 74.0, 233.5) +2020-07-25 21:00:56 [INFO] EggChad0[/127.0.0.1:52482] logged in with entity id 68527 at ([world] 88.5, 72.0, 232.5) +2020-07-25 21:01:23 [INFO] DarvigDarvy74 lost connection: disconnect.quitting +2020-07-25 21:01:25 [INFO] EggChad0 lost connection: disconnect.quitting +2020-07-25 21:03:09 [INFO] EagDeev18[/127.0.0.1:52488] logged in with entity id 68539 at ([world] 92.5, 71.0, 232.5) +2020-07-25 21:03:14 [INFO] DeevYee16[/127.0.0.1:52491] logged in with entity id 68562 at ([world] 77.5, 64.0, 215.5) +2020-07-25 21:03:29 [INFO] EagDeev18 lost connection: disconnect.quitting +2020-07-25 21:03:36 [INFO] DeevYee16 lost connection: disconnect.quitting +2020-07-25 21:07:58 [INFO] DeevisVigg13[/127.0.0.1:52499] logged in with entity id 68595 at ([world] 86.5, 63.0, 217.5) +2020-07-25 21:08:05 [INFO] ViggCum43[/127.0.0.1:52502] logged in with entity id 68623 at ([world] 79.5, 72.0, 226.5) +2020-07-25 21:08:29 [INFO] ViggCum43 lost connection: disconnect.quitting +2020-07-25 21:08:33 [INFO] DeevisVigg13 lost connection: disconnect.quitting +2020-07-25 21:27:39 [INFO] DarverVigg26[/127.0.0.1:52527] logged in with entity id 68687 at ([world] 87.5, 69.0, 222.5) +2020-07-25 21:27:44 [INFO] YeeYee52[/127.0.0.1:52530] logged in with entity id 68714 at ([world] 90.5, 61.0, 215.5) +2020-07-25 21:27:54 [INFO] YeeYee52 lost connection: disconnect.quitting +2020-07-25 21:27:55 [INFO] DarverVigg26 lost connection: disconnect.quitting +2020-07-25 21:35:50 [INFO] FlumpterDarver62[/127.0.0.1:52572] logged in with entity id 68726 at ([world] 76.5, 79.0, 231.5) +2020-07-25 21:35:57 [INFO] CumChode57[/127.0.0.1:52575] logged in with entity id 68744 at ([world] 87.5, 71.0, 225.5) +2020-07-25 21:36:23 [INFO] FlumpterDarver62 lost connection: disconnect.quitting +2020-07-25 21:36:25 [INFO] CumChode57 lost connection: disconnect.quitting +2020-07-25 21:56:58 [INFO] CumDeev8[/127.0.0.1:52626] logged in with entity id 68804 at ([world] 81.5, 73.0, 231.5) +2020-07-25 21:57:03 [INFO] DumpsterDarver24[/127.0.0.1:52629] logged in with entity id 68828 at ([world] 82.5, 73.0, 233.5) +2020-07-25 21:57:35 [INFO] DumpsterDarver24 lost connection: disconnect.quitting +2020-07-25 21:57:36 [INFO] CumDeev8 lost connection: disconnect.quitting +2020-07-25 22:04:16 [INFO] FlumpterEagler42[/127.0.0.1:52642] logged in with entity id 68908 at ([world] 92.5, 70.0, 226.5) +2020-07-25 22:04:21 [INFO] DumpsterCum12[/127.0.0.1:52645] logged in with entity id 68933 at ([world] 79.5, 66.0, 219.5) +2020-07-25 22:04:49 [INFO] FlumpterEagler42 lost connection: disconnect.quitting +2020-07-25 22:04:52 [INFO] DumpsterCum12 lost connection: disconnect.quitting +2020-07-25 22:15:51 [INFO] YeerYeet66[/127.0.0.1:52662] logged in with entity id 68956 at ([world] 75.5, 73.0, 233.5) +2020-07-25 22:15:59 [INFO] DeevDarvig26[/127.0.0.1:52671] logged in with entity id 68974 at ([world] 80.5, 66.0, 219.5) +2020-07-25 22:16:39 [INFO] YeerYeet66 lost connection: disconnect.quitting +2020-07-25 22:16:40 [INFO] DeevDarvig26 lost connection: disconnect.quitting +2020-07-25 22:17:49 [INFO] ViggDarvig20[/127.0.0.1:52675] logged in with entity id 68989 at ([world] 85.5, 67.0, 219.5) +2020-07-25 22:17:56 [INFO] EaglerYeet52[/127.0.0.1:52678] logged in with entity id 69014 at ([world] 74.5, 64.0, 215.5) +2020-07-25 22:18:16 [INFO] ViggDarvig20 lost connection: disconnect.quitting +2020-07-25 22:18:19 [INFO] EaglerYeet52 lost connection: disconnect.quitting +2020-07-25 22:21:01 [INFO] CumDeevis64[/127.0.0.1:52691] logged in with entity id 69036 at ([world] 75.5, 66.0, 224.5) +2020-07-25 22:21:11 [INFO] YeeEagler46[/127.0.0.1:52694] logged in with entity id 69063 at ([world] 77.5, 64.0, 216.5) +2020-07-25 22:21:36 [INFO] CumDeevis64 lost connection: disconnect.quitting +2020-07-25 22:21:43 [INFO] YeeEagler46 lost connection: disconnect.quitting +2020-07-25 22:24:42 [INFO] DarverVigg79[/127.0.0.1:52727] logged in with entity id 69078 at ([world] 86.5, 71.0, 224.5) +2020-07-25 22:25:11 [SEVERE] java.io.IOException: An existing connection was forcibly closed by the remote host +2020-07-25 22:25:11 [SEVERE] at sun.nio.ch.SocketDispatcher.read0(Native Method) +2020-07-25 22:25:11 [SEVERE] at sun.nio.ch.SocketDispatcher.read(Unknown Source) +2020-07-25 22:25:11 [SEVERE] at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source) +2020-07-25 22:25:11 [SEVERE] at sun.nio.ch.IOUtil.read(Unknown Source) +2020-07-25 22:25:11 [SEVERE] at sun.nio.ch.SocketChannelImpl.read(Unknown Source) +2020-07-25 22:25:11 [SEVERE] at io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:274) +2020-07-25 22:25:11 [SEVERE] at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:887) +2020-07-25 22:25:11 [SEVERE] at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:247) +2020-07-25 22:25:11 [SEVERE] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:89) +2020-07-25 22:25:11 [SEVERE] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:489) +2020-07-25 22:25:11 [SEVERE] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:464) +2020-07-25 22:25:11 [SEVERE] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:358) +2020-07-25 22:25:11 [SEVERE] at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101) +2020-07-25 22:25:11 [SEVERE] at java.lang.Thread.run(Unknown Source) +2020-07-25 22:25:11 [INFO] DarverVigg79 lost connection: disconnect.genericReason +2020-07-25 22:26:34 [INFO] EaglerDarvig80[/127.0.0.1:52782] logged in with entity id 69111 at ([world] 79.5, 67.0, 221.5) +2020-07-25 22:27:01 [INFO] EaglerDarvig80 lost connection: disconnect.quitting +2020-07-25 22:28:59 [INFO] FudglerEagler70[/127.0.0.1:52791] logged in with entity id 69175 at ([world] 88.5, 72.0, 228.5) +2020-07-25 22:29:04 [INFO] ViggYeer34[/127.0.0.1:52794] logged in with entity id 69199 at ([world] 86.5, 64.0, 218.5) +2020-07-25 22:29:15 [INFO] FudglerEagler70 lost connection: disconnect.quitting +2020-07-25 22:29:52 [INFO] FudglerEagler70[/127.0.0.1:52797] logged in with entity id 69208 at ([world] 89.33901399316095, 72.0, 231.3689488538709) +2020-07-25 22:30:00 [INFO] ViggYeer34 lost connection: disconnect.quitting +2020-07-25 22:30:02 [INFO] FudglerEagler70 lost connection: disconnect.quitting +2020-07-25 22:32:50 [INFO] ChadEagler86[/127.0.0.1:52803] logged in with entity id 69210 at ([world] 86.5, 66.0, 219.5) +2020-07-25 22:32:57 [INFO] EaglerVigg71[/127.0.0.1:52806] logged in with entity id 69235 at ([world] 85.5, 62.0, 214.5) +2020-07-25 22:33:21 [INFO] EaglerVigg71 lost connection: disconnect.quitting +2020-07-25 22:33:24 [INFO] ChadEagler86 lost connection: disconnect.quitting +2020-07-25 22:36:41 [INFO] CumDeevis54[/127.0.0.1:52816] logged in with entity id 69243 at ([world] 74.5, 65.0, 218.5) +2020-07-25 22:36:47 [INFO] ViggDeev98[/127.0.0.1:52819] logged in with entity id 69262 at ([world] 92.5, 71.0, 233.5) +2020-07-25 22:40:42 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-07-25 22:40:42 [INFO] ViggDeev98 lost connection: disconnect.genericReason +2020-07-25 22:41:00 [INFO] ViggDeev98[/127.0.0.1:52825] logged in with entity id 69416 at ([world] 71.2292246597108, 58.0, 238.32797382502585) +2020-07-25 23:26:35 [INFO] CumDeevis54 lost connection: disconnect.quitting +2020-07-25 23:26:41 [INFO] CumDeevis54[/127.0.0.1:52908] logged in with entity id 70507 at ([world] 71.45297827191558, 58.0, 237.77288995733463) +2020-07-25 23:26:48 [INFO] CumDeevis54 lost connection: disconnect.quitting +2020-07-25 23:26:53 [INFO] CumDeevis54[/127.0.0.1:52915] logged in with entity id 70510 at ([world] 72.53673958186556, 58.0, 238.846787417326) +2020-07-25 23:27:02 [INFO] CumDeevis54 lost connection: disconnect.quitting +2020-07-25 23:27:10 [INFO] CumDeevis54[/127.0.0.1:52918] logged in with entity id 70518 at ([world] 72.51335912351061, 58.0, 238.22430579990493) +2020-07-25 23:27:49 [INFO] CumDeevis54 lost connection: disconnect.quitting +2020-07-25 23:27:51 [INFO] ViggDeev98 lost connection: disconnect.quitting +2020-07-26 00:54:36 [INFO] LAX1DUDE[/127.0.0.1:53462] logged in with entity id 70521 at ([world] 92.21713723495726, 71.0, 229.02379484739632) +2020-07-26 00:55:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 01:00:11 [INFO] LAX1DUDE[/127.0.0.1:53478] logged in with entity id 70603 at ([world] 97.38316788262108, 72.0, 242.42197387444108) +2020-07-26 01:10:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 16:27:04 [INFO] LAX1DUDE[/127.0.0.1:55849] logged in with entity id 71078 at ([world] 86.70130392368884, 115.3643559654544, 231.99335909912736) +2020-07-26 16:28:07 [INFO] LAX1DUDE issued server command: /weather clear +2020-07-26 16:28:07 [INFO] LAX1DUDE: Changed weather to clear for 714 seconds. +2020-07-26 18:30:04 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 20:43:30 [INFO] LAX1DUDE[/127.0.0.1:56669] logged in with entity id 78363 at ([world] 864.9186428709857, 64.05361372427615, 359.79635942108416) +2020-07-26 20:44:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 20:44:33 [INFO] LAX1DUDE[/127.0.0.1:56675] logged in with entity id 78625 at ([world] 871.1094035230876, 63.0, 372.09765931498083) +2020-07-26 20:46:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 20:46:06 [INFO] removing player mount +2020-07-26 20:48:49 [INFO] LAX1DUDE[/127.0.0.1:56688] logged in with entity id 79098 at ([world] 863.5, 62.54999998211861, 339.8314072320912) +2020-07-26 20:54:23 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 20:54:23 [INFO] removing player mount +2020-07-26 20:57:29 [INFO] LAX1DUDE[/127.0.0.1:56714] logged in with entity id 79649 at ([world] 872.9295286768263, 62.367987493135224, 378.18536507280703) +2020-07-26 20:58:25 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 21:02:24 [INFO] LAX1DUDE[/127.0.0.1:56733] logged in with entity id 80028 at ([world] 920.057953260126, 63.0, 316.86789821131725) +2020-07-26 21:02:45 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 21:17:23 [INFO] LAX1DUDE[/127.0.0.1:56769] logged in with entity id 80231 at ([world] 920.7914928038844, 63.0, 318.3741002068958) +2020-07-26 21:17:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 21:17:55 [INFO] LAX1DUDE[/127.0.0.1:56776] logged in with entity id 80431 at ([world] 925.8381480977902, 62.0, 319.69999998807907) +2020-07-26 21:18:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 21:18:41 [INFO] LAX1DUDE[/127.0.0.1:56784] logged in with entity id 80676 at ([world] 916.6497418935533, 62.44345009723961, 334.30000001192093) +2020-07-26 21:19:03 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 21:19:08 [INFO] LAX1DUDE[/127.0.0.1:56788] logged in with entity id 80886 at ([world] 899.1166931880233, 63.0, 349.1109889672568) +2020-07-26 21:19:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 21:19:58 [INFO] removing player mount +2020-07-26 21:20:57 [INFO] LAX1DUDE[/127.0.0.1:56798] logged in with entity id 81099 at ([world] 910.2218721167468, 62.54999998211861, 346.5) +2020-07-26 21:21:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 21:21:20 [INFO] removing player mount +2020-07-26 21:23:32 [INFO] LAX1DUDE[/127.0.0.1:56810] logged in with entity id 81300 at ([world] 910.194439465356, 62.54999998211861, 346.5) +2020-07-26 21:29:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 21:30:37 [INFO] LAX1DUDE[/127.0.0.1:56832] logged in with entity id 81700 at ([world] 910.0, 63.0, 295.1473448198126) +2020-07-26 21:34:16 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 21:34:16 [INFO] removing player mount +2020-07-26 21:34:54 [INFO] LAX1DUDE[/127.0.0.1:56848] logged in with entity id 82057 at ([world] 908.5, 62.54999998211861, 293.99584696866214) +2020-07-26 21:39:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 21:42:04 [INFO] LAX1DUDE[/127.0.0.1:56869] logged in with entity id 82484 at ([world] 907.0, 64.0, 331.7100259147925) +2020-07-26 21:46:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 21:49:59 [INFO] LAX1DUDE[/127.0.0.1:56889] logged in with entity id 82947 at ([world] 905.5574752952787, 75.9893559662448, 297.7092280911031) +2020-07-26 21:53:07 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 21:53:25 [INFO] LAX1DUDE[/127.0.0.1:56904] logged in with entity id 83343 at ([world] 894.6940264105656, 63.0, 280.4652803977028) +2020-07-26 21:58:05 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 22:00:23 [INFO] LAX1DUDE[/127.0.0.1:56928] logged in with entity id 84582 at ([world] 909.6379677841422, 66.989522789652, 273.2966571678311) +2020-07-26 22:11:55 [INFO] LAX1DUDE issued server command: /kill +2020-07-26 22:11:55 [INFO] LAX1DUDE died +2020-07-26 22:20:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 22:22:32 [INFO] LAX1DUDE[/127.0.0.1:56986] logged in with entity id 89860 at ([world_the_end] 53.679732527331666, 58.0, -20.0249573279133) +2020-07-26 22:22:56 [WARNING] LAX1DUDE moved too quickly! -0.0984689688514564,0.005440410835319653,-0.2134045940075282 (3.803136015347181, 0.5705291080270691, 11.785869911421868) +2020-07-26 22:22:56 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (5.296776290106757, 0.5823174683925202, 16.759478307093886) +2020-07-26 22:22:56 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (8.581480480403235, 0.5893904846117908, 31.838920764974095) +2020-07-26 22:22:56 [WARNING] LAX1DUDE moved too quickly! -0.24544029593701566,0.0,-0.08640728271545584 (11.120459697126831, 0.8377083552619317, 6.431365564451825) +2020-07-26 22:22:56 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (10.686367543117765, 0.6226250149452982, 6.968739557482174) +2020-07-26 22:22:56 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (10.212597228752793, 0.49357501075531823, 7.257788544323292) +2020-07-26 22:22:56 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (9.730377964561514, 0.4161450082413303, 7.382494334781249) +2020-07-26 22:22:56 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (9.256797225081218, 0.3696870067329375, 7.394341378785862) +2020-07-26 22:22:56 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (9.161562624704205, 0.46181220761604114, 7.862916841778935) +2020-07-26 22:22:56 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (8.684595367422858, 0.397087326357764, 7.640076675906479) +2020-07-26 22:22:56 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (8.241511436051633, 0.35825239760279776, 7.39423765198253) +2020-07-26 22:22:56 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (7.831879815998857, 0.334951440349818, 7.133396624053489) +2020-07-26 22:22:56 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (7.454652200997964, 0.3209708659980301, 6.863347112383398) +2020-07-26 22:24:04 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (9.243603174266925, 0.5923200088262558, 5.139174426135514) +2020-07-26 22:24:04 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (23.517371392573097, 0.8353920124483107, 1.7322510952017642) +2020-07-26 22:24:04 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (20.95277495521825, 0.9812352146215437, 13.424787257772499) +2020-07-26 22:24:04 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (16.82292915274207, 1.0687411359254835, 17.844817665730407) +2020-07-26 22:24:04 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (14.340440562377088, 0.8812446851315687, 18.21572496129508) +2020-07-26 22:24:04 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (12.181148568260214, 0.7687468146552199, 18.25019169043714) +2020-07-26 22:24:04 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (10.692593935013019, 0.5812480905812712, 17.33842949222631) +2020-07-26 22:24:04 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (9.373386004364756, 0.4687488561369021, 16.43090997276149) +2020-07-26 22:24:04 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (8.203104338325751, 0.4012493154702806, 15.546144444052112) +2020-07-26 22:24:04 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (7.16419419582615, 0.36074959107030763, 14.695395600228386) +2020-07-26 22:24:05 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (6.241670979211186, 0.3364497564303239, 13.88537671466139) +2020-07-26 22:24:05 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (5.422490130532713, 0.3218698556463337, 13.119859384194916) +2020-07-26 22:24:05 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (4.695406474408751, 0.31312191517593957, 12.400706508892144) +2020-07-26 22:24:05 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (4.050673074283022, 0.3078731508937031, 11.728513496157492) +2020-07-26 22:24:05 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (3.479817578017783, 0.3047238923243612, 11.10305318170451) +2020-07-26 22:24:05 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (2.9753165088308275, 0.30283433718275604, 10.523361521296057) +2020-07-26 22:25:01 [INFO] LAX1DUDE fell out of the world +2020-07-26 22:27:59 [WARNING] LAX1DUDE moved too quickly! -551.9937487198058,37.1875,-827.9272688287613 (551.9937487198058, 37.1875, 827.9272688287613) +2020-07-26 22:28:03 [INFO] LAX1DUDE fell out of the world +2020-07-26 22:33:08 [INFO] LAX1DUDE issued server command: /gamemode 0 +2020-07-26 22:33:08 [INFO] LAX1DUDE: Set own game mode to SURVIVAL mode +2020-07-26 22:33:12 [INFO] LAX1DUDE issued server command: /gamemode 1 +2020-07-26 22:33:12 [INFO] LAX1DUDE: Set own game mode to CREATIVE mode +2020-07-26 22:33:20 [INFO] LAX1DUDE issued server command: /gamemode 0 +2020-07-26 22:33:20 [INFO] LAX1DUDE: Set own game mode to SURVIVAL mode +2020-07-26 22:34:00 [INFO] LAX1DUDE issued server command: /gamemode 1 +2020-07-26 22:34:00 [INFO] LAX1DUDE: Set own game mode to CREATIVE mode +2020-07-26 22:34:32 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 22:49:12 [INFO] LAX1DUDE[/127.0.0.1:57102] logged in with entity id 92162 at ([world] 112.59832608711476, 73.0, 272.10230301545806) +2020-07-26 22:51:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 22:51:17 [INFO] LAX1DUDE[/127.0.0.1:57102] logged in with entity id 92256 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 22:52:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 22:54:07 [INFO] LAX1DUDE[/127.0.0.1:57129] logged in with entity id 92352 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 22:54:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 22:54:43 [INFO] LAX1DUDE[/127.0.0.1:57134] logged in with entity id 92388 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 22:54:48 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 22:56:37 [INFO] LAX1DUDE[/127.0.0.1:57149] logged in with entity id 92428 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 22:56:42 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 22:59:30 [INFO] LAX1DUDE[/127.0.0.1:57164] logged in with entity id 92462 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 22:59:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:05:22 [INFO] LAX1DUDE[/127.0.0.1:57204] logged in with entity id 92496 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:05:26 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:06:46 [INFO] LAX1DUDE[/127.0.0.1:57212] logged in with entity id 92530 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:06:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:08:05 [INFO] LAX1DUDE[/127.0.0.1:57224] logged in with entity id 92573 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:08:07 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:08:47 [INFO] LAX1DUDE[/127.0.0.1:57232] logged in with entity id 92607 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:08:52 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:09:26 [INFO] LAX1DUDE[/127.0.0.1:57236] logged in with entity id 92641 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:09:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:11:46 [INFO] LAX1DUDE[/127.0.0.1:57246] logged in with entity id 92683 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:11:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:15:10 [INFO] LAX1DUDE[/127.0.0.1:57246] logged in with entity id 92740 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:15:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:15:26 [INFO] LAX1DUDE[/127.0.0.1:57278] logged in with entity id 92774 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:15:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:18:35 [INFO] LAX1DUDE[/127.0.0.1:57290] logged in with entity id 92814 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:18:40 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:19:30 [INFO] LAX1DUDE[/127.0.0.1:57296] logged in with entity id 92848 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:19:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:20:29 [INFO] LAX1DUDE[/127.0.0.1:57303] logged in with entity id 92882 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:20:33 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:22:01 [INFO] LAX1DUDE[/127.0.0.1:57312] logged in with entity id 92922 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:22:05 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:32:34 [INFO] LAX1DUDE[/127.0.0.1:57333] logged in with entity id 92956 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:32:39 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:34:13 [INFO] LAX1DUDE[/127.0.0.1:57333] logged in with entity id 92990 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:34:13 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:34:25 [INFO] LAX1DUDE[/127.0.0.1:57343] logged in with entity id 93024 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:34:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:36:26 [INFO] LAX1DUDE[/127.0.0.1:57350] logged in with entity id 93058 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:36:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:37:50 [INFO] LAX1DUDE[/127.0.0.1:57361] logged in with entity id 93092 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:37:54 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:38:52 [INFO] LAX1DUDE[/127.0.0.1:57366] logged in with entity id 93147 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:38:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:39:17 [INFO] LAX1DUDE[/127.0.0.1:57366] logged in with entity id 93189 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:39:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-26 23:50:36 [INFO] LAX1DUDE[/127.0.0.1:57389] logged in with entity id 93223 at ([world] 108.09590738680592, 74.0, 275.12462697162476) +2020-07-26 23:52:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-27 03:58:29 [INFO] LAX1DUDE[/127.0.0.1:59475] logged in with entity id 93454 at ([world] 82.52262267682053, 73.0, 231.44358922378814) +2020-07-27 03:58:45 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-27 04:05:30 [INFO] LAX1DUDE[/127.0.0.1:59492] logged in with entity id 93497 at ([world] 85.24076132294707, 71.0, 245.30118254135115) +2020-07-27 04:20:13 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-27 21:32:39 [INFO] LAX1DUDE[/127.0.0.1:61211] logged in with entity id 94605 at ([world] 228.7559266386171, 75.0, 239.60650858599462) +2020-07-27 21:32:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-27 22:57:48 [INFO] LAX1DUDE[/127.0.0.1:61501] logged in with entity id 94676 at ([world] 228.2372285240641, 75.0, 235.20909731143746) +2020-07-27 22:58:17 [INFO] LAX1DUDE issued server command: /weather rain +2020-07-27 22:58:17 [INFO] LAX1DUDE: Changed weather to rainy for 829 seconds. +2020-07-27 22:58:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-27 22:59:35 [INFO] LAX1DUDE[/127.0.0.1:61512] logged in with entity id 94797 at ([world] 208.73625913271474, 83.1143565706876, 256.22224671086553) +2020-07-27 22:59:39 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-27 23:01:27 [INFO] LAX1DUDE[/127.0.0.1:61517] logged in with entity id 94887 at ([world] 208.73625913271474, 83.1143565706876, 256.22224671086553) +2020-07-27 23:01:32 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-27 23:03:04 [INFO] LAX1DUDE[/127.0.0.1:61525] logged in with entity id 94948 at ([world] 208.73625913271474, 83.1143565706876, 256.22224671086553) +2020-07-27 23:06:11 [INFO] LAX1DUDE issued server command: /weather clear +2020-07-27 23:06:11 [INFO] LAX1DUDE: Changed weather to clear for 370 seconds. +2020-07-27 23:06:18 [INFO] LAX1DUDE issued server command: /weather clear +2020-07-27 23:06:18 [INFO] LAX1DUDE: Changed weather to clear for 327 seconds. +2020-07-27 23:06:19 [INFO] LAX1DUDE issued server command: /weather clear +2020-07-27 23:06:19 [INFO] LAX1DUDE: Changed weather to clear for 616 seconds. +2020-07-27 23:06:20 [INFO] LAX1DUDE issued server command: /weather clear +2020-07-27 23:06:20 [INFO] LAX1DUDE: Changed weather to clear for 894 seconds. +2020-07-27 23:10:16 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-27 23:10:40 [INFO] LAX1DUDE[/127.0.0.1:61544] logged in with entity id 96037 at ([world] 88.01352204202152, 72.0, 231.10912696388402) +2020-07-27 23:11:54 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-27 23:21:02 [INFO] LAX1DUDE[/127.0.0.1:61608] logged in with entity id 96106 at ([world] 88.38961689463319, 71.0, 235.63860117585247) +2020-07-27 23:21:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-27 23:22:12 [INFO] LAX1DUDE[/127.0.0.1:61615] logged in with entity id 96239 at ([world] 116.71589264783631, 71.0, 247.56929047783092) +2020-07-27 23:22:32 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-27 23:22:34 [INFO] LAX1DUDE[/127.0.0.1:61619] logged in with entity id 96284 at ([world] 126.47697506536505, 70.0, 245.8690613941062) +2020-07-27 23:30:18 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-27 23:53:30 [INFO] LAX1DUDE[/127.0.0.1:61710] logged in with entity id 97756 at ([world] 137.61513334077767, 72.60544901839599, 233.86950758870412) +2020-07-28 00:05:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-28 00:06:02 [INFO] LAX1DUDE[/127.0.0.1:61759] logged in with entity id 98836 at ([world] 102.39827881716386, 72.0, 251.2946562064543) +2020-07-28 00:12:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-28 00:12:53 [INFO] LAX1DUDE[/127.0.0.1:61781] logged in with entity id 99077 at ([world] 114.35921066981764, 87.27882139915464, 297.0257863756674) +2020-07-28 00:13:04 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-28 00:36:53 [INFO] LAX1DUDE[/127.0.0.1:61854] logged in with entity id 99118 at ([world] 113.37406474519605, 76.0, 298.45394184706737) +2020-07-28 00:37:08 [INFO] LAX1DUDE issued server command: /weather clear +2020-07-28 00:37:08 [INFO] LAX1DUDE: Changed weather to clear for 322 seconds. +2020-07-28 00:46:20 [WARNING] LAX1DUDE moved too quickly! 0.1273602393072366,0.0,0.23910992116234553 (7.451832998965034, 0.5222400077819824, 10.371764287585146) +2020-07-28 00:46:20 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (6.781168224490279, 0.31334400466918944, 9.438305773712827) +2020-07-28 00:46:20 [WARNING] LAX1DUDE moved too quickly! 0.0,0.0,0.0 (6.170863262129368, 0.18800640280151365, 8.588858501608092) +2020-07-28 00:47:03 [INFO] LAX1DUDE fell out of the world +2020-07-28 00:47:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-07-28 02:31:40 [INFO] LAX1DUDE[/127.0.0.1:62308] logged in with entity id 101611 at ([world] 79.37753267778888, 73.0, 237.88596258793285) +2020-07-28 02:32:27 [INFO] LAX1DUDE issued server command: /gamemode 0 +2020-07-28 02:32:27 [INFO] LAX1DUDE: Set own game mode to SURVIVAL mode +2020-07-28 02:32:43 [INFO] LAX1DUDE was slain by Enderman +2020-07-28 02:33:33 [INFO] LAX1DUDE was slain by Enderman +2020-07-28 02:35:57 [INFO] LAX1DUDE was pricked to death +2020-07-28 02:36:24 [INFO] LAX1DUDE issued server command: /gamemode 1 +2020-07-28 02:36:24 [INFO] LAX1DUDE: Set own game mode to CREATIVE mode +2020-07-28 02:37:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 03:29:32 [INFO] LAX1DUDE[/127.0.0.1:58969] logged in with entity id 106567 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 03:29:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 03:33:19 [INFO] LAX1DUDE[/127.0.0.1:58979] logged in with entity id 106600 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 03:33:21 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 03:33:41 [INFO] LAX1DUDE[/127.0.0.1:58984] logged in with entity id 106635 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 03:34:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 03:35:57 [INFO] LAX1DUDE[/127.0.0.1:58997] logged in with entity id 106681 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 03:36:27 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 04:02:28 [INFO] LAX1DUDE[/127.0.0.1:59060] logged in with entity id 106731 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 04:02:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 04:03:27 [INFO] LAX1DUDE[/127.0.0.1:59070] logged in with entity id 106766 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 04:03:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 04:06:41 [INFO] LAX1DUDE[/127.0.0.1:59078] logged in with entity id 106817 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 04:06:42 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 04:18:09 [INFO] LAX1DUDE[/127.0.0.1:59098] logged in with entity id 106853 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 04:18:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 04:24:23 [INFO] LAX1DUDE[/127.0.0.1:59112] logged in with entity id 106889 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 04:24:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 04:25:31 [INFO] LAX1DUDE[/127.0.0.1:59118] logged in with entity id 106925 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 04:25:33 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 04:28:52 [INFO] LAX1DUDE[/127.0.0.1:59130] logged in with entity id 106961 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 04:28:54 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 04:29:28 [INFO] LAX1DUDE[/127.0.0.1:59133] logged in with entity id 107003 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 04:29:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 04:30:13 [INFO] LAX1DUDE[/127.0.0.1:59139] logged in with entity id 107060 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 04:30:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 04:31:14 [INFO] LAX1DUDE[/127.0.0.1:59143] logged in with entity id 107118 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 04:31:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 04:31:58 [INFO] LAX1DUDE[/127.0.0.1:59147] logged in with entity id 107165 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 04:32:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 04:37:43 [INFO] LAX1DUDE[/127.0.0.1:59159] logged in with entity id 107201 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 04:37:45 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 04:38:53 [INFO] LAX1DUDE[/127.0.0.1:59166] logged in with entity id 107237 at ([world] 96.455871900237, 75.0, 274.1162805148667) +2020-08-03 04:39:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 04:53:23 [INFO] LAX1DUDE[/127.0.0.1:59218] logged in with entity id 107286 at ([world] 122.92802012061402, 108.46894998383256, 253.93593891210054) +2020-08-03 04:53:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 04:59:47 [INFO] LAX1DUDE[/127.0.0.1:59232] logged in with entity id 108017 at ([world] 179.17377091246092, 161.70005430592124, 256.2328134007972) +2020-08-03 05:00:08 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 05:00:53 [INFO] LAX1DUDE[/127.0.0.1:59240] logged in with entity id 108228 at ([world] 179.17377091246092, 161.70005430592124, 256.2328134007972) +2020-08-03 05:01:08 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 13:09:17 [INFO] LAX1DUDE[/127.0.0.1:59851] logged in with entity id 108266 at ([world] 179.17377091246092, 161.70005430592124, 256.2328134007972) +2020-08-03 13:09:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 13:12:07 [INFO] LAX1DUDE[/127.0.0.1:59860] logged in with entity id 108292 at ([world] 179.17377091246092, 161.70005430592124, 256.2328134007972) +2020-08-03 13:13:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 19:04:56 [INFO] Starting minecraft server version 1.5.2 +2020-08-03 19:04:56 [WARNING] To start the server with more ram, launch it as "java -Xmx1024M -Xms1024M -jar minecraft_server.jar" +2020-08-03 19:04:56 [INFO] Loading properties +2020-08-03 19:04:56 [INFO] Default game type: CREATIVE +2020-08-03 19:04:56 [INFO] This server is running CraftBukkit version git-Spigot-959 (MC: 1.5.2) (Implementing API version 1.5.2-R1.1-SNAPSHOT) +2020-08-03 19:04:56 [INFO] Generating keypair +2020-08-03 19:04:57 [INFO] Starting listener #0 on *:25501 +2020-08-03 19:04:57 [WARNING] **** SERVER IS RUNNING IN OFFLINE/INSECURE MODE! +2020-08-03 19:04:57 [WARNING] The server will make no attempt to authenticate usernames. Beware. +2020-08-03 19:04:57 [WARNING] 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. +2020-08-03 19:04:57 [WARNING] To change this, set "online-mode" to "true" in the server.properties file. +2020-08-03 19:04:57 [INFO] Preparing level "world" +2020-08-03 19:04:57 [INFO] -------- World Settings For [world] -------- +2020-08-03 19:04:57 [INFO] View Distance: 10 +2020-08-03 19:04:57 [INFO] Chunks to Grow per Tick: 650 +2020-08-03 19:04:57 [INFO] Experience Merge Radius: 3.0 +2020-08-03 19:04:57 [INFO] Item Merge Radius: 2.5 +2020-08-03 19:04:57 [INFO] Anti X-Ray: true +2020-08-03 19:04:57 [INFO] Engine Mode: 1 +2020-08-03 19:04:57 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-08-03 19:04:57 [INFO] Cactus Growth Modifier: 100% +2020-08-03 19:04:57 [INFO] Cane Growth Modifier: 100% +2020-08-03 19:04:57 [INFO] Melon Growth Modifier: 100% +2020-08-03 19:04:57 [INFO] Mushroom Growth Modifier: 100% +2020-08-03 19:04:57 [INFO] Pumpkin Growth Modifier: 100% +2020-08-03 19:04:57 [INFO] Sapling Growth Modifier: 100% +2020-08-03 19:04:57 [INFO] Wheat Growth Modifier: 100% +2020-08-03 19:04:57 [INFO] Mob Spawn Range: 4 +2020-08-03 19:04:57 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-08-03 19:04:57 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-08-03 19:04:57 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-08-03 19:04:57 [INFO] Random Lighting Updates: false +2020-08-03 19:04:58 [INFO] -------- World Settings For [world_nether] -------- +2020-08-03 19:04:58 [INFO] View Distance: 10 +2020-08-03 19:04:58 [INFO] Chunks to Grow per Tick: 650 +2020-08-03 19:04:58 [INFO] Experience Merge Radius: 3.0 +2020-08-03 19:04:58 [INFO] Item Merge Radius: 2.5 +2020-08-03 19:04:58 [INFO] Anti X-Ray: true +2020-08-03 19:04:58 [INFO] Engine Mode: 1 +2020-08-03 19:04:58 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-08-03 19:04:58 [INFO] Cactus Growth Modifier: 100% +2020-08-03 19:04:58 [INFO] Cane Growth Modifier: 100% +2020-08-03 19:04:58 [INFO] Melon Growth Modifier: 100% +2020-08-03 19:04:58 [INFO] Mushroom Growth Modifier: 100% +2020-08-03 19:04:58 [INFO] Pumpkin Growth Modifier: 100% +2020-08-03 19:04:58 [INFO] Sapling Growth Modifier: 100% +2020-08-03 19:04:58 [INFO] Wheat Growth Modifier: 100% +2020-08-03 19:04:58 [INFO] Mob Spawn Range: 4 +2020-08-03 19:04:58 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-08-03 19:04:58 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-08-03 19:04:58 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-08-03 19:04:58 [INFO] Random Lighting Updates: false +2020-08-03 19:04:58 [INFO] -------- World Settings For [world_the_end] -------- +2020-08-03 19:04:58 [INFO] View Distance: 10 +2020-08-03 19:04:58 [INFO] Chunks to Grow per Tick: 650 +2020-08-03 19:04:58 [INFO] Experience Merge Radius: 3.0 +2020-08-03 19:04:58 [INFO] Item Merge Radius: 2.5 +2020-08-03 19:04:58 [INFO] Anti X-Ray: true +2020-08-03 19:04:58 [INFO] Engine Mode: 1 +2020-08-03 19:04:58 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-08-03 19:04:58 [INFO] Cactus Growth Modifier: 100% +2020-08-03 19:04:58 [INFO] Cane Growth Modifier: 100% +2020-08-03 19:04:58 [INFO] Melon Growth Modifier: 100% +2020-08-03 19:04:58 [INFO] Mushroom Growth Modifier: 100% +2020-08-03 19:04:58 [INFO] Pumpkin Growth Modifier: 100% +2020-08-03 19:04:58 [INFO] Sapling Growth Modifier: 100% +2020-08-03 19:04:58 [INFO] Wheat Growth Modifier: 100% +2020-08-03 19:04:58 [INFO] Mob Spawn Range: 4 +2020-08-03 19:04:58 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-08-03 19:04:58 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-08-03 19:04:58 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-08-03 19:04:58 [INFO] Random Lighting Updates: false +2020-08-03 19:04:58 [INFO] Preparing start region for level 0 (Seed: 3826684831161612166) +2020-08-03 19:04:59 [INFO] Preparing spawn area: 45% +2020-08-03 19:05:00 [INFO] Preparing spawn area: 91% +2020-08-03 19:05:00 [INFO] Preparing start region for level 1 (Seed: 3826684831161612166) +2020-08-03 19:05:00 [INFO] Preparing start region for level 2 (Seed: 3826684831161612166) +2020-08-03 19:05:01 [INFO] Preparing spawn area: 91% +2020-08-03 19:05:01 [INFO] Server permissions file permissions.yml is empty, ignoring it +2020-08-03 19:05:01 [INFO] Done (3.583s)! For help, type "help" or "?" +2020-08-03 19:05:14 [INFO] LAX1DUDE[/127.0.0.1:52246] logged in with entity id 2769 at ([world] 186.39328557558383, 139.03803007671158, 241.26309663216813) +2020-08-03 19:05:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 20:56:43 [INFO] LAX1DUDE[/127.0.0.1:52465] logged in with entity id 2992 at ([world] 186.39328557558383, 139.03803007671158, 241.26309663216813) +2020-08-03 20:58:21 [INFO] ea +2020-08-03 21:00:23 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-03 23:57:47 [INFO] LAX1DUDE[/127.0.0.1:54451] logged in with entity id 3171 at ([world] 191.68626246596202, 62.0, 221.34022565007731) +2020-08-04 00:01:33 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:01:54 [INFO] LAX1DUDE[/127.0.0.1:54495] logged in with entity id 3300 at ([world] 191.36336957962067, 62.0, 221.67079755333592) +2020-08-04 00:02:21 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:04:08 [INFO] LAX1DUDE[/127.0.0.1:54515] logged in with entity id 3375 at ([world] 191.36336957962067, 62.0, 221.67079755333592) +2020-08-04 00:05:55 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:07:10 [INFO] LAX1DUDE[/127.0.0.1:54545] logged in with entity id 3520 at ([world] 192.69999998807907, 61.85309151814972, 221.62460496885356) +2020-08-04 00:07:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:11:12 [INFO] LAX1DUDE[/127.0.0.1:54579] logged in with entity id 3596 at ([world] 192.69999998807907, 61.85309151814972, 221.62460496885356) +2020-08-04 00:12:07 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:14:32 [INFO] LAX1DUDE[/127.0.0.1:54607] logged in with entity id 3707 at ([world] 200.40755019652528, 64.61701087255177, 224.18866787119913) +2020-08-04 00:15:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:16:35 [INFO] LAX1DUDE[/127.0.0.1:54632] logged in with entity id 3793 at ([world] 191.5018979156764, 82.31555220784617, 230.10810196690315) +2020-08-04 00:16:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:20:54 [INFO] LAX1DUDE[/127.0.0.1:54671] logged in with entity id 3862 at ([world] 191.5018979156764, 82.31555220784617, 230.10810196690315) +2020-08-04 00:22:09 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:23:31 [INFO] LAX1DUDE[/127.0.0.1:54699] logged in with entity id 3954 at ([world] 191.3826698306408, 62.0, 225.4733664679303) +2020-08-04 00:23:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:26:15 [INFO] LAX1DUDE[/127.0.0.1:54718] logged in with entity id 4016 at ([world] 191.3826698306408, 62.0, 225.4733664679303) +2020-08-04 00:28:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:28:46 [INFO] LAX1DUDE[/127.0.0.1:54728] logged in with entity id 4455 at ([world] 247.00147052127312, 74.0, 257.7258649926365) +2020-08-04 00:29:45 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:33:18 [INFO] LAX1DUDE[/127.0.0.1:54739] logged in with entity id 4580 at ([world] 239.87052247905925, 76.0, 256.326521382214) +2020-08-04 00:37:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:37:25 [INFO] LAX1DUDE[/127.0.0.1:54752] logged in with entity id 6329 at ([world] 652.6549250638398, 12.0, 827.4101047920994) +2020-08-04 00:41:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:43:58 [INFO] LAX1DUDE[/127.0.0.1:54766] logged in with entity id 6615 at ([world] 704.5634132661813, 21.20000004768371, 849.8505291676537) +2020-08-04 00:46:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:52:02 [INFO] LAX1DUDE[/127.0.0.1:54794] logged in with entity id 6858 at ([world] 710.6159160074644, 20.0, 852.8374240455412) +2020-08-04 00:52:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:56:06 [INFO] LAX1DUDE[/127.0.0.1:54806] logged in with entity id 7011 at ([world] 709.6802606350752, 21.128052079566885, 852.7706711206217) +2020-08-04 00:57:47 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:57:59 [INFO] LAX1DUDE[/127.0.0.1:54812] logged in with entity id 7207 at ([world] 704.8141925113856, 21.0, 842.507680913292) +2020-08-04 00:59:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 00:59:32 [INFO] LAX1DUDE[/127.0.0.1:54819] logged in with entity id 7401 at ([world] 708.4533345390397, 24.31205220768277, 848.6498523772173) +2020-08-04 00:59:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 01:01:13 [INFO] LAX1DUDE[/127.0.0.1:54826] logged in with entity id 7554 at ([world] 708.3000000119209, 24.0, 847.3000000119209) +2020-08-04 01:02:13 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 01:04:41 [INFO] LAX1DUDE[/127.0.0.1:54837] logged in with entity id 7711 at ([world] 704.9199399120191, 22.200000047683695, 855.3075318009662) +2020-08-04 01:05:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 01:09:42 [INFO] LAX1DUDE[/127.0.0.1:54852] logged in with entity id 7872 at ([world] 701.404773420208, 20.0, 849.855706101803) +2020-08-04 01:10:07 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 01:19:33 [INFO] LAX1DUDE[/127.0.0.1:54876] logged in with entity id 8024 at ([world] 705.3000000119209, 22.73935697417652, 855.3000000119209) +2020-08-04 01:23:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 01:24:02 [INFO] LAX1DUDE[/127.0.0.1:54887] logged in with entity id 8227 at ([world] 699.3000000119209, 21.0, 838.5916718095475) +2020-08-04 01:24:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 02:55:18 [INFO] LAX1DUDE[/127.0.0.1:55033] logged in with entity id 8388 at ([world] 700.4338337569308, 21.490643189201403, 846.4934144346852) +2020-08-04 02:55:25 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 23:20:40 [INFO] LAX1DUDE[/127.0.0.1:59336] logged in with entity id 8584 at ([world] 702.9180864648125, 21.490643189201403, 845.814290841469) +2020-08-04 23:24:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-04 23:24:50 [INFO] LAX1DUDE[/127.0.0.1:59352] logged in with entity id 8796 at ([world] 709.5342430767013, 19.0, 851.829883606794) +2020-08-05 00:05:26 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 00:12:45 [INFO] LAX1DUDE[/127.0.0.1:59528] logged in with entity id 10233 at ([world] 725.9466170463637, 63.0, 792.9210965662135) +2020-08-05 00:13:41 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 00:14:37 [INFO] LAX1DUDE[/127.0.0.1:59605] logged in with entity id 10368 at ([world] 737.2536845765031, 63.0, 804.2280366354895) +2020-08-05 00:16:01 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 00:16:31 [INFO] LAX1DUDE[/127.0.0.1:59621] logged in with entity id 10552 at ([world] 736.6656018052106, 57.0, 809.4440351675512) +2020-08-05 00:16:47 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 00:20:32 [INFO] LAX1DUDE[/127.0.0.1:59632] logged in with entity id 10688 at ([world] 737.6999999880791, 58.200000047683716, 805.7616057257544) +2020-08-05 00:27:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 00:27:26 [INFO] LAX1DUDE[/127.0.0.1:59656] logged in with entity id 10967 at ([world] 736.3000000119209, 57.0, 809.3616188830209) +2020-08-05 00:31:55 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 00:32:20 [INFO] LAX1DUDE[/127.0.0.1:59717] logged in with entity id 11219 at ([world] 737.5092998777002, 58.0, 808.1283578076321) +2020-08-05 00:33:13 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 00:33:32 [INFO] LAX1DUDE[/127.0.0.1:59733] logged in with entity id 11399 at ([world] 724.3504265933908, 63.0, 826.3081543220627) +2020-08-05 00:33:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 00:34:37 [INFO] LAX1DUDE[/127.0.0.1:59737] logged in with entity id 11529 at ([world] 724.3169490737879, 63.0, 826.9652488690002) +2020-08-05 00:34:46 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 00:35:37 [INFO] LAX1DUDE[/127.0.0.1:59744] logged in with entity id 11656 at ([world] 722.2562611395211, 63.0, 826.5219452509173) +2020-08-05 00:36:07 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 00:36:34 [INFO] LAX1DUDE[/127.0.0.1:59751] logged in with entity id 11820 at ([world] 681.1628788165863, 63.0, 802.280463065457) +2020-08-05 00:37:39 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 00:37:56 [INFO] LAX1DUDE[/127.0.0.1:59760] logged in with entity id 11946 at ([world] 685.366794529573, 54.0, 780.3000000119209) +2020-08-05 00:38:13 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 00:40:22 [INFO] LAX1DUDE[/127.0.0.1:59766] logged in with entity id 12048 at ([world] 677.3000000119209, 54.0, 780.3000000119209) +2020-08-05 00:40:54 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 00:41:22 [INFO] LAX1DUDE[/127.0.0.1:59771] logged in with entity id 12157 at ([world] 684.9185755917691, 78.22255980555681, 802.7461664606328) +2020-08-05 00:45:12 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 00:45:35 [INFO] LAX1DUDE[/127.0.0.1:59780] logged in with entity id 12417 at ([world] 699.9878657794612, 67.47035634064076, 805.2380310592706) +2020-08-05 00:49:07 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 00:56:10 [INFO] LAX1DUDE[/127.0.0.1:59857] logged in with entity id 12719 at ([world] 669.0758077696739, 58.64276807769688, 844.8703749243533) +2020-08-05 01:01:14 [INFO] LAX1DUDE issued server command: /time set day +2020-08-05 01:01:14 [INFO] LAX1DUDE: Set time to 0 +2020-08-05 01:03:16 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:05:47 [INFO] LAX1DUDE[/127.0.0.1:59881] logged in with entity id 13026 at ([world] 691.8229340034371, 73.78017659315606, 781.4083658246212) +2020-08-05 01:05:55 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:06:14 [INFO] LAX1DUDE[/127.0.0.1:59886] logged in with entity id 13135 at ([world] 691.8229340034371, 73.78017659315606, 781.4083658246212) +2020-08-05 01:25:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:25:53 [INFO] LAX1DUDE[/127.0.0.1:60017] logged in with entity id 13811 at ([world] 679.8896303204108, 56.393476633721534, 859.6072690638168) +2020-08-05 01:26:43 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:26:59 [INFO] LAX1DUDE[/127.0.0.1:60046] logged in with entity id 13962 at ([world] 679.6566192327208, 50.02772732335903, 864.048707232748) +2020-08-05 01:27:46 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:28:07 [INFO] LAX1DUDE[/127.0.0.1:60055] logged in with entity id 14106 at ([world] 672.2851313943713, 59.0, 799.3000000119209) +2020-08-05 01:28:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:28:45 [INFO] LAX1DUDE[/127.0.0.1:60059] logged in with entity id 14217 at ([world] 668.9516672738018, 55.595425159413445, 817.5319643124959) +2020-08-05 01:29:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:31:13 [INFO] LAX1DUDE[/127.0.0.1:60072] logged in with entity id 14317 at ([world] 667.4263788239431, 64.09812592342372, 801.9955814347276) +2020-08-05 01:34:04 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:35:35 [INFO] LAX1DUDE[/127.0.0.1:60087] logged in with entity id 14598 at ([world] 657.0759765595942, 64.0, 787.5868891344775) +2020-08-05 01:36:08 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:37:01 [INFO] LAX1DUDE[/127.0.0.1:60097] logged in with entity id 14695 at ([world] 671.8838768406217, 71.23713360782175, 770.9529470596082) +2020-08-05 01:39:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:41:27 [INFO] LAX1DUDE[/127.0.0.1:60106] logged in with entity id 15024 at ([world] 692.9935965190081, 72.0, 766.0022486753983) +2020-08-05 01:42:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:43:11 [INFO] LAX1DUDE[/127.0.0.1:60112] logged in with entity id 15239 at ([world] 653.2135253925442, 12.0, 828.5404194455679) +2020-08-05 01:46:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:47:41 [INFO] LAX1DUDE[/127.0.0.1:60165] logged in with entity id 15397 at ([world] 652.236025436887, 12.0, 828.077145530894) +2020-08-05 01:48:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:51:33 [INFO] LAX1DUDE[/127.0.0.1:60555] logged in with entity id 15499 at ([world] 652.9721192395609, 12.0, 827.5747619685991) +2020-08-05 01:52:37 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:55:40 [INFO] LAX1DUDE[/127.0.0.1:60578] logged in with entity id 15601 at ([world] 653.2325242708586, 12.0, 828.4557381616704) +2020-08-05 01:55:45 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:56:45 [INFO] LAX1DUDE[/127.0.0.1:60586] logged in with entity id 15696 at ([world] 652.8199164914852, 12.0, 828.4239677051153) +2020-08-05 01:56:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:57:52 [INFO] LAX1DUDE[/127.0.0.1:60591] logged in with entity id 15791 at ([world] 652.8199164914852, 12.0, 828.4239677051153) +2020-08-05 01:58:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 01:59:09 [INFO] LAX1DUDE[/127.0.0.1:60601] logged in with entity id 15886 at ([world] 652.8199164914852, 12.0, 828.4239677051153) +2020-08-05 02:01:07 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:01:54 [INFO] LAX1DUDE[/127.0.0.1:60610] logged in with entity id 15996 at ([world] 652.316897311664, 12.0, 828.4489834292925) +2020-08-05 02:02:01 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:03:36 [INFO] LAX1DUDE[/127.0.0.1:60660] logged in with entity id 16091 at ([world] 652.316897311664, 12.0, 828.4489834292925) +2020-08-05 02:03:52 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:04:37 [INFO] LAX1DUDE[/127.0.0.1:60668] logged in with entity id 16190 at ([world] 652.316897311664, 12.0, 828.4489834292925) +2020-08-05 02:05:05 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:06:20 [INFO] LAX1DUDE[/127.0.0.1:60675] logged in with entity id 16288 at ([world] 652.9402193743213, 12.0, 828.1831506094653) +2020-08-05 02:06:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:07:45 [INFO] LAX1DUDE[/127.0.0.1:60683] logged in with entity id 16389 at ([world] 653.0460311768311, 13.200000047683716, 828.1161475624704) +2020-08-05 02:08:12 [WARNING] LAX1DUDE moved too quickly! -551.9737773019947,37.1875,-828.3139096216966 (551.9737773019947, 37.1875, 828.3139096216966) +2020-08-05 02:08:17 [INFO] LAX1DUDE fell out of the world +2020-08-05 02:08:35 [INFO] LAX1DUDE issued server command: /kill +2020-08-05 02:08:35 [INFO] LAX1DUDE died +2020-08-05 02:08:49 [INFO] LAX1DUDE issued server command: /tp 600 100 700 +2020-08-05 02:08:49 [INFO] LAX1DUDE: Teleported LAX1DUDE to 600.50, 100.50, 700.50 +2020-08-05 02:10:12 [INFO] LAX1DUDE fell out of the world +2020-08-05 02:10:20 [INFO] LAX1DUDE issued server command: /tp 630 100 740 +2020-08-05 02:10:20 [INFO] LAX1DUDE: Teleported LAX1DUDE to 630.50, 100.50, 740.50 +2020-08-05 02:10:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:11:09 [INFO] LAX1DUDE[/127.0.0.1:60696] logged in with entity id 17801 at ([world] 653.4686136272594, 12.0, 827.3000000119209) +2020-08-05 02:11:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:13:17 [INFO] LAX1DUDE[/127.0.0.1:60705] logged in with entity id 17897 at ([world] 652.8606169897902, 12.0, 828.3585515257867) +2020-08-05 02:14:03 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:15:47 [INFO] LAX1DUDE[/127.0.0.1:60724] logged in with entity id 17999 at ([world] 650.8582054619992, 13.200000047683716, 828.9442500920125) +2020-08-05 02:15:52 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:21:22 [INFO] LAX1DUDE[/127.0.0.1:60791] logged in with entity id 18093 at ([world] 654.4359730531385, 13.200000047683716, 831.6999999880791) +2020-08-05 02:21:39 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:22:00 [INFO] LAX1DUDE[/127.0.0.1:60802] logged in with entity id 18196 at ([world] 653.0902604958887, 12.0, 828.2638632145089) +2020-08-05 02:22:04 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:24:04 [INFO] LAX1DUDE[/127.0.0.1:60809] logged in with entity id 18290 at ([world] 653.0902604958887, 12.0, 828.2638632145089) +2020-08-05 02:26:37 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:26:48 [INFO] LAX1DUDE[/127.0.0.1:60824] logged in with entity id 18434 at ([world] 653.4226283275048, 12.0, 828.3467713611142) +2020-08-05 02:44:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:45:09 [INFO] LAX1DUDE[/127.0.0.1:60894] logged in with entity id 19179 at ([world] 724.7172482773074, 63.0, 782.0503628628704) +2020-08-05 02:48:18 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:49:09 [INFO] LAX1DUDE[/127.0.0.1:60906] logged in with entity id 19704 at ([world] 703.0380322831804, 65.0, 771.1111617903164) +2020-08-05 02:49:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:50:46 [INFO] LAX1DUDE[/127.0.0.1:60923] logged in with entity id 19829 at ([world] 730.3943483138808, 63.0, 787.1253041778797) +2020-08-05 02:51:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:51:37 [INFO] LAX1DUDE[/127.0.0.1:60931] logged in with entity id 19962 at ([world] 691.1239560204988, 59.18341114456932, 814.1508137362255) +2020-08-05 02:51:52 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:52:10 [INFO] LAX1DUDE[/127.0.0.1:60935] logged in with entity id 20086 at ([world] 696.6999999880791, 59.0, 808.3001816048884) +2020-08-05 02:52:21 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 02:52:53 [INFO] LAX1DUDE[/127.0.0.1:60941] logged in with entity id 20208 at ([world] 698.9425628966773, 57.47308064887994, 819.0857467653565) +2020-08-05 02:53:17 [INFO] LAX1DUDE issued server command: /time set day +2020-08-05 02:53:17 [INFO] LAX1DUDE: Set time to 0 +2020-08-05 03:03:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 03:04:31 [INFO] LAX1DUDE[/127.0.0.1:61007] logged in with entity id 21278 at ([world] 720.337888557722, 113.98080091620523, 857.5927031895034) +2020-08-05 03:06:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 19:27:51 [INFO] LAX1DUDE[/127.0.0.1:57456] logged in with entity id 22551 at ([world] -37.81605274892462, 76.11435597561993, 564.0358870611396) +2020-08-05 19:27:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 19:29:06 [INFO] LAX1DUDE[/127.0.0.1:57459] logged in with entity id 22644 at ([world] -37.81605274892462, 76.11435597561993, 564.0358870611396) +2020-08-05 19:29:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 19:33:21 [INFO] LAX1DUDE[/127.0.0.1:57478] logged in with entity id 22737 at ([world] -37.81605274892462, 76.11435597561993, 564.0358870611396) +2020-08-05 19:33:25 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 19:33:50 [INFO] LAX1DUDE[/127.0.0.1:57486] logged in with entity id 22830 at ([world] -37.81605274892462, 76.11435597561993, 564.0358870611396) +2020-08-05 19:33:54 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 19:34:28 [INFO] LAX1DUDE[/127.0.0.1:57490] logged in with entity id 22923 at ([world] -37.81605274892462, 76.11435597561993, 564.0358870611396) +2020-08-05 19:34:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 19:34:40 [INFO] LAX1DUDE[/127.0.0.1:57493] logged in with entity id 23016 at ([world] -37.81605274892462, 76.11435597561993, 564.0358870611396) +2020-08-05 19:34:43 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 19:35:38 [INFO] LAX1DUDE[/127.0.0.1:57501] logged in with entity id 23109 at ([world] -37.81605274892462, 76.11435597561993, 564.0358870611396) +2020-08-05 19:35:45 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 19:38:42 [INFO] LAX1DUDE[/127.0.0.1:57509] logged in with entity id 23202 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 19:38:48 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 19:40:23 [INFO] LAX1DUDE[/127.0.0.1:57519] logged in with entity id 23295 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 19:40:35 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 19:42:37 [INFO] LAX1DUDE[/127.0.0.1:57526] logged in with entity id 23388 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 19:42:46 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 19:45:26 [INFO] LAX1DUDE[/127.0.0.1:57537] logged in with entity id 23484 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 19:45:37 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 19:47:57 [INFO] LAX1DUDE[/127.0.0.1:57546] logged in with entity id 23578 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 19:48:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 19:52:32 [INFO] LAX1DUDE[/127.0.0.1:57553] logged in with entity id 23671 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 19:52:39 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 19:54:46 [INFO] LAX1DUDE[/127.0.0.1:57559] logged in with entity id 23764 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 19:54:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 19:57:57 [INFO] LAX1DUDE[/127.0.0.1:57569] logged in with entity id 23857 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 19:58:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:01:03 [INFO] LAX1DUDE[/127.0.0.1:57577] logged in with entity id 23954 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 20:01:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:02:20 [INFO] LAX1DUDE[/127.0.0.1:57581] logged in with entity id 24047 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 20:02:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:04:24 [INFO] LAX1DUDE[/127.0.0.1:57595] logged in with entity id 24140 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 20:04:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:04:53 [INFO] LAX1DUDE[/127.0.0.1:57598] logged in with entity id 24233 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 20:04:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:07:31 [INFO] LAX1DUDE[/127.0.0.1:57607] logged in with entity id 24326 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 20:07:41 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:09:30 [INFO] LAX1DUDE[/127.0.0.1:57615] logged in with entity id 24419 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 20:09:39 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:11:07 [INFO] LAX1DUDE[/127.0.0.1:57623] logged in with entity id 24512 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 20:11:13 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:17:13 [INFO] LAX1DUDE[/127.0.0.1:58102] logged in with entity id 24604 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 20:17:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:22:44 [INFO] LAX1DUDE[/127.0.0.1:58259] logged in with entity id 24695 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 20:22:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:23:45 [INFO] LAX1DUDE[/127.0.0.1:58280] logged in with entity id 24786 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 20:23:51 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:24:29 [INFO] LAX1DUDE[/127.0.0.1:58307] logged in with entity id 24877 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 20:24:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:26:41 [INFO] LAX1DUDE[/127.0.0.1:58339] logged in with entity id 24966 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 20:26:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:27:54 [INFO] LAX1DUDE[/127.0.0.1:58352] logged in with entity id 25054 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 20:28:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:28:50 [INFO] LAX1DUDE[/127.0.0.1:58367] logged in with entity id 25143 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 20:28:59 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:31:10 [INFO] LAX1DUDE[/127.0.0.1:58390] logged in with entity id 25236 at ([world] -43.006490509786786, 76.11435597561993, 571.1923619114373) +2020-08-05 20:31:26 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:32:21 [INFO] LAX1DUDE[/127.0.0.1:58401] logged in with entity id 25394 at ([world] -64.65611029008825, 63.0, 595.680841395558) +2020-08-05 20:34:51 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:40:09 [INFO] LAX1DUDE[/127.0.0.1:56122] logged in with entity id 25570 at ([world] -64.65611029008825, 63.0, 595.680841395558) +2020-08-05 20:41:04 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:42:25 [INFO] LAX1DUDE[/127.0.0.1:56144] logged in with entity id 25698 at ([world] -60.628153163942834, 65.89655738117848, 606.6999999880791) +2020-08-05 20:45:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:45:18 [INFO] LAX1DUDE[/127.0.0.1:56177] logged in with entity id 25856 at ([world] -58.622603301021954, 66.15559932297028, 606.6999999880791) +2020-08-05 20:50:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:53:52 [INFO] LAX1DUDE[/127.0.0.1:56326] logged in with entity id 26136 at ([world] -63.22382247125307, 72.35603639146586, 609.3388558143008) +2020-08-05 20:55:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:56:03 [INFO] LAX1DUDE[/127.0.0.1:56361] logged in with entity id 26347 at ([world] -60.04626309249449, 65.73901677465356, 615.7796636343011) +2020-08-05 20:58:01 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 20:58:03 [INFO] LAX1DUDE[/127.0.0.1:56374] logged in with entity id 26968 at ([world] -83.88909413635038, 70.0, 716.3402194714072) +2020-08-05 21:02:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:02:32 [INFO] LAX1DUDE[/127.0.0.1:56491] logged in with entity id 28620 at ([world] -202.80899219867956, 91.0, 845.2831606950084) +2020-08-05 21:10:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:11:33 [INFO] LAX1DUDE[/127.0.0.1:56670] logged in with entity id 29835 at ([world] -152.88506605773196, 68.0, 904.6532754986513) +2020-08-05 21:15:35 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:16:12 [INFO] LAX1DUDE[/127.0.0.1:56733] logged in with entity id 30288 at ([world] -146.75830928973775, 94.36435596545438, 909.5665128222491) +2020-08-05 21:16:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:20:37 [INFO] LAX1DUDE[/127.0.0.1:56797] logged in with entity id 30736 at ([world] -142.4879831439542, 75.0, 908.5732854340458) +2020-08-05 21:20:43 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:21:37 [INFO] LAX1DUDE[/127.0.0.1:56807] logged in with entity id 31054 at ([world] -152.00164734901026, 74.0, 908.4094440623885) +2020-08-05 21:23:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:23:52 [INFO] LAX1DUDE[/127.0.0.1:56833] logged in with entity id 31910 at ([world] -101.52314264593188, 65.0, 909.4993729786775) +2020-08-05 21:24:04 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:24:41 [INFO] LAX1DUDE[/127.0.0.1:56846] logged in with entity id 32235 at ([world] -109.18718392693206, 67.86512829970259, 912.023119853406) +2020-08-05 21:25:07 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:25:53 [INFO] LAX1DUDE[/127.0.0.1:56863] logged in with entity id 32701 at ([world] -123.84057539113734, 72.87447404704041, 938.2689767940846) +2020-08-05 21:26:54 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:28:05 [INFO] LAX1DUDE[/127.0.0.1:56885] logged in with entity id 33087 at ([world] -112.34966157937156, 68.875, 931.0551301782854) +2020-08-05 21:28:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:28:52 [INFO] LAX1DUDE[/127.0.0.1:56891] logged in with entity id 33405 at ([world] -108.99201230355636, 66.0, 936.6363676216457) +2020-08-05 21:29:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:30:39 [INFO] LAX1DUDE[/127.0.0.1:56937] logged in with entity id 33765 at ([world] -120.38227912671935, 64.0, 949.2717058384108) +2020-08-05 21:34:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:34:26 [INFO] LAX1DUDE[/127.0.0.1:56984] logged in with entity id 34371 at ([world] -117.32551959246031, 69.0, 909.1248715763583) +2020-08-05 21:35:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:36:39 [INFO] LAX1DUDE[/127.0.0.1:57011] logged in with entity id 34903 at ([world] -128.19289447879117, 65.0, 949.5099761769159) +2020-08-05 21:37:09 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:37:51 [INFO] LAX1DUDE[/127.0.0.1:57028] logged in with entity id 35225 at ([world] -133.05593594266645, 65.0, 950.2565991760204) +2020-08-05 21:39:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:40:07 [INFO] LAX1DUDE[/127.0.0.1:57075] logged in with entity id 35741 at ([world] -107.47450755362202, 67.0, 916.0422106070849) +2020-08-05 21:42:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:44:03 [INFO] LAX1DUDE[/127.0.0.1:57124] logged in with entity id 36627 at ([world] -158.64026033709547, 64.0, 963.7973403937063) +2020-08-05 21:46:26 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:47:08 [INFO] LAX1DUDE[/127.0.0.1:57165] logged in with entity id 38445 at ([world] -123.5814553520751, 92.0, 983.2420103263523) +2020-08-05 21:47:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:49:20 [INFO] LAX1DUDE[/127.0.0.1:57228] logged in with entity id 38777 at ([world] -112.8404159364156, 90.0, 986.2242351263369) +2020-08-05 21:49:41 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:50:27 [INFO] LAX1DUDE[/127.0.0.1:57250] logged in with entity id 39252 at ([world] -91.74327988342452, 101.4799159094177, 995.691698965259) +2020-08-05 21:50:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:51:25 [INFO] LAX1DUDE[/127.0.0.1:57279] logged in with entity id 39904 at ([world] -217.6093321424461, 130.69228780388772, 920.9327737595979) +2020-08-05 21:51:51 [INFO] LAX1DUDE issued server command: /time set day +2020-08-05 21:51:51 [INFO] LAX1DUDE: Set time to 0 +2020-08-05 21:51:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:55:25 [INFO] LAX1DUDE[/127.0.0.1:57343] logged in with entity id 40402 at ([world] -154.2224369605106, 120.94228780390033, 980.4790156513147) +2020-08-05 21:55:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:56:12 [INFO] LAX1DUDE[/127.0.0.1:57360] logged in with entity id 40742 at ([world] -150.3368892309784, 114.95173297856086, 977.5892650101) +2020-08-05 21:56:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:57:22 [INFO] LAX1DUDE[/127.0.0.1:57381] logged in with entity id 42047 at ([world] -208.5974216420467, 123.5762921836189, 1007.4097421158826) +2020-08-05 21:57:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:58:05 [INFO] LAX1DUDE[/127.0.0.1:57391] logged in with entity id 42562 at ([world] -207.84300058714365, 123.5762921836189, 1002.239752664251) +2020-08-05 21:58:22 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-05 21:58:22 [INFO] LAX1DUDE: Changed weather to clear for 699 seconds. +2020-08-05 21:59:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 21:59:25 [INFO] LAX1DUDE[/127.0.0.1:57411] logged in with entity id 43319 at ([world] -219.9738609005807, 126.19306878368285, 998.8666279349807) +2020-08-05 21:59:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:00:11 [INFO] LAX1DUDE[/127.0.0.1:57422] logged in with entity id 43750 at ([world] -184.8487057388213, 127.30865555979433, 1013.9401160173983) +2020-08-05 22:00:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:01:01 [INFO] LAX1DUDE[/127.0.0.1:57518] logged in with entity id 44194 at ([world] -163.1832208135742, 117.94308379217206, 1019.3476752957004) +2020-08-05 22:01:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:03:41 [INFO] LAX1DUDE[/127.0.0.1:57564] logged in with entity id 44843 at ([world] -171.77748402761955, 100.91941974026965, 993.1583067074391) +2020-08-05 22:19:03 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:19:05 [INFO] LAX1DUDE[/127.0.0.1:57782] logged in with entity id 47896 at ([world] 23.981599078317345, 73.0, 1037.0665758095538) +2020-08-05 22:31:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:31:45 [INFO] LAX1DUDE[/127.0.0.1:57908] logged in with entity id 48829 at ([world] 7.3091424653777155, 81.0, 1060.3485767796385) +2020-08-05 22:33:09 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:33:12 [INFO] LAX1DUDE[/127.0.0.1:57926] logged in with entity id 49378 at ([world] 61.02237539324359, 71.0, 1114.3199817329707) +2020-08-05 22:33:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:33:23 [INFO] LAX1DUDE[/127.0.0.1:57929] logged in with entity id 49704 at ([world] 81.09787569508029, 105.99727989251734, 1069.7889299557455) +2020-08-05 22:35:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:36:42 [INFO] LAX1DUDE[/127.0.0.1:57957] logged in with entity id 50410 at ([world] -0.18598060044642378, 63.0, 918.8385338043946) +2020-08-05 22:38:05 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:38:16 [INFO] LAX1DUDE[/127.0.0.1:57973] logged in with entity id 50745 at ([world] -0.35127722148188095, 63.0, 924.196151118666) +2020-08-05 22:38:18 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:38:55 [INFO] LAX1DUDE[/127.0.0.1:57977] logged in with entity id 50974 at ([world] -0.35127722148188095, 63.0, 924.196151118666) +2020-08-05 22:39:51 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:40:08 [INFO] LAX1DUDE[/127.0.0.1:58004] logged in with entity id 51240 at ([world] 0.6759493150318274, 63.0, 923.6403400607838) +2020-08-05 22:40:23 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:41:14 [INFO] LAX1DUDE[/127.0.0.1:58012] logged in with entity id 51472 at ([world] 0.6759493150318274, 63.0, 923.6403400607838) +2020-08-05 22:41:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:41:39 [INFO] LAX1DUDE[/127.0.0.1:58017] logged in with entity id 51705 at ([world] 0.6759493150318274, 63.0, 923.6403400607838) +2020-08-05 22:42:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:43:10 [INFO] LAX1DUDE[/127.0.0.1:58043] logged in with entity id 51986 at ([world] -0.7054473055746446, 63.0, 922.4934087972434) +2020-08-05 22:43:39 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:46:45 [INFO] LAX1DUDE[/127.0.0.1:58094] logged in with entity id 52220 at ([world] 1.3000000119209278, 63.0, 922.2559312141809) +2020-08-05 22:47:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:47:20 [INFO] LAX1DUDE[/127.0.0.1:58099] logged in with entity id 52454 at ([world] -0.09164965629142445, 63.0, 926.6999999880791) +2020-08-05 22:47:55 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 22:51:33 [INFO] LAX1DUDE[/127.0.0.1:58143] logged in with entity id 52872 at ([world] -5.99804909374221, 64.0, 928.7813537130302) +2020-08-05 23:10:40 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 23:21:26 [INFO] LAX1DUDE[/127.0.0.1:58530] logged in with entity id 54029 at ([world] -3.9885739819200046, 87.11435596545438, 922.9974323707728) +2020-08-05 23:21:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 23:22:21 [INFO] LAX1DUDE[/127.0.0.1:58553] logged in with entity id 54264 at ([world] -3.9885739819200046, 87.11435596545438, 922.9974323707728) +2020-08-05 23:22:27 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 23:23:42 [INFO] LAX1DUDE[/127.0.0.1:58572] logged in with entity id 54500 at ([world] -3.9885739819200046, 87.11435596545438, 922.9974323707728) +2020-08-05 23:23:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 23:23:48 [INFO] LAX1DUDE[/127.0.0.1:58575] logged in with entity id 54740 at ([world] -3.9885739819200046, 87.11435596545438, 922.9974323707728) +2020-08-05 23:23:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 23:24:13 [INFO] LAX1DUDE[/127.0.0.1:58580] logged in with entity id 54976 at ([world] -3.9885739819200046, 87.11435596545438, 922.9974323707728) +2020-08-05 23:24:21 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 23:25:53 [INFO] LAX1DUDE[/127.0.0.1:58605] logged in with entity id 55212 at ([world] -3.9885739819200046, 87.11435596545438, 922.9974323707728) +2020-08-05 23:32:12 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-05 23:35:44 [INFO] LAX1DUDE[/127.0.0.1:58713] logged in with entity id 55982 at ([world] 2.125457703982179, 63.0, 922.9877960505215) +2020-08-06 00:03:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 00:03:58 [INFO] LAX1DUDE[/127.0.0.1:59113] logged in with entity id 57686 at ([world] -5.147266816727291, 64.0, 939.4104633681602) +2020-08-06 00:04:20 [INFO] LAX1DUDE issued server command: /time set day +2020-08-06 00:04:20 [INFO] LAX1DUDE: Set time to 0 +2020-08-06 00:07:40 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 00:08:15 [INFO] LAX1DUDE[/127.0.0.1:59152] logged in with entity id 58087 at ([world] -5.147266816727291, 81.37227989252115, 939.4104633681602) +2020-08-06 00:08:41 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 00:09:26 [INFO] LAX1DUDE[/127.0.0.1:59174] logged in with entity id 58348 at ([world] -5.147266816727291, 81.37227989252115, 939.4104633681602) +2020-08-06 00:21:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 00:22:13 [INFO] LAX1DUDE[/127.0.0.1:59355] logged in with entity id 59474 at ([world] -64.03318362430088, 81.83339489072563, 1028.5379569364927) +2020-08-06 00:35:03 [INFO] LAX1DUDE issued server command: /time set day +2020-08-06 00:35:03 [INFO] LAX1DUDE: Set time to 0 +2020-08-06 00:52:07 [INFO] LAX1DUDE issued server command: /time set day +2020-08-06 00:52:07 [INFO] LAX1DUDE: Set time to 0 +2020-08-06 00:56:25 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 00:56:38 [INFO] LAX1DUDE[/127.0.0.1:59779] logged in with entity id 64768 at ([world] -76.00878988111621, 106.0, 1229.2412423614046) +2020-08-06 01:03:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 01:12:18 [INFO] LAX1DUDE[/127.0.0.1:59972] logged in with entity id 66117 at ([world] -123.41061936431248, 79.0, 1146.7620500113876) +2020-08-06 01:12:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 01:12:56 [INFO] LAX1DUDE[/127.0.0.1:59976] logged in with entity id 66420 at ([world] -123.41061936431248, 79.0, 1146.7620500113876) +2020-08-06 01:13:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 01:13:19 [INFO] LAX1DUDE[/127.0.0.1:59990] logged in with entity id 66721 at ([world] -123.41061936431248, 79.0, 1146.7620500113876) +2020-08-06 01:13:38 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-06 01:13:38 [INFO] LAX1DUDE: Changed weather to clear for 402 seconds. +2020-08-06 01:24:26 [INFO] LAX1DUDE issued server command: /time set day +2020-08-06 01:24:26 [INFO] LAX1DUDE: Set time to 0 +2020-08-06 01:41:21 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 12:12:32 [INFO] LAX1DUDE[/127.0.0.1:50245] logged in with entity id 74956 at ([world] 22.64146588778864, 73.0, 1035.4073330584624) +2020-08-06 12:12:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 12:13:04 [INFO] LAX1DUDE[/127.0.0.1:50264] logged in with entity id 75203 at ([world] 22.64146588778864, 73.0, 1035.4073330584624) +2020-08-06 12:13:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 12:14:58 [INFO] LAX1DUDE[/127.0.0.1:50296] logged in with entity id 75487 at ([world] 34.16914058386312, 89.23935596545499, 1021.9595128170911) +2020-08-06 12:17:46 [INFO] LAX1DUDE issued server command: /time set day +2020-08-06 12:17:46 [INFO] LAX1DUDE: Set time to 0 +2020-08-06 12:20:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 12:21:05 [INFO] LAX1DUDE[/127.0.0.1:50348] logged in with entity id 76128 at ([world] -1.2816787321292615, 92.97990813878373, 1013.673277067207) +2020-08-06 12:21:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 12:21:59 [INFO] LAX1DUDE[/127.0.0.1:50364] logged in with entity id 76406 at ([world] -1.2816787321292615, 92.97990813878373, 1013.673277067207) +2020-08-06 12:22:03 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 12:22:59 [INFO] LAX1DUDE[/127.0.0.1:50378] logged in with entity id 76684 at ([world] -1.2816787321292615, 92.97990813878373, 1013.673277067207) +2020-08-06 12:23:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 12:25:54 [INFO] LAX1DUDE[/127.0.0.1:50406] logged in with entity id 76962 at ([world] -1.8548031597084194, 92.97990813878373, 1012.5283951389871) +2020-08-06 12:28:52 [INFO] LAX1DUDE issued server command: /time set day +2020-08-06 12:28:52 [INFO] LAX1DUDE: Set time to 0 +2020-08-06 12:31:07 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 12:31:53 [INFO] LAX1DUDE[/127.0.0.1:50469] logged in with entity id 77535 at ([world] -13.535467930933452, 81.21346877636611, 938.2166849070022) +2020-08-06 12:32:03 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 12:32:35 [INFO] LAX1DUDE[/127.0.0.1:50473] logged in with entity id 77831 at ([world] -10.69999998807907, 72.59791654175369, 938.6999999880791) +2020-08-06 12:38:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 12:38:42 [INFO] LAX1DUDE[/127.0.0.1:50543] logged in with entity id 78889 at ([world] -64.43083213165431, 63.0, 923.0515522776263) +2020-08-06 12:42:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 12:57:11 [INFO] LAX1DUDE[/127.0.0.1:50759] logged in with entity id 79881 at ([world] -124.15792496532467, 71.0, 919.6819180520727) +2020-08-06 13:29:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 13:42:34 [INFO] LAX1DUDE[/127.0.0.1:51189] logged in with entity id 82018 at ([world] -86.64112239516325, 63.0, 898.5031408879485) +2020-08-06 13:42:48 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 13:43:09 [INFO] LAX1DUDE[/127.0.0.1:51215] logged in with entity id 82281 at ([world] -86.64112239516325, 65.52936759557846, 898.5031408879485) +2020-08-06 14:03:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 14:05:42 [INFO] LAX1DUDE[/127.0.0.1:51433] logged in with entity id 83712 at ([world] -89.74206633870838, 63.021338795583, 866.4124256362389) +2020-08-06 14:05:57 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-06 14:05:57 [INFO] LAX1DUDE: Changed weather to clear for 668 seconds. +2020-08-06 14:29:32 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 14:29:46 [INFO] LAX1DUDE[/127.0.0.1:51668] logged in with entity id 85936 at ([world] -164.6322948012844, 64.0, 794.9397694258114) +2020-08-06 14:56:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 14:56:52 [INFO] LAX1DUDE[/127.0.0.1:51939] logged in with entity id 87824 at ([world] -112.99415731885566, 78.45043161732411, 794.4814297223656) +2020-08-06 15:12:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 15:13:26 [INFO] LAX1DUDE[/127.0.0.1:51972] logged in with entity id 89756 at ([world] -156.64396033842138, 89.63146325926499, 837.8593506539804) +2020-08-06 15:21:32 [INFO] LAX1DUDE issued server command: /time set day +2020-08-06 15:21:32 [INFO] LAX1DUDE: Set time to 0 +2020-08-06 15:40:43 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 15:41:21 [INFO] LAX1DUDE[/127.0.0.1:52035] logged in with entity id 94764 at ([world] -99.90370092765922, 79.87882152307257, 864.4928652732058) +2020-08-06 16:13:04 [INFO] LAX1DUDE issued server command: /time set day +2020-08-06 16:13:04 [INFO] LAX1DUDE: Set time to 0 +2020-08-06 16:21:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 16:22:09 [INFO] LAX1DUDE[/127.0.0.1:52166] logged in with entity id 101486 at ([world] -99.73388893418218, 70.9132691681201, 784.3813999844798) +2020-08-06 16:22:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 16:22:35 [INFO] LAX1DUDE[/127.0.0.1:52172] logged in with entity id 101738 at ([world] -104.3542927672102, 70.9132691681201, 778.9896189941853) +2020-08-06 16:25:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 17:31:12 [INFO] LAX1DUDE[/127.0.0.1:53104] logged in with entity id 102602 at ([world] -102.60257067855885, 77.12229206663308, 797.6306686270206) +2020-08-06 17:32:21 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 17:32:45 [INFO] LAX1DUDE[/127.0.0.1:53111] logged in with entity id 102889 at ([world] -47.34222555118686, 69.0, 809.6650236296815) +2020-08-06 17:32:52 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 17:33:29 [INFO] LAX1DUDE[/127.0.0.1:53117] logged in with entity id 103092 at ([world] -46.69889149390309, 69.0, 809.2388239309357) +2020-08-06 17:33:35 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 17:34:58 [INFO] LAX1DUDE[/127.0.0.1:53126] logged in with entity id 103293 at ([world] -48.01197510609532, 68.0, 808.3000000119209) +2020-08-06 17:35:01 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 17:38:17 [INFO] LAX1DUDE[/127.0.0.1:53134] logged in with entity id 103495 at ([world] -48.01197510609532, 68.0, 808.3000000119209) +2020-08-06 17:38:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 17:38:56 [INFO] LAX1DUDE[/127.0.0.1:53138] logged in with entity id 103697 at ([world] -48.01197510609532, 68.0, 808.3000000119209) +2020-08-06 17:38:59 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 17:39:56 [INFO] LAX1DUDE[/127.0.0.1:53143] logged in with entity id 103899 at ([world] -48.01197510609532, 68.0, 808.3000000119209) +2020-08-06 17:40:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 17:42:07 [INFO] LAX1DUDE[/127.0.0.1:53150] logged in with entity id 104112 at ([world] -48.40287205125915, 68.0, 808.3000000119209) +2020-08-06 17:42:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 17:48:39 [INFO] LAX1DUDE[/127.0.0.1:53167] logged in with entity id 104323 at ([world] -47.18541228503167, 69.0, 806.5730652610285) +2020-08-06 17:48:46 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 17:50:44 [INFO] LAX1DUDE[/127.0.0.1:53174] logged in with entity id 104524 at ([world] -46.992811508281626, 69.0, 807.3864295543276) +2020-08-06 17:50:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 18:12:01 [INFO] LAX1DUDE[/127.0.0.1:53216] logged in with entity id 104725 at ([world] -46.992811508281626, 69.0, 807.3864295543276) +2020-08-06 18:12:26 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 18:14:18 [INFO] LAX1DUDE[/127.0.0.1:53223] logged in with entity id 104930 at ([world] -45.30000001192093, 68.0, 809.6999999880791) +2020-08-06 18:14:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 18:14:41 [INFO] LAX1DUDE[/127.0.0.1:53228] logged in with entity id 105131 at ([world] -45.47006738905936, 68.0, 809.6999999880791) +2020-08-06 18:15:13 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 18:15:25 [INFO] LAX1DUDE[/127.0.0.1:53240] logged in with entity id 105355 at ([world] -45.47006738905936, 68.0, 809.6999999880791) +2020-08-06 18:15:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 18:16:20 [INFO] LAX1DUDE[/127.0.0.1:53247] logged in with entity id 105556 at ([world] -45.47006738905936, 68.0, 809.6999999880791) +2020-08-06 18:16:27 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 18:17:03 [INFO] LAX1DUDE[/127.0.0.1:53254] logged in with entity id 105758 at ([world] -45.47006738905936, 68.0, 809.6999999880791) +2020-08-06 18:17:08 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 18:17:49 [INFO] LAX1DUDE[/127.0.0.1:53268] logged in with entity id 105961 at ([world] -45.47006738905936, 68.0, 809.6999999880791) +2020-08-06 18:17:51 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 19:29:20 [INFO] LAX1DUDE[/127.0.0.1:53459] logged in with entity id 106181 at ([world] -45.47006738905936, 68.0, 809.6999999880791) +2020-08-06 19:36:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 19:37:09 [INFO] LAX1DUDE[/127.0.0.1:53476] logged in with entity id 106911 at ([world] -45.47006738905936, 68.0, 809.6999999880791) +2020-08-06 19:37:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 19:40:13 [INFO] LAX1DUDE[/127.0.0.1:53481] logged in with entity id 107120 at ([world] -45.47006738905936, 68.0, 809.6999999880791) +2020-08-06 19:45:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 19:48:48 [INFO] LAX1DUDE[/127.0.0.1:53493] logged in with entity id 108534 at ([world] -51.256011576638045, 69.0, 810.0018764327248) +2020-08-06 19:54:41 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 19:54:43 [INFO] LAX1DUDE[/127.0.0.1:53501] logged in with entity id 108955 at ([world] -49.73513606042787, 69.26543680704374, 810.8141527854718) +2020-08-06 19:54:51 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 19:55:24 [INFO] LAX1DUDE[/127.0.0.1:53509] logged in with entity id 109153 at ([world] -49.73513606042787, 69.26543680704374, 810.8141527854718) +2020-08-06 19:56:03 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 19:56:53 [INFO] LAX1DUDE[/127.0.0.1:53515] logged in with entity id 109449 at ([world] -74.3243953615228, 89.12227987650117, 808.9723995870395) +2020-08-06 19:57:41 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 19:58:09 [INFO] LAX1DUDE[/127.0.0.1:53518] logged in with entity id 109826 at ([world] -52.56274547258279, 68.0, 810.2326812649446) +2020-08-06 20:27:48 [INFO] LAX1DUDE issued server command: /time set day +2020-08-06 20:27:48 [INFO] LAX1DUDE: Set time to 0 +2020-08-06 20:39:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 20:39:38 [INFO] LAX1DUDE[/127.0.0.1:53583] logged in with entity id 115497 at ([world] -14.508487242319436, 75.0, 859.5938370606642) +2020-08-06 20:43:13 [INFO] LAX1DUDE issued server command: /time set day +2020-08-06 20:43:13 [INFO] LAX1DUDE: Set time to 0 +2020-08-06 20:46:13 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-06 20:46:13 [INFO] LAX1DUDE: Changed weather to clear for 756 seconds. +2020-08-06 20:54:25 [INFO] LAX1DUDE issued server command: /time set day +2020-08-06 20:54:25 [INFO] LAX1DUDE: Set time to 0 +2020-08-06 20:57:27 [INFO] LAX1DUDE issued server command: /time set night +2020-08-06 20:57:27 [INFO] LAX1DUDE: Set time to 12500 +2020-08-06 21:01:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 21:01:50 [INFO] LAX1DUDE[/127.0.0.1:53611] logged in with entity id 118354 at ([world] -48.314631425691644, 69.0, 805.8899622479802) +2020-08-06 21:10:54 [INFO] LAX1DUDE issued server command: /time set night +2020-08-06 21:10:54 [INFO] LAX1DUDE: Set time to 12500 +2020-08-06 21:11:02 [INFO] LAX1DUDE issued server command: /time add 2000 +2020-08-06 21:11:02 [INFO] LAX1DUDE: Added 2000 to time +2020-08-06 21:15:58 [INFO] LAX1DUDE issued server command: /time set day +2020-08-06 21:15:58 [INFO] LAX1DUDE: Set time to 0 +2020-08-06 21:21:01 [INFO] LAX1DUDE issued server command: /time set night +2020-08-06 21:21:01 [INFO] LAX1DUDE: Set time to 12500 +2020-08-06 21:25:38 [INFO] LAX1DUDE issued server command: /time set day +2020-08-06 21:25:38 [INFO] LAX1DUDE: Set time to 0 +2020-08-06 21:30:39 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 21:30:42 [INFO] LAX1DUDE[/127.0.0.1:53647] logged in with entity id 122963 at ([world] -102.89951225806196, 88.03826897642051, 814.3256547918156) +2020-08-06 21:30:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 21:30:57 [INFO] LAX1DUDE[/127.0.0.1:53653] logged in with entity id 123215 at ([world] -102.89951225806196, 88.03826897642051, 814.3256547918156) +2020-08-06 21:31:52 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 21:32:47 [INFO] LAX1DUDE[/127.0.0.1:53657] logged in with entity id 123485 at ([world] -100.8952077988691, 88.03826897642051, 817.1893114372556) +2020-08-06 21:33:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 21:35:34 [INFO] LAX1DUDE[/127.0.0.1:53664] logged in with entity id 123741 at ([world] -93.79637658317539, 88.03826897642051, 815.7638354498758) +2020-08-06 21:40:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 21:40:42 [INFO] LAX1DUDE[/127.0.0.1:53674] logged in with entity id 124409 at ([world] -44.34857675421517, 71.0, 780.6888051454607) +2020-08-06 21:42:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-06 21:42:45 [INFO] LAX1DUDE[/127.0.0.1:53682] logged in with entity id 124684 at ([world] -55.1380032346688, 81.9994713913707, 813.2602855492789) +2020-08-06 21:42:48 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 01:17:30 [INFO] LAX1DUDE[/127.0.0.1:55405] logged in with entity id 124899 at ([world] -55.1380032346688, 81.9994713913707, 813.2602855492789) +2020-08-07 01:17:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 01:18:31 [INFO] LAX1DUDE[/127.0.0.1:55413] logged in with entity id 125108 at ([world] -51.53249826797703, 81.9994713913707, 812.2124596248688) +2020-08-07 01:21:48 [INFO] LAX1DUDE issued server command: /time set day +2020-08-07 01:21:48 [INFO] LAX1DUDE: Set time to 0 +2020-08-07 01:21:59 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-07 01:21:59 [INFO] LAX1DUDE: Changed weather to clear for 767 seconds. +2020-08-07 01:32:12 [INFO] LAX1DUDE issued server command: /time set 4000 +2020-08-07 01:32:12 [INFO] LAX1DUDE: Set time to 4000 +2020-08-07 01:39:21 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-07 01:39:21 [INFO] LAX1DUDE: Changed weather to clear for 363 seconds. +2020-08-07 01:40:24 [INFO] LAX1DUDE issued server command: /time set 5000 +2020-08-07 01:40:24 [INFO] LAX1DUDE: Set time to 5000 +2020-08-07 01:44:27 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 01:44:42 [INFO] LAX1DUDE[/127.0.0.1:55452] logged in with entity id 129501 at ([world] -44.93877061080974, 71.0, 791.9485271648829) +2020-08-07 01:45:21 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 01:45:52 [INFO] LAX1DUDE[/127.0.0.1:55459] logged in with entity id 129829 at ([world] -54.06158429231435, 71.0, 779.5910978995564) +2020-08-07 01:51:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 01:51:29 [INFO] LAX1DUDE[/127.0.0.1:55472] logged in with entity id 130302 at ([world] -50.07942848984494, 80.72899100284216, 790.3470840518713) +2020-08-07 01:52:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 01:55:05 [INFO] LAX1DUDE[/127.0.0.1:55478] logged in with entity id 130588 at ([world] -42.07517161968096, 74.23981936600332, 795.0027456684624) +2020-08-07 01:55:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 01:55:44 [INFO] LAX1DUDE[/127.0.0.1:55484] logged in with entity id 130798 at ([world] -45.47037988439842, 74.23981936600332, 802.3762093794106) +2020-08-07 01:59:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 02:03:06 [INFO] LAX1DUDE[/127.0.0.1:55492] logged in with entity id 132288 at ([world] -81.69999998807907, 67.0, 810.3172015723768) +2020-08-07 02:06:44 [INFO] LAX1DUDE issued server command: /time set 5000 +2020-08-07 02:06:44 [INFO] LAX1DUDE: Set time to 5000 +2020-08-07 02:18:26 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 02:18:39 [INFO] LAX1DUDE[/127.0.0.1:55521] logged in with entity id 136228 at ([world] -79.30484940516297, 66.0, 812.3000000119209) +2020-08-07 02:34:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 02:34:17 [INFO] LAX1DUDE[/127.0.0.1:55554] logged in with entity id 138132 at ([world] -53.92471821839709, 70.0, 786.927622292385) +2020-08-07 02:35:35 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 03:03:18 [INFO] LAX1DUDE[/127.0.0.1:55577] logged in with entity id 138448 at ([world] -45.00523006629384, 70.0, 799.9815255997977) +2020-08-07 03:13:49 [INFO] LAX1DUDE issued server command: /time set day +2020-08-07 03:13:49 [INFO] LAX1DUDE: Set time to 0 +2020-08-07 03:24:32 [INFO] LAX1DUDE issued server command: /time set day +2020-08-07 03:24:32 [INFO] LAX1DUDE: Set time to 0 +2020-08-07 03:31:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 03:32:01 [INFO] LAX1DUDE[/127.0.0.1:55630] logged in with entity id 141783 at ([world] -65.79965552917642, 71.0, 782.0613357379824) +2020-08-07 03:33:08 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 03:33:55 [INFO] LAX1DUDE[/127.0.0.1:55636] logged in with entity id 142120 at ([world] -73.76137368683744, 71.0, 760.2334662281417) +2020-08-07 03:35:59 [INFO] LAX1DUDE issued server command: /time set day +2020-08-07 03:35:59 [INFO] LAX1DUDE: Set time to 0 +2020-08-07 03:47:27 [INFO] LAX1DUDE issued server command: /time set day +2020-08-07 03:47:27 [INFO] LAX1DUDE: Set time to 0 +2020-08-07 03:59:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 03:59:51 [INFO] LAX1DUDE[/127.0.0.1:55665] logged in with entity id 146316 at ([world] -121.00224502828527, 64.0, 765.151147043124) +2020-08-07 04:00:49 [INFO] LAX1DUDE issued server command: /time set day +2020-08-07 04:00:49 [INFO] LAX1DUDE: Set time to 0 +2020-08-07 04:16:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 04:19:10 [INFO] LAX1DUDE[/127.0.0.1:55706] logged in with entity id 149051 at ([world_nether] -8.664233844977804, 92.0, 91.79582596213181) +2020-08-07 04:20:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 19:45:04 [INFO] LAX1DUDE[/127.0.0.1:56637] logged in with entity id 149353 at ([world] -52.831502021609566, 87.96601656408455, 800.0923244682549) +2020-08-07 19:54:03 [INFO] LAX1DUDE issued server command: /time set day +2020-08-07 19:54:03 [INFO] LAX1DUDE: Set time to 0 +2020-08-07 19:55:39 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 19:56:02 [INFO] LAX1DUDE[/127.0.0.1:56655] logged in with entity id 152217 at ([world] -348.1715912202204, 63.0, 574.1902340252901) +2020-08-07 19:56:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 19:56:33 [INFO] LAX1DUDE[/127.0.0.1:56660] logged in with entity id 152383 at ([world] -348.1715912202204, 63.0, 574.1902340252901) +2020-08-07 19:57:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 19:57:42 [INFO] LAX1DUDE[/127.0.0.1:56667] logged in with entity id 152554 at ([world] -340.82445179825066, 63.0, 577.1399848221425) +2020-08-07 19:59:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 20:09:58 [INFO] LAX1DUDE[/127.0.0.1:56687] logged in with entity id 152759 at ([world] -325.0638895093989, 62.0, 579.6032290336259) +2020-08-07 20:10:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 20:10:32 [INFO] LAX1DUDE[/127.0.0.1:56692] logged in with entity id 152905 at ([world] -325.0638895093989, 62.0, 579.6032290336259) +2020-08-07 20:13:54 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-07 20:13:54 [INFO] LAX1DUDE: Changed weather to clear for 484 seconds. +2020-08-07 20:29:47 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 20:30:00 [INFO] LAX1DUDE[/127.0.0.1:56787] logged in with entity id 154985 at ([world] -364.01280980542947, 92.29373923493075, 686.2950034737707) +2020-08-07 20:30:23 [INFO] LAX1DUDE issued server command: /time set day +2020-08-07 20:30:23 [INFO] LAX1DUDE: Set time to 0 +2020-08-07 20:37:25 [INFO] LAX1DUDE issued server command: /tp 29999998 100 29999998 +2020-08-07 20:37:25 [INFO] LAX1DUDE: Teleported LAX1DUDE to 29999998.50, 100.50, 29999998.50 +2020-08-07 20:39:08 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 22:57:27 [INFO] LAX1DUDE[/127.0.0.1:57965] logged in with entity id 160142 at ([world] 2.9999989743685782E7, 130.62388109781105, 2.9999839108018585E7) +2020-08-07 23:02:31 [INFO] LAX1DUDE issued server command: /tp 10000 100 10000 +2020-08-07 23:02:31 [INFO] LAX1DUDE: Teleported LAX1DUDE to 10000.50, 100.50, 10000.50 +2020-08-07 23:02:50 [INFO] LAX1DUDE issued server command: /tp 1000000 100 10000000 +2020-08-07 23:02:50 [INFO] LAX1DUDE: Teleported LAX1DUDE to 1000000.50, 100.50, 10000000.50 +2020-08-07 23:03:38 [INFO] LAX1DUDE issued server command: /kill +2020-08-07 23:03:38 [INFO] LAX1DUDE died +2020-08-07 23:07:47 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 23:13:08 [INFO] LAX1DUDE[/127.0.0.1:58167] logged in with entity id 179405 at ([world] 316.9669946086778, 98.0, 436.9534863559767) +2020-08-07 23:24:19 [INFO] LAX1DUDE issued server command: /time set day +2020-08-07 23:24:19 [INFO] LAX1DUDE: Set time to 0 +2020-08-07 23:30:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 23:37:32 [INFO] LAX1DUDE[/127.0.0.1:58237] logged in with entity id 181110 at ([world] 282.8641825749792, 70.61463400578373, 348.01669413976674) +2020-08-07 23:37:40 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 23:39:19 [INFO] LAX1DUDE[/127.0.0.1:58244] logged in with entity id 181216 at ([world] 282.2573410405495, 70.61463400578373, 343.5114075583083) +2020-08-07 23:39:27 [INFO] LAX1DUDE issued server command: /time set day +2020-08-07 23:39:27 [INFO] LAX1DUDE: Set time to 0 +2020-08-07 23:42:25 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 23:46:06 [INFO] LAX1DUDE[/127.0.0.1:58259] logged in with entity id 181568 at ([world] 288.36862118722627, 71.0, 352.6362119355584) +2020-08-07 23:46:35 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 23:48:06 [INFO] LAX1DUDE[/127.0.0.1:58265] logged in with entity id 181690 at ([world] 298.4189850410498, 67.0, 353.1941944490107) +2020-08-07 23:49:35 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 23:49:46 [INFO] LAX1DUDE[/127.0.0.1:58272] logged in with entity id 182001 at ([world] 309.14323570044644, 68.0, 346.02754302836695) +2020-08-07 23:50:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 23:50:46 [INFO] LAX1DUDE[/127.0.0.1:58278] logged in with entity id 182165 at ([world] 308.91630184892705, 68.0, 344.3578951362533) +2020-08-07 23:51:09 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 23:53:35 [INFO] LAX1DUDE[/127.0.0.1:58286] logged in with entity id 182280 at ([world] 309.14605796910644, 67.0, 338.7083764487144) +2020-08-07 23:54:19 [INFO] LAX1DUDE issued server command: /time set day +2020-08-07 23:54:19 [INFO] LAX1DUDE: Set time to 0 +2020-08-07 23:55:33 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 23:56:09 [INFO] LAX1DUDE[/127.0.0.1:58295] logged in with entity id 182440 at ([world] 312.9233324438445, 67.0, 341.7204958876373) +2020-08-07 23:56:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 23:57:32 [INFO] LAX1DUDE[/127.0.0.1:58304] logged in with entity id 182562 at ([world] 318.88238252386424, 67.0, 341.4887809905656) +2020-08-07 23:58:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-07 23:58:30 [INFO] LAX1DUDE[/127.0.0.1:58307] logged in with entity id 182805 at ([world] 323.7603765431868, 68.875, 315.58761206622097) +2020-08-08 00:26:40 [INFO] LAX1DUDE issued server command: /time set day +2020-08-08 00:26:40 [INFO] LAX1DUDE: Set time to 0 +2020-08-08 00:38:36 [INFO] LAX1DUDE issued server command: /time set day +2020-08-08 00:38:36 [INFO] LAX1DUDE: Set time to 0 +2020-08-08 00:53:47 [INFO] LAX1DUDE issued server command: /time set day +2020-08-08 00:53:47 [INFO] LAX1DUDE: Set time to 0 +2020-08-08 00:54:05 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 00:54:22 [INFO] LAX1DUDE[/127.0.0.1:58423] logged in with entity id 190595 at ([world] 161.27202665601234, 67.0, 385.5985575152089) +2020-08-08 01:32:50 [INFO] LAX1DUDE issued server command: /time set 18000 +2020-08-08 01:32:50 [INFO] LAX1DUDE: Set time to 18000 +2020-08-08 01:33:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 01:34:12 [INFO] LAX1DUDE[/127.0.0.1:58522] logged in with entity id 195664 at ([world] 175.43830214904088, 67.0, 383.58842628983473) +2020-08-08 01:36:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 01:36:34 [INFO] LAX1DUDE[/127.0.0.1:58532] logged in with entity id 195804 at ([world] 175.43830214904088, 90.48935596545438, 383.58842628983473) +2020-08-08 01:36:47 [INFO] LAX1DUDE issued server command: /time set 18000 +2020-08-08 01:36:47 [INFO] LAX1DUDE: Set time to 18000 +2020-08-08 01:38:30 [INFO] LAX1DUDE issued server command: /time set 0 +2020-08-08 01:38:30 [INFO] LAX1DUDE: Set time to 0 +2020-08-08 01:38:37 [INFO] LAX1DUDE issued server command: /time set 22000 +2020-08-08 01:38:37 [INFO] LAX1DUDE: Set time to 22000 +2020-08-08 01:38:43 [INFO] LAX1DUDE issued server command: /time set 23000 +2020-08-08 01:38:43 [INFO] LAX1DUDE: Set time to 23000 +2020-08-08 01:56:40 [INFO] LAX1DUDE issued server command: /time set day +2020-08-08 01:56:40 [INFO] LAX1DUDE: Set time to 0 +2020-08-08 02:04:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 02:06:11 [INFO] LAX1DUDE[/127.0.0.1:58581] logged in with entity id 237692 at ([world] 84.96628603011752, 64.0, 302.1083163123995) +2020-08-08 02:08:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 02:11:09 [INFO] LAX1DUDE[/127.0.0.1:58596] logged in with entity id 237787 at ([world] 84.98484066088517, 63.0, 289.3067196167313) +2020-08-08 02:43:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 02:44:29 [INFO] LAX1DUDE[/127.0.0.1:58676] logged in with entity id 238940 at ([world] 66.39674861845258, 61.0, 235.30000001192096) +2020-08-08 02:49:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 03:27:16 [INFO] LAX1DUDE[/127.0.0.1:58769] logged in with entity id 239126 at ([world] 77.26078209052875, 76.75314036734254, 235.55742268733283) +2020-08-08 03:27:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 03:29:59 [INFO] LAX1DUDE[/127.0.0.1:58780] logged in with entity id 239169 at ([world] 89.06276426113513, 74.87814068591004, 248.28438611184268) +2020-08-08 03:30:04 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 03:56:18 [INFO] LAX1DUDE[/127.0.0.1:58831] logged in with entity id 239207 at ([world] 89.06276426113513, 74.87814068591004, 248.28438611184268) +2020-08-08 03:56:56 [INFO] LAX1DUDE issued server command: /gamemode 1 +2020-08-08 03:57:03 [INFO] LAX1DUDE issued server command: /time set day +2020-08-08 03:57:03 [INFO] LAX1DUDE: Set time to 0 +2020-08-08 03:57:07 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 03:59:05 [INFO] LAX1DUDE[/127.0.0.1:58840] logged in with entity id 239363 at ([world] 132.48815042767444, 68.53555045008231, 238.91867765185066) +2020-08-08 03:59:17 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-08 03:59:17 [INFO] LAX1DUDE: Changed weather to clear for 607 seconds. +2020-08-08 03:59:30 [INFO] LAX1DUDE issued server command: /time set day +2020-08-08 03:59:30 [INFO] LAX1DUDE: Set time to 0 +2020-08-08 03:59:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 04:00:37 [INFO] LAX1DUDE[/127.0.0.1:58846] logged in with entity id 239440 at ([world] 97.04712082670707, 89.35491236299302, 203.84176450596485) +2020-08-08 04:05:43 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 04:11:55 [INFO] LAX1DUDE[/127.0.0.1:58875] logged in with entity id 240368 at ([world] 66.59330662961878, 65.0, 321.6898444726944) +2020-08-08 04:12:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 04:49:42 [INFO] LAX1DUDE[/127.0.0.1:58953] logged in with entity id 240423 at ([world] 68.3654064374329, 73.0, 314.66780883741507) +2020-08-08 04:50:12 [INFO] LAX1DUDE issued server command: /kill +2020-08-08 04:50:12 [INFO] LAX1DUDE died +2020-08-08 04:50:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 05:17:08 [INFO] LAX1DUDE[/127.0.0.1:59004] logged in with entity id 240676 at ([world] 21.01077679033246, 85.56415214949169, 338.0347585965473) +2020-08-08 05:18:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 21:36:20 [INFO] LAX1DUDE[/127.0.0.1:62842] logged in with entity id 241035 at ([world] 72.63045841475113, 74.60383389807429, 348.69266133780246) +2020-08-08 21:38:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 21:38:39 [INFO] LAX1DUDE[/127.0.0.1:62850] logged in with entity id 241314 at ([world] -15.752562753236184, 92.24727989251734, 447.70418326582126) +2020-08-08 21:39:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 21:39:44 [INFO] LAX1DUDE[/127.0.0.1:62857] logged in with entity id 241391 at ([world] -32.65307167953406, 83.21542976092482, 439.44031795892425) +2020-08-08 21:40:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 21:40:24 [INFO] LAX1DUDE[/127.0.0.1:62860] logged in with entity id 241894 at ([world] -32.42510721048464, 173.9297408882151, 425.9666373635014) +2020-08-08 21:55:08 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 21:55:31 [INFO] LAX1DUDE[/127.0.0.1:62887] logged in with entity id 242878 at ([world] 79.54862611985584, 85.0, 534.81170188991) +2020-08-08 21:58:51 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 21:58:55 [INFO] LAX1DUDE[/127.0.0.1:62895] logged in with entity id 243758 at ([world] 236.40264610745078, 76.0, 248.8206873264618) +2020-08-08 21:59:42 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 22:00:02 [INFO] LAX1DUDE[/127.0.0.1:62903] logged in with entity id 243875 at ([world] 230.46947425280226, 75.0, 245.56009402933532) +2020-08-08 22:00:13 [INFO] LAX1DUDE issued server command: /time set day +2020-08-08 22:00:13 [INFO] LAX1DUDE: Set time to 0 +2020-08-08 22:01:23 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 22:01:34 [INFO] LAX1DUDE[/127.0.0.1:62912] logged in with entity id 244087 at ([world] 229.47575915407626, 92.73037152600493, 247.87296194007988) +2020-08-08 22:02:12 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 22:02:33 [INFO] LAX1DUDE[/127.0.0.1:62915] logged in with entity id 244232 at ([world] 238.30000001192093, 65.0, 254.81608863562326) +2020-08-08 22:06:04 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-08 23:52:57 [INFO] LAX1DUDE[/127.0.0.1:63739] logged in with entity id 244667 at ([world] 256.16189849834643, 92.54055220768377, 214.53401369267715) +2020-08-08 23:53:04 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 00:07:29 [INFO] LAX1DUDE[/127.0.0.1:63778] logged in with entity id 244778 at ([world] 253.16028408295384, 92.54055220768377, 207.96808225652808) +2020-08-09 00:09:43 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 00:10:02 [INFO] LAX1DUDE[/127.0.0.1:63788] logged in with entity id 244945 at ([world] 287.05431206732555, 66.0, 187.36111267633459) +2020-08-09 00:10:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 00:12:17 [INFO] LAX1DUDE[/127.0.0.1:63798] logged in with entity id 245052 at ([world] 285.1092252548809, 66.0, 191.24397041944798) +2020-08-09 00:12:24 [INFO] LAX1DUDE issued server command: /time set day +2020-08-09 00:12:24 [INFO] LAX1DUDE: Set time to 0 +2020-08-09 00:12:39 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 00:30:12 [INFO] LAX1DUDE[/127.0.0.1:63849] logged in with entity id 245158 at ([world] 284.72416121267696, 66.0, 184.30848284190546) +2020-08-09 00:30:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 00:35:13 [INFO] LAX1DUDE[/127.0.0.1:63868] logged in with entity id 245267 at ([world] 285.3295044078477, 66.0, 185.33871741305865) +2020-08-09 00:35:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 00:54:31 [INFO] LAX1DUDE[/127.0.0.1:63910] logged in with entity id 245375 at ([world] 281.4378402028089, 66.0, 191.9804272987632) +2020-08-09 00:55:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 00:56:30 [INFO] LAX1DUDE[/127.0.0.1:63920] logged in with entity id 245587 at ([world] 211.10088316688902, 63.75995886213549, 165.10887754878786) +2020-08-09 00:58:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 01:04:33 [INFO] LAX1DUDE[/127.0.0.1:63940] logged in with entity id 245805 at ([world] 179.52413530598423, 63.44345009723961, 188.32922294612564) +2020-08-09 01:04:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 01:09:31 [INFO] LAX1DUDE[/127.0.0.1:63961] logged in with entity id 245888 at ([world] 187.7129589150497, 63.0, 182.01168500196462) +2020-08-09 01:09:45 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 01:10:20 [INFO] LAX1DUDE[/127.0.0.1:63966] logged in with entity id 245972 at ([world] 188.95941189380522, 63.0, 181.7946955967681) +2020-08-09 01:10:36 [INFO] LAX1DUDE issued server command: /time set day +2020-08-09 01:10:36 [INFO] LAX1DUDE: Set time to 0 +2020-08-09 01:10:47 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 01:12:31 [INFO] LAX1DUDE[/127.0.0.1:63974] logged in with entity id 246067 at ([world] 184.2141551172021, 63.0, 193.69999998807907) +2020-08-09 01:12:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 01:19:31 [INFO] LAX1DUDE[/127.0.0.1:64010] logged in with entity id 246148 at ([world] 186.4154520095141, 64.0, 192.4592464497026) +2020-08-09 01:20:42 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 01:23:14 [INFO] LAX1DUDE[/127.0.0.1:64027] logged in with entity id 246362 at ([world] 194.03775603593866, 51.0, 189.52075329825115) +2020-08-09 01:24:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 01:27:35 [INFO] LAX1DUDE[/127.0.0.1:64041] logged in with entity id 246514 at ([world] 261.7463456274631, 72.0, 203.98393766885349) +2020-08-09 01:27:49 [INFO] LAX1DUDE issued server command: /time set day +2020-08-09 01:27:49 [INFO] LAX1DUDE: Set time to 0 +2020-08-09 01:27:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 01:29:13 [INFO] LAX1DUDE[/127.0.0.1:64050] logged in with entity id 246619 at ([world] 272.08365362060096, 69.1116330269739, 196.30645537085414) +2020-08-09 01:30:01 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 01:30:31 [INFO] LAX1DUDE[/127.0.0.1:64057] logged in with entity id 246725 at ([world] 264.0667149120474, 72.0, 207.69999998807907) +2020-08-09 01:30:52 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 01:31:25 [INFO] LAX1DUDE[/127.0.0.1:64062] logged in with entity id 246820 at ([world] 246.63442731811148, 72.0, 185.67527265363896) +2020-08-09 01:48:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 01:52:11 [INFO] LAX1DUDE[/127.0.0.1:64104] logged in with entity id 249406 at ([world] 223.90886004692936, 63.0, 75.70231827045916) +2020-08-09 01:52:18 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 01:52:42 [INFO] LAX1DUDE[/127.0.0.1:64110] logged in with entity id 249555 at ([world] 224.76323288641242, 63.0, 72.697629190668) +2020-08-09 01:54:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 01:54:51 [INFO] LAX1DUDE[/127.0.0.1:64117] logged in with entity id 249805 at ([world] 220.81828994560422, 63.0, 66.87929837719894) +2020-08-09 01:55:40 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 01:57:05 [INFO] LAX1DUDE[/127.0.0.1:64130] logged in with entity id 250238 at ([world] 257.197015563033, 73.0, 100.18890997932714) +2020-08-09 01:58:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 01:58:34 [INFO] LAX1DUDE[/127.0.0.1:64134] logged in with entity id 250823 at ([world] 176.0648756812988, 82.44003040000526, 103.1182927511483) +2020-08-09 02:04:23 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 02:06:16 [INFO] LAX1DUDE[/127.0.0.1:64155] logged in with entity id 251867 at ([world] 357.7137838057839, 64.0, 335.51721674235296) +2020-08-09 02:14:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 02:23:54 [INFO] LAX1DUDE[/127.0.0.1:64193] logged in with entity id 252666 at ([world] 222.18232156602346, 76.0, 244.4858357110925) +2020-08-09 02:24:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 02:24:44 [INFO] LAX1DUDE[/127.0.0.1:64199] logged in with entity id 252759 at ([world] 224.9331232210319, 75.0, 247.96612348477618) +2020-08-09 02:36:08 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 02:39:49 [INFO] LAX1DUDE[/127.0.0.1:64232] logged in with entity id 254455 at ([world] 119.4241554912081, 62.0, 394.69999998807907) +2020-08-09 02:55:55 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 03:15:59 [INFO] LAX1DUDE[/127.0.0.1:64295] logged in with entity id 256941 at ([world] 653.609130730518, 12.0, 829.1366406973563) +2020-08-09 03:17:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-09 03:17:19 [INFO] LAX1DUDE[/127.0.0.1:64301] logged in with entity id 257042 at ([world] 653.609130730518, 12.0, 829.1366406973563) +2020-08-09 03:18:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 00:02:19 [INFO] LAX1DUDE[/127.0.0.1:51599] logged in with entity id 257198 at ([world] 653.609130730518, 12.0, 829.1366406973563) +2020-08-10 00:02:32 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 00:06:53 [INFO] LAX1DUDE[/127.0.0.1:51613] logged in with entity id 257295 at ([world] 653.609130730518, 12.0, 829.1366406973563) +2020-08-10 00:07:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 00:31:28 [INFO] LAX1DUDE[/127.0.0.1:51681] logged in with entity id 257395 at ([world] 652.3570328940541, 77.52805215402397, 826.5760600769839) +2020-08-10 00:32:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 00:42:43 [INFO] LAX1DUDE[/127.0.0.1:51705] logged in with entity id 257555 at ([world] 678.1898825516447, 85.61455591034863, 844.3240685562839) +2020-08-10 00:43:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 00:46:58 [INFO] LAX1DUDE[/127.0.0.1:51718] logged in with entity id 257827 at ([world] 661.9018648641578, 89.56150955231057, 854.3315904829951) +2020-08-10 00:47:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 00:57:10 [INFO] LAX1DUDE[/127.0.0.1:51735] logged in with entity id 257937 at ([world] 661.9018648641578, 89.56150955231057, 854.3315904829951) +2020-08-10 00:57:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 00:58:08 [INFO] LAX1DUDE[/127.0.0.1:51739] logged in with entity id 258047 at ([world] 661.9018648641578, 89.56150955231057, 854.3315904829951) +2020-08-10 00:58:40 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 01:02:59 [INFO] LAX1DUDE[/127.0.0.1:51750] logged in with entity id 258172 at ([world] 649.1503411106457, 131.1647165347106, 852.7727298444524) +2020-08-10 01:03:09 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 01:16:30 [INFO] LAX1DUDE[/127.0.0.1:51781] logged in with entity id 258319 at ([world] 630.8143411070544, 73.28135211299187, 821.0294659598766) +2020-08-10 01:16:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 01:17:16 [INFO] LAX1DUDE[/127.0.0.1:51785] logged in with entity id 258440 at ([world] 672.6263238339802, 50.200000047683716, 787.3334424116183) +2020-08-10 01:18:04 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 02:03:01 [INFO] LAX1DUDE[/127.0.0.1:51855] logged in with entity id 258666 at ([world] 695.8981863538303, 74.15383663523454, 773.5676865194564) +2020-08-10 02:04:08 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 02:04:15 [INFO] LAX1DUDE[/127.0.0.1:51860] logged in with entity id 258882 at ([world] 731.7179626473226, 63.0, 787.9507528077247) +2020-08-10 02:04:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 02:12:45 [INFO] LAX1DUDE[/127.0.0.1:51978] logged in with entity id 259016 at ([world] 715.5902383635413, 63.0, 789.3078940619068) +2020-08-10 02:15:59 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 02:16:32 [INFO] LAX1DUDE[/127.0.0.1:51991] logged in with entity id 259530 at ([world] 721.4725106327286, 63.0, 798.2212744881909) +2020-08-10 02:23:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 02:23:34 [INFO] LAX1DUDE[/127.0.0.1:52007] logged in with entity id 261049 at ([world] 803.7653539092044, 71.0, 759.4344611114036) +2020-08-10 02:25:05 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 02:36:09 [INFO] LAX1DUDE[/127.0.0.1:52361] logged in with entity id 262084 at ([world] 1106.2146206852408, 70.8155566499162, 852.7245388543929) +2020-08-10 02:36:15 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-10 02:36:15 [INFO] LAX1DUDE: Changed weather to clear for 398 seconds. +2020-08-10 02:38:09 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 02:38:18 [INFO] LAX1DUDE[/127.0.0.1:52367] logged in with entity id 262456 at ([world] 1096.8535861305343, 63.0, 851.3892596043255) +2020-08-10 02:45:16 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 03:26:20 [INFO] LAX1DUDE[/127.0.0.1:52481] logged in with entity id 267789 at ([world] 1026.2819102235503, 97.88978779514534, 1117.607285218142) +2020-08-10 03:26:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 03:27:44 [INFO] LAX1DUDE[/127.0.0.1:52487] logged in with entity id 268120 at ([world] 1021.0301319000534, 77.0, 1098.151371052719) +2020-08-10 03:27:56 [INFO] LAX1DUDE issued server command: /time set day +2020-08-10 03:27:56 [INFO] LAX1DUDE: Set time to 0 +2020-08-10 03:28:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 03:34:48 [INFO] LAX1DUDE[/127.0.0.1:52505] logged in with entity id 268593 at ([world] 990.6733317506362, 77.0, 1106.9796271527646) +2020-08-10 03:35:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 03:41:02 [INFO] LAX1DUDE[/127.0.0.1:52518] logged in with entity id 268881 at ([world] 1007.1967306204663, 78.0, 1102.4492201481821) +2020-08-10 03:41:16 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 03:45:42 [INFO] LAX1DUDE[/127.0.0.1:52531] logged in with entity id 269168 at ([world] 976.2629149621931, 77.0, 1109.0243745670361) +2020-08-10 03:45:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-10 03:52:28 [INFO] LAX1DUDE[/127.0.0.1:52542] logged in with entity id 269413 at ([world] 976.2629149621931, 77.0, 1109.0243745670361) +2020-08-10 04:01:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-12 03:44:10 [INFO] LAX1DUDE[/127.0.0.1:60166] logged in with entity id 273586 at ([world] 856.0403459516394, 100.0, 1034.8070132287692) +2020-08-12 03:45:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-12 19:29:13 [INFO] LAX1DUDE[/127.0.0.1:65533] logged in with entity id 274726 at ([world] 987.1849637834437, 90.79055212721747, 901.6314696260416) +2020-08-12 20:08:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-12 21:42:30 [INFO] LAX1DUDE[/127.0.0.1:56273] logged in with entity id 285039 at ([world] 634.0759615354323, 78.0, 1047.674346590763) +2020-08-12 21:45:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-12 21:47:21 [INFO] LAX1DUDE[/127.0.0.1:56651] logged in with entity id 286076 at ([world] 759.4104416902381, 75.89044745325997, 891.592615925459) +2020-08-12 21:49:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-12 21:52:42 [INFO] LAX1DUDE[/127.0.0.1:57067] logged in with entity id 286661 at ([world] 770.6961134893002, 66.0, 875.4506305198655) +2020-08-12 22:02:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-12 22:05:41 [INFO] LAX1DUDE[/127.0.0.1:58207] logged in with entity id 287607 at ([world] 736.9362440033162, 77.08048324646101, 928.842683740088) +2020-08-12 22:05:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-12 22:06:19 [INFO] LAX1DUDE[/127.0.0.1:58243] logged in with entity id 287801 at ([world] 735.5367774725363, 80.0, 918.9681165665312) +2020-08-12 22:06:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-12 22:09:26 [INFO] LAX1DUDE[/127.0.0.1:58483] logged in with entity id 288266 at ([world] 759.8911048622252, 74.40585301918797, 832.7884247035716) +2020-08-12 22:09:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-12 22:10:47 [INFO] LAX1DUDE[/127.0.0.1:58564] logged in with entity id 288487 at ([world] 801.3823498265618, 91.963703242352, 813.8681179615187) +2020-08-12 22:23:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-12 22:25:01 [INFO] LAX1DUDE[/127.0.0.1:59624] logged in with entity id 291374 at ([world] 866.6547895263402, 67.0, 812.061414560846) +2020-08-12 22:26:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-12 22:26:48 [INFO] LAX1DUDE[/127.0.0.1:59742] logged in with entity id 291692 at ([world] 871.8715301640907, 67.0, 812.8952983639552) +2020-08-12 22:28:09 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-12 22:36:28 [INFO] LAX1DUDE[/127.0.0.1:60437] logged in with entity id 291968 at ([world] 887.7679317972271, 77.9972799084176, 814.550564972136) +2020-08-12 22:50:50 [INFO] LAX1DUDE issued server command: /kill +2020-08-12 22:50:50 [INFO] LAX1DUDE died +2020-08-12 23:38:01 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-13 00:56:27 [INFO] LAX1DUDE[/127.0.0.1:54305] logged in with entity id 295389 at ([world] 42.76851812256518, 77.0, 254.61542703355647) +2020-08-13 01:18:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-13 01:19:14 [INFO] LAX1DUDE[/127.0.0.1:55490] logged in with entity id 296773 at ([world] 42.84964848339599, 84.49727989255196, 127.42144301850047) +2020-08-13 01:19:26 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-13 01:19:33 [INFO] LAX1DUDE[/127.0.0.1:55512] logged in with entity id 296833 at ([world] 45.7814218116181, 70.0, 133.05867229167566) +2020-08-13 01:20:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-14 13:46:51 [INFO] YeeYee61[/127.0.0.1:60888] logged in with entity id 297078 at ([world] 41.5, 72.0, 257.5) +2020-08-14 13:50:12 [INFO] YeeYee61 lost connection: disconnect.quitting +2020-08-14 13:50:15 [INFO] YeeYee61[/127.0.0.1:60896] logged in with entity id 297611 at ([world] 21.185708798595343, 64.0, 258.69999998807907) +2020-08-14 13:53:34 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-14 13:53:34 [INFO] YeeYee61 lost connection: disconnect.genericReason +2020-08-14 14:16:32 [INFO] YeeDarvig55[/127.0.0.1:61758] logged in with entity id 297777 at ([world] 46.5, 72.0, 247.5) +2020-08-14 14:18:11 [INFO] YeeDarvig55 lost connection: disconnect.quitting +2020-08-14 14:20:21 [INFO] ViggFudgler33[/127.0.0.1:61954] logged in with entity id 297850 at ([world] 44.5, 76.0, 254.5) +2020-08-14 14:20:51 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-14 14:20:51 [INFO] ViggFudgler33 lost connection: disconnect.genericReason +2020-08-14 14:24:30 [INFO] DeevFudgli32[/127.0.0.1:62168] logged in with entity id 297899 at ([world] 33.5, 74.0, 244.5) +2020-08-14 14:25:00 [INFO] DeevFudgli32 lost connection: disconnect.quitting +2020-08-14 14:30:02 [INFO] ViggDarver83[/127.0.0.1:62451] logged in with entity id 297946 at ([world] 49.5, 72.0, 254.5) +2020-08-14 14:31:48 [INFO] ViggDarver83 lost connection: disconnect.quitting +2020-08-14 14:36:28 [INFO] LAX1DUDE[/127.0.0.1:62780] logged in with entity id 298118 at ([world] 60.47024783519306, 78.0, 169.3456823139804) +2020-08-14 14:36:33 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-14 14:47:43 [INFO] LAX1DUDE[/127.0.0.1:63357] logged in with entity id 298273 at ([world] 60.47024783519306, 78.0, 169.3456823139804) +2020-08-14 14:47:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-14 14:51:15 [INFO] ChadDarvy55[/127.0.0.1:63555] logged in with entity id 298347 at ([world] 33.5, 71.0, 261.5) +2020-08-14 14:51:21 [INFO] ChadDarvy55 lost connection: disconnect.quitting +2020-08-14 14:53:58 [INFO] DarvyChode72[/127.0.0.1:63711] logged in with entity id 298559 at ([world] 45.5, 74.0, 258.5) +2020-08-14 14:54:05 [INFO] DarvyChode72 lost connection: disconnect.quitting +2020-08-14 14:57:05 [INFO] LAX1DUDE[/127.0.0.1:63870] logged in with entity id 298596 at ([world] 65.87444892525411, 71.0, 181.87702961810814) +2020-08-14 14:57:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-14 15:00:47 [INFO] YeetDumpster49[/127.0.0.1:64073] logged in with entity id 298678 at ([world] 45.5, 72.0, 245.5) +2020-08-14 15:01:05 [INFO] YeetDumpster49 lost connection: disconnect.quitting +2020-08-14 15:06:48 [INFO] FudglerFudgler60[/127.0.0.1:64440] logged in with entity id 298755 at ([world] 39.5, 72.0, 258.5) +2020-08-14 15:14:20 [INFO] FudglerFudgler60 lost connection: disconnect.quitting +2020-08-14 15:27:46 [INFO] FlumpterEagler59[/127.0.0.1:49273] logged in with entity id 299372 at ([world] 41.5, 73.0, 248.5) +2020-08-14 15:30:05 [INFO] FlumpterEagler59 lost connection: disconnect.quitting +2020-08-14 15:30:25 [INFO] YeeYeet79[/127.0.0.1:49613] logged in with entity id 299650 at ([world] 36.5, 64.0, 255.5) +2020-08-14 15:38:26 [INFO] YeeYeet79 lost connection: disconnect.quitting +2020-08-14 15:57:44 [INFO] DeevisVigg23[/127.0.0.1:51109] logged in with entity id 303619 at ([world] 33.5, 64.0, 253.5) +2020-08-14 15:59:54 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-14 15:59:54 [INFO] DeevisVigg23 lost connection: disconnect.genericReason +2020-08-14 16:04:43 [INFO] LAX1DUDE[/127.0.0.1:51467] logged in with entity id 303815 at ([world] 63.59912922088097, 67.10634309830826, 188.69999998807907) +2020-08-14 16:13:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-14 16:18:44 [INFO] DeevFudgler18[/127.0.0.1:52167] logged in with entity id 304914 at ([world] 46.5, 72.0, 255.5) +2020-08-14 16:23:15 [INFO] DeevFudgler18 lost connection: disconnect.quitting +2020-08-14 17:10:17 [INFO] DeevFudgler18[/127.0.0.1:55063] logged in with entity id 305431 at ([world] 85.3763623829428, 84.79373923493608, 129.35509045904809) +2020-08-14 17:12:46 [INFO] LAX1DUDE[/127.0.0.1:55192] logged in with entity id 305635 at ([world] 85.31927189281339, 71.0, 208.19781730656584) +2020-08-14 17:14:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-14 17:15:11 [INFO] LAX1DUDE[/127.0.0.1:55317] logged in with entity id 305947 at ([world] 79.9655755989016, 80.98935601251729, 207.65179490367655) +2020-08-14 17:15:16 [INFO] LAX1DUDE issued server command: /tp DeevFudgler18 +2020-08-14 17:15:16 [INFO] LAX1DUDE: Teleported LAX1DUDE to DeevFudgler18 +2020-08-14 17:16:02 [INFO] DeevFudgler18 lost connection: disconnect.quitting +2020-08-14 17:16:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-14 18:16:40 [INFO] DeevFudgler18[/127.0.0.1:59400] logged in with entity id 306057 at ([world] 24.49918234466354, 72.0, 128.66967086188504) +2020-08-14 18:17:45 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-14 18:17:45 [INFO] DeevFudgler18 lost connection: disconnect.genericReason +2020-08-14 18:30:42 [INFO] Starting minecraft server version 1.5.2 +2020-08-14 18:30:42 [WARNING] To start the server with more ram, launch it as "java -Xmx1024M -Xms1024M -jar minecraft_server.jar" +2020-08-14 18:30:42 [INFO] Loading properties +2020-08-14 18:30:42 [INFO] Default game type: CREATIVE +2020-08-14 18:30:43 [INFO] This server is running CraftBukkit version git-Spigot-959 (MC: 1.5.2) (Implementing API version 1.5.2-R1.1-SNAPSHOT) +2020-08-14 18:30:43 [INFO] Generating keypair +2020-08-14 18:30:43 [INFO] Starting listener #0 on *:25501 +2020-08-14 18:30:44 [WARNING] **** SERVER IS RUNNING IN OFFLINE/INSECURE MODE! +2020-08-14 18:30:44 [WARNING] The server will make no attempt to authenticate usernames. Beware. +2020-08-14 18:30:44 [WARNING] 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. +2020-08-14 18:30:44 [WARNING] To change this, set "online-mode" to "true" in the server.properties file. +2020-08-14 18:30:44 [INFO] Preparing level "world" +2020-08-14 18:30:44 [INFO] -------- World Settings For [world] -------- +2020-08-14 18:30:44 [INFO] Item Merge Radius: 2.5 +2020-08-14 18:30:44 [INFO] View Distance: 10 +2020-08-14 18:30:44 [INFO] Chunks to Grow per Tick: 650 +2020-08-14 18:30:44 [INFO] Experience Merge Radius: 3.0 +2020-08-14 18:30:44 [INFO] Mob Spawn Range: 4 +2020-08-14 18:30:44 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-08-14 18:30:44 [INFO] Anti X-Ray: true +2020-08-14 18:30:44 [INFO] Engine Mode: 1 +2020-08-14 18:30:44 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-08-14 18:30:44 [INFO] Cactus Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Cane Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Melon Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Mushroom Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Pumpkin Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Sapling Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Wheat Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-08-14 18:30:44 [INFO] Random Lighting Updates: false +2020-08-14 18:30:44 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-08-14 18:30:44 [INFO] -------- World Settings For [world_nether] -------- +2020-08-14 18:30:44 [INFO] Item Merge Radius: 2.5 +2020-08-14 18:30:44 [INFO] View Distance: 10 +2020-08-14 18:30:44 [INFO] Chunks to Grow per Tick: 650 +2020-08-14 18:30:44 [INFO] Experience Merge Radius: 3.0 +2020-08-14 18:30:44 [INFO] Mob Spawn Range: 4 +2020-08-14 18:30:44 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-08-14 18:30:44 [INFO] Anti X-Ray: true +2020-08-14 18:30:44 [INFO] Engine Mode: 1 +2020-08-14 18:30:44 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-08-14 18:30:44 [INFO] Cactus Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Cane Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Melon Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Mushroom Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Pumpkin Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Sapling Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Wheat Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-08-14 18:30:44 [INFO] Random Lighting Updates: false +2020-08-14 18:30:44 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-08-14 18:30:44 [INFO] -------- World Settings For [world_the_end] -------- +2020-08-14 18:30:44 [INFO] Item Merge Radius: 2.5 +2020-08-14 18:30:44 [INFO] View Distance: 10 +2020-08-14 18:30:44 [INFO] Chunks to Grow per Tick: 650 +2020-08-14 18:30:44 [INFO] Experience Merge Radius: 3.0 +2020-08-14 18:30:44 [INFO] Mob Spawn Range: 4 +2020-08-14 18:30:44 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-08-14 18:30:44 [INFO] Anti X-Ray: true +2020-08-14 18:30:44 [INFO] Engine Mode: 1 +2020-08-14 18:30:44 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-08-14 18:30:44 [INFO] Cactus Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Cane Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Melon Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Mushroom Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Pumpkin Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Sapling Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Wheat Growth Modifier: 100% +2020-08-14 18:30:44 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-08-14 18:30:44 [INFO] Random Lighting Updates: false +2020-08-14 18:30:44 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-08-14 18:30:44 [INFO] Preparing start region for level 0 (Seed: 5274138452079716158) +2020-08-14 18:30:45 [INFO] Preparing spawn area: 20% +2020-08-14 18:30:46 [INFO] Preparing start region for level 1 (Seed: 5274138452079716158) +2020-08-14 18:30:46 [INFO] Preparing spawn area: 49% +2020-08-14 18:30:47 [INFO] Preparing start region for level 2 (Seed: 5274138452079716158) +2020-08-14 18:30:47 [INFO] Server permissions file permissions.yml is empty, ignoring it +2020-08-14 18:30:47 [INFO] Done (3.171s)! For help, type "help" or "?" +2020-08-14 18:31:07 [INFO] DeevVigg69[/127.0.0.1:54284] logged in with entity id 978 at ([world] 234.5, 75.0, 255.5) +2020-08-14 18:32:01 [INFO] DeevVigg69 lost connection: disconnect.quitting +2020-08-15 16:57:34 [INFO] DarverFlumpter58[/127.0.0.1:59276] logged in with entity id 1939 at ([world] 231.5, 74.0, 256.5) +2020-08-15 16:58:39 [INFO] DarverFlumpter58 lost connection: disconnect.quitting +2020-08-15 16:58:41 [INFO] DarverFlumpter58[/127.0.0.1:59280] logged in with entity id 2353 at ([world] 263.5269896087231, 66.0, 293.7949604606663) +2020-08-15 17:00:25 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-15 17:00:25 [INFO] DarverFlumpter58 lost connection: disconnect.genericReason +2020-08-15 17:19:28 [INFO] EaglerDarver31[/127.0.0.1:60197] logged in with entity id 3060 at ([world] 230.5, 75.0, 248.5) +2020-08-15 17:21:13 [INFO] EaglerDarver31 lost connection: disconnect.quitting +2020-08-15 18:39:48 [INFO] EaglerDarver77[/127.0.0.1:64432] logged in with entity id 3352 at ([world] 222.5, 72.0, 260.5) +2020-08-15 18:40:06 [INFO] EaglerDarver77 lost connection: disconnect.quitting +2020-08-15 18:59:32 [INFO] LAX1DUDE[/127.0.0.1:65410] logged in with entity id 3432 at ([world] 22.57614972495638, 72.0, 128.2951730339671) +2020-08-15 19:00:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-15 19:03:43 [INFO] LAX1DUDE[/127.0.0.1:49247] logged in with entity id 4169 at ([world] 25.288661744041512, 74.2844664004314, 168.71752695931985) +2020-08-15 19:06:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-15 19:07:23 [INFO] LAX1DUDE[/127.0.0.1:49433] logged in with entity id 4681 at ([world] 59.858036298245246, 87.0, 148.23956553539355) +2020-08-15 19:07:32 [INFO] LAX1DUDE issued server command: /time set day +2020-08-15 19:07:32 [INFO] LAX1DUDE: Set time to 0 +2020-08-15 19:08:41 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-15 19:09:17 [INFO] LAX1DUDE[/127.0.0.1:49531] logged in with entity id 5336 at ([world] 178.94609344868277, 105.13323012004095, 156.27643639044385) +2020-08-15 19:15:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-15 19:16:12 [INFO] LAX1DUDE[/127.0.0.1:49882] logged in with entity id 5584 at ([world] 120.63220479997591, 67.43931267303535, 192.23704230719576) +2020-08-15 19:16:18 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-15 20:00:29 [INFO] LAX1DUDE[/127.0.0.1:52103] logged in with entity id 5688 at ([world] 120.63220479997591, 63.0, 192.23704230719576) +2020-08-15 20:00:37 [INFO] LAX1DUDE issued server command: /time set day +2020-08-15 20:00:37 [INFO] LAX1DUDE: Set time to 0 +2020-08-15 20:02:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-15 20:10:28 [INFO] ChadYee79[/127.0.0.1:52615] logged in with entity id 6414 at ([world] 219.5, 75.0, 251.5) +2020-08-15 20:23:38 [INFO] ChadYee79 lost connection: disconnect.quitting +2020-08-15 20:23:58 [INFO] DumpsterDeev29[/127.0.0.1:53293] logged in with entity id 7313 at ([world] 234.5, 73.0, 260.5) +2020-08-15 20:26:07 [INFO] DumpsterDeev29 lost connection: disconnect.quitting +2020-08-15 20:26:24 [INFO] DarvyVigg5[/127.0.0.1:53423] logged in with entity id 7472 at ([world] 226.5, 75.0, 243.5) +2020-08-15 20:36:20 [INFO] DarvyVigg5 lost connection: disconnect.quitting +2020-08-15 20:36:38 [INFO] DeevisFlumpter43[/127.0.0.1:53467] logged in with entity id 7784 at ([world] 231.5, 75.0, 250.5) +2020-08-15 20:39:45 [INFO] DeevisFlumpter43 lost connection: disconnect.quitting +2020-08-15 20:40:08 [INFO] DarvyChode90[/127.0.0.1:53491] logged in with entity id 7927 at ([world] 233.5, 75.0, 248.5) +2020-08-15 20:40:40 [INFO] DarvyChode90 lost connection: disconnect.quitting +2020-08-15 20:46:04 [INFO] FudgliDeev6[/127.0.0.1:53548] logged in with entity id 8026 at ([world] 226.5, 75.0, 249.5) +2020-08-15 20:46:21 [INFO] FudgliDeev6 lost connection: disconnect.quitting +2020-08-15 20:50:02 [INFO] DarvigFudgler7[/127.0.0.1:53562] logged in with entity id 8138 at ([world] 234.5, 76.0, 250.5) +2020-08-15 20:50:32 [INFO] DarvigFudgler7 lost connection: disconnect.quitting +2020-08-15 20:52:13 [INFO] FudgliFudgli68[/127.0.0.1:53574] logged in with entity id 8284 at ([world] 221.5, 76.0, 247.5) +2020-08-15 20:54:40 [INFO] FudgliFudgli68 lost connection: disconnect.quitting +2020-08-15 20:54:57 [INFO] EggVigg22[/127.0.0.1:53587] logged in with entity id 8394 at ([world] 229.5, 73.0, 259.5) +2020-08-15 21:05:08 [INFO] EggVigg22 lost connection: disconnect.quitting +2020-08-15 21:05:26 [INFO] DumpsterEag56[/127.0.0.1:53621] logged in with entity id 8719 at ([world] 222.5, 76.0, 244.5) +2020-08-15 21:11:04 [INFO] DumpsterEag56 lost connection: disconnect.quitting +2020-08-15 21:11:28 [INFO] ViggDarvig54[/127.0.0.1:53641] logged in with entity id 9011 at ([world] 234.5, 75.0, 244.5) +2020-08-15 21:21:26 [INFO] ViggDarvig54 lost connection: disconnect.quitting +2020-08-15 21:21:45 [INFO] DeevisYeer42[/127.0.0.1:53677] logged in with entity id 9377 at ([world] 228.5, 75.0, 253.5) +2020-08-15 21:22:44 [INFO] DeevisYeer42 lost connection: disconnect.quitting +2020-08-15 21:23:06 [INFO] ChodeDumpster1[/127.0.0.1:53684] logged in with entity id 9640 at ([world] 223.5, 73.0, 259.5) +2020-08-15 21:25:07 [INFO] ChodeDumpster1 lost connection: disconnect.quitting +2020-08-15 21:27:41 [INFO] DarverDumpster17[/127.0.0.1:53836] logged in with entity id 9842 at ([world] 232.5, 75.0, 253.5) +2020-08-15 21:39:47 [INFO] DarverDumpster17 lost connection: disconnect.quitting +2020-08-15 21:41:03 [INFO] DarverDumpster17[/127.0.0.1:54548] logged in with entity id 10230 at ([world] 223.15858566232984, 82.98935876746026, 245.33608062240504) +2020-08-15 21:41:17 [INFO] DarverDumpster17 lost connection: disconnect.quitting +2020-08-15 21:41:50 [INFO] EggEag75[/127.0.0.1:54591] logged in with entity id 10293 at ([world] 236.5, 75.0, 244.5) +2020-08-15 21:45:58 [INFO] EggEag75 lost connection: disconnect.quitting +2020-08-15 21:46:16 [INFO] DarvigDarver65[/127.0.0.1:54820] logged in with entity id 10637 at ([world] 237.5, 75.0, 255.5) +2020-08-15 21:46:34 [INFO] DarvigDarver65 lost connection: disconnect.quitting +2020-08-15 21:48:19 [INFO] DarvigDarver65[/127.0.0.1:54933] logged in with entity id 10691 at ([world] 237.5, 75.0, 255.5) +2020-08-15 21:49:53 [INFO] DarvigDarver65 lost connection: disconnect.quitting +2020-08-15 21:50:11 [INFO] FudglerYeer47[/127.0.0.1:55040] logged in with entity id 10773 at ([world] 223.5, 76.0, 245.5) +2020-08-16 01:08:54 [INFO] LAX1DUDE[/127.0.0.1:65508] logged in with entity id 16603 at ([world] 40.05519495128386, 67.0, 160.21884460990063) +2020-08-16 01:09:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 01:21:30 [INFO] LAX1DUDE[/127.0.0.1:49802] logged in with entity id 17250 at ([world] 59.09208361581804, 88.0, 143.69357212157598) +2020-08-16 01:24:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 01:24:35 [INFO] LAX1DUDE[/127.0.0.1:49961] logged in with entity id 17567 at ([world] 7.811427449251015, 129.46608864046237, 128.47050084998432) +2020-08-16 01:30:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 01:33:20 [INFO] LAX1DUDE[/127.0.0.1:50442] logged in with entity id 18268 at ([world] 30.2007072569311, 72.0, 107.87586936414819) +2020-08-16 01:33:55 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-16 01:33:55 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-16 01:34:45 [INFO] LAX1DUDE[/127.0.0.1:50516] logged in with entity id 18423 at ([world] 26.28935744291681, 72.0, 109.86317316677338) +2020-08-16 01:36:27 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 01:36:51 [INFO] LAX1DUDE[/127.0.0.1:50622] logged in with entity id 18724 at ([world] 43.57772461608842, 70.0, 111.49642449502647) +2020-08-16 01:38:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 01:38:44 [INFO] FudglerYeer47 lost connection: disconnect.quitting +2020-08-16 02:29:47 [INFO] YeetYeer58[/127.0.0.1:51388] logged in with entity id 18915 at ([world] 218.5, 75.0, 242.5) +2020-08-16 02:34:25 [INFO] YeetYeer58 lost connection: disconnect.quitting +2020-08-16 02:39:41 [INFO] GroonDeev73[/127.0.0.1:51435] logged in with entity id 19508 at ([world] 227.5, 75.0, 243.5) +2020-08-16 02:43:54 [INFO] GroonDeev73 lost connection: disconnect.quitting +2020-08-16 02:45:16 [INFO] GroonDeev73[/127.0.0.1:51447] logged in with entity id 20538 at ([world] 216.82639260642492, 73.97478100179646, 337.77178404635856) +2020-08-16 02:46:21 [INFO] GroonDeev73 lost connection: disconnect.quitting +2020-08-16 02:52:45 [INFO] DarverEag58[/127.0.0.1:51486] logged in with entity id 21107 at ([world] 232.5, 73.0, 259.5) +2020-08-16 02:52:58 [INFO] DarverEag58 lost connection: disconnect.quitting +2020-08-16 02:53:14 [INFO] ChadEgg82[/127.0.0.1:51489] logged in with entity id 21166 at ([world] 224.5, 75.0, 252.5) +2020-08-16 02:55:05 [INFO] ChadEgg82 lost connection: disconnect.quitting +2020-08-16 02:57:51 [INFO] ChodeVigg16[/127.0.0.1:51531] logged in with entity id 21435 at ([world] 222.5, 76.0, 242.5) +2020-08-16 02:58:23 [INFO] ChodeVigg16 lost connection: disconnect.quitting +2020-08-16 03:14:12 [INFO] DarvigDeevis72[/127.0.0.1:52045] logged in with entity id 21630 at ([world] 235.5, 75.0, 245.5) +2020-08-16 03:17:01 [INFO] DarvigDeevis72 lost connection: disconnect.quitting +2020-08-16 03:18:18 [INFO] DarvigDeevis72[/127.0.0.1:52075] logged in with entity id 22147 at ([world] 178.85895427196215, 86.25305219801389, 269.6748565901225) +2020-08-16 03:18:22 [INFO] DarvigDeevis72 lost connection: disconnect.quitting +2020-08-16 03:18:39 [INFO] ChodeVigg58[/127.0.0.1:52081] logged in with entity id 22235 at ([world] 222.5, 76.0, 242.5) +2020-08-16 03:19:58 [INFO] ChodeVigg58 lost connection: disconnect.quitting +2020-08-16 03:20:23 [INFO] DeevisGroon51[/127.0.0.1:52089] logged in with entity id 22469 at ([world] 236.5, 75.0, 257.5) +2020-08-16 03:20:25 [INFO] DeevisGroon51 lost connection: disconnect.quitting +2020-08-16 03:22:03 [INFO] DarverDarvig81[/127.0.0.1:52103] logged in with entity id 22529 at ([world] 237.5, 74.0, 261.5) +2020-08-16 03:27:07 [INFO] DarverDarvig81 lost connection: disconnect.quitting +2020-08-16 03:27:31 [INFO] EagYee87[/127.0.0.1:52124] logged in with entity id 23448 at ([world] 233.5, 75.0, 244.5) +2020-08-16 03:27:34 [INFO] EagYee87 lost connection: disconnect.quitting +2020-08-16 03:28:03 [INFO] DeevDarver9[/127.0.0.1:52127] logged in with entity id 23634 at ([world] 235.5, 75.0, 244.5) +2020-08-16 03:28:06 [INFO] DeevDarver9 lost connection: disconnect.quitting +2020-08-16 03:30:00 [INFO] DeevVigg80[/127.0.0.1:52147] logged in with entity id 23695 at ([world] 225.5, 75.0, 246.5) +2020-08-16 03:33:34 [INFO] DeevVigg80 lost connection: disconnect.quitting +2020-08-16 04:14:47 [INFO] LAX1DUDE[/127.0.0.1:52217] logged in with entity id 24557 at ([world] 21.16583778382393, 72.0, 124.17301827037497) +2020-08-16 04:15:18 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-16 04:15:18 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-16 04:16:54 [INFO] LAX1DUDE[/127.0.0.1:52223] logged in with entity id 24712 at ([world] 21.16583778382393, 72.0, 124.17301827037497) +2020-08-16 04:17:25 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-16 04:17:25 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-16 04:23:49 [INFO] LAX1DUDE[/127.0.0.1:52238] logged in with entity id 24831 at ([world] 21.16583778382393, 72.0, 124.17301827037497) +2020-08-16 04:24:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 04:25:57 [INFO] LAX1DUDE[/127.0.0.1:52245] logged in with entity id 24943 at ([world] 21.16583778382393, 72.0, 124.17301827037497) +2020-08-16 04:26:42 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-16 04:26:42 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-16 04:28:04 [INFO] LAX1DUDE[/127.0.0.1:52258] logged in with entity id 25158 at ([world] 12.582294961156538, 84.21076918374975, 152.7330428416252) +2020-08-16 04:28:34 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-16 04:28:34 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-16 04:32:52 [INFO] LAX1DUDE[/127.0.0.1:52277] logged in with entity id 25295 at ([world] 12.582294961156538, 84.21076918374975, 152.7330428416252) +2020-08-16 04:33:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 04:37:10 [INFO] CumGroon42[/127.0.0.1:52320] logged in with entity id 25485 at ([world] 230.5, 75.0, 245.5) +2020-08-16 04:37:38 [INFO] CumGroon42 lost connection: disconnect.quitting +2020-08-16 04:48:11 [INFO] LAX1DUDE[/127.0.0.1:52360] logged in with entity id 25695 at ([world] 34.513874299738085, 72.0, 114.41774652688733) +2020-08-16 04:50:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 04:52:48 [INFO] EaglerYeet49[/127.0.0.1:52382] logged in with entity id 26262 at ([world] 221.5, 75.0, 248.5) +2020-08-16 04:54:59 [INFO] LAX1DUDE[/127.0.0.1:52389] logged in with entity id 26856 at ([world] -12.369487367509402, 71.0, 126.62525933299194) +2020-08-16 04:55:06 [INFO] LAX1DUDE issued server command: /tp EaglerYeet49 +2020-08-16 04:55:06 [INFO] LAX1DUDE: Teleported LAX1DUDE to EaglerYeet49 +2020-08-16 04:57:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 04:57:36 [INFO] EaglerYeet49 lost connection: disconnect.quitting +2020-08-16 05:05:51 [INFO] FudglerVigg38[/127.0.0.1:52432] logged in with entity id 27070 at ([world] 231.5, 74.0, 256.5) +2020-08-16 05:10:12 [INFO] FudglerVigg38 lost connection: disconnect.quitting +2020-08-16 05:10:47 [INFO] FudglerVigg38[/127.0.0.1:52451] logged in with entity id 29268 at ([world] 260.7887945180213, 91.62873245196546, 200.86974113715976) +2020-08-16 05:17:32 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-16 05:17:32 [INFO] FudglerVigg38 lost connection: disconnect.genericReason +2020-08-16 05:24:03 [INFO] DeevDeev62[/127.0.0.1:52500] logged in with entity id 32017 at ([world] 219.5, 75.0, 253.5) +2020-08-16 05:28:47 [INFO] DeevDeev62 lost connection: disconnect.quitting +2020-08-16 05:34:09 [INFO] LAX1DUDE[/127.0.0.1:52537] logged in with entity id 33773 at ([world] 282.42350162080226, 70.0, 345.545402206334) +2020-08-16 05:34:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 05:37:05 [INFO] EagCum4[/127.0.0.1:52545] logged in with entity id 34126 at ([world] 228.5, 75.0, 243.5) +2020-08-16 05:37:18 [INFO] EagCum4 lost connection: disconnect.quitting +2020-08-16 05:40:28 [INFO] LAX1DUDE[/127.0.0.1:52555] logged in with entity id 34265 at ([world] 289.4344220941207, 94.0, 401.13205414226314) +2020-08-16 05:41:09 [INFO] LAX1DUDE issued server command: /weather rain +2020-08-16 05:41:09 [INFO] LAX1DUDE: Changed weather to rainy for 464 seconds. +2020-08-16 05:41:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 05:46:18 [INFO] LAX1DUDE[/127.0.0.1:52574] logged in with entity id 34478 at ([world] 263.26337554567573, 110.71119985165953, 395.2203031317518) +2020-08-16 05:49:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 05:49:55 [INFO] EagCum4[/127.0.0.1:52587] logged in with entity id 35748 at ([world] 225.71634941238034, 75.0, 241.96312405946418) +2020-08-16 05:50:38 [INFO] CONSOLE: Teleported EagCum4 to 29000000.50, 100.50, 29000000.50 +2020-08-16 05:51:44 [INFO] Please provide a player! +2020-08-16 05:51:55 [INFO] CONSOLE: Teleported EagCum4 to 100000.50, 100.50, 100000.50 +2020-08-16 05:53:21 [INFO] You can only perform this command as a player +2020-08-16 05:53:26 [INFO] You can only perform this command as a player +2020-08-16 05:53:43 [INFO] CONSOLE: Teleported EagCum4 to 255.50, 100.50, 241.50 +2020-08-16 05:55:21 [INFO] EagCum4 lost connection: disconnect.quitting +2020-08-16 15:44:41 [INFO] LAX1DUDE[/127.0.0.1:60651] logged in with entity id 56307 at ([world] 30.44004208320593, 71.62228147028273, 320.203555635068) +2020-08-16 15:45:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 15:50:12 [INFO] YeetDarvig12[/127.0.0.1:60693] logged in with entity id 59467 at ([world] 223.5, 75.0, 249.5) +2020-08-16 15:53:15 [INFO] YeetDarvig12 lost connection: disconnect.quitting +2020-08-16 16:07:09 [INFO] DumpsterVigg93[/127.0.0.1:60821] logged in with entity id 60500 at ([world] 231.5, 75.0, 249.5) +2020-08-16 16:12:50 [INFO] DumpsterVigg93 lost connection: disconnect.quitting +2020-08-16 16:18:02 [INFO] FudglerChad33[/127.0.0.1:60886] logged in with entity id 61054 at ([world] 233.5, 74.0, 257.5) +2020-08-16 16:20:55 [INFO] FudglerChad33 lost connection: disconnect.quitting +2020-08-16 16:21:13 [INFO] CumDeev16[/127.0.0.1:60899] logged in with entity id 61418 at ([world] 237.5, 75.0, 255.5) +2020-08-16 16:34:03 [INFO] CumDeev16 lost connection: disconnect.quitting +2020-08-16 16:40:50 [INFO] CumDeev16[/127.0.0.1:60932] logged in with entity id 63441 at ([world] 356.56263452352044, 80.16702703440265, 573.4978914504727) +2020-08-16 16:42:34 [INFO] CumDeev16 lost connection: disconnect.quitting +2020-08-16 16:44:21 [INFO] LAX1DUDE[/127.0.0.1:60952] logged in with entity id 63916 at ([world] -83.97468864543936, 170.95728632753747, 345.1670528691484) +2020-08-16 16:45:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 16:48:07 [INFO] ChodeYeer47[/127.0.0.1:60966] logged in with entity id 64915 at ([world] 229.5, 75.0, 246.5) +2020-08-16 16:48:37 [INFO] ChodeYeer47 lost connection: disconnect.quitting +2020-08-16 21:55:36 [INFO] LAX1DUDE[/127.0.0.1:63264] logged in with entity id 65558 at ([world] 62.259338954859786, 123.97991079079387, 352.4052669233559) +2020-08-16 21:55:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 22:09:18 [INFO] LAX1DUDE[/127.0.0.1:63667] logged in with entity id 65683 at ([world] 62.259338954859786, 123.97991079079387, 352.4052669233559) +2020-08-16 22:09:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 22:10:13 [INFO] LAX1DUDE[/127.0.0.1:63683] logged in with entity id 65824 at ([world] 64.38582027588501, 70.0, 351.94424029677646) +2020-08-16 22:11:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 22:12:10 [INFO] LAX1DUDE[/127.0.0.1:63708] logged in with entity id 66062 at ([world] 62.474359251939354, 84.0, 337.3576050900423) +2020-08-16 22:12:16 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 22:21:24 [INFO] LAX1DUDE[/127.0.0.1:63898] logged in with entity id 66189 at ([world] 53.043034242604854, 80.0, 344.2030636185753) +2020-08-16 22:21:44 [INFO] LAX1DUDE issued server command: /time set day +2020-08-16 22:21:44 [INFO] LAX1DUDE: Set time to 0 +2020-08-16 22:22:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 22:24:33 [INFO] LAX1DUDE[/127.0.0.1:63980] logged in with entity id 66333 at ([world] 67.26182773438728, 87.19071089511604, 307.97346613873617) +2020-08-16 22:24:46 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 22:26:41 [INFO] LAX1DUDE[/127.0.0.1:64010] logged in with entity id 66447 at ([world] 63.300263022112205, 78.0, 319.76064964148355) +2020-08-16 22:26:43 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 22:29:07 [INFO] LAX1DUDE[/127.0.0.1:64040] logged in with entity id 66559 at ([world] 63.300263022112205, 77.0, 319.76064964148355) +2020-08-16 22:30:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 22:53:17 [INFO] LAX1DUDE[/127.0.0.1:64576] logged in with entity id 66855 at ([world] -35.69999998807907, 82.0, 311.58182581897114) +2020-08-16 22:59:54 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-16 23:08:16 [INFO] YeeEagler76[/127.0.0.1:64728] logged in with entity id 67589 at ([world] 225.5, 75.0, 246.5) +2020-08-16 23:10:13 [INFO] YeeEagler76 lost connection: disconnect.quitting +2020-08-16 23:35:06 [INFO] FudglerEagler14[/127.0.0.1:64772] logged in with entity id 68256 at ([world] 220.5, 76.0, 243.5) +2020-08-16 23:37:07 [INFO] FudglerEagler14 lost connection: disconnect.quitting +2020-08-16 23:39:41 [INFO] FlumpterChode59[/127.0.0.1:64783] logged in with entity id 68768 at ([world] 229.5, 75.0, 242.5) +2020-08-16 23:42:14 [INFO] FlumpterChode59 lost connection: disconnect.quitting +2020-08-16 23:47:29 [INFO] LAX1DUDE[/127.0.0.1:64796] logged in with entity id 70289 at ([world] 153.38679084332205, 79.0, 233.92761736618283) +2020-08-16 23:49:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-17 00:04:17 [INFO] LAX1DUDE[/127.0.0.1:64824] logged in with entity id 71712 at ([world] 103.18214126053022, 82.0, 250.69999998807907) +2020-08-17 00:04:23 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-17 00:09:05 [INFO] LAX1DUDE[/127.0.0.1:64843] logged in with entity id 71826 at ([world] 103.18214126053022, 82.0, 250.69999998807907) +2020-08-17 00:09:09 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-17 03:09:10 [INFO] DeevDarver89[/127.0.0.1:65359] logged in with entity id 71941 at ([world] 232.5, 75.0, 254.5) +2020-08-17 03:10:46 [INFO] DeevDarver89 lost connection: disconnect.quitting +2020-08-17 03:11:17 [INFO] GroonEgg7[/127.0.0.1:65366] logged in with entity id 72237 at ([world] 230.5, 75.0, 254.5) +2020-08-17 03:15:55 [INFO] LAX1DUDE[/127.0.0.1:65375] logged in with entity id 73451 at ([world] 103.18214126053022, 82.0, 250.69999998807907) +2020-08-17 03:16:09 [INFO] GroonEgg7 lost connection: disconnect.quitting +2020-08-17 03:16:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-17 03:16:20 [INFO] LAX1DUDE[/127.0.0.1:65378] logged in with entity id 73565 at ([world] 103.74995221314765, 83.0, 251.581324063466) +2020-08-17 03:16:41 [INFO] YeeYeer35[/127.0.0.1:65384] logged in with entity id 73704 at ([world] 222.5, 74.0, 254.5) +2020-08-17 03:16:51 [INFO] LAX1DUDE issued server command: /tp YeeYeer35 +2020-08-17 03:16:51 [INFO] LAX1DUDE: Teleported LAX1DUDE to YeeYeer35 +2020-08-17 03:16:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-17 03:17:02 [INFO] LAX1DUDE[/127.0.0.1:65387] logged in with entity id 73854 at ([world] 226.96563133702602, 74.0, 256.5018603898749) +2020-08-17 03:18:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-17 03:20:24 [INFO] YeeYeer35 lost connection: disconnect.quitting +2020-08-17 17:38:37 [INFO] DarverFudgler15[/127.0.0.1:50546] logged in with entity id 73959 at ([world] 231.5, 73.0, 242.5) +2020-08-17 17:40:11 [INFO] DarverFudgler15 lost connection: disconnect.quitting +2020-08-17 19:02:04 [INFO] EagDeev32[/127.0.0.1:56938] logged in with entity id 74357 at ([world] 228.5, 73.0, 260.5) +2020-08-17 19:06:27 [INFO] EagDeev32 lost connection: disconnect.quitting +2020-08-17 19:06:56 [INFO] EaglerYee6[/127.0.0.1:56997] logged in with entity id 74662 at ([world] 234.5, 75.0, 248.5) +2020-08-17 19:07:51 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-17 19:07:51 [INFO] EaglerYee6 lost connection: disconnect.genericReason +2020-08-17 19:10:41 [INFO] ViggDumpster19[/127.0.0.1:57036] logged in with entity id 74838 at ([world] 229.5, 74.0, 257.5) +2020-08-17 19:12:33 [INFO] ViggDumpster19 lost connection: disconnect.quitting +2020-08-17 19:12:55 [INFO] DarverCum94[/127.0.0.1:57050] logged in with entity id 74963 at ([world] 231.5, 75.0, 253.5) +2020-08-17 19:14:19 [INFO] DarverCum94 lost connection: disconnect.quitting +2020-08-17 19:16:41 [INFO] EaglerEagler61[/127.0.0.1:57067] logged in with entity id 75144 at ([world] 232.5, 75.0, 254.5) +2020-08-17 19:19:40 [INFO] EaglerEagler61 lost connection: disconnect.quitting +2020-08-17 19:20:01 [INFO] EaglerChode4[/127.0.0.1:57090] logged in with entity id 75374 at ([world] 234.5, 75.0, 244.5) +2020-08-17 19:20:21 [INFO] EaglerChode4 lost connection: disconnect.quitting +2020-08-17 19:21:33 [INFO] YeerYee16[/127.0.0.1:57107] logged in with entity id 75441 at ([world] 230.5, 74.0, 253.5) +2020-08-17 19:25:27 [INFO] YeerYee16 lost connection: disconnect.quitting +2020-08-17 19:25:47 [INFO] DumpsterFudgler0[/127.0.0.1:57129] logged in with entity id 75700 at ([world] 232.5, 75.0, 242.5) +2020-08-17 19:29:47 [INFO] DumpsterFudgler0 lost connection: disconnect.quitting +2020-08-17 19:30:13 [INFO] DarvyChode65[/127.0.0.1:57151] logged in with entity id 76144 at ([world] 231.5, 74.0, 254.5) +2020-08-17 19:33:47 [INFO] DarvyChode65 lost connection: disconnect.quitting +2020-08-17 19:34:05 [INFO] ChadYee12[/127.0.0.1:57185] logged in with entity id 77275 at ([world] 223.5, 73.0, 257.5) +2020-08-17 19:39:00 [INFO] ChadYee12 lost connection: disconnect.quitting +2020-08-17 20:15:02 [INFO] DarverFudgli63_[/127.0.0.1:64688] logged in with entity id 77771 at ([world] 228.5, 73.0, 258.5) +2020-08-17 20:15:15 [INFO] DarverFudgli63_ lost connection: disconnect.quitting +2020-08-17 20:27:10 [INFO] DarverFudgli63_[/127.0.0.1:65347] logged in with entity id 77906 at ([world] 233.69999998807907, 75.0, 251.5068406930772) +2020-08-17 20:33:24 [INFO] DarverFudgli63_ lost connection: disconnect.quitting +2020-08-17 20:33:56 [INFO] LAX1DUDE[/127.0.0.1:49326] logged in with entity id 78891 at ([world] 225.1067961774185, 75.0, 252.51208852736426) +2020-08-17 20:35:10 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-17 20:35:10 [INFO] LAX1DUDE: Changed weather to clear for 672 seconds. +2020-08-17 20:35:45 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-17 20:35:51 [INFO] LAX1DUDE[/127.0.0.1:49426] logged in with entity id 79327 at ([world] 212.32370641749407, 69.0, 311.6762490041205) +2020-08-17 20:36:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-17 20:36:10 [INFO] LAX1DUDE[/127.0.0.1:49446] logged in with entity id 79377 at ([world] 216.23001304350348, 70.0, 299.33746306051495) +2020-08-17 20:56:56 [INFO] LAX1DUDE issued server command: /gamerule keepInventory true +2020-08-17 20:56:56 [INFO] LAX1DUDE: Game rule keepInventory has been set to: true +2020-08-17 21:02:35 [INFO] LAX1DUDE issued server command: /kill +2020-08-17 21:02:35 [INFO] LAX1DUDE died +2020-08-17 21:18:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-17 21:36:18 [INFO] LAX1DUDE[/127.0.0.1:51993] logged in with entity id 87655 at ([world] 353.6999999880791, 72.0, 433.90497544223393) +2020-08-17 21:51:25 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-17 21:51:50 [INFO] YeeEagler95[/127.0.0.1:52030] logged in with entity id 96885 at ([world] 224.5, 72.0, 261.5) +2020-08-17 21:52:26 [INFO] YeeEagler95 lost connection: disconnect.quitting +2020-08-17 21:52:41 [INFO] FlumpterCum23[/127.0.0.1:52034] logged in with entity id 96958 at ([world] 220.5, 75.0, 254.5) +2020-08-17 21:53:19 [INFO] FlumpterCum23 lost connection: disconnect.quitting +2020-08-17 22:00:19 [INFO] EaglerYee10[/127.0.0.1:52126] logged in with entity id 97066 at ([world] 226.5, 74.0, 255.5) +2020-08-17 22:01:15 [INFO] EaglerYee10 lost connection: disconnect.quitting +2020-08-17 22:09:47 [INFO] EagVigg39[/127.0.0.1:52199] logged in with entity id 97209 at ([world] 235.5, 75.0, 245.5) +2020-08-17 22:10:24 [INFO] EagVigg39 lost connection: disconnect.quitting +2020-08-17 22:15:14 [INFO] EggDeev76[/127.0.0.1:52223] logged in with entity id 97422 at ([world] 236.5, 73.0, 261.5) +2020-08-17 22:16:03 [INFO] EggDeev76 lost connection: disconnect.quitting +2020-08-18 01:35:35 [INFO] FudgliEagler97[/127.0.0.1:57034] logged in with entity id 97556 at ([world] 220.5, 75.0, 250.5) +2020-08-18 01:37:26 [INFO] FudgliEagler97 lost connection: disconnect.quitting +2020-08-18 02:54:25 [INFO] YeerDeev12[/127.0.0.1:57438] logged in with entity id 97696 at ([world] 233.5, 73.0, 260.5) +2020-08-18 02:55:05 [INFO] yee[/127.0.0.1:57442] logged in with entity id 97811 at ([world] 229.5, 74.0, 256.5) +2020-08-18 02:55:22 [INFO] yee lost connection: disconnect.quitting +2020-08-18 02:55:47 [INFO] YeerDeev12 lost connection: disconnect.quitting +2020-08-18 03:15:01 [INFO] DumpsterYee20[/127.0.0.1:57570] logged in with entity id 97923 at ([world] 219.5, 73.0, 257.5) +2020-08-18 03:15:57 [INFO] LAX1DUDE[/127.0.0.1:57605] logged in with entity id 97983 at ([world] 260.24517872084573, 65.0, 228.8267738012216) +2020-08-18 03:17:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-18 03:17:24 [INFO] DumpsterYee20 lost connection: disconnect.quitting +2020-08-18 03:21:09 [INFO] LAX1DUDE[/127.0.0.1:57633] logged in with entity id 98037 at ([world] 217.58605757020723, 75.0, 251.58492673336897) +2020-08-18 03:22:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-18 03:46:16 [INFO] LAX1DUDE[/127.0.0.1:57741] logged in with entity id 98210 at ([world] 237.19993364233056, 75.0, 227.31793202412032) +2020-08-18 03:49:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-18 03:49:29 [INFO] LAX1DUDE[/127.0.0.1:57764] logged in with entity id 98400 at ([world] 221.86098920995076, 75.86435618333834, 228.51365405578505) +2020-08-18 03:51:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-18 03:51:11 [INFO] removing player mount +2020-08-18 03:51:24 [INFO] LAX1DUDE[/127.0.0.1:57778] logged in with entity id 98622 at ([world] 236.50999999046326, 73.5499999821186, 228.5) +2020-08-18 03:52:12 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-18 03:52:12 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-18 03:52:12 [INFO] removing player mount +2020-08-18 03:54:16 [INFO] LAX1DUDE[/127.0.0.1:57809] logged in with entity id 98700 at ([world] 215.65923787982427, 73.69999998807907, 228.5) +2020-08-18 03:56:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-18 03:57:35 [INFO] LAX1DUDE[/127.0.0.1:57843] logged in with entity id 98912 at ([world] 236.91357629813862, 75.0, 227.43517065209514) +2020-08-18 04:02:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-18 04:03:07 [INFO] LAX1DUDE[/127.0.0.1:57885] logged in with entity id 99141 at ([world] 214.35580218542037, 74.0, 228.0) +2020-08-18 04:04:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-18 04:05:06 [INFO] LAX1DUDE[/127.0.0.1:57896] logged in with entity id 99294 at ([world] 240.37271145655495, 64.0, 210.8401196703254) +2020-08-18 04:08:01 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-18 14:26:32 [INFO] LAX1DUDE[/127.0.0.1:58943] logged in with entity id 99778 at ([world] 236.29095767565101, 65.125, 203.28433756039) +2020-08-18 14:42:48 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-22 21:22:36 [INFO] Starting minecraft server version 1.5.2 +2020-08-22 21:22:36 [WARNING] To start the server with more ram, launch it as "java -Xmx1024M -Xms1024M -jar minecraft_server.jar" +2020-08-22 21:22:36 [INFO] Loading properties +2020-08-22 21:22:36 [INFO] Default game type: CREATIVE +2020-08-22 21:22:36 [INFO] This server is running CraftBukkit version git-Spigot-959 (MC: 1.5.2) (Implementing API version 1.5.2-R1.1-SNAPSHOT) +2020-08-22 21:22:36 [INFO] Generating keypair +2020-08-22 21:22:37 [INFO] Starting listener #0 on *:25501 +2020-08-22 21:22:38 [WARNING] **** SERVER IS RUNNING IN OFFLINE/INSECURE MODE! +2020-08-22 21:22:38 [WARNING] The server will make no attempt to authenticate usernames. Beware. +2020-08-22 21:22:38 [WARNING] 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. +2020-08-22 21:22:38 [WARNING] To change this, set "online-mode" to "true" in the server.properties file. +2020-08-22 21:22:38 [INFO] Preparing level "world" +2020-08-22 21:22:38 [INFO] -------- World Settings For [world] -------- +2020-08-22 21:22:38 [INFO] Item Merge Radius: 2.5 +2020-08-22 21:22:38 [INFO] View Distance: 10 +2020-08-22 21:22:38 [INFO] Chunks to Grow per Tick: 650 +2020-08-22 21:22:38 [INFO] Experience Merge Radius: 3.0 +2020-08-22 21:22:38 [INFO] Mob Spawn Range: 4 +2020-08-22 21:22:38 [INFO] Cactus Growth Modifier: 100% +2020-08-22 21:22:38 [INFO] Cane Growth Modifier: 100% +2020-08-22 21:22:38 [INFO] Melon Growth Modifier: 100% +2020-08-22 21:22:38 [INFO] Mushroom Growth Modifier: 100% +2020-08-22 21:22:38 [INFO] Pumpkin Growth Modifier: 100% +2020-08-22 21:22:38 [INFO] Sapling Growth Modifier: 100% +2020-08-22 21:22:38 [INFO] Wheat Growth Modifier: 100% +2020-08-22 21:22:38 [INFO] Anti X-Ray: true +2020-08-22 21:22:38 [INFO] Engine Mode: 1 +2020-08-22 21:22:38 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-08-22 21:22:38 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-08-22 21:22:38 [INFO] Random Lighting Updates: false +2020-08-22 21:22:38 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-08-22 21:22:38 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-08-22 21:22:38 [INFO] -------- World Settings For [world_nether] -------- +2020-08-22 21:22:38 [INFO] Item Merge Radius: 2.5 +2020-08-22 21:22:38 [INFO] View Distance: 10 +2020-08-22 21:22:38 [INFO] Chunks to Grow per Tick: 650 +2020-08-22 21:22:38 [INFO] Experience Merge Radius: 3.0 +2020-08-22 21:22:38 [INFO] Mob Spawn Range: 4 +2020-08-22 21:22:38 [INFO] Cactus Growth Modifier: 100% +2020-08-22 21:22:38 [INFO] Cane Growth Modifier: 100% +2020-08-22 21:22:38 [INFO] Melon Growth Modifier: 100% +2020-08-22 21:22:38 [INFO] Mushroom Growth Modifier: 100% +2020-08-22 21:22:38 [INFO] Pumpkin Growth Modifier: 100% +2020-08-22 21:22:38 [INFO] Sapling Growth Modifier: 100% +2020-08-22 21:22:38 [INFO] Wheat Growth Modifier: 100% +2020-08-22 21:22:38 [INFO] Anti X-Ray: true +2020-08-22 21:22:39 [INFO] Engine Mode: 1 +2020-08-22 21:22:39 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-08-22 21:22:39 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-08-22 21:22:39 [INFO] Random Lighting Updates: false +2020-08-22 21:22:39 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-08-22 21:22:39 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-08-22 21:22:39 [INFO] -------- World Settings For [world_the_end] -------- +2020-08-22 21:22:39 [INFO] Item Merge Radius: 2.5 +2020-08-22 21:22:39 [INFO] View Distance: 10 +2020-08-22 21:22:39 [INFO] Chunks to Grow per Tick: 650 +2020-08-22 21:22:39 [INFO] Experience Merge Radius: 3.0 +2020-08-22 21:22:39 [INFO] Mob Spawn Range: 4 +2020-08-22 21:22:39 [INFO] Cactus Growth Modifier: 100% +2020-08-22 21:22:39 [INFO] Cane Growth Modifier: 100% +2020-08-22 21:22:39 [INFO] Melon Growth Modifier: 100% +2020-08-22 21:22:39 [INFO] Mushroom Growth Modifier: 100% +2020-08-22 21:22:39 [INFO] Pumpkin Growth Modifier: 100% +2020-08-22 21:22:39 [INFO] Sapling Growth Modifier: 100% +2020-08-22 21:22:39 [INFO] Wheat Growth Modifier: 100% +2020-08-22 21:22:39 [INFO] Anti X-Ray: true +2020-08-22 21:22:39 [INFO] Engine Mode: 1 +2020-08-22 21:22:39 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-08-22 21:22:39 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-08-22 21:22:39 [INFO] Random Lighting Updates: false +2020-08-22 21:22:39 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-08-22 21:22:39 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-08-22 21:22:39 [INFO] Preparing start region for level 0 (Seed: 7241753816500133348) +2020-08-22 21:22:40 [INFO] Preparing spawn area: 37% +2020-08-22 21:22:41 [INFO] Preparing spawn area: 83% +2020-08-22 21:22:41 [INFO] Preparing start region for level 1 (Seed: 7241753816500133348) +2020-08-22 21:22:41 [INFO] Preparing start region for level 2 (Seed: 7241753816500133348) +2020-08-22 21:22:42 [INFO] Preparing spawn area: 0% +2020-08-22 21:22:42 [INFO] Server permissions file permissions.yml is empty, ignoring it +2020-08-22 21:22:42 [INFO] Done (4.284s)! For help, type "help" or "?" +2020-08-22 21:22:42 [INFO] LAX1DUDE[/127.0.0.1:56427] logged in with entity id 272 at ([world] 253.380702666368, 76.86435596911396, 223.5234041225977) +2020-08-22 21:26:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-23 04:19:47 [INFO] LAX1DUDE[/127.0.0.1:61178] logged in with entity id 2116 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 04:20:13 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-23 04:22:28 [INFO] LAX1DUDE[/127.0.0.1:61199] logged in with entity id 2166 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 04:23:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-23 04:25:07 [INFO] LAX1DUDE_[/127.0.0.1:61237] logged in with entity id 2247 at ([world] 164.5, 70.0, 236.5) +2020-08-23 04:25:48 [INFO] LAX1DUDE_ lost connection: disconnect.quitting +2020-08-23 04:26:03 [INFO] LAX1DUDE__[/127.0.0.1:61246] logged in with entity id 2402 at ([world] 172.5, 88.0, 224.5) +2020-08-23 04:27:35 [INFO] LAX1DUDE__ lost connection: disconnect.genericReason +2020-08-23 04:27:35 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-23 04:29:33 [INFO] LAX1DUDE[/127.0.0.1:61270] logged in with entity id 2504 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 04:30:12 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-23 04:30:12 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-23 04:31:28 [INFO] LAX1DUDE[/127.0.0.1:61306] logged in with entity id 2612 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 04:32:09 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-23 04:32:09 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-23 04:43:19 [INFO] LAX1DUDE[/127.0.0.1:61572] logged in with entity id 2683 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 04:44:05 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-23 04:44:05 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-23 04:48:23 [INFO] LAX1DUDE[/127.0.0.1:61819] logged in with entity id 2761 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 04:49:07 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-23 04:49:07 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-23 05:11:14 [INFO] LAX1DUDE[/127.0.0.1:62105] logged in with entity id 2874 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 05:11:54 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-23 05:11:54 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-23 14:58:30 [INFO] LAX1DUDE[/127.0.0.1:63192] logged in with entity id 2956 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 14:59:12 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-23 14:59:12 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-23 15:55:50 [INFO] LAX1DUDE[/127.0.0.1:63737] logged in with entity id 3032 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 15:56:31 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-23 15:56:31 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-23 16:19:18 [INFO] LAX1DUDE[/127.0.0.1:64109] logged in with entity id 3138 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 16:19:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-23 16:34:43 [INFO] LAX1DUDE[/127.0.0.1:64219] logged in with entity id 3190 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 16:35:28 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-23 16:35:28 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-23 16:51:28 [INFO] LAX1DUDE[/127.0.0.1:64329] logged in with entity id 3306 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 16:52:09 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-23 16:56:59 [INFO] LAX1DUDE[/127.0.0.1:64367] logged in with entity id 3387 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 16:57:30 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-23 16:57:30 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-23 17:11:21 [INFO] LAX1DUDE[/127.0.0.1:64436] logged in with entity id 3427 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 17:11:51 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-23 17:11:51 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-23 20:02:07 [INFO] LAX1DUDE[/127.0.0.1:56948] logged in with entity id 3494 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 20:02:37 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-23 20:02:37 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-23 20:10:35 [INFO] LAX1DUDE[/127.0.0.1:57045] logged in with entity id 3532 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 20:11:06 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-23 20:11:06 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-23 21:08:27 [INFO] LAX1DUDE[/127.0.0.1:57601] logged in with entity id 3593 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 21:08:57 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-23 21:08:57 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-23 21:23:13 [INFO] LAX1DUDE[/127.0.0.1:57649] logged in with entity id 3638 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 21:23:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-23 21:23:56 [INFO] LAX1DUDE[/127.0.0.1:57662] logged in with entity id 3688 at ([world] 244.34775397214688, 98.61742012725202, 211.889554689879) +2020-08-23 21:26:41 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-23 21:35:23 [INFO] LAX1DUDE[/127.0.0.1:57716] logged in with entity id 4035 at ([world] 188.78662615913493, 64.0, 243.07381118736635) +2020-08-23 21:38:03 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-23 22:26:21 [INFO] LAX1DUDE[/127.0.0.1:57851] logged in with entity id 5205 at ([world] 400.7237953497695, 66.0, 414.1113185638011) +2020-08-23 22:34:33 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-23 22:40:36 [INFO] LAX1DUDE[/127.0.0.1:57929] logged in with entity id 7208 at ([world] 290.8183722530016, 71.0, 351.9104695815987) +2020-08-23 22:41:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-23 22:50:35 [INFO] LAX1DUDE[/127.0.0.1:58002] logged in with entity id 7367 at ([world] 291.77576246988275, 71.0, 358.4606254071166) +2020-08-23 22:51:32 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 02:57:39 [INFO] LAX1DUDE[/127.0.0.1:58870] logged in with entity id 7531 at ([world] 300.44086247263806, 108.9893559654544, 366.90742786215935) +2020-08-24 02:58:11 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-24 02:58:11 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-24 02:59:17 [INFO] LAX1DUDE[/127.0.0.1:58877] logged in with entity id 7646 at ([world] 299.4897494959438, 108.9893559654544, 367.4258174545806) +2020-08-24 02:59:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 03:00:00 [INFO] LAX1DUDE[/127.0.0.1:58880] logged in with entity id 7777 at ([world] 294.96320010307136, 88.63235758851732, 326.6508922149812) +2020-08-24 03:00:13 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 03:00:15 [INFO] LAX1DUDE[/127.0.0.1:58883] logged in with entity id 7882 at ([world] 304.6836823186047, 65.0, 302.6049625689285) +2020-08-24 03:07:08 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 03:09:13 [INFO] LAX1DUDE[/127.0.0.1:58903] logged in with entity id 8692 at ([world] 657.8088973361085, 64.0, 791.4079960651819) +2020-08-24 03:12:04 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 03:25:25 [INFO] LAX1DUDE[/127.0.0.1:58944] logged in with entity id 10097 at ([world] 1001.0544939596631, 64.0, 662.4864794634447) +2020-08-24 03:25:41 [INFO] LAX1DUDE issued server command: /kill +2020-08-24 03:25:41 [INFO] LAX1DUDE died +2020-08-24 03:26:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 16:47:55 [INFO] LAX1DUDE[/127.0.0.1:61233] logged in with entity id 11127 at ([world] 368.92361966247614, 63.0, 352.65515316836974) +2020-08-24 16:48:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 16:58:52 [INFO] LAX1DUDE[/127.0.0.1:61334] logged in with entity id 11300 at ([world] 343.31256432185216, 66.0, 379.06251752399254) +2020-08-24 16:59:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 17:00:10 [INFO] LAX1DUDE[/127.0.0.1:61341] logged in with entity id 11454 at ([world] 322.8299034051356, 105.0, 399.65598703185685) +2020-08-24 17:01:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 19:27:08 [INFO] LAX1DUDE[/127.0.0.1:61676] logged in with entity id 11739 at ([world] 319.55136836422645, 70.0, 415.77542849552117) +2020-08-24 19:27:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 19:27:22 [INFO] LAX1DUDE[/127.0.0.1:61679] logged in with entity id 11853 at ([world] 313.084854808739, 69.0, 410.30000001192093) +2020-08-24 19:28:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 19:28:21 [INFO] LAX1DUDE[/127.0.0.1:61683] logged in with entity id 12222 at ([world] 469.0051215298077, 72.49069049819323, 396.96940925510694) +2020-08-24 19:29:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 19:30:22 [INFO] LAX1DUDE[/127.0.0.1:61693] logged in with entity id 12707 at ([world] 309.45855750773615, 70.0, 377.28473445628765) +2020-08-24 19:31:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 19:33:34 [INFO] LAX1DUDE[/127.0.0.1:61706] logged in with entity id 12858 at ([world] 309.45855750773615, 70.0, 377.28473445628765) +2020-08-24 19:33:59 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 19:34:29 [INFO] LAX1DUDE[/127.0.0.1:61711] logged in with entity id 13032 at ([world] 306.9415221227334, 70.0, 377.6892588006891) +2020-08-24 19:34:59 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 19:35:43 [INFO] LAX1DUDE[/127.0.0.1:61719] logged in with entity id 13161 at ([world] 309.92706214280804, 70.0, 374.57077708739814) +2020-08-24 19:36:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 19:36:59 [INFO] LAX1DUDE[/127.0.0.1:61724] logged in with entity id 13675 at ([world] 308.1076612871802, 63.0, 242.61733529490317) +2020-08-24 19:37:54 [INFO] LAX1DUDE issued server command: /kill +2020-08-24 19:37:54 [INFO] LAX1DUDE died +2020-08-24 19:38:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 20:33:58 [INFO] LAX1DUDE[/127.0.0.1:61828] logged in with entity id 14504 at ([world] 304.92212450703016, 70.0, 375.2940145985848) +2020-08-24 20:35:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 20:38:54 [INFO] LAX1DUDE[/127.0.0.1:61844] logged in with entity id 14689 at ([world] 306.23231189426383, 69.0, 380.93997285633804) +2020-08-24 20:40:39 [INFO] LAX1DUDE issued server command: /tp 0 100 0 +2020-08-24 20:40:39 [INFO] LAX1DUDE: Teleported LAX1DUDE to 0.50, 100.50, 0.50 +2020-08-24 20:42:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 20:44:08 [INFO] LAX1DUDE[/127.0.0.1:61862] logged in with entity id 15672 at ([world] 65.85474727031601, 100.9704624604754, 102.44931822762003) +2020-08-24 20:47:54 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-24 20:47:54 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-24 20:48:01 [INFO] LAX1DUDE[/127.0.0.1:61871] logged in with entity id 15838 at ([world] 73.79971673442472, 78.25071840212016, 98.84937072818538) +2020-08-24 20:51:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 21:12:42 [INFO] LAX1DUDE[/127.0.0.1:61921] logged in with entity id 16895 at ([world] 150.00171583807798, 79.0, 187.6999999880791) +2020-08-24 21:13:04 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 21:13:42 [INFO] LAX1DUDE[/127.0.0.1:61925] logged in with entity id 16944 at ([world] 150.00171583807798, 79.0, 187.6999999880791) +2020-08-24 21:14:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 21:14:38 [INFO] LAX1DUDE[/127.0.0.1:61930] logged in with entity id 17025 at ([world] 150.00171583807798, 79.0, 187.6999999880791) +2020-08-24 21:19:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 21:21:00 [INFO] LAX1DUDE[/127.0.0.1:61950] logged in with entity id 17738 at ([world] 241.65631781260964, 72.0, 279.2688185502775) +2020-08-24 21:24:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 21:28:10 [INFO] LAX1DUDE[/127.0.0.1:61971] logged in with entity id 17889 at ([world] 228.04708843677696, 103.98783471785681, 273.82755583580575) +2020-08-24 21:31:46 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 21:32:15 [INFO] LAX1DUDE[/127.0.0.1:61986] logged in with entity id 18444 at ([world] 304.465516877964, 71.0, 366.2557286865526) +2020-08-24 21:39:07 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 21:41:17 [INFO] LAX1DUDE[/127.0.0.1:62011] logged in with entity id 19102 at ([world] 258.69999998807907, 67.48937758587036, 317.30365763114287) +2020-08-24 21:44:26 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 21:44:47 [INFO] LAX1DUDE[/127.0.0.1:62024] logged in with entity id 19253 at ([world] 277.01116885774195, 84.88172032910893, 314.29994407478284) +2020-08-24 21:47:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 21:47:47 [INFO] LAX1DUDE[/127.0.0.1:62032] logged in with entity id 19458 at ([world] 244.39624187120216, 88.9811953492014, 307.8079811181049) +2020-08-24 21:51:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 21:51:18 [INFO] LAX1DUDE[/127.0.0.1:62049] logged in with entity id 19937 at ([world] 240.3267618828973, 75.23935609618474, 328.82293501590044) +2020-08-24 21:52:45 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 21:53:23 [INFO] LAX1DUDE[/127.0.0.1:62059] logged in with entity id 20307 at ([world] 147.47319024676284, 73.23936374880412, 331.9355654920006) +2020-08-24 21:56:41 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 21:58:24 [INFO] LAX1DUDE[/127.0.0.1:62072] logged in with entity id 21770 at ([world] 157.9284998205154, 64.0, 328.9284951819973) +2020-08-24 21:59:39 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:00:12 [INFO] LAX1DUDE[/127.0.0.1:62082] logged in with entity id 22507 at ([world] 84.71893888632385, 89.11419294764805, 272.27175833867784) +2020-08-24 22:00:23 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:01:20 [INFO] LAX1DUDE[/127.0.0.1:62088] logged in with entity id 22583 at ([world] 91.83447830604821, 69.0, 282.7215664695871) +2020-08-24 22:01:32 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:05:17 [INFO] LAX1DUDE[/127.0.0.1:62098] logged in with entity id 22661 at ([world] 122.76025265284132, 97.29971172313708, 287.3227864872885) +2020-08-24 22:08:47 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:09:05 [INFO] LAX1DUDE[/127.0.0.1:62107] logged in with entity id 23007 at ([world] 94.01783155818951, 85.71086908835048, 322.77695114585356) +2020-08-24 22:10:40 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:12:23 [INFO] LAX1DUDE[/127.0.0.1:62119] logged in with entity id 23669 at ([world] 124.4806869104006, 69.0, 354.5179754960296) +2020-08-24 22:12:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:14:21 [INFO] LAX1DUDE[/127.0.0.1:62126] logged in with entity id 23779 at ([world] 76.8631010597962, 75.04300695689565, 305.95392043797415) +2020-08-24 22:30:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:30:32 [INFO] LAX1DUDE[/127.0.0.1:62164] logged in with entity id 25196 at ([world] 148.31021061654545, 63.0, 351.69999998807907) +2020-08-24 22:30:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:31:51 [INFO] LAX1DUDE[/127.0.0.1:62171] logged in with entity id 25291 at ([world] 148.36977369429886, 63.0, 340.43505605738795) +2020-08-24 22:32:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:32:37 [INFO] LAX1DUDE[/127.0.0.1:62176] logged in with entity id 25508 at ([world] 168.09110794474026, 92.4893559654544, 329.6481895523987) +2020-08-24 22:34:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:39:31 [INFO] LAX1DUDE[/127.0.0.1:62198] logged in with entity id 25701 at ([world] 101.37621254600437, 63.0, 305.1890486074996) +2020-08-24 22:40:18 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:41:08 [INFO] LAX1DUDE[/127.0.0.1:62207] logged in with entity id 25807 at ([world] 98.36477538298621, 64.91458975992987, 298.2794788353372) +2020-08-24 22:41:18 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:42:08 [INFO] LAX1DUDE[/127.0.0.1:62214] logged in with entity id 25893 at ([world] 100.49716520435655, 64.36443348999127, 294.3510072548014) +2020-08-24 22:42:33 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:45:56 [INFO] LAX1DUDE[/127.0.0.1:62226] logged in with entity id 25976 at ([world] 102.5271546455782, 65.45765296752599, 296.84603286017835) +2020-08-24 22:46:42 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:48:30 [INFO] LAX1DUDE[/127.0.0.1:62236] logged in with entity id 26098 at ([world] 114.59030242178409, 64.0, 291.98044842582) +2020-08-24 22:49:48 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:51:10 [INFO] LAX1DUDE[/127.0.0.1:62251] logged in with entity id 26235 at ([world] 112.66114878948002, 64.0, 293.0231310208275) +2020-08-24 22:52:12 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:53:28 [INFO] LAX1DUDE[/127.0.0.1:62262] logged in with entity id 26728 at ([world] 107.14641500232986, 93.69817727046708, 277.36590415900486) +2020-08-24 22:53:51 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:54:55 [INFO] LAX1DUDE[/127.0.0.1:62267] logged in with entity id 26806 at ([world] 117.78127115980158, 69.2505303532831, 284.25154204426065) +2020-08-24 22:56:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 22:58:47 [INFO] LAX1DUDE[/127.0.0.1:62279] logged in with entity id 27059 at ([world] 121.54848881961632, 66.2225814258704, 283.69999998807907) +2020-08-24 22:59:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:01:14 [INFO] LAX1DUDE[/127.0.0.1:62288] logged in with entity id 27278 at ([world] 138.2883078248909, 68.93137639813247, 293.75178678455353) +2020-08-24 23:01:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:03:31 [INFO] LAX1DUDE[/127.0.0.1:62296] logged in with entity id 27405 at ([world] 160.81939944336722, 72.0, 281.1990305626625) +2020-08-24 23:05:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:05:43 [INFO] LAX1DUDE[/127.0.0.1:62303] logged in with entity id 27773 at ([world] 162.24739812392073, 64.0, 310.35181432341136) +2020-08-24 23:06:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:07:21 [INFO] LAX1DUDE[/127.0.0.1:62310] logged in with entity id 27984 at ([world] 110.15055949796505, 70.0, 358.1168807551118) +2020-08-24 23:08:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:09:51 [INFO] LAX1DUDE[/127.0.0.1:62320] logged in with entity id 28133 at ([world] 112.69999998807907, 70.47256081417649, 365.5109314822338) +2020-08-24 23:10:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:14:23 [INFO] LAX1DUDE[/127.0.0.1:62334] logged in with entity id 28304 at ([world] 112.30000001192093, 61.0, 365.30000001192093) +2020-08-24 23:15:03 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:15:19 [INFO] LAX1DUDE[/127.0.0.1:62341] logged in with entity id 28418 at ([world] 112.69999998807907, 61.0, 365.6769426566257) +2020-08-24 23:15:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:16:49 [INFO] LAX1DUDE[/127.0.0.1:62347] logged in with entity id 28619 at ([world] 112.69999998807907, 72.98048636212631, 354.69999998807907) +2020-08-24 23:17:01 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:18:41 [INFO] LAX1DUDE[/127.0.0.1:62355] logged in with entity id 28737 at ([world] 114.62557728054355, 72.0288225327488, 356.47521934200216) +2020-08-24 23:18:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:19:16 [INFO] LAX1DUDE[/127.0.0.1:62360] logged in with entity id 28854 at ([world] 112.69999998807907, 65.0, 354.69999998807907) +2020-08-24 23:22:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:22:32 [INFO] LAX1DUDE[/127.0.0.1:62371] logged in with entity id 29043 at ([world] 97.69421669864096, 73.73941602216549, 356.69999998807907) +2020-08-24 23:23:46 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:24:00 [INFO] LAX1DUDE[/127.0.0.1:62379] logged in with entity id 29221 at ([world] 112.03761334413792, 63.0, 348.2770132703514) +2020-08-24 23:24:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:30:24 [INFO] LAX1DUDE[/127.0.0.1:62391] logged in with entity id 29342 at ([world] 128.00495804625027, 63.0, 335.07843883697035) +2020-08-24 23:31:26 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:35:14 [INFO] LAX1DUDE[/127.0.0.1:62411] logged in with entity id 29480 at ([world] 123.77415998946654, 85.23935596545438, 294.69995630421386) +2020-08-24 23:36:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:40:12 [INFO] LAX1DUDE[/127.0.0.1:62429] logged in with entity id 29839 at ([world] 126.92945941025678, 70.55740003959669, 306.15147107907194) +2020-08-24 23:42:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:46:22 [INFO] LAX1DUDE[/127.0.0.1:62445] logged in with entity id 30783 at ([world] 138.28307182479926, 84.26478779514535, 301.25112638794866) +2020-08-24 23:49:40 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:50:23 [INFO] LAX1DUDE[/127.0.0.1:62460] logged in with entity id 31208 at ([world] 238.5061107205657, 83.73935596545444, 339.90266698007343) +2020-08-24 23:51:43 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:53:39 [INFO] LAX1DUDE[/127.0.0.1:62474] logged in with entity id 31509 at ([world] 271.008691899164, 79.61435535142162, 352.4512420932338) +2020-08-24 23:54:13 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-24 23:57:33 [INFO] LAX1DUDE[/127.0.0.1:62484] logged in with entity id 31623 at ([world] 274.8454434719203, 69.0, 335.36536576162234) +2020-08-24 23:57:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 00:08:54 [INFO] LAX1DUDE[/127.0.0.1:62509] logged in with entity id 31754 at ([world] 246.8895306878518, 64.0, 352.93649300065914) +2020-08-25 00:16:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 00:18:36 [INFO] LAX1DUDE[/127.0.0.1:62528] logged in with entity id 32911 at ([world] 244.77719957376118, 71.11435596562512, 331.1019500110608) +2020-08-25 00:19:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 00:19:34 [INFO] LAX1DUDE[/127.0.0.1:62532] logged in with entity id 33075 at ([world] 244.5516384393174, 51.90405170915385, 354.30000001192093) +2020-08-25 00:22:16 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 00:23:06 [INFO] LAX1DUDE[/127.0.0.1:62553] logged in with entity id 33489 at ([world] 249.2138553436024, 65.0, 343.8413468964294) +2020-08-25 00:23:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 00:26:43 [INFO] LAX1DUDE[/127.0.0.1:62562] logged in with entity id 33570 at ([world] 261.9185706062797, 67.0, 329.803490947034) +2020-08-25 00:26:54 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 00:28:01 [INFO] LAX1DUDE[/127.0.0.1:62568] logged in with entity id 33634 at ([world] 271.6067550490042, 97.6143559654544, 311.60449009467817) +2020-08-25 00:28:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 00:38:24 [INFO] LAX1DUDE[/127.0.0.1:62593] logged in with entity id 33719 at ([world] 226.51557841058445, 70.0, 285.30000001192093) +2020-08-25 00:39:21 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 00:42:50 [INFO] LAX1DUDE[/127.0.0.1:62611] logged in with entity id 34267 at ([world] 315.20894912794495, 69.0, 400.4646187353595) +2020-08-25 00:42:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 00:43:25 [INFO] LAX1DUDE[/127.0.0.1:62617] logged in with entity id 34405 at ([world] 341.9130479066655, 65.0, 406.8530120221154) +2020-08-25 00:44:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 00:48:26 [INFO] LAX1DUDE[/127.0.0.1:62657] logged in with entity id 34758 at ([world] 347.37101850174315, 64.0, 358.1652747047909) +2020-08-25 00:49:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 00:50:11 [INFO] LAX1DUDE[/127.0.0.1:62667] logged in with entity id 35284 at ([world] 237.47591302322053, 75.0, 243.5704289719653) +2020-08-25 00:52:47 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 00:54:54 [INFO] LAX1DUDE[/127.0.0.1:62687] logged in with entity id 36321 at ([world] 226.1464708619026, 67.0, 333.3261555643985) +2020-08-25 00:56:25 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 00:56:48 [INFO] LAX1DUDE[/127.0.0.1:62697] logged in with entity id 36810 at ([world] 211.12464968918968, 69.70191536415892, 308.25631808282344) +2020-08-25 00:59:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 00:59:32 [INFO] LAX1DUDE[/127.0.0.1:62704] logged in with entity id 37190 at ([world] 270.2061779218003, 71.36435764665791, 274.7490605805787) +2020-08-25 01:00:59 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 01:03:34 [INFO] LAX1DUDE[/127.0.0.1:62715] logged in with entity id 37766 at ([world] 384.4984487626875, 65.0, 395.156162006764) +2020-08-25 01:04:47 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 01:05:54 [INFO] LAX1DUDE[/127.0.0.1:62723] logged in with entity id 38091 at ([world] 395.4718276213918, 66.0, 403.43037975075504) +2020-08-25 01:09:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 01:12:42 [INFO] LAX1DUDE[/127.0.0.1:62738] logged in with entity id 38786 at ([world] 287.68660009858735, 67.0, 325.8100158019364) +2020-08-25 01:14:03 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 01:14:34 [INFO] LAX1DUDE[/127.0.0.1:62745] logged in with entity id 39247 at ([world] 350.32655056472737, 65.0, 376.23750001192093) +2020-08-25 01:15:42 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 01:16:04 [INFO] LAX1DUDE[/127.0.0.1:62751] logged in with entity id 39914 at ([world] 209.23834174911826, 68.99078237090826, 318.37231368529086) +2020-08-25 01:16:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 01:20:56 [INFO] LAX1DUDE[/127.0.0.1:62763] logged in with entity id 39978 at ([world] 207.77722469303356, 68.99078237090826, 318.37178310968505) +2020-08-25 01:22:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 01:23:25 [INFO] LAX1DUDE[/127.0.0.1:62777] logged in with entity id 40089 at ([world] 217.2190924281433, 73.6280522076553, 316.6332646486487) +2020-08-25 01:24:47 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 01:25:18 [INFO] LAX1DUDE[/127.0.0.1:62784] logged in with entity id 40370 at ([world] 230.31552730587697, 66.0, 214.21977063961924) +2020-08-25 01:45:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 06:59:32 [INFO] LAX1DUDE[/127.0.0.1:63496] logged in with entity id 42229 at ([world] 299.3213846039564, 82.09134880680024, 363.54379631828493) +2020-08-25 07:00:03 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-25 07:00:03 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-25 07:01:13 [INFO] LAX1DUDE[/127.0.0.1:63502] logged in with entity id 42443 at ([world] 299.3213846039564, 82.09134880680024, 363.54379631828493) +2020-08-25 07:01:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 07:03:50 [INFO] LAX1DUDE[/127.0.0.1:63510] logged in with entity id 42529 at ([world] 299.3213846039564, 82.09134880680024, 363.54379631828493) +2020-08-25 07:04:20 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-25 07:04:20 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-25 07:30:47 [INFO] LAX1DUDE[/127.0.0.1:63575] logged in with entity id 42639 at ([world] 299.3213846039564, 82.09134880680024, 363.54379631828493) +2020-08-25 07:31:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 07:33:13 [INFO] LAX1DUDE[/127.0.0.1:63587] logged in with entity id 42895 at ([world] 272.10674044757207, 59.0, 382.7231384726567) +2020-08-25 07:33:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 07:43:19 [INFO] LAX1DUDE[/127.0.0.1:63624] logged in with entity id 42992 at ([world] 258.8092565359443, 73.5243403162514, 357.6255475531108) +2020-08-25 07:43:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 07:45:05 [INFO] LAX1DUDE[/127.0.0.1:63633] logged in with entity id 43150 at ([world] 227.23147368722132, 65.0, 351.7496683842794) +2020-08-25 07:45:12 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 18:29:25 [INFO] LAX1DUDE[/127.0.0.1:65021] logged in with entity id 43309 at ([world] 226.0962791270435, 79.25373245305624, 356.1443785065556) +2020-08-25 18:29:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 18:32:06 [INFO] LAX1DUDE[/127.0.0.1:65031] logged in with entity id 43391 at ([world] 231.30611192152404, 68.61463400578373, 341.65222956034245) +2020-08-25 18:32:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 18:35:06 [INFO] LAX1DUDE[/127.0.0.1:65039] logged in with entity id 43500 at ([world] 242.3765160975855, 94.09573834190456, 310.4018290043643) +2020-08-25 18:41:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 18:43:42 [INFO] LAX1DUDE[/127.0.0.1:65061] logged in with entity id 44623 at ([world] 273.4111957360825, 67.0, 311.8885777667874) +2020-08-25 18:45:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 18:48:44 [INFO] LAX1DUDE[/127.0.0.1:65081] logged in with entity id 44886 at ([world] 277.60400243865763, 67.0, 311.30000001192093) +2020-08-25 18:48:54 [INFO] LAX1DUDE issued server command: /time set day +2020-08-25 18:48:54 [INFO] LAX1DUDE: Set time to 0 +2020-08-25 18:49:07 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 19:30:34 [INFO] LAX1DUDE[/127.0.0.1:65160] logged in with entity id 45039 at ([world] 267.8866829593464, 111.53817397121793, 361.54483851206163) +2020-08-25 19:35:18 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 19:37:25 [INFO] LAX1DUDE[/127.0.0.1:65179] logged in with entity id 45949 at ([world] 321.10035331518674, 70.0, 390.36301587530335) +2020-08-25 19:38:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 19:39:43 [INFO] LAX1DUDE[/127.0.0.1:65193] logged in with entity id 46128 at ([world] 271.57299617564263, 112.0, 421.728046985796) +2020-08-25 19:40:06 [INFO] LAX1DUDE issued server command: /time set day +2020-08-25 19:40:06 [INFO] LAX1DUDE: Set time to 0 +2020-08-25 19:41:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 19:42:28 [INFO] LAX1DUDE[/127.0.0.1:65203] logged in with entity id 46774 at ([world] 310.7120781377664, 91.84690619664127, 417.5289805958811) +2020-08-25 19:43:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 19:44:11 [INFO] LAX1DUDE[/127.0.0.1:65212] logged in with entity id 47462 at ([world] 323.26221937822464, 70.0, 405.38850689672455) +2020-08-25 19:44:33 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 19:47:43 [INFO] LAX1DUDE[/127.0.0.1:65222] logged in with entity id 47670 at ([world] 308.79226658493053, 78.23935609618474, 359.21405149129333) +2020-08-25 19:49:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 19:50:02 [INFO] LAX1DUDE[/127.0.0.1:65232] logged in with entity id 48121 at ([world] 256.07743461437565, 95.0, 382.00361175375167) +2020-08-25 19:50:51 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 19:52:10 [INFO] LAX1DUDE[/127.0.0.1:65243] logged in with entity id 48350 at ([world] 259.2118407746801, 95.0, 386.4287776829831) +2020-08-25 19:52:19 [INFO] LAX1DUDE issued server command: /time set day +2020-08-25 19:52:19 [INFO] LAX1DUDE: Set time to 0 +2020-08-25 19:53:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 19:54:24 [INFO] LAX1DUDE[/127.0.0.1:65253] logged in with entity id 48610 at ([world] 320.68616217528313, 73.36384984476831, 296.2317243093432) +2020-08-25 19:54:54 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 19:59:32 [INFO] LAX1DUDE[/127.0.0.1:65264] logged in with entity id 48811 at ([world] 332.0024164739284, 71.0, 284.3807908328756) +2020-08-25 19:59:55 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 20:00:35 [INFO] LAX1DUDE[/127.0.0.1:65268] logged in with entity id 48918 at ([world] 292.30000001192093, 65.63438245958041, 302.689002066831) +2020-08-25 20:01:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 20:04:42 [INFO] LAX1DUDE[/127.0.0.1:65284] logged in with entity id 49090 at ([world] 279.5996448350866, 71.0, 353.57711616894966) +2020-08-25 20:04:51 [INFO] LAX1DUDE issued server command: /time set day +2020-08-25 20:04:51 [INFO] LAX1DUDE: Set time to 0 +2020-08-25 20:05:42 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 20:06:18 [INFO] LAX1DUDE[/127.0.0.1:65292] logged in with entity id 49294 at ([world] 254.7407216207908, 84.61285282288695, 348.6529152340609) +2020-08-25 20:07:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 20:07:56 [INFO] LAX1DUDE[/127.0.0.1:65298] logged in with entity id 49686 at ([world] 321.523089665119, 71.0, 294.99020724099273) +2020-08-25 20:09:09 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 20:10:30 [INFO] LAX1DUDE[/127.0.0.1:65307] logged in with entity id 50148 at ([world] 294.7051796371734, 95.48977720670833, 399.864108824775) +2020-08-25 20:10:46 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 20:15:14 [INFO] LAX1DUDE[/127.0.0.1:65319] logged in with entity id 50352 at ([world] 346.8996420029771, 103.0, 455.1037128294464) +2020-08-25 20:15:51 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 20:22:30 [INFO] LAX1DUDE[/127.0.0.1:65360] logged in with entity id 50549 at ([world] 325.6831149304631, 73.53267624565378, 470.4915255243089) +2020-08-25 20:22:39 [INFO] LAX1DUDE issued server command: /time set day +2020-08-25 20:22:39 [INFO] LAX1DUDE: Set time to 0 +2020-08-25 20:22:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 21:25:17 [INFO] LAX1DUDE[/127.0.0.1:49255] logged in with entity id 50786 at ([world] 362.7305591602276, 102.3983870930675, 427.3025601904716) +2020-08-25 21:25:47 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 21:29:16 [INFO] LAX1DUDE[/127.0.0.1:49271] logged in with entity id 50951 at ([world] 348.20752892496245, 64.0, 415.3522262383729) +2020-08-25 21:29:54 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 21:32:00 [INFO] LAX1DUDE[/127.0.0.1:49280] logged in with entity id 51120 at ([world] 355.0649587582484, 94.0, 435.1880229581306) +2020-08-25 21:33:35 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 21:34:26 [INFO] LAX1DUDE[/127.0.0.1:49289] logged in with entity id 51687 at ([world] 319.0818314680555, 70.0, 389.7861406360772) +2020-08-25 21:34:34 [INFO] LAX1DUDE issued server command: /time set day +2020-08-25 21:34:34 [INFO] LAX1DUDE: Set time to 0 +2020-08-25 21:41:51 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 21:42:15 [INFO] LAX1DUDE[/127.0.0.1:49316] logged in with entity id 54484 at ([world] 244.36321782176768, 79.0, 405.2145450762941) +2020-08-25 21:49:07 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 21:51:16 [INFO] LAX1DUDE[/127.0.0.1:49341] logged in with entity id 55017 at ([world] 245.43012125958387, 73.71231706126254, 300.09541010274927) +2020-08-25 21:51:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 21:53:17 [INFO] LAX1DUDE[/127.0.0.1:49348] logged in with entity id 55156 at ([world] 242.58893576232668, 72.0, 273.5697747243164) +2020-08-25 21:53:35 [INFO] LAX1DUDE issued server command: /time set day +2020-08-25 21:53:35 [INFO] LAX1DUDE: Set time to 0 +2020-08-25 21:59:09 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 22:26:07 [INFO] LAX1DUDE[/127.0.0.1:49405] logged in with entity id 56355 at ([world] 216.49433020435004, 77.489357802002, 292.42508048592344) +2020-08-25 22:28:43 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 22:30:19 [INFO] LAX1DUDE[/127.0.0.1:49420] logged in with entity id 56584 at ([world] 309.69999998807907, 66.0, 281.2270173358805) +2020-08-25 22:30:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 22:30:58 [INFO] LAX1DUDE[/127.0.0.1:49424] logged in with entity id 56652 at ([world] 306.8442793521999, 63.0, 282.5004925200059) +2020-08-25 22:31:01 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 22:31:21 [INFO] LAX1DUDE[/127.0.0.1:49427] logged in with entity id 56720 at ([world] 307.6392018569278, 63.0, 283.9485634850038) +2020-08-25 22:31:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 22:32:22 [INFO] LAX1DUDE[/127.0.0.1:49433] logged in with entity id 56788 at ([world] 307.6392018569278, 63.0, 283.9485634850038) +2020-08-25 22:32:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 22:33:13 [INFO] LAX1DUDE[/127.0.0.1:49440] logged in with entity id 56857 at ([world] 312.0299278032124, 76.73935596573894, 274.79717885104435) +2020-08-25 22:33:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 22:33:52 [INFO] LAX1DUDE[/127.0.0.1:49447] logged in with entity id 57005 at ([world] 325.306863446695, 71.84535894289779, 270.16392514666495) +2020-08-25 22:45:47 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 22:46:01 [INFO] LAX1DUDE[/127.0.0.1:49477] logged in with entity id 57793 at ([world] 347.7881336950112, 91.91847710948808, 287.6100447810917) +2020-08-25 23:05:06 [INFO] LAX1DUDE issued server command: /time set day +2020-08-25 23:05:06 [INFO] LAX1DUDE: Set time to 0 +2020-08-25 23:13:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 23:17:01 [INFO] LAX1DUDE[/127.0.0.1:49537] logged in with entity id 62942 at ([world] 882.4105227643038, 85.74727565757627, 797.0859105204402) +2020-08-25 23:17:06 [INFO] LAX1DUDE issued server command: /time set day +2020-08-25 23:17:06 [INFO] LAX1DUDE: Set time to 0 +2020-08-25 23:24:59 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 23:27:40 [INFO] LAX1DUDE[/127.0.0.1:49562] logged in with entity id 67420 at ([world] 1025.906693496714, 78.0, 939.5169879766338) +2020-08-25 23:27:58 [INFO] LAX1DUDE issued server command: /time set day +2020-08-25 23:27:58 [INFO] LAX1DUDE: Set time to 0 +2020-08-25 23:34:35 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-25 23:34:35 [INFO] LAX1DUDE: Changed weather to clear for 432 seconds. +2020-08-25 23:37:47 [INFO] LAX1DUDE issued server command: /kill +2020-08-25 23:37:47 [INFO] LAX1DUDE died +2020-08-25 23:39:09 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-25 23:57:18 [INFO] LAX1DUDE[/127.0.0.1:49626] logged in with entity id 76657 at ([world] 271.9649329286919, 116.8643559654544, 95.33176081132578) +2020-08-25 23:58:45 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 00:00:00 [INFO] LAX1DUDE[/127.0.0.1:49634] logged in with entity id 76963 at ([world] 254.5027892689854, 73.0, 99.93046615173958) +2020-08-26 00:00:08 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 00:10:10 [INFO] LAX1DUDE[/127.0.0.1:49653] logged in with entity id 77056 at ([world] 250.82296078152348, 71.0, 101.06617259276283) +2020-08-26 00:10:16 [INFO] LAX1DUDE issued server command: /weather rain +2020-08-26 00:10:16 [INFO] LAX1DUDE: Changed weather to rainy for 710 seconds. +2020-08-26 00:18:01 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-26 00:18:01 [INFO] LAX1DUDE: Changed weather to clear for 501 seconds. +2020-08-26 00:19:30 [INFO] LAX1DUDE issued server command: /time set day +2020-08-26 00:19:30 [INFO] LAX1DUDE: Set time to 0 +2020-08-26 00:24:33 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 00:25:58 [INFO] LAX1DUDE[/127.0.0.1:49692] logged in with entity id 80043 at ([world] 162.8449753876584, 93.6143559654544, 369.7400397076346) +2020-08-26 00:30:11 [INFO] LAX1DUDE issued server command: /time set day +2020-08-26 00:30:11 [INFO] LAX1DUDE: Set time to 0 +2020-08-26 00:35:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 00:52:41 [INFO] LAX1DUDE[/127.0.0.1:49766] logged in with entity id 82404 at ([world] 179.24623462676945, 72.0, 309.8790863934545) +2020-08-26 00:52:48 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-26 00:52:48 [INFO] LAX1DUDE: Changed weather to clear for 629 seconds. +2020-08-26 00:57:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 01:01:05 [INFO] LAX1DUDE[/127.0.0.1:49783] logged in with entity id 83886 at ([world] 293.28508444269585, 76.15458515715505, 309.3024852705803) +2020-08-26 01:01:49 [INFO] LAX1DUDE issued server command: /time set day +2020-08-26 01:01:49 [INFO] LAX1DUDE: Set time to 0 +2020-08-26 01:06:44 [INFO] LAX1DUDE issued server command: /kill +2020-08-26 01:06:44 [INFO] LAX1DUDE died +2020-08-26 01:11:03 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 01:17:34 [INFO] LAX1DUDE[/127.0.0.1:49811] logged in with entity id 89948 at ([world] 182.30000001192093, 62.0, 328.69999998807907) +2020-08-26 01:17:48 [INFO] LAX1DUDE issued server command: /time set day +2020-08-26 01:17:48 [INFO] LAX1DUDE: Set time to 0 +2020-08-26 01:26:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 01:26:53 [INFO] LAX1DUDE[/127.0.0.1:49832] logged in with entity id 91936 at ([world] 272.63607452705264, 72.36107644410093, 328.76353083621234) +2020-08-26 01:28:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 01:31:01 [INFO] LAX1DUDE[/127.0.0.1:49843] logged in with entity id 92973 at ([world] 282.2529333267656, 70.0, 361.30000001192093) +2020-08-26 01:31:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 01:40:36 [INFO] LAX1DUDE[/127.0.0.1:49870] logged in with entity id 93212 at ([world] 235.89556128285471, 76.0, 253.61523718562543) +2020-08-26 01:49:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 01:49:49 [INFO] LAX1DUDE[/127.0.0.1:49895] logged in with entity id 93663 at ([world] 186.1327890636731, 67.0, 239.8590323670037) +2020-08-26 01:51:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 01:51:28 [INFO] LAX1DUDE[/127.0.0.1:49910] logged in with entity id 93773 at ([world] 221.68439618993693, 72.0, 232.44725830644796) +2020-08-26 01:52:02 [INFO] LAX1DUDE issued server command: /time set day +2020-08-26 01:52:02 [INFO] LAX1DUDE: Set time to 0 +2020-08-26 01:57:13 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 01:58:07 [INFO] LAX1DUDE[/127.0.0.1:49924] logged in with entity id 95063 at ([world] 231.7624999880791, 71.0, 294.4487672038647) +2020-08-26 02:07:35 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 04:10:21 [INFO] LAX1DUDE[/127.0.0.1:50170] logged in with entity id 97390 at ([world] 267.54350027788615, 66.0, 303.6953336540738) +2020-08-26 04:11:01 [INFO] LAX1DUDE issued server command: /time set day +2020-08-26 04:11:01 [INFO] LAX1DUDE: Set time to 0 +2020-08-26 04:20:04 [INFO] LAX1DUDE issued server command: /gamemode 1 +2020-08-26 04:20:12 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 04:20:14 [INFO] LAX1DUDE[/127.0.0.1:50197] logged in with entity id 100764 at ([world] 277.14532395213297, 75.0, -340.6999999880792) +2020-08-26 04:25:23 [INFO] LAX1DUDE issued server command: /time set day +2020-08-26 04:25:23 [INFO] LAX1DUDE: Set time to 0 +2020-08-26 04:28:27 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 04:49:38 [INFO] LAX1DUDE[/127.0.0.1:50260] logged in with entity id 105124 at ([world] 714.761357146047, 69.0, 4.6386232371399885) +2020-08-26 04:49:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 04:50:30 [INFO] LAX1DUDE[/127.0.0.1:50265] logged in with entity id 105325 at ([world] 699.2887629182078, 70.0, 21.446603413882123) +2020-08-26 04:50:45 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 04:52:36 [INFO] LAX1DUDE[/127.0.0.1:50276] logged in with entity id 105526 at ([world] 715.5402468206103, 73.74430538728716, 10.935741717137187) +2020-08-26 04:53:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 04:58:50 [INFO] LAX1DUDE[/127.0.0.1:50291] logged in with entity id 105911 at ([world] 701.9815591074367, 66.0, -23.885079451329982) +2020-08-26 04:59:01 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 05:04:16 [INFO] LAX1DUDE[/127.0.0.1:50303] logged in with entity id 106110 at ([world] 706.6852306917879, 66.0, -23.850759584208788) +2020-08-26 05:20:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 05:20:58 [INFO] LAX1DUDE[/127.0.0.1:50339] logged in with entity id 116608 at ([world] 824.0976810250303, 74.0, -86.07699483767017) +2020-08-26 05:21:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 05:22:11 [INFO] LAX1DUDE[/127.0.0.1:50347] logged in with entity id 116853 at ([world] 772.3000000119209, 68.0, -105.42569199388012) +2020-08-26 05:24:09 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 05:27:41 [INFO] LAX1DUDE[/127.0.0.1:50362] logged in with entity id 117221 at ([world] 823.9481378868073, 74.0, -87.15430296907826) +2020-08-26 05:27:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 05:30:25 [INFO] LAX1DUDE[/127.0.0.1:50369] logged in with entity id 117415 at ([world] 823.6190814539387, 74.0, -87.11477211560965) +2020-08-26 05:30:40 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 05:32:53 [INFO] LAX1DUDE[/127.0.0.1:50379] logged in with entity id 117598 at ([world] 833.8154040569812, 72.0, -80.25514596578549) +2020-08-26 05:33:18 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 05:34:54 [INFO] LAX1DUDE[/127.0.0.1:50386] logged in with entity id 117760 at ([world] 833.8154040569812, 72.0, -80.25514596578549) +2020-08-26 05:35:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 06:21:12 [INFO] LAX1DUDE[/127.0.0.1:50536] logged in with entity id 118025 at ([world] 803.3030559697177, 75.0, -70.58574271637241) +2020-08-26 06:21:18 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 06:34:35 [INFO] LAX1DUDE[/127.0.0.1:50570] logged in with entity id 118212 at ([world] 794.7860103805384, 74.0, -60.27100884174977) +2020-08-26 06:34:38 [INFO] .j +2020-08-26 06:35:02 [INFO] ..j +2020-08-26 06:35:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 07:06:34 [INFO] LAX1DUDE[/127.0.0.1:50670] logged in with entity id 118399 at ([world] 798.8548131411668, 73.0, -57.30000001192093) +2020-08-26 07:06:43 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 08:03:41 [INFO] LAX1DUDE[/127.0.0.1:50793] logged in with entity id 118588 at ([world] 800.3000000119209, 75.0, -74.69999998807907) +2020-08-26 08:05:03 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 08:14:54 [INFO] LAX1DUDE[/127.0.0.1:50820] logged in with entity id 118815 at ([world] 804.2252504140492, 71.0, -81.38984223554277) +2020-08-26 08:14:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 08:21:53 [INFO] LAX1DUDE[/127.0.0.1:50835] logged in with entity id 118994 at ([world] 804.2252504140492, 71.0, -81.38984223554277) +2020-08-26 08:30:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 08:30:32 [INFO] LAX1DUDE[/127.0.0.1:50856] logged in with entity id 120532 at ([world] 915.5002729811453, 72.0, -129.48526646024328) +2020-08-26 08:36:41 [INFO] t/time set day +2020-08-26 08:36:46 [INFO] LAX1DUDE issued server command: /time set day +2020-08-26 08:36:46 [INFO] LAX1DUDE: Set time to 0 +2020-08-26 08:42:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 10:23:08 [INFO] LAX1DUDE[/127.0.0.1:51714] logged in with entity id 122326 at ([world] 877.2724033867191, 70.0, -151.079526755033) +2020-08-26 10:23:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 10:26:15 [INFO] LAX1DUDE[/127.0.0.1:51773] logged in with entity id 122531 at ([world] 877.2724033867191, 70.0, -151.079526755033) +2020-08-26 10:26:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 10:29:41 [INFO] LAX1DUDE[/127.0.0.1:51821] logged in with entity id 122728 at ([world] 879.6281940421974, 69.0, -147.54415555738524) +2020-08-26 10:45:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 10:45:24 [INFO] LAX1DUDE[/127.0.0.1:59801] logged in with entity id 123696 at ([world] 870.7118386303233, 70.0, -150.5945990690505) +2020-08-26 10:45:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 10:47:54 [INFO] LAX1DUDE[/127.0.0.1:59820] logged in with entity id 123879 at ([world] 870.7118386303233, 70.0, -150.5945990690505) +2020-08-26 10:48:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 10:48:53 [INFO] LAX1DUDE[/127.0.0.1:59843] logged in with entity id 124066 at ([world] 870.7118386303233, 70.0, -150.5945990690505) +2020-08-26 10:48:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 10:55:29 [INFO] LAX1DUDE[/127.0.0.1:59913] logged in with entity id 124265 at ([world] 870.7118386303233, 70.0, -150.5945990690505) +2020-08-26 10:55:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 10:58:43 [INFO] LAX1DUDE[/127.0.0.1:59960] logged in with entity id 124453 at ([world] 867.2913294875373, 71.0, -144.2859070267732) +2020-08-26 10:59:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 11:03:22 [INFO] LAX1DUDE[/127.0.0.1:60009] logged in with entity id 124732 at ([world] 902.1382583719811, 92.2661755724198, -138.93223946561864) +2020-08-26 11:03:47 [INFO] LAX1DUDE issued server command: /kill +2020-08-26 11:03:47 [INFO] LAX1DUDE died +2020-08-26 11:10:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 11:13:16 [INFO] LAX1DUDE[/127.0.0.1:59184] logged in with entity id 125534 at ([world] 261.31408978312754, 72.0, 209.30000001192093) +2020-08-26 11:14:04 [INFO] LAX1DUDE issued server command: /time set day +2020-08-26 11:14:04 [INFO] LAX1DUDE: Set time to 0 +2020-08-26 11:17:40 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 11:17:43 [INFO] LAX1DUDE[/127.0.0.1:59473] logged in with entity id 125905 at ([world] 267.69999998807907, 66.0, 303.4217344974179) +2020-08-26 11:18:27 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 11:19:29 [INFO] LAX1DUDE[/127.0.0.1:59532] logged in with entity id 126072 at ([world] 233.18867305969155, 73.98851433296349, 302.96523607434494) +2020-08-26 11:20:51 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 11:35:03 [INFO] LAX1DUDE[/127.0.0.1:65177] logged in with entity id 126329 at ([world] 291.75634679083623, 69.0, 305.45080336654536) +2020-08-26 11:37:37 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 11:37:44 [INFO] LAX1DUDE[/127.0.0.1:65209] logged in with entity id 126860 at ([world] 277.31754246551907, 67.0, 302.34145828078533) +2020-08-26 11:40:35 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 11:41:31 [INFO] LAX1DUDE[/127.0.0.1:65240] logged in with entity id 127546 at ([world] 286.99100587809045, 67.0, 304.6999999880791) +2020-08-26 11:42:48 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 11:43:25 [INFO] LAX1DUDE[/127.0.0.1:65269] logged in with entity id 128251 at ([world] 284.52700175378425, 69.0, 305.3477039623663) +2020-08-26 11:44:37 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 11:44:50 [INFO] LAX1DUDE[/127.0.0.1:65290] logged in with entity id 128606 at ([world] 291.7171315549792, 86.87370986087072, 302.4104888710668) +2020-08-26 11:47:01 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 11:49:25 [INFO] LAX1DUDE[/127.0.0.1:65323] logged in with entity id 128915 at ([world] 291.43471620818804, 66.0, 307.01736811206337) +2020-08-26 11:49:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 11:51:13 [INFO] LAX1DUDE[/127.0.0.1:65352] logged in with entity id 128983 at ([world] 296.76249998807907, 65.0, 302.22087173107053) +2020-08-26 11:52:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 16:16:01 [INFO] LAX1DUDE[/127.0.0.1:49425] logged in with entity id 129236 at ([world] 295.7252391086164, 65.88391922170094, 305.17700009818833) +2020-08-26 16:23:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 16:42:54 [INFO] LAX1DUDE[/127.0.0.1:49530] logged in with entity id 130565 at ([world] 324.67780858411703, 67.0, 324.9307849464298) +2020-08-26 16:45:27 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 16:45:43 [INFO] LAX1DUDE[/127.0.0.1:49751] logged in with entity id 130686 at ([world] 289.1915790540416, 66.0, 307.2467459647879) +2020-08-26 16:45:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 16:47:34 [INFO] LAX1DUDE[/127.0.0.1:49779] logged in with entity id 130758 at ([world] 289.76248238764975, 66.0, 306.30000001192093) +2020-08-26 16:47:48 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 17:19:08 [INFO] LAX1DUDE[/127.0.0.1:50067] logged in with entity id 130845 at ([world] 290.0315942699221, 66.0, 306.65916667880174) +2020-08-26 17:19:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 18:58:20 [INFO] LAX1DUDE[/127.0.0.1:50343] logged in with entity id 130927 at ([world] 288.27191313417734, 66.0, 307.8252891561104) +2020-08-26 18:59:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:12:01 [INFO] LAX1DUDE[/127.0.0.1:50394] logged in with entity id 131204 at ([world] 295.99612559066117, 65.0, 303.5673055539664) +2020-08-26 19:14:45 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:24:12 [INFO] LAX1DUDE[/127.0.0.1:50436] logged in with entity id 131531 at ([world] 288.0384044521488, 69.0, 304.93665197736016) +2020-08-26 19:24:21 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:25:43 [INFO] LAX1DUDE[/127.0.0.1:50443] logged in with entity id 131603 at ([world] 288.0384044521488, 69.0, 304.93665197736016) +2020-08-26 19:26:12 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:27:02 [INFO] LAX1DUDE[/127.0.0.1:50450] logged in with entity id 131763 at ([world] 319.4705378068423, 68.6155562125007, 303.8737935311047) +2020-08-26 19:27:27 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:28:52 [INFO] LAX1DUDE[/127.0.0.1:50459] logged in with entity id 131956 at ([world] 283.8756996748661, 67.0, 303.3389271503923) +2020-08-26 19:31:48 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:32:20 [INFO] LAX1DUDE[/127.0.0.1:50471] logged in with entity id 132155 at ([world] 273.79795617556476, 67.61512829970268, 304.69999998807907) +2020-08-26 19:32:58 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:33:44 [INFO] LAX1DUDE[/127.0.0.1:50478] logged in with entity id 132286 at ([world] 275.30000001192093, 66.0, 295.15843929174895) +2020-08-26 19:34:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:34:49 [INFO] LAX1DUDE[/127.0.0.1:50484] logged in with entity id 132435 at ([world] 296.71183082956185, 65.0, 301.59766737075256) +2020-08-26 19:34:54 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:35:30 [INFO] LAX1DUDE[/127.0.0.1:50489] logged in with entity id 132519 at ([world] 297.6081829660893, 65.0, 301.1344740745295) +2020-08-26 19:35:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:36:00 [INFO] LAX1DUDE[/127.0.0.1:50498] logged in with entity id 132597 at ([world] 288.7301216546367, 67.1116330269739, 303.1398722941951) +2020-08-26 19:36:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:36:54 [INFO] LAX1DUDE[/127.0.0.1:50507] logged in with entity id 132713 at ([world] 306.3878701110757, 66.50925836723405, 308.76249998807907) +2020-08-26 19:37:08 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:37:33 [INFO] LAX1DUDE[/127.0.0.1:50513] logged in with entity id 132798 at ([world] 307.00764810966024, 65.01058114321357, 308.02047401118097) +2020-08-26 19:38:18 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:38:31 [INFO] LAX1DUDE[/127.0.0.1:50523] logged in with entity id 132906 at ([world] 291.8995442888125, 66.23193747248253, 304.6812277636491) +2020-08-26 19:38:59 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:39:32 [INFO] LAX1DUDE[/127.0.0.1:50532] logged in with entity id 133162 at ([world] 306.1337765253707, 68.46104202090349, 302.6775771974353) +2020-08-26 19:40:06 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:41:05 [INFO] LAX1DUDE[/127.0.0.1:50539] logged in with entity id 133278 at ([world] 297.22362835644776, 65.0, 301.76249998807907) +2020-08-26 19:41:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:41:51 [INFO] LAX1DUDE[/127.0.0.1:50545] logged in with entity id 133374 at ([world] 288.2671498403887, 67.15473176351254, 303.89970141601475) +2020-08-26 19:42:01 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:42:40 [INFO] LAX1DUDE[/127.0.0.1:50551] logged in with entity id 133480 at ([world] 290.309394588729, 66.23763708577005, 301.92916319795535) +2020-08-26 19:43:12 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:43:35 [INFO] LAX1DUDE[/127.0.0.1:50559] logged in with entity id 133635 at ([world] 286.71624402993365, 67.0, 303.69756626187086) +2020-08-26 19:43:39 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:44:10 [INFO] LAX1DUDE[/127.0.0.1:50564] logged in with entity id 133703 at ([world] 289.5591940095018, 67.0, 303.63593523172653) +2020-08-26 19:44:12 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:44:37 [INFO] LAX1DUDE[/127.0.0.1:50570] logged in with entity id 133780 at ([world] 289.5591940095018, 67.0, 303.63593523172653) +2020-08-26 19:44:42 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:45:10 [INFO] LAX1DUDE[/127.0.0.1:50575] logged in with entity id 133857 at ([world] 286.41435658933375, 67.0, 303.3057669401339) +2020-08-26 19:45:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:47:15 [INFO] LAX1DUDE[/127.0.0.1:50582] logged in with entity id 133983 at ([world] 323.4400149095459, 68.42524576948806, 305.9382445646604) +2020-08-26 19:47:52 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:48:05 [INFO] LAX1DUDE[/127.0.0.1:50590] logged in with entity id 134082 at ([world] 288.5934027797711, 67.0, 303.45056495337803) +2020-08-26 19:48:09 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:48:37 [INFO] LAX1DUDE[/127.0.0.1:50598] logged in with entity id 134158 at ([world] 286.2761126096431, 67.0, 303.3901175282622) +2020-08-26 19:48:43 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:49:09 [INFO] LAX1DUDE[/127.0.0.1:50603] logged in with entity id 134225 at ([world] 288.89003390996464, 69.0, 305.6108609968088) +2020-08-26 19:49:25 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:50:10 [INFO] LAX1DUDE[/127.0.0.1:50609] logged in with entity id 134312 at ([world] 288.5387332279012, 67.11439199948107, 304.2176576813178) +2020-08-26 19:50:16 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:50:36 [INFO] LAX1DUDE[/127.0.0.1:50614] logged in with entity id 134394 at ([world] 289.2266809397734, 67.11439199948107, 302.4666452232648) +2020-08-26 19:50:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:51:49 [INFO] LAX1DUDE[/127.0.0.1:50622] logged in with entity id 134473 at ([world] 278.64548490078056, 66.0, 306.55050148812603) +2020-08-26 19:51:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:52:25 [INFO] LAX1DUDE[/127.0.0.1:50627] logged in with entity id 134559 at ([world] 276.68072901067836, 66.0, 306.39969945937077) +2020-08-26 19:54:13 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:54:44 [INFO] LAX1DUDE[/127.0.0.1:50638] logged in with entity id 134734 at ([world] 281.30000001192093, 67.0, 303.05444176256265) +2020-08-26 19:54:50 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:55:13 [INFO] LAX1DUDE[/127.0.0.1:50658] logged in with entity id 134801 at ([world] 283.9341873738991, 66.0, 300.5978285336681) +2020-08-26 19:55:21 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 19:58:43 [INFO] LAX1DUDE[/127.0.0.1:50669] logged in with entity id 134867 at ([world] 283.44769301853745, 67.0, 302.38405062498947) +2020-08-26 19:59:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 20:00:10 [INFO] LAX1DUDE[/127.0.0.1:50675] logged in with entity id 134948 at ([world] 288.3134484936687, 67.0, 303.8084901492631) +2020-08-26 20:26:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 20:27:06 [INFO] LAX1DUDE[/127.0.0.1:50712] logged in with entity id 136152 at ([world] 278.4860604900803, 67.3837588480488, 306.7588075981342) +2020-08-26 20:33:23 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 20:33:40 [INFO] LAX1DUDE[/127.0.0.1:50742] logged in with entity id 136374 at ([world] 270.3397104201358, 69.0, 305.5066324801696) +2020-08-26 20:42:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 20:42:52 [INFO] LAX1DUDE[/127.0.0.1:50763] logged in with entity id 136953 at ([world] 275.6279344995666, 77.10218523174136, 315.66459332593473) +2020-08-26 21:24:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 21:24:37 [INFO] LAX1DUDE[/127.0.0.1:50926] logged in with entity id 139378 at ([world] 275.30808220832404, 68.0, 303.42089214422555) +2020-08-26 21:48:32 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 22:03:24 [INFO] LAX1DUDE[/127.0.0.1:51037] logged in with entity id 140939 at ([world] 289.01931948231015, 69.0, 306.00076100535625) +2020-08-26 22:09:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 22:14:07 [INFO] LAX1DUDE[/127.0.0.1:51058] logged in with entity id 141435 at ([world] 278.85110578332376, 67.0, 302.97759298143944) +2020-08-26 22:15:28 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 22:16:26 [INFO] LAX1DUDE[/127.0.0.1:51067] logged in with entity id 141561 at ([world] 280.7904116432773, 69.0, 305.1574332778702) +2020-08-26 22:48:41 [INFO] LAX1DUDE issued server command: /time set day +2020-08-26 22:48:41 [INFO] LAX1DUDE: Set time to 0 +2020-08-26 23:01:09 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 23:01:26 [INFO] LAX1DUDE[/127.0.0.1:51166] logged in with entity id 144456 at ([world] 277.01875992999095, 67.0, 302.69999998807907) +2020-08-26 23:23:44 [INFO] LAX1DUDE issued server command: /time set day +2020-08-26 23:23:44 [INFO] LAX1DUDE: Set time to 0 +2020-08-26 23:39:40 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 23:40:22 [INFO] LAX1DUDE[/127.0.0.1:51246] logged in with entity id 146528 at ([world] 284.4146311751908, 68.0, 314.8581439511946) +2020-08-26 23:43:45 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 23:45:41 [INFO] LAX1DUDE[/127.0.0.1:51258] logged in with entity id 146758 at ([world] 288.4795259408754, 66.0, 295.91409482033254) +2020-08-26 23:45:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 23:50:08 [INFO] LAX1DUDE[/127.0.0.1:51303] logged in with entity id 146939 at ([world] 324.9492126939718, 77.28069614645025, 305.7278295316155) +2020-08-26 23:50:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 23:56:56 [INFO] LAX1DUDE[/127.0.0.1:51830] logged in with entity id 147161 at ([world] 340.60377712106265, 72.0, 307.26407087944443) +2020-08-26 23:57:13 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 23:57:33 [INFO] LAX1DUDE[/127.0.0.1:51895] logged in with entity id 147255 at ([world] 340.60377712106265, 72.0, 307.26407087944443) +2020-08-26 23:58:03 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-26 23:58:19 [INFO] LAX1DUDE[/127.0.0.1:51992] logged in with entity id 147361 at ([world] 340.60377712106265, 72.0, 307.26407087944443) +2020-08-26 23:58:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 00:03:49 [INFO] LAX1DUDE[/127.0.0.1:52331] logged in with entity id 147465 at ([world] 341.26642643790615, 72.0, 308.01960878974916) +2020-08-27 00:06:03 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 00:06:45 [INFO] LAX1DUDE[/127.0.0.1:52556] logged in with entity id 147754 at ([world] 302.5188779642422, 70.0, 363.69999998807907) +2020-08-27 00:07:29 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-27 00:07:29 [INFO] LAX1DUDE: Changed weather to clear for 759 seconds. +2020-08-27 00:10:44 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 00:11:18 [INFO] LAX1DUDE[/127.0.0.1:52837] logged in with entity id 149556 at ([world] 559.9955354656273, 64.0, 317.1257671388983) +2020-08-27 00:11:44 [INFO] LAX1DUDE issued server command: /kill +2020-08-27 00:11:44 [INFO] LAX1DUDE died +2020-08-27 00:12:03 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 00:12:20 [INFO] LAX1DUDE[/127.0.0.1:52859] logged in with entity id 150239 at ([world] 236.54881139493352, 74.0, 231.46417318444986) +2020-08-27 00:12:25 [INFO] LAX1DUDE issued server command: /kill +2020-08-27 00:12:25 [INFO] LAX1DUDE died +2020-08-27 00:13:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 00:14:01 [INFO] LAX1DUDE[/127.0.0.1:52940] logged in with entity id 150482 at ([world] 272.436321517151, 67.0, 302.72221890710364) +2020-08-27 00:16:41 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 00:34:43 [INFO] LAX1DUDE[/127.0.0.1:53867] logged in with entity id 151024 at ([world] 247.8960998711345, 72.53584062504456, 262.3942568383673) +2020-08-27 00:52:39 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 00:56:28 [INFO] LAX1DUDE[/127.0.0.1:54379] logged in with entity id 152262 at ([world] 269.971056121045, 70.79054527192238, 303.5081519075195) +2020-08-27 00:57:22 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 00:57:38 [INFO] LAX1DUDE[/127.0.0.1:54405] logged in with entity id 152345 at ([world] 277.0386991949298, 71.79119069035022, 305.71238515360886) +2020-08-27 01:02:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 01:11:10 [INFO] LAX1DUDE[/127.0.0.1:54819] logged in with entity id 152871 at ([world] 264.5756704804538, 66.0, 289.7537153115208) +2020-08-27 01:14:26 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 01:15:26 [INFO] LAX1DUDE[/127.0.0.1:54904] logged in with entity id 153223 at ([world] 254.72481034678174, 71.61032991789054, 305.1291428235808) +2020-08-27 01:23:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 01:23:52 [INFO] LAX1DUDE[/127.0.0.1:55093] logged in with entity id 153647 at ([world] 239.01962477994186, 75.0, 249.46130434598183) +2020-08-27 01:24:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 01:27:18 [INFO] LAX1DUDE[/127.0.0.1:55185] logged in with entity id 153700 at ([world] 233.1051045783065, 75.0, 255.3763899722829) +2020-08-27 01:30:04 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-27 01:30:04 [INFO] LAX1DUDE: Changed weather to clear for 874 seconds. +2020-08-27 01:33:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 01:54:39 [INFO] FudglerCum84[/127.0.0.1:55948] logged in with entity id 154704 at ([world] 181.5, 62.0, 217.5) +2020-08-27 02:10:48 [INFO] FudglerCum84 lost connection: disconnect.quitting +2020-08-27 03:21:25 [INFO] LAX1DUDE[/127.0.0.1:57991] logged in with entity id 156334 at ([world] 384.3880159762041, 65.0, 374.74352004192656) +2020-08-27 03:21:55 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 03:27:08 [INFO] LAX1DUDE[/127.0.0.1:58138] logged in with entity id 156572 at ([world] 384.3880159762041, 65.0, 374.74352004192656) +2020-08-27 03:27:25 [WARNING] LAX1DUDE moved too quickly! -375.9439763949705,-67.03999999165535,-374.2615854552706 (375.9439763949705, 67.03999999165535, 374.2615854552706) +2020-08-27 03:27:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 03:28:15 [INFO] LAX1DUDE[/127.0.0.1:58165] logged in with entity id 156708 at ([world] 375.9439763949705, 65.41999998688698, 374.2615854552706) +2020-08-27 03:28:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 03:30:22 [INFO] LAX1DUDE[/127.0.0.1:58220] logged in with entity id 156934 at ([world] 388.69999998807907, 65.0, 372.71066170245945) +2020-08-27 03:36:40 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 03:39:29 [INFO] LAX1DUDE[/127.0.0.1:58441] logged in with entity id 157546 at ([world] 371.19505099308543, 70.0, 331.28064557862376) +2020-08-27 03:47:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 03:56:23 [INFO] LAX1DUDE[/127.0.0.1:58817] logged in with entity id 160534 at ([world] 805.670468154079, 88.0, -275.37368554189834) +2020-08-27 03:58:05 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-27 03:58:05 [INFO] LAX1DUDE: Changed weather to clear for 765 seconds. +2020-08-27 04:39:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 07:49:09 [INFO] ViggYee58[/127.0.0.1:64420] logged in with entity id 162861 at ([world] 183.5, 62.0, 217.5) +2020-08-27 07:57:02 [INFO] ViggYee58 issued server command: /time set day +2020-08-27 07:57:08 [INFO] ViggYee58 lost connection: disconnect.quitting +2020-08-27 07:59:18 [INFO] LAX1DUDE[/127.0.0.1:64674] logged in with entity id 163617 at ([world] 807.4999437052705, 71.0, -63.30000001192093) +2020-08-27 08:00:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-27 19:16:54 [INFO] LAX1DUDE[/127.0.0.1:62272] logged in with entity id 163979 at ([world] 782.8652631529708, 88.35159509899962, -41.92576093205458) +2020-08-27 19:35:38 [INFO] LAX1DUDE issued server command: /weather rain +2020-08-27 19:35:38 [INFO] LAX1DUDE: Changed weather to rainy for 700 seconds. +2020-08-27 19:36:14 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-27 19:36:14 [INFO] LAX1DUDE: Changed weather to clear for 651 seconds. +2020-08-27 19:43:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-28 17:10:36 [INFO] LAX1DUDE[/127.0.0.1:49431] logged in with entity id 166090 at ([world] 908.8532880947807, 68.0, -155.7880161044017) +2020-08-28 17:12:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 00:28:54 [INFO] LAX1DUDE[/127.0.0.1:57683] logged in with entity id 166729 at ([world] 920.2161538428165, 69.0, -62.00031467734547) +2020-08-29 00:29:23 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 00:30:13 [INFO] LAX1DUDE[/127.0.0.1:57706] logged in with entity id 166873 at ([world] 919.8865148044499, 69.0, -67.18370514383658) +2020-08-29 03:11:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 13:12:26 [INFO] Starting minecraft server version 1.5.2 +2020-08-29 13:12:26 [WARNING] To start the server with more ram, launch it as "java -Xmx1024M -Xms1024M -jar minecraft_server.jar" +2020-08-29 13:12:26 [INFO] Loading properties +2020-08-29 13:12:27 [INFO] Default game type: CREATIVE +2020-08-29 13:12:27 [INFO] This server is running CraftBukkit version git-Spigot-959 (MC: 1.5.2) (Implementing API version 1.5.2-R1.1-SNAPSHOT) +2020-08-29 13:12:27 [INFO] Generating keypair +2020-08-29 13:12:28 [INFO] Starting listener #0 on *:25501 +2020-08-29 13:12:28 [WARNING] **** SERVER IS RUNNING IN OFFLINE/INSECURE MODE! +2020-08-29 13:12:28 [WARNING] The server will make no attempt to authenticate usernames. Beware. +2020-08-29 13:12:28 [WARNING] 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. +2020-08-29 13:12:28 [WARNING] To change this, set "online-mode" to "true" in the server.properties file. +2020-08-29 13:12:28 [INFO] Preparing level "world" +2020-08-29 13:12:28 [INFO] -------- World Settings For [world] -------- +2020-08-29 13:12:28 [INFO] View Distance: 10 +2020-08-29 13:12:28 [INFO] Chunks to Grow per Tick: 650 +2020-08-29 13:12:28 [INFO] Experience Merge Radius: 3.0 +2020-08-29 13:12:28 [INFO] Item Merge Radius: 2.5 +2020-08-29 13:12:28 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-08-29 13:12:28 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-08-29 13:12:28 [INFO] Cactus Growth Modifier: 100% +2020-08-29 13:12:28 [INFO] Cane Growth Modifier: 100% +2020-08-29 13:12:28 [INFO] Melon Growth Modifier: 100% +2020-08-29 13:12:28 [INFO] Mushroom Growth Modifier: 100% +2020-08-29 13:12:28 [INFO] Pumpkin Growth Modifier: 100% +2020-08-29 13:12:28 [INFO] Sapling Growth Modifier: 100% +2020-08-29 13:12:28 [INFO] Wheat Growth Modifier: 100% +2020-08-29 13:12:28 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-08-29 13:12:28 [INFO] Random Lighting Updates: false +2020-08-29 13:12:28 [INFO] Anti X-Ray: true +2020-08-29 13:12:28 [INFO] Engine Mode: 1 +2020-08-29 13:12:28 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-08-29 13:12:28 [INFO] Mob Spawn Range: 4 +2020-08-29 13:12:29 [INFO] -------- World Settings For [world_nether] -------- +2020-08-29 13:12:29 [INFO] View Distance: 10 +2020-08-29 13:12:29 [INFO] Chunks to Grow per Tick: 650 +2020-08-29 13:12:29 [INFO] Experience Merge Radius: 3.0 +2020-08-29 13:12:29 [INFO] Item Merge Radius: 2.5 +2020-08-29 13:12:29 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-08-29 13:12:29 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-08-29 13:12:29 [INFO] Cactus Growth Modifier: 100% +2020-08-29 13:12:29 [INFO] Cane Growth Modifier: 100% +2020-08-29 13:12:29 [INFO] Melon Growth Modifier: 100% +2020-08-29 13:12:29 [INFO] Mushroom Growth Modifier: 100% +2020-08-29 13:12:29 [INFO] Pumpkin Growth Modifier: 100% +2020-08-29 13:12:29 [INFO] Sapling Growth Modifier: 100% +2020-08-29 13:12:29 [INFO] Wheat Growth Modifier: 100% +2020-08-29 13:12:29 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-08-29 13:12:29 [INFO] Random Lighting Updates: false +2020-08-29 13:12:29 [INFO] Anti X-Ray: true +2020-08-29 13:12:29 [INFO] Engine Mode: 1 +2020-08-29 13:12:29 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-08-29 13:12:29 [INFO] Mob Spawn Range: 4 +2020-08-29 13:12:29 [INFO] -------- World Settings For [world_the_end] -------- +2020-08-29 13:12:29 [INFO] View Distance: 10 +2020-08-29 13:12:29 [INFO] Chunks to Grow per Tick: 650 +2020-08-29 13:12:29 [INFO] Experience Merge Radius: 3.0 +2020-08-29 13:12:29 [INFO] Item Merge Radius: 2.5 +2020-08-29 13:12:29 [INFO] Entity Activation Range: An 32 / Mo 32 / Mi 16 +2020-08-29 13:12:29 [INFO] Hopper Transfer: 8 Hopper Check: 8 +2020-08-29 13:12:29 [INFO] Cactus Growth Modifier: 100% +2020-08-29 13:12:29 [INFO] Cane Growth Modifier: 100% +2020-08-29 13:12:29 [INFO] Melon Growth Modifier: 100% +2020-08-29 13:12:29 [INFO] Mushroom Growth Modifier: 100% +2020-08-29 13:12:29 [INFO] Pumpkin Growth Modifier: 100% +2020-08-29 13:12:29 [INFO] Sapling Growth Modifier: 100% +2020-08-29 13:12:29 [INFO] Wheat Growth Modifier: 100% +2020-08-29 13:12:29 [INFO] Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64 +2020-08-29 13:12:29 [INFO] Random Lighting Updates: false +2020-08-29 13:12:29 [INFO] Anti X-Ray: true +2020-08-29 13:12:29 [INFO] Engine Mode: 1 +2020-08-29 13:12:29 [INFO] Blocks: [1, 5, 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130] +2020-08-29 13:12:29 [INFO] Mob Spawn Range: 4 +2020-08-29 13:12:29 [INFO] Preparing start region for level 0 (Seed: 2278403607148349813) +2020-08-29 13:12:30 [INFO] Preparing spawn area: 99% +2020-08-29 13:12:30 [INFO] Preparing start region for level 1 (Seed: 2278403607148349813) +2020-08-29 13:12:31 [INFO] Preparing spawn area: 99% +2020-08-29 13:12:31 [INFO] Preparing start region for level 2 (Seed: 2278403607148349813) +2020-08-29 13:12:32 [INFO] Server permissions file permissions.yml is empty, ignoring it +2020-08-29 13:12:32 [INFO] Done (3.466s)! For help, type "help" or "?" +2020-08-29 13:13:08 [INFO] LAX1DUDE[/127.0.0.1:57240] logged in with entity id 273 at ([world] 891.6020000693486, 73.0, -124.36172354991554) +2020-08-29 13:13:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 13:47:54 [INFO] LAX1DUDE[/127.0.0.1:57297] logged in with entity id 444 at ([world] 891.6020000693486, 73.0, -124.36172354991554) +2020-08-29 13:48:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 13:49:22 [INFO] LAX1DUDE[/127.0.0.1:57304] logged in with entity id 617 at ([world] 891.6020000693486, 73.0, -124.36172354991554) +2020-08-29 13:49:42 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 16:57:11 [INFO] LAX1DUDE[/127.0.0.1:57611] logged in with entity id 790 at ([world] 891.6020000693486, 79.49728719698678, -124.36172354991554) +2020-08-29 16:58:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 16:58:52 [INFO] LAX1DUDE[/127.0.0.1:57623] logged in with entity id 992 at ([world] 891.6020000693486, 73.0, -124.36172354991554) +2020-08-29 16:59:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 17:04:17 [INFO] LAX1DUDE[/127.0.0.1:57636] logged in with entity id 1166 at ([world] 891.6020000693486, 73.0, -124.36172354991554) +2020-08-29 17:05:42 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 17:08:28 [INFO] LAX1DUDE[/127.0.0.1:57648] logged in with entity id 1344 at ([world] 891.6020000693486, 73.0, -124.36172354991554) +2020-08-29 17:08:33 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 17:13:27 [INFO] LAX1DUDE[/127.0.0.1:57943] logged in with entity id 1510 at ([world] 891.6020000693486, 73.0, -124.36172354991554) +2020-08-29 17:13:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 17:15:53 [INFO] LAX1DUDE[/127.0.0.1:57953] logged in with entity id 1676 at ([world] 891.6020000693486, 73.0, -124.36172354991554) +2020-08-29 17:15:59 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 17:22:54 [INFO] LAX1DUDE[/127.0.0.1:57979] logged in with entity id 1844 at ([world] 891.6020000693486, 73.0, -124.36172354991554) +2020-08-29 17:23:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 22:11:52 [INFO] LAX1DUDE[/127.0.0.1:58704] logged in with entity id 2013 at ([world] 891.6020000693486, 73.0, -124.36172354991554) +2020-08-29 22:11:56 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 22:13:11 [INFO] LAX1DUDE[/127.0.0.1:58720] logged in with entity id 2179 at ([world] 891.6020000693486, 73.0, -124.36172354991554) +2020-08-29 22:13:15 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 22:25:25 [INFO] LAX1DUDE[/127.0.0.1:58743] logged in with entity id 2345 at ([world] 891.6020000693486, 73.0, -124.36172354991554) +2020-08-29 22:25:30 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 22:27:53 [INFO] LAX1DUDE[/127.0.0.1:58754] logged in with entity id 2511 at ([world] 891.6020000693486, 73.0, -124.36172354991554) +2020-08-29 22:28:15 [INFO] LAX1DUDE issued server command: /time set day +2020-08-29 22:28:15 [INFO] LAX1DUDE: Set time to 0 +2020-08-29 22:28:33 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 23:13:15 [INFO] LAX1DUDE[/127.0.0.1:58838] logged in with entity id 2691 at ([world] 882.0590375530448, 72.0, -133.49253955676258) +2020-08-29 23:15:43 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 23:18:31 [INFO] LAX1DUDE[/127.0.0.1:58853] logged in with entity id 3150 at ([world] 861.1508059873045, 71.0, -145.46209853154426) +2020-08-29 23:19:51 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 23:22:47 [INFO] LAX1DUDE[/127.0.0.1:58868] logged in with entity id 3415 at ([world] 860.2375000119209, 71.0, -147.177999481281) +2020-08-29 23:23:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 23:26:17 [INFO] LAX1DUDE[/127.0.0.1:58881] logged in with entity id 3618 at ([world] 860.2375000119209, 71.0, -147.020943867823) +2020-08-29 23:36:46 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-29 23:37:29 [INFO] LAX1DUDE[/127.0.0.1:58932] logged in with entity id 4362 at ([world] 905.2286104966051, 77.6222799498094, -150.3997811405482) +2020-08-29 23:39:34 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 16:30:26 [INFO] LAX1DUDE[/127.0.0.1:61816] logged in with entity id 4663 at ([world] 898.0661319196578, 72.0, -125.51062663142201) +2020-08-30 16:35:12 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 16:36:21 [INFO] LAX1DUDE[/127.0.0.1:61836] logged in with entity id 5082 at ([world] 898.0661319196578, 72.0, -125.51062663142201) +2020-08-30 16:36:27 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 16:36:49 [INFO] LAX1DUDE[/127.0.0.1:61842] logged in with entity id 5239 at ([world] 898.0661319196578, 72.0, -125.51062663142201) +2020-08-30 16:36:52 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 16:37:40 [INFO] LAX1DUDE[/127.0.0.1:61847] logged in with entity id 5396 at ([world] 898.0661319196578, 72.0, -125.51062663142201) +2020-08-30 16:37:43 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 16:41:13 [INFO] LAX1DUDE[/127.0.0.1:61857] logged in with entity id 5553 at ([world] 898.0661319196578, 72.0, -125.51062663142201) +2020-08-30 16:43:03 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 16:56:50 [INFO] LAX1DUDE[/127.0.0.1:61885] logged in with entity id 5739 at ([world] 898.0661319196578, 72.0, -125.51062663142201) +2020-08-30 16:58:16 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 16:59:58 [INFO] LAX1DUDE[/127.0.0.1:61896] logged in with entity id 5960 at ([world] 895.9864640516882, 73.0, -124.44436724362775) +2020-08-30 17:00:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 17:02:08 [INFO] LAX1DUDE[/127.0.0.1:61904] logged in with entity id 6150 at ([world] 901.7471884628758, 72.0, -131.37925643915958) +2020-08-30 17:02:16 [INFO] LAX1DUDE issued server command: /time set dat +2020-08-30 17:02:16 [INFO] LAX1DUDE: Set time to 0 +2020-08-30 17:03:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 17:07:27 [INFO] LAX1DUDE[/127.0.0.1:61923] logged in with entity id 6364 at ([world] 903.7548301703714, 72.0, -132.36470722746716) +2020-08-30 17:13:24 [INFO] LAX1DUDE issued server command: /time set day +2020-08-30 17:13:24 [INFO] LAX1DUDE: Set time to 0 +2020-08-30 17:17:49 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 17:48:35 [INFO] LAX1DUDE[/127.0.0.1:62127] logged in with entity id 7180 at ([world] 881.8529314556896, 74.9375, -135.5028007753229) +2020-08-30 17:49:08 [INFO] LAX1DUDE issued server command: /time set day +2020-08-30 17:49:08 [INFO] LAX1DUDE: Set time to 0 +2020-08-30 17:54:25 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 18:00:49 [INFO] LAX1DUDE[/127.0.0.1:62152] logged in with entity id 8051 at ([world] 842.6602411338739, 80.61435596677181, -176.0709445170843) +2020-08-30 18:01:36 [INFO] LAX1DUDE issued server command: /time set day +2020-08-30 18:01:36 [INFO] LAX1DUDE: Set time to 0 +2020-08-30 18:07:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 18:07:37 [INFO] LAX1DUDE[/127.0.0.1:62168] logged in with entity id 9621 at ([world] 936.5423266975155, 96.1143559654544, -18.14358557152034) +2020-08-30 18:08:40 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 18:10:47 [INFO] LAX1DUDE[/127.0.0.1:62184] logged in with entity id 9843 at ([world] 941.7348560759721, 79.56935794268347, 18.942190539460046) +2020-08-30 18:10:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 18:11:22 [INFO] LAX1DUDE[/127.0.0.1:62189] logged in with entity id 9952 at ([world] 932.9742187629532, 77.0437392359439, 11.110805059773078) +2020-08-30 18:11:27 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 18:12:14 [INFO] LAX1DUDE[/127.0.0.1:62194] logged in with entity id 10054 at ([world] 932.9742187629532, 65.0, 11.110805059773078) +2020-08-30 18:12:38 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 18:16:32 [INFO] LAX1DUDE[/127.0.0.1:62209] logged in with entity id 10172 at ([world] 920.8371946239924, 84.11000012388666, -19.7722317553851) +2020-08-30 18:16:44 [INFO] LAX1DUDE issued server command: /times set day +2020-08-30 18:16:49 [INFO] LAX1DUDE issued server command: /time set day +2020-08-30 18:16:49 [INFO] LAX1DUDE: Set time to 0 +2020-08-30 18:16:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 18:42:27 [INFO] LAX1DUDE[/127.0.0.1:62252] logged in with entity id 10284 at ([world] 920.8371946239924, 69.8908568781011, -19.7722317553851) +2020-08-30 18:44:25 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 18:50:33 [INFO] LAX1DUDE[/127.0.0.1:62296] logged in with entity id 18415 at ([world] 897.5581854157291, 67.0, -49.76248502777415) +2020-08-30 18:50:45 [INFO] LAX1DUDE issued server command: /time set day +2020-08-30 18:50:45 [INFO] LAX1DUDE: Set time to 0 +2020-08-30 18:50:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 18:52:50 [INFO] LAX1DUDE[/127.0.0.1:62308] logged in with entity id 18544 at ([world] 897.4706745707633, 67.0, -49.14531073718258) +2020-08-30 19:00:53 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 19:01:34 [INFO] LAX1DUDE[/127.0.0.1:62326] logged in with entity id 29074 at ([world] 1091.2969939415202, 91.12164889847182, -100.01698398954203) +2020-08-30 19:01:50 [INFO] LAX1DUDE issued server command: /time set day +2020-08-30 19:01:50 [INFO] LAX1DUDE: Set time to 0 +2020-08-30 19:03:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 19:04:31 [INFO] LAX1DUDE[/127.0.0.1:62335] logged in with entity id 36153 at ([world] 1031.526925195882, 64.0, -16.9255191814231) +2020-08-30 19:06:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 19:07:09 [INFO] LAX1DUDE[/127.0.0.1:62346] logged in with entity id 36463 at ([world] 1033.699999988079, 63.0, -4.699999988079066) +2020-08-30 19:07:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 19:43:11 [INFO] LAX1DUDE[/127.0.0.1:62693] logged in with entity id 36590 at ([world] 1032.8515042659733, 70.0, -47.60708004558296) +2020-08-30 19:44:01 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 19:45:43 [INFO] LAX1DUDE[/127.0.0.1:62701] logged in with entity id 37029 at ([world] 996.5434276321694, 64.67269944352356, 62.054907913916736) +2020-08-30 19:45:57 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 19:46:32 [INFO] LAX1DUDE[/127.0.0.1:62704] logged in with entity id 37133 at ([world] 1006.1061464393462, 64.99886658913736, 60.57263497283367) +2020-08-30 19:48:47 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 19:50:00 [INFO] LAX1DUDE[/127.0.0.1:62717] logged in with entity id 37585 at ([world] 1088.0659781744193, 68.0, -59.457645088072866) +2020-08-30 19:52:43 [INFO] LAX1DUDE issued server command: /time set day +2020-08-30 19:52:43 [INFO] LAX1DUDE: Set time to 0 +2020-08-30 19:54:24 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 19:54:53 [INFO] LAX1DUDE[/127.0.0.1:62737] logged in with entity id 38991 at ([world] 965.4387140620381, 91.9906630435781, -109.6124139488063) +2020-08-30 20:04:14 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 21:20:52 [INFO] LAX1DUDE[/127.0.0.1:63241] logged in with entity id 40479 at ([world] 796.8933228557179, 65.0, 45.21980558520328) +2020-08-30 21:24:31 [INFO] LAX1DUDE issued server command: /time set day +2020-08-30 21:24:31 [INFO] LAX1DUDE: Set time to 0 +2020-08-30 21:25:59 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 21:34:01 [INFO] LAX1DUDE[/127.0.0.1:63278] logged in with entity id 41394 at ([world] 848.7715947241478, 64.0, 50.64193285152884) +2020-08-30 21:34:10 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 21:35:15 [INFO] LAX1DUDE[/127.0.0.1:63287] logged in with entity id 41507 at ([world] 848.7715947241478, 64.0, 50.64193285152884) +2020-08-30 21:35:19 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 21:39:21 [INFO] LAX1DUDE[/127.0.0.1:63323] logged in with entity id 41631 at ([world] 848.7715947241478, 64.0, 50.64193285152884) +2020-08-30 21:39:27 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 21:44:47 [INFO] LAX1DUDE[/127.0.0.1:63363] logged in with entity id 41744 at ([world] 848.7715947241478, 64.0, 50.64193285152884) +2020-08-30 21:45:28 [SEVERE] io.netty.handler.timeout.ReadTimeoutException +2020-08-30 21:45:28 [INFO] LAX1DUDE lost connection: disconnect.genericReason +2020-08-30 21:48:22 [INFO] LAX1DUDE[/127.0.0.1:63384] logged in with entity id 41871 at ([world] 847.0988213313864, 82.23935596545499, 50.69564939611023) +2020-08-30 21:48:52 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 21:57:03 [INFO] LAX1DUDE[/127.0.0.1:63419] logged in with entity id 42014 at ([world] 847.0988213313864, 82.23935596545499, 50.69564939611023) +2020-08-30 21:59:30 [INFO] LAX1DUDE issued server command: /time set day +2020-08-30 21:59:30 [INFO] LAX1DUDE: Set time to 0 +2020-08-30 22:00:54 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 22:35:07 [INFO] LAX1DUDE[/127.0.0.1:63587] logged in with entity id 42560 at ([world] 991.919951308211, 63.0, 56.002647743001724) +2020-08-30 22:37:02 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 22:40:13 [INFO] LAX1DUDE[/127.0.0.1:63609] logged in with entity id 42924 at ([world] 1022.9486683367529, 79.04250823608922, 88.32782183606513) +2020-08-30 22:42:46 [INFO] LAX1DUDE issued server command: /tp 0 100 0 +2020-08-30 22:42:46 [INFO] LAX1DUDE: Teleported LAX1DUDE to 0.50, 100.50, 0.50 +2020-08-30 22:43:00 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 22:44:19 [INFO] LAX1DUDE[/127.0.0.1:63620] logged in with entity id 43832 at ([world] -6.54196583391991, 69.0, -17.98104335963274) +2020-08-30 22:48:11 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 23:12:17 [INFO] LAX1DUDE[/127.0.0.1:64992] logged in with entity id 44847 at ([world] -64.30898418192783, 65.0, 0.2323962317458901) +2020-08-30 23:12:27 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-30 23:13:38 [INFO] LAX1DUDE[/127.0.0.1:65027] logged in with entity id 45035 at ([world] -64.30898418192783, 65.0, 0.23239623174589008) +2020-08-30 23:14:08 [INFO] LAX1DUDE issued server command: /time set day +2020-08-30 23:14:08 [INFO] LAX1DUDE: Set time to 0 +2020-08-30 23:14:46 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-31 00:57:24 [INFO] LAX1DUDE[/127.0.0.1:53818] logged in with entity id 45237 at ([world] -64.65582260272669, 65.0, 9.171318253057473) +2020-08-31 00:57:29 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-31 00:59:50 [INFO] LAX1DUDE[/127.0.0.1:53948] logged in with entity id 45418 at ([world] -64.65582260272669, 65.0, 9.171318253057473) +2020-08-31 01:01:41 [WARNING] LAX1DUDE moved too quickly! 279.18185207723235,-79.90041499648981,-40.21390973428488 (279.18185207723235, 79.90041499648981, 40.21390973428488) +2020-08-31 01:01:52 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-31 01:02:03 [INFO] LAX1DUDE[/127.0.0.1:54060] logged in with entity id 46967 at ([world] -279.18185207723235, 78.28041499172144, 40.21390973428488) +2020-08-31 01:06:17 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-31 01:07:03 [INFO] LAX1DUDE[/127.0.0.1:54317] logged in with entity id 52138 at ([world] -220.4014480454133, 71.0, 351.3988346083596) +2020-08-31 01:07:54 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-31 01:20:16 [INFO] LAX1DUDE[/127.0.0.1:54988] logged in with entity id 52404 at ([world] -194.0166235616091, 69.2567279369895, 504.8808582167125) +2020-08-31 01:23:36 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-31 01:28:38 [INFO] LAX1DUDE[/127.0.0.1:55182] logged in with entity id 53548 at ([world] -532.8722989253956, 66.0, 291.57058064610897) +2020-08-31 01:29:07 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-31 01:29:22 [INFO] LAX1DUDE[/127.0.0.1:55187] logged in with entity id 53722 at ([world] -532.8722989253956, 66.0, 291.57058064610897) +2020-08-31 01:29:31 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-31 01:30:46 [INFO] LAX1DUDE_[/127.0.0.1:55202] logged in with entity id 53909 at ([world] 194.30112244601236, 74.62227991901771, 216.68671579313758) +2020-08-31 01:32:10 [INFO] LAX1DUDE_ lost connection: disconnect.quitting +2020-08-31 01:40:08 [INFO] LAX1DUDE_[/127.0.0.1:55227] logged in with entity id 55271 at ([world] 225.70637997650357, 68.0, 307.3000000119208) +2020-08-31 01:41:15 [INFO] yee +2020-08-31 01:42:41 [INFO] LAX1DUDE_ lost connection: disconnect.quitting +2020-08-31 02:07:45 [INFO] LAX1DUDE_[/127.0.0.1:55268] logged in with entity id 55860 at ([world] 215.56027430846342, 75.0, 240.61859828298475) +2020-08-31 02:08:20 [INFO] LAX1DUDE_ issued server command: /time set day +2020-08-31 02:08:23 [INFO] LAX1DUDE_ lost connection: disconnect.quitting +2020-08-31 02:08:29 [INFO] LAX1DUDE[/127.0.0.1:55287] logged in with entity id 56063 at ([world] -541.0797493562203, 86.86435596545437, 292.4892503114358) +2020-08-31 02:08:36 [INFO] LAX1DUDE issued server command: /time set day +2020-08-31 02:08:36 [INFO] LAX1DUDE: Set time to 0 +2020-08-31 02:12:43 [INFO] LAX1DUDE issued server command: /kill +2020-08-31 02:12:43 [INFO] LAX1DUDE died +2020-08-31 02:13:32 [INFO] LAX1DUDE issued server command: /weather clear +2020-08-31 02:13:32 [INFO] LAX1DUDE: Changed weather to clear for 384 seconds. +2020-08-31 02:18:08 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-31 16:42:43 [INFO] LAX1DUDE[/127.0.0.1:56831] logged in with entity id 62083 at ([world] 561.7529517916029, 64.0, 330.2208981053272) +2020-08-31 16:43:02 [INFO] LAX1DUDE issued server command: /time set day +2020-08-31 16:43:02 [INFO] LAX1DUDE: Set time to 0 +2020-08-31 16:45:01 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-31 16:46:11 [INFO] LAX1DUDE[/127.0.0.1:56846] logged in with entity id 62676 at ([world] 560.8115821672475, 71.0, 269.0642767287913) +2020-08-31 16:46:46 [INFO] LAX1DUDE issued server command: /kill +2020-08-31 16:46:46 [INFO] LAX1DUDE died +2020-08-31 16:47:08 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-31 16:48:10 [INFO] LAX1DUDE[/127.0.0.1:56856] logged in with entity id 64450 at ([world] 30.40010722085392, 79.41712062943917, 381.5571085765432) +2020-08-31 16:59:55 [INFO] LAX1DUDE issued server command: /time set day +2020-08-31 16:59:55 [INFO] LAX1DUDE: Set time to 0 +2020-08-31 17:00:16 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-31 17:00:53 [INFO] LAX1DUDE[/127.0.0.1:56876] logged in with entity id 67576 at ([world] 861.6662225640706, 76.14679443723294, 899.9618718008342) +2020-08-31 17:01:48 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-31 17:19:41 [INFO] LAX1DUDE[/127.0.0.1:56937] logged in with entity id 68353 at ([world] 896.4325310119247, 66.0, 950.1970002895569) +2020-08-31 17:24:27 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-31 17:24:37 [INFO] LAX1DUDE[/127.0.0.1:56963] logged in with entity id 69363 at ([world] 881.6870705562906, 66.0, 903.1384240938572) +2020-08-31 17:27:20 [INFO] LAX1DUDE lost connection: disconnect.quitting +2020-08-31 17:36:21 [INFO] FudglerCum84[/127.0.0.1:57054] logged in with entity id 69856 at ([world] 283.5399894549392, 69.0, 314.7719454337554) +2020-08-31 17:36:44 [INFO] FudglerCum84 lost connection: disconnect.quitting +2020-08-31 17:36:47 [INFO] FudglerCum84[/127.0.0.1:57059] logged in with entity id 70087 at ([world] 278.4163896199539, 71.9375, 338.62857907697025) +2020-08-31 17:45:07 [INFO] FudglerCum84 lost connection: disconnect.quitting diff --git a/spigot-server/server.log.lck b/spigot-server/server.log.lck new file mode 100644 index 0000000..e69de29 diff --git a/spigot-server/server.properties b/spigot-server/server.properties new file mode 100644 index 0000000..28c0649 --- /dev/null +++ b/spigot-server/server.properties @@ -0,0 +1,30 @@ +#Minecraft server properties +#Sat Aug 29 13:12:27 PDT 2020 +generator-settings= +allow-nether=true +level-name=world +enable-query=false +allow-flight=false +server-port=25501 +level-type=DEFAULT +enable-rcon=false +force-gamemode=true +level-seed= +server-ip= +max-build-height=256 +spawn-npcs=true +white-list=false +spawn-animals=true +texture-pack= +snooper-enabled=true +hardcore=false +online-mode=false +pvp=true +difficulty=1 +gamemode=1 +max-players=20 +spawn-monsters=true +view-distance=10 +generate-structures=true +spawn-protection=16 +motd=A Minecraft Server diff --git a/spigot-server/spigot-1.5.2-R1.1-SNAPSHOT.jar b/spigot-server/spigot-1.5.2-R1.1-SNAPSHOT.jar new file mode 100644 index 0000000..5b18ede Binary files /dev/null and b/spigot-server/spigot-1.5.2-R1.1-SNAPSHOT.jar differ diff --git a/spigot-server/spigot.yml b/spigot-server/spigot.yml new file mode 100644 index 0000000..69ac5dd --- /dev/null +++ b/spigot-server/spigot.yml @@ -0,0 +1,87 @@ +# This is the main configuration file for Spigot. +# As you can see, there's tons to configure. Some options may impact gameplay, so use +# with caution, and make sure you know what each option does before configuring. +# For a reference for any variable inside this file, check out the Spigot wiki at +# http://www.spigotmc.org/wiki/spigot-configuration/ +# +# If you need help with the configuration or have any questions related to Spigot, +# join us at the IRC or drop by our forums and leave a post. +# +# IRC: #spigot @ irc.esper.net ( http://webchat.esper.net/?channel=spigot ) +# Forums: http://www.spigotmc.org/forum/ + +config-version: 1 +commands: + tab-complete: true + spam-exclusions: + - /skill + log: true +listeners: +- port: default + host: default + netty: true +settings: + netty-threads: 3 + prevent-proxies: false + bungeecord-addresses: + - 127.0.0.1 + bungeecord: true + timeout-time: 60 + restart-on-crash: true + restart-script: ./start.sh + log-filters: + - ^(.*)(/login)(.*)$ +messages: + whitelist: You are not whitelisted on this server! + unknown-command: Unknown command. Type "help" for help. + server-full: The server is full! +world-settings: + default: + verbose: true + view-distance: 10 + chunks-per-tick: 650 + merge-radius: + exp: 3.0 + item: 2.5 + entity-activation-range: + animals: 32 + monsters: 32 + misc: 16 + ticks-per: + hopper-check: 8 + hopper-transfer: 8 + growth: + cactus-modifier: 100 + cane-modifier: 100 + melon-modifier: 100 + mushroom-modifier: 100 + pumpkin-modifier: 100 + sapling-modifier: 100 + wheat-modifier: 100 + entity-tracking-range: + players: 48 + animals: 48 + monsters: 48 + misc: 32 + other: 64 + random-light-updates: false + anti-xray: + enabled: true + engine-mode: 1 + blocks: + - 1 + - 5 + - 14 + - 15 + - 16 + - 21 + - 48 + - 49 + - 54 + - 56 + - 73 + - 74 + - 82 + - 129 + - 130 + mob-spawn-range: 4 diff --git a/spigot-server/white-list.txt b/spigot-server/white-list.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/lwjgl/java/com/jcraft/jzlib/Adler32.java b/src/lwjgl/java/com/jcraft/jzlib/Adler32.java new file mode 100644 index 0000000..02a07e1 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/Adler32.java @@ -0,0 +1,118 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class Adler32 implements Checksum { + + // largest prime smaller than 65536 + static final private int BASE=65521; + // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 + static final private int NMAX=5552; + + private long s1=1L; + private long s2=0L; + + public void reset(long init){ + s1=init&0xffff; + s2=(init>>16)&0xffff; + } + + public void reset(){ + s1=1L; + s2=0L; + } + + public long getValue(){ + return ((s2<<16)|s1); + } + + public void update(byte[] buf, int index, int len){ + + if(len==1){ + s1+=buf[index++]&0xff; s2+=s1; + s1%=BASE; + s2%=BASE; + return; + } + + int len1 = len/NMAX; + int len2 = len%NMAX; + while(len1-->0) { + int k=NMAX; + len-=k; + while(k-->0){ + s1+=buf[index++]&0xff; s2+=s1; + } + s1%=BASE; + s2%=BASE; + } + + int k=len2; + len-=k; + while(k-->0){ + s1+=buf[index++]&0xff; s2+=s1; + } + s1%=BASE; + s2%=BASE; + } + + public Adler32 copy(){ + Adler32 foo = new Adler32(); + foo.s1 = this.s1; + foo.s2 = this.s2; + return foo; + } + + // The following logic has come from zlib.1.2. + static long combine(long adler1, long adler2, long len2){ + long BASEL = (long)BASE; + long sum1; + long sum2; + long rem; // unsigned int + + rem = len2 % BASEL; + sum1 = adler1 & 0xffffL; + sum2 = rem * sum1; + sum2 %= BASEL; // MOD(sum2); + sum1 += (adler2 & 0xffffL) + BASEL - 1; + sum2 += ((adler1 >> 16) & 0xffffL) + ((adler2 >> 16) & 0xffffL) + BASEL - rem; + if (sum1 >= BASEL) sum1 -= BASEL; + if (sum1 >= BASEL) sum1 -= BASEL; + if (sum2 >= (BASEL << 1)) sum2 -= (BASEL << 1); + if (sum2 >= BASEL) sum2 -= BASEL; + return sum1 | (sum2 << 16); + } + +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/CRC32.java b/src/lwjgl/java/com/jcraft/jzlib/CRC32.java new file mode 100644 index 0000000..a1b6e75 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/CRC32.java @@ -0,0 +1,157 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class CRC32 implements Checksum { + + /* + * The following logic has come from RFC1952. + */ + private int v = 0; + private static int[] crc_table = null; + static { + crc_table = new int[256]; + for (int n = 0; n < 256; n++) { + int c = n; + for (int k = 8; --k >= 0; ) { + if ((c & 1) != 0) + c = 0xedb88320 ^ (c >>> 1); + else + c = c >>> 1; + } + crc_table[n] = c; + } + } + + public void update (byte[] buf, int index, int len) { + int c = ~v; + while (--len >= 0) + c = crc_table[(c^buf[index++])&0xff]^(c >>> 8); + v = ~c; + } + + public void reset(){ + v = 0; + } + + public void reset(long vv){ + v = (int)(vv&0xffffffffL); + } + + public long getValue(){ + return (long)(v&0xffffffffL); + } + + // The following logic has come from zlib.1.2. + private static final int GF2_DIM = 32; + static long combine(long crc1, long crc2, long len2){ + long row; + long[] even = new long[GF2_DIM]; + long[] odd = new long[GF2_DIM]; + + // degenerate case (also disallow negative lengths) + if (len2 <= 0) + return crc1; + + // put operator for one zero bit in odd + odd[0] = 0xedb88320L; // CRC-32 polynomial + row = 1; + for (int n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + // put operator for two zero bits in even + gf2_matrix_square(even, odd); + + // put operator for four zero bits in odd + gf2_matrix_square(odd, even); + + // apply len2 zeros to crc1 (first square will put the operator for one + // zero byte, eight zero bits, in even) + do { + // apply zeros operator for this bit of len2 + gf2_matrix_square(even, odd); + if ((len2 & 1)!=0) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + // if no more bits set, then done + if (len2 == 0) + break; + + // another iteration of the loop with odd and even swapped + gf2_matrix_square(odd, even); + if ((len2 & 1)!=0) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + // if no more bits set, then done + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; + } + + private static long gf2_matrix_times(long[] mat, long vec){ + long sum = 0; + int index = 0; + while (vec!=0) { + if ((vec & 1)!=0) + sum ^= mat[index]; + vec >>= 1; + index++; + } + return sum; + } + + static final void gf2_matrix_square(long[] square, long[] mat) { + for (int n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); + } + + public CRC32 copy(){ + CRC32 foo = new CRC32(); + foo.v = this.v; + return foo; + } + + public static int[] getCRC32Table(){ + int[] tmp = new int[crc_table.length]; + System.arraycopy(crc_table, 0, tmp, 0, tmp.length); + return tmp; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/Checksum.java b/src/lwjgl/java/com/jcraft/jzlib/Checksum.java new file mode 100644 index 0000000..1139093 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/Checksum.java @@ -0,0 +1,43 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +interface Checksum { + void update(byte[] buf, int index, int len); + void reset(); + void reset(long init); + long getValue(); + Checksum copy(); +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/Deflate.java b/src/lwjgl/java/com/jcraft/jzlib/Deflate.java new file mode 100644 index 0000000..cfda0f0 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/Deflate.java @@ -0,0 +1,1757 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +public +final class Deflate implements Cloneable { + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_DEFAULT_COMPRESSION=-1; + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_MEM_LEVEL=8; + + static class Config{ + int good_length; // reduce lazy search above this match length + int max_lazy; // do not perform lazy search above this match length + int nice_length; // quit search above this match length + int max_chain; + int func; + Config(int good_length, int max_lazy, + int nice_length, int max_chain, int func){ + this.good_length=good_length; + this.max_lazy=max_lazy; + this.nice_length=nice_length; + this.max_chain=max_chain; + this.func=func; + } + } + + static final private int STORED=0; + static final private int FAST=1; + static final private int SLOW=2; + static final private Config[] config_table; + static{ + config_table=new Config[10]; + // good lazy nice chain + config_table[0]=new Config(0, 0, 0, 0, STORED); + config_table[1]=new Config(4, 4, 8, 4, FAST); + config_table[2]=new Config(4, 5, 16, 8, FAST); + config_table[3]=new Config(4, 6, 32, 32, FAST); + + config_table[4]=new Config(4, 4, 16, 16, SLOW); + config_table[5]=new Config(8, 16, 32, 32, SLOW); + config_table[6]=new Config(8, 16, 128, 128, SLOW); + config_table[7]=new Config(8, 32, 128, 256, SLOW); + config_table[8]=new Config(32, 128, 258, 1024, SLOW); + config_table[9]=new Config(32, 258, 258, 4096, SLOW); + } + + static final private String[] z_errmsg = { + "need dictionary", // Z_NEED_DICT 2 + "stream end", // Z_STREAM_END 1 + "", // Z_OK 0 + "file error", // Z_ERRNO (-1) + "stream error", // Z_STREAM_ERROR (-2) + "data error", // Z_DATA_ERROR (-3) + "insufficient memory", // Z_MEM_ERROR (-4) + "buffer error", // Z_BUF_ERROR (-5) + "incompatible version",// Z_VERSION_ERROR (-6) + "" + }; + + // block not completed, need more input or more output + static final private int NeedMore=0; + + // block flush performed + static final private int BlockDone=1; + + // finish started, need only more output at next deflate + static final private int FinishStarted=2; + + // finish done, accept no more input or output + static final private int FinishDone=3; + + // preset dictionary flag in zlib header + static final private int PRESET_DICT=0x20; + + static final private int Z_FILTERED=1; + static final private int Z_HUFFMAN_ONLY=2; + static final private int Z_DEFAULT_STRATEGY=0; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + static final private int INIT_STATE=42; + static final private int BUSY_STATE=113; + static final private int FINISH_STATE=666; + + // The deflate compression method + static final private int Z_DEFLATED=8; + + static final private int STORED_BLOCK=0; + static final private int STATIC_TREES=1; + static final private int DYN_TREES=2; + + // The three kinds of block type + static final private int Z_BINARY=0; + static final private int Z_ASCII=1; + static final private int Z_UNKNOWN=2; + + static final private int Buf_size=8*2; + + // repeat previous bit length 3-6 times (2 bits of repeat count) + static final private int REP_3_6=16; + + // repeat a zero length 3-10 times (3 bits of repeat count) + static final private int REPZ_3_10=17; + + // repeat a zero length 11-138 times (7 bits of repeat count) + static final private int REPZ_11_138=18; + + static final private int MIN_MATCH=3; + static final private int MAX_MATCH=258; + static final private int MIN_LOOKAHEAD=(MAX_MATCH+MIN_MATCH+1); + + static final private int MAX_BITS=15; + static final private int D_CODES=30; + static final private int BL_CODES=19; + static final private int LENGTH_CODES=29; + static final private int LITERALS=256; + static final private int L_CODES=(LITERALS+1+LENGTH_CODES); + static final private int HEAP_SIZE=(2*L_CODES+1); + + static final private int END_BLOCK=256; + + ZStream strm; // pointer back to this zlib stream + int status; // as the name implies + byte[] pending_buf; // output still pending + int pending_buf_size; // size of pending_buf + int pending_out; // next pending byte to output to the stream + int pending; // nb of bytes in the pending buffer + int wrap = 1; + byte data_type; // UNKNOWN, BINARY or ASCII + byte method; // STORED (for zip only) or DEFLATED + int last_flush; // value of flush param for previous deflate call + + int w_size; // LZ77 window size (32K by default) + int w_bits; // log2(w_size) (8..16) + int w_mask; // w_size - 1 + + byte[] window; + // Sliding window. Input bytes are read into the second half of the window, + // and move to the first half later to keep a dictionary of at least wSize + // bytes. With this organization, matches are limited to a distance of + // wSize-MAX_MATCH bytes, but this ensures that IO is always + // performed with a length multiple of the block size. Also, it limits + // the window size to 64K, which is quite useful on MSDOS. + // To do: use the user input buffer as sliding window. + + int window_size; + // Actual size of window: 2*wSize, except when the user input buffer + // is directly used as sliding window. + + short[] prev; + // Link to older string with same hash index. To limit the size of this + // array to 64K, this link is maintained only for the last 32K strings. + // An index in this array is thus a window index modulo 32K. + + short[] head; // Heads of the hash chains or NIL. + + int ins_h; // hash index of string to be inserted + int hash_size; // number of elements in hash table + int hash_bits; // log2(hash_size) + int hash_mask; // hash_size-1 + + // Number of bits by which ins_h must be shifted at each input + // step. It must be such that after MIN_MATCH steps, the oldest + // byte no longer takes part in the hash key, that is: + // hash_shift * MIN_MATCH >= hash_bits + int hash_shift; + + // Window position at the beginning of the current output block. Gets + // negative when the window is moved backwards. + + int block_start; + + int match_length; // length of best match + int prev_match; // previous match + int match_available; // set if previous match exists + int strstart; // start of string to insert + int match_start; // start of matching string + int lookahead; // number of valid bytes ahead in window + + // Length of the best match at previous step. Matches not greater than this + // are discarded. This is used in the lazy match evaluation. + int prev_length; + + // To speed up deflation, hash chains are never searched beyond this + // length. A higher limit improves compression ratio but degrades the speed. + int max_chain_length; + + // Attempt to find a better match only when the current match is strictly + // smaller than this value. This mechanism is used only for compression + // levels >= 4. + int max_lazy_match; + + // Insert new strings in the hash table only if the match length is not + // greater than this length. This saves time but degrades compression. + // max_insert_length is used only for compression levels <= 3. + + int level; // compression level (1..9) + int strategy; // favor or force Huffman coding + + // Use a faster search when the previous match is longer than this + int good_match; + + // Stop searching when current match exceeds this + int nice_match; + + short[] dyn_ltree; // literal and length tree + short[] dyn_dtree; // distance tree + short[] bl_tree; // Huffman tree for bit lengths + + Tree l_desc=new Tree(); // desc for literal tree + Tree d_desc=new Tree(); // desc for distance tree + Tree bl_desc=new Tree(); // desc for bit length tree + + // number of codes at each bit length for an optimal tree + short[] bl_count=new short[MAX_BITS+1]; + // working area to be used in Tree#gen_codes() + short[] next_code=new short[MAX_BITS+1]; + + // heap used to build the Huffman trees + int[] heap=new int[2*L_CODES+1]; + + int heap_len; // number of elements in the heap + int heap_max; // element of largest frequency + // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + // The same heap array is used to build all trees. + + // Depth of each subtree used as tie breaker for trees of equal frequency + byte[] depth=new byte[2*L_CODES+1]; + + byte[] l_buf; // index for literals or lengths */ + + // Size of match buffer for literals/lengths. There are 4 reasons for + // limiting lit_bufsize to 64K: + // - frequencies can be kept in 16 bit counters + // - if compression is not successful for the first block, all input + // data is still in the window so we can still emit a stored block even + // when input comes from standard input. (This can also be done for + // all blocks if lit_bufsize is not greater than 32K.) + // - if compression is not successful for a file smaller than 64K, we can + // even emit a stored file instead of a stored block (saving 5 bytes). + // This is applicable only for zip (not gzip or zlib). + // - creating new Huffman trees less frequently may not provide fast + // adaptation to changes in the input data statistics. (Take for + // example a binary file with poorly compressible code followed by + // a highly compressible string table.) Smaller buffer sizes give + // fast adaptation but have of course the overhead of transmitting + // trees more frequently. + // - I can't count above 4 + int lit_bufsize; + + int last_lit; // running index in l_buf + + // Buffer for distances. To simplify the code, d_buf and l_buf have + // the same number of elements. To use different lengths, an extra flag + // array would be necessary. + + int d_buf; // index of pendig_buf + + int opt_len; // bit length of current block with optimal trees + int static_len; // bit length of current block with static trees + int matches; // number of string matches in current block + int last_eob_len; // bit length of EOB code for last block + + // Output buffer. bits are inserted starting at the bottom (least + // significant bits). + short bi_buf; + + // Number of valid bits in bi_buf. All bits above the last valid bit + // are always zero. + int bi_valid; + + GZIPHeader gheader = null; + + Deflate(ZStream strm){ + this.strm=strm; + dyn_ltree=new short[HEAP_SIZE*2]; + dyn_dtree=new short[(2*D_CODES+1)*2]; // distance tree + bl_tree=new short[(2*BL_CODES+1)*2]; // Huffman tree for bit lengths + } + + void lm_init() { + window_size=2*w_size; + + head[hash_size-1]=0; + for(int i=0; i= 3; max_blindex--) { + if (bl_tree[Tree.bl_order[max_blindex]*2+1] != 0) break; + } + // Update opt_len to include the bit length tree and counts + opt_len += 3*(max_blindex+1) + 5+5+4; + + return max_blindex; + } + + + // Send the header for a block using dynamic Huffman trees: the counts, the + // lengths of the bit length codes, the literal tree and the distance tree. + // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + void send_all_trees(int lcodes, int dcodes, int blcodes){ + int rank; // index in bl_order + + send_bits(lcodes-257, 5); // not +255 as stated in appnote.txt + send_bits(dcodes-1, 5); + send_bits(blcodes-4, 4); // not -3 as stated in appnote.txt + for (rank = 0; rank < blcodes; rank++) { + send_bits(bl_tree[Tree.bl_order[rank]*2+1], 3); + } + send_tree(dyn_ltree, lcodes-1); // literal tree + send_tree(dyn_dtree, dcodes-1); // distance tree + } + + // Send a literal or distance tree in compressed form, using the codes in + // bl_tree. + void send_tree (short[] tree,// the tree to be sent + int max_code // and its largest code of non zero frequency + ){ + int n; // iterates over all tree elements + int prevlen = -1; // last emitted length + int curlen; // length of current code + int nextlen = tree[0*2+1]; // length of next code + int count = 0; // repeat count of the current code + int max_count = 7; // max repeat count + int min_count = 4; // min repeat count + + if (nextlen == 0){ max_count = 138; min_count = 3; } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[(n+1)*2+1]; + if(++count < max_count && curlen == nextlen) { + continue; + } + else if(count < min_count) { + do { send_code(curlen, bl_tree); } while (--count != 0); + } + else if(curlen != 0){ + if(curlen != prevlen){ + send_code(curlen, bl_tree); count--; + } + send_code(REP_3_6, bl_tree); + send_bits(count-3, 2); + } + else if(count <= 10){ + send_code(REPZ_3_10, bl_tree); + send_bits(count-3, 3); + } + else{ + send_code(REPZ_11_138, bl_tree); + send_bits(count-11, 7); + } + count = 0; prevlen = curlen; + if(nextlen == 0){ + max_count = 138; min_count = 3; + } + else if(curlen == nextlen){ + max_count = 6; min_count = 3; + } + else{ + max_count = 7; min_count = 4; + } + } + } + + // Output a byte on the stream. + // IN assertion: there is enough room in pending_buf. + final void put_byte(byte[] p, int start, int len){ + System.arraycopy(p, start, pending_buf, pending, len); + pending+=len; + } + + final void put_byte(byte c){ + pending_buf[pending++]=c; + } + final void put_short(int w) { + put_byte((byte)(w/*&0xff*/)); + put_byte((byte)(w>>>8)); + } + final void putShortMSB(int b){ + put_byte((byte)(b>>8)); + put_byte((byte)(b/*&0xff*/)); + } + + final void send_code(int c, short[] tree){ + int c2=c*2; + send_bits((tree[c2]&0xffff), (tree[c2+1]&0xffff)); + } + + void send_bits(int value, int length){ + int len = length; + if (bi_valid > (int)Buf_size - len) { + int val = value; +// bi_buf |= (val << bi_valid); + bi_buf |= ((val << bi_valid)&0xffff); + put_short(bi_buf); + bi_buf = (short)(val >>> (Buf_size - bi_valid)); + bi_valid += len - Buf_size; + } else { +// bi_buf |= (value) << bi_valid; + bi_buf |= (((value) << bi_valid)&0xffff); + bi_valid += len; + } + } + + // Send one empty static block to give enough lookahead for inflate. + // This takes 10 bits, of which 7 may remain in the bit buffer. + // The current inflate code requires 9 bits of lookahead. If the + // last two codes for the previous block (real code plus EOB) were coded + // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + // the last real code. In this case we send two empty static blocks instead + // of one. (There are no problems if the previous block is stored or fixed.) + // To simplify the code, we assume the worst case of last real code encoded + // on one bit only. + void _tr_align(){ + send_bits(STATIC_TREES<<1, 3); + send_code(END_BLOCK, StaticTree.static_ltree); + + bi_flush(); + + // Of the 10 bits for the empty block, we have already sent + // (10 - bi_valid) bits. The lookahead for the last real code (before + // the EOB of the previous block) was thus at least one plus the length + // of the EOB plus what we have just sent of the empty static block. + if (1 + last_eob_len + 10 - bi_valid < 9) { + send_bits(STATIC_TREES<<1, 3); + send_code(END_BLOCK, StaticTree.static_ltree); + bi_flush(); + } + last_eob_len = 7; + } + + + // Save the match info and tally the frequency counts. Return true if + // the current block must be flushed. + boolean _tr_tally (int dist, // distance of matched string + int lc // match length-MIN_MATCH or unmatched char (if dist==0) + ){ + + pending_buf[d_buf+last_lit*2] = (byte)(dist>>>8); + pending_buf[d_buf+last_lit*2+1] = (byte)dist; + + l_buf[last_lit] = (byte)lc; last_lit++; + + if (dist == 0) { + // lc is the unmatched char + dyn_ltree[lc*2]++; + } + else { + matches++; + // Here, lc is the match length - MIN_MATCH + dist--; // dist = match distance - 1 + dyn_ltree[(Tree._length_code[lc]+LITERALS+1)*2]++; + dyn_dtree[Tree.d_code(dist)*2]++; + } + + if ((last_lit & 0x1fff) == 0 && level > 2) { + // Compute an upper bound for the compressed length + int out_length = last_lit*8; + int in_length = strstart - block_start; + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (int)dyn_dtree[dcode*2] * + (5L+Tree.extra_dbits[dcode]); + } + out_length >>>= 3; + if ((matches < (last_lit/2)) && out_length < in_length/2) return true; + } + + return (last_lit == lit_bufsize-1); + // We avoid equality with lit_bufsize because of wraparound at 64K + // on 16 bit machines and because stored blocks are restricted to + // 64K-1 bytes. + } + + // Send the block data compressed using the given Huffman trees + void compress_block(short[] ltree, short[] dtree){ + int dist; // distance of matched string + int lc; // match length or unmatched char (if dist == 0) + int lx = 0; // running index in l_buf + int code; // the code to send + int extra; // number of extra bits to send + + if (last_lit != 0){ + do{ + dist=((pending_buf[d_buf+lx*2]<<8)&0xff00)| + (pending_buf[d_buf+lx*2+1]&0xff); + lc=(l_buf[lx])&0xff; lx++; + + if(dist == 0){ + send_code(lc, ltree); // send a literal byte + } + else{ + // Here, lc is the match length - MIN_MATCH + code = Tree._length_code[lc]; + + send_code(code+LITERALS+1, ltree); // send the length code + extra = Tree.extra_lbits[code]; + if(extra != 0){ + lc -= Tree.base_length[code]; + send_bits(lc, extra); // send the extra length bits + } + dist--; // dist is now the match distance - 1 + code = Tree.d_code(dist); + + send_code(code, dtree); // send the distance code + extra = Tree.extra_dbits[code]; + if (extra != 0) { + dist -= Tree.base_dist[code]; + send_bits(dist, extra); // send the extra distance bits + } + } // literal or match pair ? + + // Check that the overlay between pending_buf and d_buf+l_buf is ok: + } + while (lx < last_lit); + } + + send_code(END_BLOCK, ltree); + last_eob_len = ltree[END_BLOCK*2+1]; + } + + // Set the data type to ASCII or BINARY, using a crude approximation: + // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + // IN assertion: the fields freq of dyn_ltree are set and the total of all + // frequencies does not exceed 64K (to fit in an int on 16 bit machines). + void set_data_type(){ + int n = 0; + int ascii_freq = 0; + int bin_freq = 0; + while(n<7){ bin_freq += dyn_ltree[n*2]; n++;} + while(n<128){ ascii_freq += dyn_ltree[n*2]; n++;} + while(n (ascii_freq >>> 2) ? Z_BINARY : Z_ASCII); + } + + // Flush the bit buffer, keeping at most 7 bits in it. + void bi_flush(){ + if (bi_valid == 16) { + put_short(bi_buf); + bi_buf=0; + bi_valid=0; + } + else if (bi_valid >= 8) { + put_byte((byte)bi_buf); + bi_buf>>>=8; + bi_valid-=8; + } + } + + // Flush the bit buffer and align the output on a byte boundary + void bi_windup(){ + if (bi_valid > 8) { + put_short(bi_buf); + } else if (bi_valid > 0) { + put_byte((byte)bi_buf); + } + bi_buf = 0; + bi_valid = 0; + } + + // Copy a stored block, storing first the length and its + // one's complement if requested. + void copy_block(int buf, // the input data + int len, // its length + boolean header // true if block header must be written + ){ + int index=0; + bi_windup(); // align on byte boundary + last_eob_len = 8; // enough lookahead for inflate + + if (header) { + put_short((short)len); + put_short((short)~len); + } + + // while(len--!=0) { + // put_byte(window[buf+index]); + // index++; + // } + put_byte(window, buf, len); + } + + void flush_block_only(boolean eof){ + _tr_flush_block(block_start>=0 ? block_start : -1, + strstart-block_start, + eof); + block_start=strstart; + strm.flush_pending(); + } + + // Copy without compression as much as possible from the input stream, return + // the current block state. + // This function does not insert new strings in the dictionary since + // uncompressible data is probably not useful. This function is used + // only for the level=0 compression option. + // NOTE: this function should be optimized to avoid extra copying from + // window to pending_buf. + int deflate_stored(int flush){ + // Stored blocks are limited to 0xffff bytes, pending_buf is limited + // to pending_buf_size, and each stored block has a 5 byte header: + + int max_block_size = 0xffff; + int max_start; + + if(max_block_size > pending_buf_size - 5) { + max_block_size = pending_buf_size - 5; + } + + // Copy as much as possible from input to output: + while(true){ + // Fill the window as much as possible: + if(lookahead<=1){ + fill_window(); + if(lookahead==0 && flush==Z_NO_FLUSH) return NeedMore; + if(lookahead==0) break; // flush the current block + } + + strstart+=lookahead; + lookahead=0; + + // Emit a stored block if pending_buf will be full: + max_start=block_start+max_block_size; + if(strstart==0|| strstart>=max_start) { + // strstart == 0 is possible when wraparound on 16-bit machine + lookahead = (int)(strstart-max_start); + strstart = (int)max_start; + + flush_block_only(false); + if(strm.avail_out==0) return NeedMore; + + } + + // Flush if we may have to slide, otherwise block_start may become + // negative and the data will be gone: + if(strstart-block_start >= w_size-MIN_LOOKAHEAD) { + flush_block_only(false); + if(strm.avail_out==0) return NeedMore; + } + } + + flush_block_only(flush == Z_FINISH); + if(strm.avail_out==0) + return (flush == Z_FINISH) ? FinishStarted : NeedMore; + + return flush == Z_FINISH ? FinishDone : BlockDone; + } + + // Send a stored block + void _tr_stored_block(int buf, // input block + int stored_len, // length of input block + boolean eof // true if this is the last block for a file + ){ + send_bits((STORED_BLOCK<<1)+(eof?1:0), 3); // send block type + copy_block(buf, stored_len, true); // with header + } + + // Determine the best encoding for the current block: dynamic trees, static + // trees or store, and output the encoded block to the zip file. + void _tr_flush_block(int buf, // input block, or NULL if too old + int stored_len, // length of input block + boolean eof // true if this is the last block for a file + ) { + int opt_lenb, static_lenb;// opt_len and static_len in bytes + int max_blindex = 0; // index of last bit length code of non zero freq + + // Build the Huffman trees unless a stored block is forced + if(level > 0) { + // Check if the file is ascii or binary + if(data_type == Z_UNKNOWN) set_data_type(); + + // Construct the literal and distance trees + l_desc.build_tree(this); + + d_desc.build_tree(this); + + // At this point, opt_len and static_len are the total bit lengths of + // the compressed block data, excluding the tree representations. + + // Build the bit length tree for the above two trees, and get the index + // in bl_order of the last bit length code to send. + max_blindex=build_bl_tree(); + + // Determine the best encoding. Compute first the block length in bytes + opt_lenb=(opt_len+3+7)>>>3; + static_lenb=(static_len+3+7)>>>3; + + if(static_lenb<=opt_lenb) opt_lenb=static_lenb; + } + else { + opt_lenb=static_lenb=stored_len+5; // force a stored block + } + + if(stored_len+4<=opt_lenb && buf != -1){ + // 4: two words for the lengths + // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + // Otherwise we can't have processed more than WSIZE input bytes since + // the last block flush, because compression would have been + // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + // transform a block into a stored block. + _tr_stored_block(buf, stored_len, eof); + } + else if(static_lenb == opt_lenb){ + send_bits((STATIC_TREES<<1)+(eof?1:0), 3); + compress_block(StaticTree.static_ltree, StaticTree.static_dtree); + } + else{ + send_bits((DYN_TREES<<1)+(eof?1:0), 3); + send_all_trees(l_desc.max_code+1, d_desc.max_code+1, max_blindex+1); + compress_block(dyn_ltree, dyn_dtree); + } + + // The above check is made mod 2^32, for files larger than 512 MB + // and uLong implemented on 32 bits. + + init_block(); + + if(eof){ + bi_windup(); + } + } + + // Fill the window when the lookahead becomes insufficient. + // Updates strstart and lookahead. + // + // IN assertion: lookahead < MIN_LOOKAHEAD + // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + // At least one byte has been read, or avail_in == 0; reads are + // performed for at least two bytes (required for the zip translate_eol + // option -- not supported here). + void fill_window(){ + int n, m; + int p; + int more; // Amount of free space at the end of the window. + + do{ + more = (window_size-lookahead-strstart); + + // Deal with !@#$% 64K limit: + if(more==0 && strstart==0 && lookahead==0){ + more = w_size; + } + else if(more==-1) { + // Very unlikely, but possible on 16 bit machine if strstart == 0 + // and lookahead == 1 (input done one byte at time) + more--; + + // If the window is almost full and there is insufficient lookahead, + // move the upper half to the lower one to make room in the upper half. + } + else if(strstart >= w_size+ w_size-MIN_LOOKAHEAD) { + System.arraycopy(window, w_size, window, 0, w_size); + match_start-=w_size; + strstart-=w_size; // we now have strstart >= MAX_DIST + block_start-=w_size; + + // Slide the hash table (could be avoided with 32 bit values + // at the expense of memory usage). We slide even when level == 0 + // to keep the hash table consistent if we switch back to level > 0 + // later. (Using level 0 permanently is not an optimal usage of + // zlib, so we don't care about this pathological case.) + + n = hash_size; + p=n; + do { + m = (head[--p]&0xffff); + head[p]=(m>=w_size ? (short)(m-w_size) : 0); + } + while (--n != 0); + + n = w_size; + p = n; + do { + m = (prev[--p]&0xffff); + prev[p] = (m >= w_size ? (short)(m-w_size) : 0); + // If n is not on any hash chain, prev[n] is garbage but + // its value will never be used. + } + while (--n!=0); + more += w_size; + } + + if (strm.avail_in == 0) return; + + // If there was no sliding: + // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + // more == window_size - lookahead - strstart + // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + // => more >= window_size - 2*WSIZE + 2 + // In the BIG_MEM or MMAP case (not yet supported), + // window_size == input_size + MIN_LOOKAHEAD && + // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + // Otherwise, window_size == 2*WSIZE so more >= 2. + // If there was sliding, more >= WSIZE. So in all cases, more >= 2. + + n = strm.read_buf(window, strstart + lookahead, more); + lookahead += n; + + // Initialize the hash value now that we have some input: + if(lookahead >= MIN_MATCH) { + ins_h = window[strstart]&0xff; + ins_h=(((ins_h)<= MIN_MATCH){ + ins_h=(((ins_h)<=MIN_MATCH){ + // check_match(strstart, match_start, match_length); + + bflush=_tr_tally(strstart-match_start, match_length-MIN_MATCH); + + lookahead -= match_length; + + // Insert new strings in the hash table only if the match length + // is not too large. This saves time but degrades compression. + if(match_length <= max_lazy_match && + lookahead >= MIN_MATCH) { + match_length--; // string at strstart already in hash table + do{ + strstart++; + + ins_h=((ins_h<= MIN_MATCH) { + ins_h=(((ins_h)< 4096))) { + + // If prev_match is also MIN_MATCH, match_start is garbage + // but we will ignore the current match anyway. + match_length = MIN_MATCH-1; + } + } + + // If there was a match at the previous step and the current + // match is not better, output the previous match: + if(prev_length >= MIN_MATCH && match_length <= prev_length) { + int max_insert = strstart + lookahead - MIN_MATCH; + // Do not insert strings in hash table beyond this. + + // check_match(strstart-1, prev_match, prev_length); + + bflush=_tr_tally(strstart-1-prev_match, prev_length - MIN_MATCH); + + // Insert in hash table all strings up to the end of the match. + // strstart-1 and strstart are already inserted. If there is not + // enough lookahead, the last two strings are not inserted in + // the hash table. + lookahead -= prev_length-1; + prev_length -= 2; + do{ + if(++strstart <= max_insert) { + ins_h=(((ins_h)<(w_size-MIN_LOOKAHEAD) ? + strstart-(w_size-MIN_LOOKAHEAD) : 0; + int nice_match=this.nice_match; + + // Stop when cur_match becomes <= limit. To simplify the code, + // we prevent matches with the string of window index 0. + + int wmask = w_mask; + + int strend = strstart + MAX_MATCH; + byte scan_end1 = window[scan+best_len-1]; + byte scan_end = window[scan+best_len]; + + // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + // It is easy to get rid of this optimization if necessary. + + // Do not waste too much time if we already have a good match: + if (prev_length >= good_match) { + chain_length >>= 2; + } + + // Do not look for matches beyond the end of the input. This is necessary + // to make deflate deterministic. + if (nice_match > lookahead) nice_match = lookahead; + + do { + match = cur_match; + + // Skip to next match if the match length cannot increase + // or if the match length is less than 2: + if (window[match+best_len] != scan_end || + window[match+best_len-1] != scan_end1 || + window[match] != window[scan] || + window[++match] != window[scan+1]) continue; + + // The check at best_len-1 can be removed because it will be made + // again later. (This heuristic is not always a win.) + // It is not necessary to compare scan[2] and match[2] since they + // are always equal when the other bytes match, given that + // the hash keys are equal and that HASH_BITS >= 8. + scan += 2; match++; + + // We check for insufficient lookahead only every 8th comparison; + // the 256th check will be made at strstart+258. + do { + } while (window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + scan < strend); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + + if(len>best_len) { + match_start = cur_match; + best_len = len; + if (len >= nice_match) break; + scan_end1 = window[scan+best_len-1]; + scan_end = window[scan+best_len]; + } + + } while ((cur_match = (prev[cur_match & wmask]&0xffff)) > limit + && --chain_length != 0); + + if (best_len <= lookahead) return best_len; + return lookahead; + } + + int deflateInit(int level, int bits, int memlevel){ + return deflateInit(level, Z_DEFLATED, bits, memlevel, + Z_DEFAULT_STRATEGY); + } + + int deflateInit(int level, int bits){ + return deflateInit(level, Z_DEFLATED, bits, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY); + } + int deflateInit(int level){ + return deflateInit(level, MAX_WBITS); + } + private int deflateInit(int level, int method, int windowBits, + int memLevel, int strategy){ + int wrap = 1; + // byte[] my_version=ZLIB_VERSION; + + // + // if (version == null || version[0] != my_version[0] + // || stream_size != sizeof(z_stream)) { + // return Z_VERSION_ERROR; + // } + + strm.msg = null; + + if (level == Z_DEFAULT_COMPRESSION) level = 6; + + if (windowBits < 0) { // undocumented feature: suppress zlib header + wrap = 0; + windowBits = -windowBits; + } + else if(windowBits > 15){ + wrap = 2; + windowBits -= 16; + strm.adler=new CRC32(); + } + + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || + method != Z_DEFLATED || + windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + + strm.dstate = (Deflate)this; + + this.wrap = wrap; + w_bits = windowBits; + w_size = 1 << w_bits; + w_mask = w_size - 1; + + hash_bits = memLevel + 7; + hash_size = 1 << hash_bits; + hash_mask = hash_size - 1; + hash_shift = ((hash_bits+MIN_MATCH-1)/MIN_MATCH); + + window = new byte[w_size*2]; + prev = new short[w_size]; + head = new short[hash_size]; + + lit_bufsize = 1 << (memLevel + 6); // 16K elements by default + + // We overlay pending_buf and d_buf+l_buf. This works since the average + // output size for (length,distance) codes is <= 24 bits. + pending_buf = new byte[lit_bufsize*3]; + pending_buf_size = lit_bufsize*3; + + d_buf = lit_bufsize; + l_buf = new byte[lit_bufsize]; + + this.level = level; + + this.strategy = strategy; + this.method = (byte)method; + + return deflateReset(); + } + + int deflateReset(){ + strm.total_in = strm.total_out = 0; + strm.msg = null; // + strm.data_type = Z_UNKNOWN; + + pending = 0; + pending_out = 0; + + if(wrap < 0){ + wrap = -wrap; + } + status = (wrap==0) ? BUSY_STATE : INIT_STATE; + strm.adler.reset(); + + last_flush = Z_NO_FLUSH; + + tr_init(); + lm_init(); + return Z_OK; + } + + int deflateEnd(){ + if(status!=INIT_STATE && status!=BUSY_STATE && status!=FINISH_STATE){ + return Z_STREAM_ERROR; + } + // Deallocate in reverse order of allocations: + pending_buf=null; + l_buf=null; + head=null; + prev=null; + window=null; + // free + // dstate=null; + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; + } + + int deflateParams(int _level, int _strategy){ + int err=Z_OK; + + if(_level == Z_DEFAULT_COMPRESSION){ + _level = 6; + } + if(_level < 0 || _level > 9 || + _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + + if(config_table[level].func!=config_table[_level].func && + strm.total_in != 0) { + // Flush the last buffer: + err = strm.deflate(Z_PARTIAL_FLUSH); + } + + if(level != _level) { + level = _level; + max_lazy_match = config_table[level].max_lazy; + good_match = config_table[level].good_length; + nice_match = config_table[level].nice_length; + max_chain_length = config_table[level].max_chain; + } + strategy = _strategy; + return err; + } + + int deflateSetDictionary (byte[] dictionary, int dictLength){ + int length = dictLength; + int index=0; + + if(dictionary == null || status != INIT_STATE) + return Z_STREAM_ERROR; + + strm.adler.update(dictionary, 0, dictLength); + + if(length < MIN_MATCH) return Z_OK; + if(length > w_size-MIN_LOOKAHEAD){ + length = w_size-MIN_LOOKAHEAD; + index=dictLength-length; // use the tail of the dictionary + } + System.arraycopy(dictionary, index, window, 0, length); + strstart = length; + block_start = length; + + // Insert all strings in the hash table (except for the last two bytes). + // s->lookahead stays null, so s->ins_h will be recomputed at the next + // call of fill_window. + + ins_h = window[0]&0xff; + ins_h=(((ins_h)<Z_FINISH || flush<0){ + return Z_STREAM_ERROR; + } + + if(strm.next_out == null || + (strm.next_in == null && strm.avail_in != 0) || + (status == FINISH_STATE && flush != Z_FINISH)) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_STREAM_ERROR)]; + return Z_STREAM_ERROR; + } + if(strm.avail_out == 0){ + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + old_flush = last_flush; + last_flush = flush; + + // Write the zlib header + if(status == INIT_STATE) { + if(wrap == 2){ + getGZIPHeader().put(this); + status=BUSY_STATE; + strm.adler.reset(); + } + else{ + int header = (Z_DEFLATED+((w_bits-8)<<4))<<8; + int level_flags=((level-1)&0xff)>>1; + + if(level_flags>3) level_flags=3; + header |= (level_flags<<6); + if(strstart!=0) header |= PRESET_DICT; + header+=31-(header % 31); + + status=BUSY_STATE; + putShortMSB(header); + + + // Save the adler32 of the preset dictionary: + if(strstart!=0){ + long adler=strm.adler.getValue(); + putShortMSB((int)(adler>>>16)); + putShortMSB((int)(adler&0xffff)); + } + strm.adler.reset(); + } + } + + // Flush as much pending output as possible + if(pending != 0) { + strm.flush_pending(); + if(strm.avail_out == 0) { + // Since avail_out is 0, deflate will be called again with + // more output space, but possibly with both pending and + // avail_in equal to zero. There won't be anything to do, + // but this is not an error situation so make sure we + // return OK instead of BUF_ERROR at next call of deflate: + last_flush = -1; + return Z_OK; + } + + // Make sure there is something to do and avoid duplicate consecutive + // flushes. For repeated and useless calls with Z_FINISH, we keep + // returning Z_STREAM_END instead of Z_BUFF_ERROR. + } + else if(strm.avail_in==0 && flush <= old_flush && + flush != Z_FINISH) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + // User must not provide more input after the first FINISH: + if(status == FINISH_STATE && strm.avail_in != 0) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + // Start a new block or continue the current one. + if(strm.avail_in!=0 || lookahead!=0 || + (flush != Z_NO_FLUSH && status != FINISH_STATE)) { + int bstate=-1; + switch(config_table[level].func){ + case STORED: + bstate = deflate_stored(flush); + break; + case FAST: + bstate = deflate_fast(flush); + break; + case SLOW: + bstate = deflate_slow(flush); + break; + default: + } + + if (bstate==FinishStarted || bstate==FinishDone) { + status = FINISH_STATE; + } + if (bstate==NeedMore || bstate==FinishStarted) { + if(strm.avail_out == 0) { + last_flush = -1; // avoid BUF_ERROR next call, see above + } + return Z_OK; + // If flush != Z_NO_FLUSH && avail_out == 0, the next call + // of deflate should use the same flush parameter to make sure + // that the flush is complete. So we don't have to output an + // empty block here, this will be done at next call. This also + // ensures that for a very small output buffer, we emit at most + // one empty block. + } + + if (bstate==BlockDone) { + if(flush == Z_PARTIAL_FLUSH) { + _tr_align(); + } + else { // FULL_FLUSH or SYNC_FLUSH + _tr_stored_block(0, 0, false); + // For a full flush, this empty block will be recognized + // as a special marker by inflate_sync(). + if(flush == Z_FULL_FLUSH) { + //state.head[s.hash_size-1]=0; + for(int i=0; i>8)&0xff)); + put_byte((byte)((adler>>16)&0xff)); + put_byte((byte)((adler>>24)&0xff)); + put_byte((byte)(strm.total_in&0xff)); + put_byte((byte)((strm.total_in>>8)&0xff)); + put_byte((byte)((strm.total_in>>16)&0xff)); + put_byte((byte)((strm.total_in>>24)&0xff)); + + getGZIPHeader().setCRC(adler); + } + else{ + // Write the zlib trailer (adler32) + long adler=strm.adler.getValue(); + putShortMSB((int)(adler>>>16)); + putShortMSB((int)(adler&0xffff)); + } + + strm.flush_pending(); + + // If avail_out is zero, the application will call deflate again + // to flush the rest. + + if(wrap > 0) wrap = -wrap; // write the trailer only once! + return pending != 0 ? Z_OK : Z_STREAM_END; + } + + static int deflateCopy(ZStream dest, ZStream src){ + + if(src.dstate == null){ + return Z_STREAM_ERROR; + } + + if(src.next_in!=null){ + dest.next_in = new byte[src.next_in.length]; + System.arraycopy(src.next_in, 0, dest.next_in, 0, src.next_in.length); + } + dest.next_in_index = src.next_in_index; + dest.avail_in = src.avail_in; + dest.total_in = src.total_in; + + if(src.next_out!=null){ + dest.next_out = new byte[src.next_out.length]; + System.arraycopy(src.next_out, 0, dest.next_out ,0 , src.next_out.length); + } + + dest.next_out_index = src.next_out_index; + dest.avail_out = src.avail_out; + dest.total_out = src.total_out; + + dest.msg = src.msg; + dest.data_type = src.data_type; + dest.adler = src.adler.copy(); + + try{ + dest.dstate = (Deflate)src.dstate.clone(); + dest.dstate.strm = dest; + } + catch(CloneNotSupportedException e){ + // + } + return Z_OK; + } + + public Object clone() throws CloneNotSupportedException { + Deflate dest = (Deflate)super.clone(); + + dest.pending_buf = dup(dest.pending_buf); + dest.d_buf = dest.d_buf; + dest.l_buf = dup(dest.l_buf); + dest.window = dup(dest.window); + + dest.prev = dup(dest.prev); + dest.head = dup(dest.head); + dest.dyn_ltree = dup(dest.dyn_ltree); + dest.dyn_dtree = dup(dest.dyn_dtree); + dest.bl_tree = dup(dest.bl_tree); + + dest.bl_count = dup(dest.bl_count); + dest.next_code = dup(dest.next_code); + dest.heap = dup(dest.heap); + dest.depth = dup(dest.depth); + + dest.l_desc.dyn_tree = dest.dyn_ltree; + dest.d_desc.dyn_tree = dest.dyn_dtree; + dest.bl_desc.dyn_tree = dest.bl_tree; + + /* + dest.l_desc.stat_desc = StaticTree.static_l_desc; + dest.d_desc.stat_desc = StaticTree.static_d_desc; + dest.bl_desc.stat_desc = StaticTree.static_bl_desc; + */ + + if(dest.gheader!=null){ + dest.gheader = (GZIPHeader)dest.gheader.clone(); + } + + return dest; + } + + private byte[] dup(byte[] buf){ + byte[] foo = new byte[buf.length]; + System.arraycopy(buf, 0, foo, 0, foo.length); + return foo; + } + private short[] dup(short[] buf){ + short[] foo = new short[buf.length]; + System.arraycopy(buf, 0, foo, 0, foo.length); + return foo; + } + private int[] dup(int[] buf){ + int[] foo = new int[buf.length]; + System.arraycopy(buf, 0, foo, 0, foo.length); + return foo; + } + + synchronized GZIPHeader getGZIPHeader(){ + if(gheader==null){ + gheader = new GZIPHeader(); + } + return gheader; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/Deflater.java b/src/lwjgl/java/com/jcraft/jzlib/Deflater.java new file mode 100644 index 0000000..ce0580d --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/Deflater.java @@ -0,0 +1,171 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class Deflater extends ZStream{ + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_WBITS=MAX_WBITS; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + private boolean finished = false; + + public Deflater(){ + super(); + } + + public Deflater(int level) throws GZIPException { + this(level, MAX_WBITS); + } + + public Deflater(int level, boolean nowrap) throws GZIPException { + this(level, MAX_WBITS, nowrap); + } + + public Deflater(int level, int bits) throws GZIPException { + this(level, bits, false); + } + + public Deflater(int level, int bits, boolean nowrap) throws GZIPException { + super(); + int ret = init(level, bits, nowrap); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + public Deflater(int level, int bits, int memlevel, JZlib.WrapperType wrapperType) throws GZIPException { + super(); + int ret = init(level, bits, memlevel, wrapperType); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + public Deflater(int level, int bits, int memlevel) throws GZIPException { + super(); + int ret = init(level, bits, memlevel); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + public int init(int level){ + return init(level, MAX_WBITS); + } + public int init(int level, boolean nowrap){ + return init(level, MAX_WBITS, nowrap); + } + public int init(int level, int bits){ + return init(level, bits, false); + } + public int init(int level, int bits, int memlevel, JZlib.WrapperType wrapperType){ + if(bits < 9 || bits > 15){ + return Z_STREAM_ERROR; + } + if(wrapperType == JZlib.W_NONE) { + bits *= -1; + } + else if(wrapperType == JZlib.W_GZIP) { + bits += 16; + } + else if(wrapperType == JZlib.W_ANY) { + return Z_STREAM_ERROR; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return init(level, bits, memlevel); + } + public int init(int level, int bits, int memlevel){ + finished = false; + dstate=new Deflate(this); + return dstate.deflateInit(level, bits, memlevel); + } + public int init(int level, int bits, boolean nowrap){ + finished = false; + dstate=new Deflate(this); + return dstate.deflateInit(level, nowrap?-bits:bits); + } + + public int deflate(int flush){ + if(dstate==null){ + return Z_STREAM_ERROR; + } + int ret = dstate.deflate(flush); + if(ret == Z_STREAM_END) + finished = true; + return ret; + } + public int end(){ + finished = true; + if(dstate==null) return Z_STREAM_ERROR; + int ret=dstate.deflateEnd(); + dstate=null; + free(); + return ret; + } + public int params(int level, int strategy){ + if(dstate==null) return Z_STREAM_ERROR; + return dstate.deflateParams(level, strategy); + } + public int setDictionary (byte[] dictionary, int dictLength){ + if(dstate == null) + return Z_STREAM_ERROR; + return dstate.deflateSetDictionary(dictionary, dictLength); + } + + public boolean finished(){ + return finished; + } + + public int copy(Deflater src){ + this.finished = src.finished; + return Deflate.deflateCopy(this, src); + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/DeflaterOutputStream.java b/src/lwjgl/java/com/jcraft/jzlib/DeflaterOutputStream.java new file mode 100644 index 0000000..3c18836 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/DeflaterOutputStream.java @@ -0,0 +1,181 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jcraft.jzlib; +import java.io.*; + +public class DeflaterOutputStream extends FilterOutputStream { + + protected final Deflater deflater; + + protected byte[] buffer; + + private boolean closed = false; + + private boolean syncFlush = false; + + private final byte[] buf1 = new byte[1]; + + protected boolean mydeflater = false; + + private boolean close_out = true; + + protected static final int DEFAULT_BUFSIZE = 512; + + public DeflaterOutputStream(OutputStream out) throws IOException { + this(out, + new Deflater(JZlib.Z_DEFAULT_COMPRESSION), + DEFAULT_BUFSIZE, true); + mydeflater = true; + } + + public DeflaterOutputStream(OutputStream out, Deflater def) throws IOException { + this(out, def, DEFAULT_BUFSIZE, true); + } + + public DeflaterOutputStream(OutputStream out, + Deflater deflater, + int size) throws IOException { + this(out, deflater, size, true); + } + public DeflaterOutputStream(OutputStream out, + Deflater deflater, + int size, + boolean close_out) throws IOException { + super(out); + if (out == null || deflater == null) { + throw new NullPointerException(); + } + else if (size <= 0) { + throw new IllegalArgumentException("buffer size must be greater than 0"); + } + this.deflater = deflater; + buffer = new byte[size]; + this.close_out = close_out; + } + + public void write(int b) throws IOException { + buf1[0] = (byte)(b & 0xff); + write(buf1, 0, 1); + } + + public void write(byte[] b, int off, int len) throws IOException { + if (deflater.finished()) { + throw new IOException("finished"); + } + else if (off<0 | len<0 | off+len>b.length) { + throw new IndexOutOfBoundsException(); + } + else if (len == 0) { + return; + } + else { + int flush = syncFlush ? JZlib.Z_SYNC_FLUSH : JZlib.Z_NO_FLUSH; + deflater.setInput(b, off, len, true); + while (deflater.avail_in>0) { + int err = deflate(flush); + if (err == JZlib.Z_STREAM_END) + break; + } + } + } + + public void finish() throws IOException { + while (!deflater.finished()) { + deflate(JZlib.Z_FINISH); + } + } + + public void close() throws IOException { + if (!closed) { + finish(); + if (mydeflater){ + deflater.end(); + } + if(close_out) + out.close(); + closed = true; + } + } + + protected int deflate(int flush) throws IOException { + deflater.setOutput(buffer, 0, buffer.length); + int err = deflater.deflate(flush); + switch(err) { + case JZlib.Z_OK: + case JZlib.Z_STREAM_END: + break; + case JZlib.Z_BUF_ERROR: + if(deflater.avail_in<=0 && flush!=JZlib.Z_FINISH){ + // flush() without any data + break; + } + default: + throw new IOException("failed to deflate: error="+err+" avail_out="+deflater.avail_out); + } + int len = deflater.next_out_index; + if (len > 0) { + out.write(buffer, 0, len); + } + return err; + } + + public void flush() throws IOException { + if (syncFlush && !deflater.finished()) { + while (true) { + int err = deflate(JZlib.Z_SYNC_FLUSH); + if (deflater.next_out_index < buffer.length) + break; + if (err == JZlib.Z_STREAM_END) + break; + } + } + out.flush(); + } + + public long getTotalIn() { + return deflater.getTotalIn(); + } + + public long getTotalOut() { + return deflater.getTotalOut(); + } + + public void setSyncFlush(boolean syncFlush){ + this.syncFlush = syncFlush; + } + + public boolean getSyncFlush(){ + return this.syncFlush; + } + + public Deflater getDeflater(){ + return deflater; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/GZIPException.java b/src/lwjgl/java/com/jcraft/jzlib/GZIPException.java new file mode 100644 index 0000000..0beef40 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/GZIPException.java @@ -0,0 +1,44 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +public class GZIPException extends java.io.IOException { + public GZIPException() { + super(); + } + public GZIPException(String s) { + super(s); + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/GZIPHeader.java b/src/lwjgl/java/com/jcraft/jzlib/GZIPHeader.java new file mode 100644 index 0000000..0405e00 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/GZIPHeader.java @@ -0,0 +1,214 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +import java.io.UnsupportedEncodingException; + +/** + * @see "http://www.ietf.org/rfc/rfc1952.txt" + */ +public class GZIPHeader implements Cloneable { + + public static final byte OS_MSDOS = (byte) 0x00; + public static final byte OS_AMIGA = (byte) 0x01; + public static final byte OS_VMS = (byte) 0x02; + public static final byte OS_UNIX = (byte) 0x03; + public static final byte OS_ATARI = (byte) 0x05; + public static final byte OS_OS2 = (byte) 0x06; + public static final byte OS_MACOS = (byte) 0x07; + public static final byte OS_TOPS20 = (byte) 0x0a; + public static final byte OS_WIN32 = (byte) 0x0b; + public static final byte OS_VMCMS = (byte) 0x04; + public static final byte OS_ZSYSTEM = (byte) 0x08; + public static final byte OS_CPM = (byte) 0x09; + public static final byte OS_QDOS = (byte) 0x0c; + public static final byte OS_RISCOS = (byte) 0x0d; + public static final byte OS_UNKNOWN = (byte) 0xff; + + boolean text = false; + private boolean fhcrc = false; + long time; + int xflags; + int os = 255; + byte[] extra; + byte[] name; + byte[] comment; + int hcrc; + long crc; + boolean done = false; + long mtime = 0; + + public void setModifiedTime(long mtime) { + this.mtime = mtime; + } + + public long getModifiedTime() { + return mtime; + } + + public void setOS(int os) { + if((0<=os && os <=13) || os==255) + this.os=os; + else + throw new IllegalArgumentException("os: "+os); + } + + public int getOS(){ + return os; + } + + public void setName(String name) { + try{ + this.name=name.getBytes("ISO-8859-1"); + } + catch(UnsupportedEncodingException e){ + throw new IllegalArgumentException("name must be in ISO-8859-1 "+name); + } + } + + public String getName(){ + if(name==null) return ""; + try { + return new String(name, "ISO-8859-1"); + } + catch (UnsupportedEncodingException e) { + throw new InternalError(e.toString()); + } + } + + public void setComment(String comment) { + try{ + this.comment=comment.getBytes("ISO-8859-1"); + } + catch(UnsupportedEncodingException e){ + throw new IllegalArgumentException("comment must be in ISO-8859-1 "+name); + } + } + + public String getComment(){ + if(comment==null) return ""; + try { + return new String(comment, "ISO-8859-1"); + } + catch (UnsupportedEncodingException e) { + throw new InternalError(e.toString()); + } + } + + public void setCRC(long crc){ + this.crc = crc; + } + + public long getCRC(){ + return crc; + } + + void put(Deflate d){ + int flag = 0; + if(text){ + flag |= 1; // FTEXT + } + if(fhcrc){ + flag |= 2; // FHCRC + } + if(extra!=null){ + flag |= 4; // FEXTRA + } + if(name!=null){ + flag |= 8; // FNAME + } + if(comment!=null){ + flag |= 16; // FCOMMENT + } + int xfl = 0; + if(d.level == JZlib.Z_BEST_SPEED){ + xfl |= 4; + } + else if (d.level == JZlib.Z_BEST_COMPRESSION){ + xfl |= 2; + } + + d.put_short((short)0x8b1f); // ID1 ID2 + d.put_byte((byte)8); // CM(Compression Method) + d.put_byte((byte)flag); + d.put_byte((byte)mtime); + d.put_byte((byte)(mtime>>8)); + d.put_byte((byte)(mtime>>16)); + d.put_byte((byte)(mtime>>24)); + d.put_byte((byte)xfl); + d.put_byte((byte)os); + + if(extra!=null){ + d.put_byte((byte)extra.length); + d.put_byte((byte)(extra.length>>8)); + d.put_byte(extra, 0, extra.length); + } + + if(name!=null){ + d.put_byte(name, 0, name.length); + d.put_byte((byte)0); + } + + if(comment!=null){ + d.put_byte(comment, 0, comment.length); + d.put_byte((byte)0); + } + } + + @Override + public Object clone() throws CloneNotSupportedException { + GZIPHeader gheader = (GZIPHeader)super.clone(); + byte[] tmp; + if(gheader.extra!=null){ + tmp=new byte[gheader.extra.length]; + System.arraycopy(gheader.extra, 0, tmp, 0, tmp.length); + gheader.extra = tmp; + } + + if(gheader.name!=null){ + tmp=new byte[gheader.name.length]; + System.arraycopy(gheader.name, 0, tmp, 0, tmp.length); + gheader.name = tmp; + } + + if(gheader.comment!=null){ + tmp=new byte[gheader.comment.length]; + System.arraycopy(gheader.comment, 0, tmp, 0, tmp.length); + gheader.comment = tmp; + } + + return gheader; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/GZIPInputStream.java b/src/lwjgl/java/com/jcraft/jzlib/GZIPInputStream.java new file mode 100644 index 0000000..5d29dca --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/GZIPInputStream.java @@ -0,0 +1,145 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jcraft.jzlib; +import java.io.*; + +public class GZIPInputStream extends InflaterInputStream { + + public GZIPInputStream(InputStream in) throws IOException { + this(in, DEFAULT_BUFSIZE, true); + } + + public GZIPInputStream(InputStream in, + int size, + boolean close_in) throws IOException { + this(in, new Inflater(15+16), size, close_in); + myinflater = true; + } + + public GZIPInputStream(InputStream in, + Inflater inflater, + int size, + boolean close_in) throws IOException { + super(in, inflater, size, close_in); + } + + public long getModifiedtime() { + return inflater.istate.getGZIPHeader().getModifiedTime(); + } + + public int getOS() { + return inflater.istate.getGZIPHeader().getOS(); + } + + public String getName() { + return inflater.istate.getGZIPHeader().getName(); + } + + public String getComment() { + return inflater.istate.getGZIPHeader().getComment(); + } + + public long getCRC() throws GZIPException { + if(inflater.istate.mode != 12 /*DONE*/) + throw new GZIPException("checksum is not calculated yet."); + return inflater.istate.getGZIPHeader().getCRC(); + } + + public void readHeader() throws IOException { + + byte[] empty = "".getBytes(); + inflater.setOutput(empty, 0, 0); + inflater.setInput(empty, 0, 0, false); + + byte[] b = new byte[10]; + + int n = fill(b); + if(n!=10){ + if(n>0){ + inflater.setInput(b, 0, n, false); + //inflater.next_in_index = n; + inflater.next_in_index = 0; + inflater.avail_in = n; + } + throw new IOException("no input"); + } + + inflater.setInput(b, 0, n, false); + + byte[] b1 = new byte[1]; + do{ + if(inflater.avail_in<=0){ + int i = in.read(b1); + if(i<=0) + throw new IOException("no input"); + inflater.setInput(b1, 0, 1, true); + } + + int err = inflater.inflate(JZlib.Z_NO_FLUSH); + + if(err!=0/*Z_OK*/){ + int len = 2048-inflater.next_in.length; + if(len>0){ + byte[] tmp = new byte[len]; + n = fill(tmp); + if(n>0){ + inflater.avail_in += inflater.next_in_index; + inflater.next_in_index = 0; + inflater.setInput(tmp, 0, n, true); + } + } + //inflater.next_in_index = inflater.next_in.length; + inflater.avail_in += inflater.next_in_index; + inflater.next_in_index = 0; + throw new IOException(inflater.msg); + } + } + while(inflater.istate.inParsingHeader()); + } + + private int fill(byte[] buf) { + int len = buf.length; + int n = 0; + do{ + int i = -1; + try { + i = in.read(buf, n, buf.length - n); + } + catch(IOException e){ + } + if(i == -1){ + break; + } + n+=i; + } + while(n>> 1){ + case 0: // stored + {b>>>=(3);k-=(3);} + t = k & 7; // go to byte boundary + + {b>>>=(t);k-=(t);} + mode = LENS; // get length of stored block + break; + case 1: // fixed + InfTree.inflate_trees_fixed(bl, bd, tl, td, z); + codes.init(bl[0], bd[0], tl[0], 0, td[0], 0); + + {b>>>=(3);k-=(3);} + + mode = CODES; + break; + case 2: // dynamic + + {b>>>=(3);k-=(3);} + + mode = TABLE; + break; + case 3: // illegal + + {b>>>=(3);k-=(3);} + mode = BAD; + z.msg = "invalid block type"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + break; + case LENS: + + while(k<(32)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>> 16) & 0xffff) != (b & 0xffff)){ + mode = BAD; + z.msg = "invalid stored block lengths"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + left = (b & 0xffff); + b = k = 0; // dump bits + mode = left!=0 ? STORED : (last!=0 ? DRY : TYPE); + break; + case STORED: + if (n == 0){ + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + + if(m==0){ + if(q==end&&read!=0){ + q=0; m=(int)(qn) t = n; + if(t>m) t = m; + System.arraycopy(z.next_in, p, window, q, t); + p += t; n -= t; + q += t; m -= t; + if ((left -= t) != 0) + break; + mode = last!=0 ? DRY : TYPE; + break; + case TABLE: + + while(k<(14)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)< 29 || ((t >> 5) & 0x1f) > 29) + { + mode = BAD; + z.msg = "too many length or distance symbols"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if(blens==null || blens.length>>=(14);k-=(14);} + + index = 0; + mode = BTREE; + case BTREE: + while (index < 4 + (table >>> 10)){ + while(k<(3)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>>=(3);k-=(3);} + } + + while(index < 19){ + blens[border[index++]] = 0; + } + + bb[0] = 7; + t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); + if (t != Z_OK){ + r = t; + if (r == Z_DATA_ERROR){ + blens=null; + mode = BAD; + } + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + + index = 0; + mode = DTREE; + case DTREE: + while (true){ + t = table; + if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){ + break; + } + + int[] h; + int i, j, c; + + t = bb[0]; + + while(k<(t)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); + blens[index++] = c; + } + else { // c == 16..18 + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + + while(k<(t+i)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); + + j += (b & inflate_mask[i]); + + b>>>=(i);k-=(i); + + i = index; + t = table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)){ + blens=null; + mode = BAD; + z.msg = "invalid bit length repeat"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + + c = c == 16 ? blens[i-1] : 0; + do{ + blens[i++] = c; + } + while (--j!=0); + index = i; + } + } + + tb[0]=-1; + { + bl[0] = 9; // must be <= 9 for lookahead assumptions + bd[0] = 6; // must be <= 9 for lookahead assumptions + t = table; + t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), + 1 + ((t >> 5) & 0x1f), + blens, bl, bd, tli, tdi, hufts, z); + + if (t != Z_OK){ + if (t == Z_DATA_ERROR){ + blens=null; + mode = BAD; + } + r = t; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]); + } + mode = CODES; + case CODES: + bitb=b; bitk=k; + z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + + if ((r = codes.proc(r)) != Z_STREAM_END){ + return inflate_flush(r); + } + r = Z_OK; + codes.free(z); + + p=z.next_in_index; n=z.avail_in;b=bitb;k=bitk; + q=write;m=(int)(q z.avail_out) n = z.avail_out; + if(n!=0 && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if(check && n>0){ + z.adler.update(window, q, n); + } + + // copy as far as end of window + System.arraycopy(window, q, z.next_out, p, n); + p += n; + q += n; + + // see if more to copy at beginning of window + if (q == end){ + // wrap pointers + q = 0; + if (write == end) + write = 0; + + // compute bytes to copy + n = write - q; + if (n > z.avail_out) n = z.avail_out; + if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if(check && n>0){ + z.adler.update(window, q, n); + } + + // copy + System.arraycopy(window, q, z.next_out, p, n); + p += n; + q += n; + } + + // update pointers + z.next_out_index = p; + read = q; + + // done + return r; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/InfCodes.java b/src/lwjgl/java/com/jcraft/jzlib/InfCodes.java new file mode 100644 index 0000000..aaf69cd --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/InfCodes.java @@ -0,0 +1,610 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final class InfCodes{ + + static final private int[] inflate_mask = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, + 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, + 0x00007fff, 0x0000ffff + }; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + // waiting for "i:"=input, + // "o:"=output, + // "x:"=nothing + static final private int START=0; // x: set up for LEN + static final private int LEN=1; // i: get length/literal/eob next + static final private int LENEXT=2; // i: getting length extra (have base) + static final private int DIST=3; // i: get distance next + static final private int DISTEXT=4;// i: getting distance extra + static final private int COPY=5; // o: copying bytes in window, waiting for space + static final private int LIT=6; // o: got literal, waiting for output space + static final private int WASH=7; // o: got eob, possibly still output waiting + static final private int END=8; // x: got eob and all data flushed + static final private int BADCODE=9;// x: got error + + int mode; // current inflate_codes mode + + // mode dependent information + int len; + + int[] tree; // pointer into tree + int tree_index=0; + int need; // bits needed + + int lit; + + // if EXT or COPY, where and how much + int get; // bits to get for extra + int dist; // distance back to copy from + + byte lbits; // ltree bits decoded per branch + byte dbits; // dtree bits decoder per branch + int[] ltree; // literal/length/eob tree + int ltree_index; // literal/length/eob tree + int[] dtree; // distance tree + int dtree_index; // distance tree + + private final ZStream z; + private final InfBlocks s; + InfCodes(ZStream z, InfBlocks s){ + this.z=z; + this.s=s; + } + + void init(int bl, int bd, + int[] tl, int tl_index, + int[] td, int td_index){ + mode=START; + lbits=(byte)bl; + dbits=(byte)bd; + ltree=tl; + ltree_index=tl_index; + dtree = td; + dtree_index=td_index; + tree=null; + } + + int proc(int r){ + int j; // temporary storage + int[] t; // temporary pointer + int tindex; // temporary pointer + int e; // extra bits or operation + int b=0; // bit buffer + int k=0; // bits in bit buffer + int p=0; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; // bytes to end of window or read pointer + int f; // pointer to copy strings from + + // copy input/output information to locals (UPDATE macro restores) + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; + q=s.write;m=q= 258 && n >= 10){ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + r = inflate_fast(lbits, dbits, + ltree, ltree_index, + dtree, dtree_index, + s, z); + + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; + q=s.write;m=q>>=(tree[tindex+1]); + k-=(tree[tindex+1]); + + e=tree[tindex]; + + if(e == 0){ // literal + lit = tree[tindex+2]; + mode = LIT; + break; + } + if((e & 16)!=0 ){ // length + get = e & 15; + len = tree[tindex+2]; + mode = LENEXT; + break; + } + if ((e & 64) == 0){ // next table + need = e; + tree_index = tindex/3+tree[tindex+2]; + break; + } + if ((e & 32)!=0){ // end of block + mode = WASH; + break; + } + mode = BADCODE; // invalid code + z.msg = "invalid literal/length code"; + r = Z_DATA_ERROR; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + + case LENEXT: // i: getting length extra (have base) + j = get; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + } + n--; b|=(z.next_in[p++]&0xff)<>=j; + k-=j; + + need = dbits; + tree = dtree; + tree_index=dtree_index; + mode = DIST; + case DIST: // i: get distance next + j = need; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + } + n--; b|=(z.next_in[p++]&0xff)<>=tree[tindex+1]; + k-=tree[tindex+1]; + + e = (tree[tindex]); + if((e & 16)!=0){ // distance + get = e & 15; + dist = tree[tindex+2]; + mode = DISTEXT; + break; + } + if ((e & 64) == 0){ // next table + need = e; + tree_index = tindex/3 + tree[tindex+2]; + break; + } + mode = BADCODE; // invalid code + z.msg = "invalid distance code"; + r = Z_DATA_ERROR; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + + case DISTEXT: // i: getting distance extra + j = get; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + } + n--; b|=(z.next_in[p++]&0xff)<>=j; + k-=j; + + mode = COPY; + case COPY: // o: copying bytes in window, waiting for space + f = q - dist; + while(f < 0){ // modulo window size-"while" instead + f += s.end; // of "if" handles invalid distances + } + while (len!=0){ + + if(m==0){ + if(q==s.end&&s.read!=0){q=0;m=q 7){ // return unused byte, if any + k -= 8; + n++; + p--; // can always return one + } + + s.write=q; r=s.inflate_flush(r); + q=s.write;m=q= 258 && n >= 10 + // get literal/length code + while(k<(20)){ // max bits for literal/length code + n--; + b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + s.window[q++] = (byte)tp[tp_index_t_3+2]; + m--; + continue; + } + do { + + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + if((e&16)!=0){ + e &= 15; + c = tp[tp_index_t_3+2] + ((int)b & inflate_mask[e]); + + b>>=e; k-=e; + + // decode distance base of block to copy + while(k<(15)){ // max bits for distance code + n--; + b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + if((e&16)!=0){ + // get extra bits to add to distance base + e &= 15; + while(k<(e)){ // get extra bits (up to 13) + n--; + b|=(z.next_in[p++]&0xff)<>=(e); k-=(e); + + // do the copy + m -= c; + if (q >= d){ // offset before dest + // just copy + r=q-d; + if(q-r>0 && 2>(q-r)){ + s.window[q++]=s.window[r++]; // minimum count is three, + s.window[q++]=s.window[r++]; // so unroll loop a little + c-=2; + } + else{ + System.arraycopy(s.window, r, s.window, q, 2); + q+=2; r+=2; c-=2; + } + } + else{ // else offset after destination + r=q-d; + do{ + r+=s.end; // force pointer in window + }while(r<0); // covers invalid distances + e=s.end-r; + if(c>e){ // if source crosses, + c-=e; // wrapped copy + if(q-r>0 && e>(q-r)){ + do{s.window[q++] = s.window[r++];} + while(--e!=0); + } + else{ + System.arraycopy(s.window, r, s.window, q, e); + q+=e; r+=e; e=0; + } + r = 0; // copy rest from start of window + } + + } + + // copy all or what's left + if(q-r>0 && c>(q-r)){ + do{s.window[q++] = s.window[r++];} + while(--c!=0); + } + else{ + System.arraycopy(s.window, r, s.window, q, c); + q+=c; r+=c; c=0; + } + break; + } + else if((e&64)==0){ + t+=tp[tp_index_t_3+2]; + t+=(b&inflate_mask[e]); + tp_index_t_3=(tp_index+t)*3; + e=tp[tp_index_t_3]; + } + else{ + z.msg = "invalid distance code"; + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_DATA_ERROR; + } + } + while(true); + break; + } + + if((e&64)==0){ + t+=tp[tp_index_t_3+2]; + t+=(b&inflate_mask[e]); + tp_index_t_3=(tp_index+t)*3; + if((e=tp[tp_index_t_3])==0){ + + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + s.window[q++]=(byte)tp[tp_index_t_3+2]; + m--; + break; + } + } + else if((e&32)!=0){ + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_STREAM_END; + } + else{ + z.msg="invalid literal/length code"; + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_DATA_ERROR; + } + } + while(true); + } + while(m>=258 && n>= 10); + + // not enough input or output--restore pointers and return + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_OK; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/InfTree.java b/src/lwjgl/java/com/jcraft/jzlib/InfTree.java new file mode 100644 index 0000000..80a2b7b --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/InfTree.java @@ -0,0 +1,518 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final class InfTree{ + + static final private int MANY=1440; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + static final int fixed_bl = 9; + static final int fixed_bd = 5; + + static final int[] fixed_tl = { + 96,7,256, 0,8,80, 0,8,16, 84,8,115, + 82,7,31, 0,8,112, 0,8,48, 0,9,192, + 80,7,10, 0,8,96, 0,8,32, 0,9,160, + 0,8,0, 0,8,128, 0,8,64, 0,9,224, + 80,7,6, 0,8,88, 0,8,24, 0,9,144, + 83,7,59, 0,8,120, 0,8,56, 0,9,208, + 81,7,17, 0,8,104, 0,8,40, 0,9,176, + 0,8,8, 0,8,136, 0,8,72, 0,9,240, + 80,7,4, 0,8,84, 0,8,20, 85,8,227, + 83,7,43, 0,8,116, 0,8,52, 0,9,200, + 81,7,13, 0,8,100, 0,8,36, 0,9,168, + 0,8,4, 0,8,132, 0,8,68, 0,9,232, + 80,7,8, 0,8,92, 0,8,28, 0,9,152, + 84,7,83, 0,8,124, 0,8,60, 0,9,216, + 82,7,23, 0,8,108, 0,8,44, 0,9,184, + 0,8,12, 0,8,140, 0,8,76, 0,9,248, + 80,7,3, 0,8,82, 0,8,18, 85,8,163, + 83,7,35, 0,8,114, 0,8,50, 0,9,196, + 81,7,11, 0,8,98, 0,8,34, 0,9,164, + 0,8,2, 0,8,130, 0,8,66, 0,9,228, + 80,7,7, 0,8,90, 0,8,26, 0,9,148, + 84,7,67, 0,8,122, 0,8,58, 0,9,212, + 82,7,19, 0,8,106, 0,8,42, 0,9,180, + 0,8,10, 0,8,138, 0,8,74, 0,9,244, + 80,7,5, 0,8,86, 0,8,22, 192,8,0, + 83,7,51, 0,8,118, 0,8,54, 0,9,204, + 81,7,15, 0,8,102, 0,8,38, 0,9,172, + 0,8,6, 0,8,134, 0,8,70, 0,9,236, + 80,7,9, 0,8,94, 0,8,30, 0,9,156, + 84,7,99, 0,8,126, 0,8,62, 0,9,220, + 82,7,27, 0,8,110, 0,8,46, 0,9,188, + 0,8,14, 0,8,142, 0,8,78, 0,9,252, + 96,7,256, 0,8,81, 0,8,17, 85,8,131, + 82,7,31, 0,8,113, 0,8,49, 0,9,194, + 80,7,10, 0,8,97, 0,8,33, 0,9,162, + 0,8,1, 0,8,129, 0,8,65, 0,9,226, + 80,7,6, 0,8,89, 0,8,25, 0,9,146, + 83,7,59, 0,8,121, 0,8,57, 0,9,210, + 81,7,17, 0,8,105, 0,8,41, 0,9,178, + 0,8,9, 0,8,137, 0,8,73, 0,9,242, + 80,7,4, 0,8,85, 0,8,21, 80,8,258, + 83,7,43, 0,8,117, 0,8,53, 0,9,202, + 81,7,13, 0,8,101, 0,8,37, 0,9,170, + 0,8,5, 0,8,133, 0,8,69, 0,9,234, + 80,7,8, 0,8,93, 0,8,29, 0,9,154, + 84,7,83, 0,8,125, 0,8,61, 0,9,218, + 82,7,23, 0,8,109, 0,8,45, 0,9,186, + 0,8,13, 0,8,141, 0,8,77, 0,9,250, + 80,7,3, 0,8,83, 0,8,19, 85,8,195, + 83,7,35, 0,8,115, 0,8,51, 0,9,198, + 81,7,11, 0,8,99, 0,8,35, 0,9,166, + 0,8,3, 0,8,131, 0,8,67, 0,9,230, + 80,7,7, 0,8,91, 0,8,27, 0,9,150, + 84,7,67, 0,8,123, 0,8,59, 0,9,214, + 82,7,19, 0,8,107, 0,8,43, 0,9,182, + 0,8,11, 0,8,139, 0,8,75, 0,9,246, + 80,7,5, 0,8,87, 0,8,23, 192,8,0, + 83,7,51, 0,8,119, 0,8,55, 0,9,206, + 81,7,15, 0,8,103, 0,8,39, 0,9,174, + 0,8,7, 0,8,135, 0,8,71, 0,9,238, + 80,7,9, 0,8,95, 0,8,31, 0,9,158, + 84,7,99, 0,8,127, 0,8,63, 0,9,222, + 82,7,27, 0,8,111, 0,8,47, 0,9,190, + 0,8,15, 0,8,143, 0,8,79, 0,9,254, + 96,7,256, 0,8,80, 0,8,16, 84,8,115, + 82,7,31, 0,8,112, 0,8,48, 0,9,193, + + 80,7,10, 0,8,96, 0,8,32, 0,9,161, + 0,8,0, 0,8,128, 0,8,64, 0,9,225, + 80,7,6, 0,8,88, 0,8,24, 0,9,145, + 83,7,59, 0,8,120, 0,8,56, 0,9,209, + 81,7,17, 0,8,104, 0,8,40, 0,9,177, + 0,8,8, 0,8,136, 0,8,72, 0,9,241, + 80,7,4, 0,8,84, 0,8,20, 85,8,227, + 83,7,43, 0,8,116, 0,8,52, 0,9,201, + 81,7,13, 0,8,100, 0,8,36, 0,9,169, + 0,8,4, 0,8,132, 0,8,68, 0,9,233, + 80,7,8, 0,8,92, 0,8,28, 0,9,153, + 84,7,83, 0,8,124, 0,8,60, 0,9,217, + 82,7,23, 0,8,108, 0,8,44, 0,9,185, + 0,8,12, 0,8,140, 0,8,76, 0,9,249, + 80,7,3, 0,8,82, 0,8,18, 85,8,163, + 83,7,35, 0,8,114, 0,8,50, 0,9,197, + 81,7,11, 0,8,98, 0,8,34, 0,9,165, + 0,8,2, 0,8,130, 0,8,66, 0,9,229, + 80,7,7, 0,8,90, 0,8,26, 0,9,149, + 84,7,67, 0,8,122, 0,8,58, 0,9,213, + 82,7,19, 0,8,106, 0,8,42, 0,9,181, + 0,8,10, 0,8,138, 0,8,74, 0,9,245, + 80,7,5, 0,8,86, 0,8,22, 192,8,0, + 83,7,51, 0,8,118, 0,8,54, 0,9,205, + 81,7,15, 0,8,102, 0,8,38, 0,9,173, + 0,8,6, 0,8,134, 0,8,70, 0,9,237, + 80,7,9, 0,8,94, 0,8,30, 0,9,157, + 84,7,99, 0,8,126, 0,8,62, 0,9,221, + 82,7,27, 0,8,110, 0,8,46, 0,9,189, + 0,8,14, 0,8,142, 0,8,78, 0,9,253, + 96,7,256, 0,8,81, 0,8,17, 85,8,131, + 82,7,31, 0,8,113, 0,8,49, 0,9,195, + 80,7,10, 0,8,97, 0,8,33, 0,9,163, + 0,8,1, 0,8,129, 0,8,65, 0,9,227, + 80,7,6, 0,8,89, 0,8,25, 0,9,147, + 83,7,59, 0,8,121, 0,8,57, 0,9,211, + 81,7,17, 0,8,105, 0,8,41, 0,9,179, + 0,8,9, 0,8,137, 0,8,73, 0,9,243, + 80,7,4, 0,8,85, 0,8,21, 80,8,258, + 83,7,43, 0,8,117, 0,8,53, 0,9,203, + 81,7,13, 0,8,101, 0,8,37, 0,9,171, + 0,8,5, 0,8,133, 0,8,69, 0,9,235, + 80,7,8, 0,8,93, 0,8,29, 0,9,155, + 84,7,83, 0,8,125, 0,8,61, 0,9,219, + 82,7,23, 0,8,109, 0,8,45, 0,9,187, + 0,8,13, 0,8,141, 0,8,77, 0,9,251, + 80,7,3, 0,8,83, 0,8,19, 85,8,195, + 83,7,35, 0,8,115, 0,8,51, 0,9,199, + 81,7,11, 0,8,99, 0,8,35, 0,9,167, + 0,8,3, 0,8,131, 0,8,67, 0,9,231, + 80,7,7, 0,8,91, 0,8,27, 0,9,151, + 84,7,67, 0,8,123, 0,8,59, 0,9,215, + 82,7,19, 0,8,107, 0,8,43, 0,9,183, + 0,8,11, 0,8,139, 0,8,75, 0,9,247, + 80,7,5, 0,8,87, 0,8,23, 192,8,0, + 83,7,51, 0,8,119, 0,8,55, 0,9,207, + 81,7,15, 0,8,103, 0,8,39, 0,9,175, + 0,8,7, 0,8,135, 0,8,71, 0,9,239, + 80,7,9, 0,8,95, 0,8,31, 0,9,159, + 84,7,99, 0,8,127, 0,8,63, 0,9,223, + 82,7,27, 0,8,111, 0,8,47, 0,9,191, + 0,8,15, 0,8,143, 0,8,79, 0,9,255 + }; + static final int[] fixed_td = { + 80,5,1, 87,5,257, 83,5,17, 91,5,4097, + 81,5,5, 89,5,1025, 85,5,65, 93,5,16385, + 80,5,3, 88,5,513, 84,5,33, 92,5,8193, + 82,5,9, 90,5,2049, 86,5,129, 192,5,24577, + 80,5,2, 87,5,385, 83,5,25, 91,5,6145, + 81,5,7, 89,5,1537, 85,5,97, 93,5,24577, + 80,5,4, 88,5,769, 84,5,49, 92,5,12289, + 82,5,13, 90,5,3073, 86,5,193, 192,5,24577 + }; + + // Tables for deflate from PKZIP's appnote.txt. + static final int[] cplens = { // Copy lengths for literal codes 257..285 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 + }; + + // see note #13 above about 258 + static final int[] cplext = { // Extra bits for literal codes 257..285 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid + }; + + static final int[] cpdist = { // Copy offsets for distance codes 0..29 + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577 + }; + + static final int[] cpdext = { // Extra bits for distance codes + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + // If BMAX needs to be larger than 16, then h and x[] should be uLong. + static final int BMAX=15; // maximum bit length of any code + + int[] hn = null; // hufts used in space + int[] v = null; // work area for huft_build + int[] c = null; // bit length count table + int[] r = null; // table entry for structure assignment + int[] u = null; // table stack + int[] x = null; // bit offsets, then code stack + + private int huft_build(int[] b, // code lengths in bits (all assumed <= BMAX) + int bindex, + int n, // number of codes (assumed <= 288) + int s, // number of simple-valued codes (0..s-1) + int[] d, // list of base values for non-simple codes + int[] e, // list of extra bits for non-simple codes + int[] t, // result: starting table + int[] m, // maximum lookup bits, returns actual + int[] hp,// space for trees + int[] hn,// hufts used in space + int[] v // working area: values in order of bit length + ){ + // Given a list of code lengths and a maximum table size, make a set of + // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + // if the given code set is incomplete (the tables are still built in this + // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of + // lengths), or Z_MEM_ERROR if not enough memory. + + int a; // counter for codes of length k + int f; // i repeats in table every f entries + int g; // maximum code length + int h; // table level + int i; // counter, current code + int j; // counter + int k; // number of bits in current code + int l; // bits per table (returned in m) + int mask; // (1 << w) - 1, to avoid cc -O bug on HP + int p; // pointer into c[], b[], or v[] + int q; // points to current table + int w; // bits before this table == (l * h) + int xp; // pointer into x + int y; // number of dummy codes added + int z; // number of entries in current table + + // Generate counts for each bit length + + p = 0; i = n; + do { + c[b[bindex+p]]++; p++; i--; // assume all entries <= BMAX + }while(i!=0); + + if(c[0] == n){ // null input--all zero length codes + t[0] = -1; + m[0] = 0; + return Z_OK; + } + + // Find minimum and maximum length, bound *m by those + l = m[0]; + for (j = 1; j <= BMAX; j++) + if(c[j]!=0) break; + k = j; // minimum code length + if(l < j){ + l = j; + } + for (i = BMAX; i!=0; i--){ + if(c[i]!=0) break; + } + g = i; // maximum code length + if(l > i){ + l = i; + } + m[0] = l; + + // Adjust last length count to fill out codes, if needed + for (y = 1 << j; j < i; j++, y <<= 1){ + if ((y -= c[j]) < 0){ + return Z_DATA_ERROR; + } + } + if ((y -= c[i]) < 0){ + return Z_DATA_ERROR; + } + c[i] += y; + + // Generate starting offsets into the value table for each length + x[1] = j = 0; + p = 1; xp = 2; + while (--i!=0) { // note that i == g from above + x[xp] = (j += c[p]); + xp++; + p++; + } + + // Make a table of values in order of bit lengths + i = 0; p = 0; + do { + if ((j = b[bindex+p]) != 0){ + v[x[j]++] = i; + } + p++; + } + while (++i < n); + n = x[g]; // set n to length of v + + // Generate the Huffman codes and for each, make the table entries + x[0] = i = 0; // first Huffman code is zero + p = 0; // grab values in bit order + h = -1; // no tables yet--level -1 + w = -l; // bits decoded == (l * h) + u[0] = 0; // just to keep compilers happy + q = 0; // ditto + z = 0; // ditto + + // go through the bit lengths (k already is bits in shortest code) + for (; k <= g; k++){ + a = c[k]; + while (a--!=0){ + // here i is the Huffman code of length k bits for value *p + // make tables up to required level + while (k > w + l){ + h++; + w += l; // previous table always l bits + // compute minimum size table less than or equal to l bits + z = g - w; + z = (z > l) ? l : z; // table size upper limit + if((f=1<<(j=k-w))>a+1){ // try a k-w bit table + // too few codes for k-w bit table + f -= a + 1; // deduct codes from patterns left + xp = k; + if(j < z){ + while (++j < z){ // try smaller tables up to z bits + if((f <<= 1) <= c[++xp]) + break; // enough codes to use up j bits + f -= c[xp]; // else deduct codes from patterns + } + } + } + z = 1 << j; // table entries for j-bit table + + // allocate new table + if (hn[0] + z > MANY){ // (note: doesn't matter for fixed) + return Z_DATA_ERROR; // overflow of MANY + } + u[h] = q = /*hp+*/ hn[0]; // DEBUG + hn[0] += z; + + // connect to last table, if there is one + if(h!=0){ + x[h]=i; // save pattern for backing up + r[0]=(byte)j; // bits in this table + r[1]=(byte)l; // bits to dump before this table + j=i>>>(w - l); + r[2] = (int)(q - u[h-1] - j); // offset to this table + System.arraycopy(r, 0, hp, (u[h-1]+j)*3, 3); // connect to last table + } + else{ + t[0] = q; // first table is returned result + } + } + + // set up table entry in r + r[1] = (byte)(k - w); + if (p >= n){ + r[0] = 128 + 64; // out of values--invalid code + } + else if (v[p] < s){ + r[0] = (byte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block + r[2] = v[p++]; // simple code is just the value + } + else{ + r[0]=(byte)(e[v[p]-s]+16+64); // non-simple--look up in lists + r[2]=d[v[p++] - s]; + } + + // fill code-like entries with r + f=1<<(k-w); + for (j=i>>>w;j>>= 1){ + i ^= j; + } + i ^= j; + + // backup over finished tables + mask = (1 << w) - 1; // needed on HP, cc -O bug + while ((i & mask) != x[h]){ + h--; // don't need to update q + w -= l; + mask = (1 << w) - 1; + } + } + } + // Return Z_BUF_ERROR if we were given an incomplete table + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; + } + + int inflate_trees_bits(int[] c, // 19 code lengths + int[] bb, // bits tree desired/actual depth + int[] tb, // bits tree result + int[] hp, // space for trees + ZStream z // for messages + ){ + int result; + initWorkArea(19); + hn[0]=0; + result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); + + if(result == Z_DATA_ERROR){ + z.msg = "oversubscribed dynamic bit lengths tree"; + } + else if(result == Z_BUF_ERROR || bb[0] == 0){ + z.msg = "incomplete dynamic bit lengths tree"; + result = Z_DATA_ERROR; + } + return result; + } + + int inflate_trees_dynamic(int nl, // number of literal/length codes + int nd, // number of distance codes + int[] c, // that many (total) code lengths + int[] bl, // literal desired/actual bit depth + int[] bd, // distance desired/actual bit depth + int[] tl, // literal/length tree result + int[] td, // distance tree result + int[] hp, // space for trees + ZStream z // for messages + ){ + int result; + + // build literal/length tree + initWorkArea(288); + hn[0]=0; + result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); + if (result != Z_OK || bl[0] == 0){ + if(result == Z_DATA_ERROR){ + z.msg = "oversubscribed literal/length tree"; + } + else if (result != Z_MEM_ERROR){ + z.msg = "incomplete literal/length tree"; + result = Z_DATA_ERROR; + } + return result; + } + + // build distance tree + initWorkArea(288); + result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); + + if (result != Z_OK || (bd[0] == 0 && nl > 257)){ + if (result == Z_DATA_ERROR){ + z.msg = "oversubscribed distance tree"; + } + else if (result == Z_BUF_ERROR) { + z.msg = "incomplete distance tree"; + result = Z_DATA_ERROR; + } + else if (result != Z_MEM_ERROR){ + z.msg = "empty distance tree with lengths"; + result = Z_DATA_ERROR; + } + return result; + } + + return Z_OK; + } + + static int inflate_trees_fixed(int[] bl, //literal desired/actual bit depth + int[] bd, //distance desired/actual bit depth + int[][] tl,//literal/length tree result + int[][] td,//distance tree result + ZStream z //for memory allocation + ){ + bl[0]=fixed_bl; + bd[0]=fixed_bd; + tl[0]=fixed_tl; + td[0]=fixed_td; + return Z_OK; + } + + private void initWorkArea(int vsize){ + if(hn==null){ + hn=new int[1]; + v=new int[vsize]; + c=new int[BMAX+1]; + r=new int[3]; + u=new int[BMAX]; + x=new int[BMAX+1]; + } + if(v.length> 4) + 1; + if(w < 48) + w &= 15; + } + + if(w<8 ||w>15){ + inflateEnd(); + return Z_STREAM_ERROR; + } + if(blocks != null && wbits != w){ + blocks.free(); + blocks=null; + } + + // set window size + wbits=w; + + this.blocks=new InfBlocks(z, 1<>8))&0xff; + + if(((wrap&1)==0 || // check if zlib header allowed + (((this.method << 8)+b) % 31)!=0) && + (this.method&0xf)!=Z_DEFLATED){ + if(wrap == 4){ + z.next_in_index -= 2; + z.avail_in += 2; + z.total_in -= 2; + wrap = 0; + this.mode = BLOCKS; + break; + } + this.mode = BAD; + z.msg = "incorrect header check"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + if((this.method&0xf)!=Z_DEFLATED){ + this.mode = BAD; + z.msg="unknown compression method"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + if(wrap == 4){ + wrap = 1; + } + + if((this.method>>4)+8>this.wbits){ + this.mode = BAD; + z.msg="invalid window size"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + z.adler=new Adler32(); + + if((b&PRESET_DICT)==0){ + this.mode = BLOCKS; + break; + } + this.mode = DICT4; + case DICT4: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + this.mode=DICT3; + case DICT3: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + this.mode=DICT2; + case DICT2: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + this.mode=DICT1; + case DICT1: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need += (z.next_in[z.next_in_index++]&0xffL); + z.adler.reset(this.need); + this.mode = DICT0; + return Z_NEED_DICT; + case DICT0: + this.mode = BAD; + z.msg = "need dictionary"; + this.marker = 0; // can try inflateSync + return Z_STREAM_ERROR; + case BLOCKS: + r = this.blocks.proc(r); + if(r == Z_DATA_ERROR){ + this.mode = BAD; + this.marker = 0; // can try inflateSync + break; + } + if(r == Z_OK){ + r = f; + } + if(r != Z_STREAM_END){ + return r; + } + r = f; + this.was=z.adler.getValue(); + this.blocks.reset(); + if(this.wrap==0){ + this.mode=DONE; + break; + } + this.mode=CHECK4; + case CHECK4: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + this.mode=CHECK3; + case CHECK3: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + this.mode = CHECK2; + case CHECK2: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + this.mode = CHECK1; + case CHECK1: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=(z.next_in[z.next_in_index++]&0xffL); + + if(flags!=0){ // gzip + this.need = ((this.need&0xff000000)>>24 | + (this.need&0x00ff0000)>>8 | + (this.need&0x0000ff00)<<8 | + (this.need&0x0000ffff)<<24)&0xffffffffL; + } + + if(((int)(this.was)) != ((int)(this.need))){ + z.msg = "incorrect data check"; + // chack is delayed + /* + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + */ + } + else if(flags!=0 && gheader!=null){ + gheader.crc = this.need; + } + + this.mode = LENGTH; + case LENGTH: + if (wrap!=0 && flags!=0) { + + try { r=readBytes(4, r, f); } + catch(Return e){ return e.r; } + + if(z.msg!=null && z.msg.equals("incorrect data check")){ + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + } + + if (this.need != (z.total_out & 0xffffffffL)) { + z.msg = "incorrect length check"; + this.mode = BAD; + break; + } + z.msg = null; + } + else { + if(z.msg!=null && z.msg.equals("incorrect data check")){ + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + } + } + + this.mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + + case FLAGS: + + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + + flags = ((int)this.need)&0xffff; + + if ((flags & 0xff) != Z_DEFLATED) { + z.msg = "unknown compression method"; + this.mode = BAD; + break; + } + if ((flags & 0xe000)!=0) { + z.msg = "unknown header flags set"; + this.mode = BAD; + break; + } + + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + + this.mode = TIME; + + case TIME: + try { r=readBytes(4, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null) + gheader.time = this.need; + if ((flags & 0x0200)!=0){ + checksum(4, this.need); + } + this.mode = OS; + case OS: + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.xflags = ((int)this.need)&0xff; + gheader.os = (((int)this.need)>>8)&0xff; + } + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + this.mode = EXLEN; + case EXLEN: + if ((flags & 0x0400)!=0) { + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.extra = new byte[((int)this.need)&0xffff]; + } + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + } + else if(gheader!=null){ + gheader.extra=null; + } + this.mode = EXTRA; + + case EXTRA: + if ((flags & 0x0400)!=0) { + try { + r=readBytes(r, f); + if(gheader!=null){ + byte[] foo = tmp_string.toByteArray(); + tmp_string=null; + if(foo.length == gheader.extra.length){ + System.arraycopy(foo, 0, gheader.extra, 0, foo.length); + } + else{ + z.msg = "bad extra field length"; + this.mode = BAD; + break; + } + } + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.extra=null; + } + this.mode = NAME; + case NAME: + if ((flags & 0x0800)!=0) { + try { + r=readString(r, f); + if(gheader!=null){ + gheader.name=tmp_string.toByteArray(); + } + tmp_string=null; + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.name=null; + } + this.mode = COMMENT; + case COMMENT: + if ((flags & 0x1000)!=0) { + try { + r=readString(r, f); + if(gheader!=null){ + gheader.comment=tmp_string.toByteArray(); + } + tmp_string=null; + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.comment=null; + } + this.mode = HCRC; + case HCRC: + if ((flags & 0x0200)!=0) { + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.hcrc=(int)(this.need&0xffff); + } + if(this.need != (z.adler.getValue()&0xffffL)){ + this.mode = BAD; + z.msg = "header crc mismatch"; + this.marker = 5; // can't try inflateSync + break; + } + } + z.adler = new CRC32(); + + this.mode = BLOCKS; + break; + default: + return Z_STREAM_ERROR; + } + } + } + + int inflateSetDictionary(byte[] dictionary, int dictLength){ + if(z==null || (this.mode != DICT0 && this.wrap != 0)){ + return Z_STREAM_ERROR; + } + + int index=0; + int length = dictLength; + + if(this.mode==DICT0){ + long adler_need=z.adler.getValue(); + z.adler.reset(); + z.adler.update(dictionary, 0, dictLength); + if(z.adler.getValue()!=adler_need){ + return Z_DATA_ERROR; + } + } + + z.adler.reset(); + + if(length >= (1<0){ + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + this.need = this.need | + ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8)); + need_bytes--; + } + if(n==2){ + this.need&=0xffffL; + } + else if(n==4) { + this.need&=0xffffffffL; + } + need_bytes=-1; + return r; + } + class Return extends Exception{ + int r; + Return(int r){this.r=r; } + } + + private java.io.ByteArrayOutputStream tmp_string = null; + private int readString(int r, int f) throws Return{ + if(tmp_string == null){ + tmp_string=new java.io.ByteArrayOutputStream(); + } + int b=0; + do { + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + b = z.next_in[z.next_in_index]; + if(b!=0) tmp_string.write(z.next_in, z.next_in_index, 1); + z.adler.update(z.next_in, z.next_in_index, 1); + z.next_in_index++; + }while(b!=0); + return r; + } + + private int readBytes(int r, int f) throws Return{ + if(tmp_string == null){ + tmp_string=new java.io.ByteArrayOutputStream(); + } + int b=0; + while(this.need>0){ + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + b = z.next_in[z.next_in_index]; + tmp_string.write(z.next_in, z.next_in_index, 1); + z.adler.update(z.next_in, z.next_in_index, 1); + z.next_in_index++; + this.need--; + } + return r; + } + + private void checksum(int n, long v){ + for(int i=0; i>=8; + } + z.adler.update(crcbuf, 0, n); + } + + public GZIPHeader getGZIPHeader(){ + return gheader; + } + + boolean inParsingHeader(){ + switch(mode){ + case HEAD: + case DICT4: + case DICT3: + case DICT2: + case DICT1: + case FLAGS: + case TIME: + case OS: + case EXLEN: + case EXTRA: + case NAME: + case COMMENT: + case HCRC: + return true; + default: + return false; + } + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/Inflater.java b/src/lwjgl/java/com/jcraft/jzlib/Inflater.java new file mode 100644 index 0000000..0fb0b09 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/Inflater.java @@ -0,0 +1,168 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class Inflater extends ZStream{ + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_WBITS=MAX_WBITS; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + public Inflater() { + super(); + init(); + } + + public Inflater(JZlib.WrapperType wrapperType) throws GZIPException { + this(DEF_WBITS, wrapperType); + } + + public Inflater(int w, JZlib.WrapperType wrapperType) throws GZIPException { + super(); + int ret = init(w, wrapperType); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + public Inflater(int w) throws GZIPException { + this(w, false); + } + + public Inflater(boolean nowrap) throws GZIPException { + this(DEF_WBITS, nowrap); + } + + public Inflater(int w, boolean nowrap) throws GZIPException { + super(); + int ret = init(w, nowrap); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + private boolean finished = false; + + public int init(){ + return init(DEF_WBITS); + } + + public int init(JZlib.WrapperType wrapperType){ + return init(DEF_WBITS, wrapperType); + } + + public int init(int w, JZlib.WrapperType wrapperType) { + boolean nowrap = false; + if(wrapperType == JZlib.W_NONE){ + nowrap = true; + } + else if(wrapperType == JZlib.W_GZIP) { + w += 16; + } + else if(wrapperType == JZlib.W_ANY) { + w |= Inflate.INFLATE_ANY; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return init(w, nowrap); + } + + public int init(boolean nowrap){ + return init(DEF_WBITS, nowrap); + } + + public int init(int w){ + return init(w, false); + } + + public int init(int w, boolean nowrap){ + finished = false; + istate=new Inflate(this); + return istate.inflateInit(nowrap?-w:w); + } + + public int inflate(int f){ + if(istate==null) return Z_STREAM_ERROR; + int ret = istate.inflate(f); + if(ret == Z_STREAM_END) + finished = true; + return ret; + } + + public int end(){ + finished = true; + if(istate==null) return Z_STREAM_ERROR; + int ret=istate.inflateEnd(); +// istate = null; + return ret; + } + + public int sync(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSync(); + } + + public int syncPoint(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSyncPoint(); + } + + public int setDictionary(byte[] dictionary, int dictLength){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSetDictionary(dictionary, dictLength); + } + + public boolean finished(){ + return istate.mode==12 /*DONE*/; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/InflaterInputStream.java b/src/lwjgl/java/com/jcraft/jzlib/InflaterInputStream.java new file mode 100644 index 0000000..0420582 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/InflaterInputStream.java @@ -0,0 +1,247 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jcraft.jzlib; +import java.io.*; + +public class InflaterInputStream extends FilterInputStream { + protected final Inflater inflater; + protected byte[] buf; + + private boolean closed = false; + + private boolean eof = false; + + private boolean close_in = true; + + protected static final int DEFAULT_BUFSIZE = 512; + + public InflaterInputStream(InputStream in) throws IOException { + this(in, false); + } + + public InflaterInputStream(InputStream in, boolean nowrap) throws IOException { + this(in, new Inflater(nowrap)); + myinflater = true; + } + + public InflaterInputStream(InputStream in, Inflater inflater) throws IOException { + this(in, inflater, DEFAULT_BUFSIZE); + } + + public InflaterInputStream(InputStream in, + Inflater inflater, int size) throws IOException { + this(in, inflater, size, true); + } + + public InflaterInputStream(InputStream in, + Inflater inflater, + int size, boolean close_in) throws IOException { + super(in); + if (in == null || inflater == null) { + throw new NullPointerException(); + } + else if (size <= 0) { + throw new IllegalArgumentException("buffer size must be greater than 0"); + } + this.inflater = inflater; + buf = new byte[size]; + this.close_in = close_in; + } + + protected boolean myinflater = false; + + private byte[] byte1 = new byte[1]; + + public int read() throws IOException { + if (closed) { throw new IOException("Stream closed"); } + return read(byte1, 0, 1) == -1 ? -1 : byte1[0] & 0xff; + } + + public int read(byte[] b, int off, int len) throws IOException { + if (closed) { throw new IOException("Stream closed"); } + if (b == null) { + throw new NullPointerException(); + } + else if (off < 0 || len < 0 || len > b.length - off) { + throw new IndexOutOfBoundsException(); + } + else if (len == 0) { + return 0; + } + else if (eof) { + return -1; + } + + int n = 0; + inflater.setOutput(b, off, len); + while(!eof) { + if(inflater.avail_in==0) + fill(); + int err = inflater.inflate(JZlib.Z_NO_FLUSH); + n += inflater.next_out_index - off; + off = inflater.next_out_index; + switch(err) { + case JZlib.Z_DATA_ERROR: + throw new IOException(inflater.msg); + case JZlib.Z_STREAM_END: + case JZlib.Z_NEED_DICT: + eof = true; + if(err == JZlib.Z_NEED_DICT) + return -1; + break; + default: + } + if(inflater.avail_out==0) + break; + } + return n; + } + + public int available() throws IOException { + if (closed) { throw new IOException("Stream closed"); } + if (eof) { + return 0; + } + else { + return 1; + } + } + + private byte[] b = new byte[512]; + + public long skip(long n) throws IOException { + if (n < 0) { + throw new IllegalArgumentException("negative skip length"); + } + + if (closed) { throw new IOException("Stream closed"); } + + int max = (int)Math.min(n, Integer.MAX_VALUE); + int total = 0; + while (total < max) { + int len = max - total; + if (len > b.length) { + len = b.length; + } + len = read(b, 0, len); + if (len == -1) { + eof = true; + break; + } + total += len; + } + return total; + } + + public void close() throws IOException { + if (!closed) { + if (myinflater) + inflater.end(); + if(close_in) + in.close(); + closed = true; + } + } + + protected void fill() throws IOException { + if (closed) { throw new IOException("Stream closed"); } + int len = in.read(buf, 0, buf.length); + if (len == -1) { + if(inflater.istate.wrap == 0 && + !inflater.finished()){ + buf[0]=0; + len=1; + } + else if(inflater.istate.was != -1){ // in reading trailer + throw new IOException("footer is not found"); + } + else{ + throw new EOFException("Unexpected end of ZLIB input stream"); + } + } + inflater.setInput(buf, 0, len, true); + } + + public boolean markSupported() { + return false; + } + + public synchronized void mark(int readlimit) { + } + + public synchronized void reset() throws IOException { + throw new IOException("mark/reset not supported"); + } + + public long getTotalIn() { + return inflater.getTotalIn(); + } + + public long getTotalOut() { + return inflater.getTotalOut(); + } + + public byte[] getAvailIn() { + if(inflater.avail_in<=0) + return null; + byte[] tmp = new byte[inflater.avail_in]; + System.arraycopy(inflater.next_in, inflater.next_in_index, + tmp, 0, inflater.avail_in); + return tmp; + } + + public void readHeader() throws IOException { + + byte[] empty = "".getBytes(); + inflater.setInput(empty, 0, 0, false); + inflater.setOutput(empty, 0, 0); + + int err = inflater.inflate(JZlib.Z_NO_FLUSH); + if(!inflater.istate.inParsingHeader()){ + return; + } + + byte[] b1 = new byte[1]; + do{ + int i = in.read(b1); + if(i<=0) + throw new IOException("no input"); + inflater.setInput(b1); + err = inflater.inflate(JZlib.Z_NO_FLUSH); + if(err!=0/*Z_OK*/) + throw new IOException(inflater.msg); + } + while(inflater.istate.inParsingHeader()); + } + + public Inflater getInflater(){ + return inflater; + } +} \ No newline at end of file diff --git a/src/lwjgl/java/com/jcraft/jzlib/JZlib.java b/src/lwjgl/java/com/jcraft/jzlib/JZlib.java new file mode 100644 index 0000000..a4bb341 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/JZlib.java @@ -0,0 +1,92 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class JZlib{ + private static final String version="1.1.0"; + public static String version(){return version;} + + static final public int MAX_WBITS=15; // 32K LZ77 window + static final public int DEF_WBITS=MAX_WBITS; + + public enum WrapperType { + NONE, ZLIB, GZIP, ANY + } + + public static final WrapperType W_NONE = WrapperType.NONE; + public static final WrapperType W_ZLIB = WrapperType.ZLIB; + public static final WrapperType W_GZIP = WrapperType.GZIP; + public static final WrapperType W_ANY = WrapperType.ANY; + + // compression levels + static final public int Z_NO_COMPRESSION=0; + static final public int Z_BEST_SPEED=1; + static final public int Z_BEST_COMPRESSION=9; + static final public int Z_DEFAULT_COMPRESSION=(-1); + + // compression strategy + static final public int Z_FILTERED=1; + static final public int Z_HUFFMAN_ONLY=2; + static final public int Z_DEFAULT_STRATEGY=0; + + static final public int Z_NO_FLUSH=0; + static final public int Z_PARTIAL_FLUSH=1; + static final public int Z_SYNC_FLUSH=2; + static final public int Z_FULL_FLUSH=3; + static final public int Z_FINISH=4; + + static final public int Z_OK=0; + static final public int Z_STREAM_END=1; + static final public int Z_NEED_DICT=2; + static final public int Z_ERRNO=-1; + static final public int Z_STREAM_ERROR=-2; + static final public int Z_DATA_ERROR=-3; + static final public int Z_MEM_ERROR=-4; + static final public int Z_BUF_ERROR=-5; + static final public int Z_VERSION_ERROR=-6; + + // The three kinds of block type + static final public byte Z_BINARY = 0; + static final public byte Z_ASCII = 1; + static final public byte Z_UNKNOWN = 2; + + public static long adler32_combine(long adler1, long adler2, long len2){ + return Adler32.combine(adler1, adler2, len2); + } + + public static long crc32_combine(long crc1, long crc2, long len2){ + return CRC32.combine(crc1, crc2, len2); + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/StaticTree.java b/src/lwjgl/java/com/jcraft/jzlib/StaticTree.java new file mode 100644 index 0000000..e35931c --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/StaticTree.java @@ -0,0 +1,148 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final class StaticTree{ + static final private int MAX_BITS=15; + + static final private int BL_CODES=19; + static final private int D_CODES=30; + static final private int LITERALS=256; + static final private int LENGTH_CODES=29; + static final private int L_CODES=(LITERALS+1+LENGTH_CODES); + + // Bit length codes must not exceed MAX_BL_BITS bits + static final int MAX_BL_BITS=7; + + static final short[] static_ltree = { + 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, + 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, + 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, + 252, 8, 2, 8, 130, 8, 66, 8, 194, 8, + 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, + 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, + 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, + 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, + 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, + 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, + 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, + 230, 8, 22, 8, 150, 8, 86, 8, 214, 8, + 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, + 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, + 110, 8, 238, 8, 30, 8, 158, 8, 94, 8, + 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, + 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, + 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, + 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, + 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, + 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, + 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, + 121, 8, 249, 8, 5, 8, 133, 8, 69, 8, + 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, + 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, + 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, + 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, + 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, + 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, + 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, + 211, 9, 467, 9, 51, 9, 307, 9, 179, 9, + 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, + 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, + 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, + 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, + 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, + 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, + 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, + 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, + 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, + 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, + 359, 9, 231, 9, 487, 9, 23, 9, 279, 9, + 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, + 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, + 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, + 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, + 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, + 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, + 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, + 351, 9, 223, 9, 479, 9, 63, 9, 319, 9, + 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, + 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, + 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, + 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, + 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, + 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, + 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, + 163, 8, 99, 8, 227, 8 + }; + + static final short[] static_dtree = { + 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, + 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, + 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, + 30, 5, 1, 5, 17, 5, 9, 5, 25, 5, + 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, + 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 + }; + + static StaticTree static_l_desc = + new StaticTree(static_ltree, Tree.extra_lbits, + LITERALS+1, L_CODES, MAX_BITS); + + static StaticTree static_d_desc = + new StaticTree(static_dtree, Tree.extra_dbits, + 0, D_CODES, MAX_BITS); + + static StaticTree static_bl_desc = + new StaticTree(null, Tree.extra_blbits, + 0, BL_CODES, MAX_BL_BITS); + + short[] static_tree; // static tree or null + int[] extra_bits; // extra bits for each code or null + int extra_base; // base index for extra_bits + int elems; // max number of elements in the tree + int max_length; // max bit length for the codes + + private StaticTree(short[] static_tree, + int[] extra_bits, + int extra_base, + int elems, + int max_length){ + this.static_tree=static_tree; + this.extra_bits=extra_bits; + this.extra_base=extra_base; + this.elems=elems; + this.max_length=max_length; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/Tree.java b/src/lwjgl/java/com/jcraft/jzlib/Tree.java new file mode 100644 index 0000000..38cb40f --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/Tree.java @@ -0,0 +1,367 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final class Tree{ + static final private int MAX_BITS=15; + static final private int BL_CODES=19; + static final private int D_CODES=30; + static final private int LITERALS=256; + static final private int LENGTH_CODES=29; + static final private int L_CODES=(LITERALS+1+LENGTH_CODES); + static final private int HEAP_SIZE=(2*L_CODES+1); + + // Bit length codes must not exceed MAX_BL_BITS bits + static final int MAX_BL_BITS=7; + + // end of block literal code + static final int END_BLOCK=256; + + // repeat previous bit length 3-6 times (2 bits of repeat count) + static final int REP_3_6=16; + + // repeat a zero length 3-10 times (3 bits of repeat count) + static final int REPZ_3_10=17; + + // repeat a zero length 11-138 times (7 bits of repeat count) + static final int REPZ_11_138=18; + + // extra bits for each length code + static final int[] extra_lbits={ + 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0 + }; + + // extra bits for each distance code + static final int[] extra_dbits={ + 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 + }; + + // extra bits for each bit length code + static final int[] extra_blbits={ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7 + }; + + static final byte[] bl_order={ + 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; + + + // The lengths of the bit length codes are sent in order of decreasing + // probability, to avoid transmitting the lengths for unused bit + // length codes. + + static final int Buf_size=8*2; + + // see definition of array dist_code below + static final int DIST_CODE_LEN=512; + + static final byte[] _dist_code = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, + 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 + }; + + static final byte[] _length_code={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, + 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, + 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 + }; + + static final int[] base_length = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, + 64, 80, 96, 112, 128, 160, 192, 224, 0 + }; + + static final int[] base_dist = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 + }; + + // Mapping from a distance to a distance code. dist is the distance - 1 and + // must not have side effects. _dist_code[256] and _dist_code[257] are never + // used. + static int d_code(int dist){ + return ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>>7)]); + } + + short[] dyn_tree; // the dynamic tree + int max_code; // largest code with non zero frequency + StaticTree stat_desc; // the corresponding static tree + + // Compute the optimal bit lengths for a tree and update the total bit length + // for the current block. + // IN assertion: the fields freq and dad are set, heap[heap_max] and + // above are the tree nodes sorted by increasing frequency. + // OUT assertions: the field len is set to the optimal bit length, the + // array bl_count contains the frequencies for each bit length. + // The length opt_len is updated; static_len is also updated if stree is + // not null. + void gen_bitlen(Deflate s){ + short[] tree = dyn_tree; + short[] stree = stat_desc.static_tree; + int[] extra = stat_desc.extra_bits; + int base = stat_desc.extra_base; + int max_length = stat_desc.max_length; + int h; // heap index + int n, m; // iterate over the tree elements + int bits; // bit length + int xbits; // extra bits + short f; // frequency + int overflow = 0; // number of elements with bit length too large + + for (bits = 0; bits <= MAX_BITS; bits++) s.bl_count[bits] = 0; + + // In a first pass, compute the optimal bit lengths (which may + // overflow in the case of the bit length tree). + tree[s.heap[s.heap_max]*2+1] = 0; // root of the heap + + for(h=s.heap_max+1; h max_length){ bits = max_length; overflow++; } + tree[n*2+1] = (short)bits; + // We overwrite tree[n*2+1] which is no longer needed + + if (n > max_code) continue; // not a leaf node + + s.bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n*2]; + s.opt_len += f * (bits + xbits); + if (stree!=null) s.static_len += f * (stree[n*2+1] + xbits); + } + if (overflow == 0) return; + + // This happens for example on obj2 and pic of the Calgary corpus + // Find the first bit length which could increase: + do { + bits = max_length-1; + while(s.bl_count[bits]==0) bits--; + s.bl_count[bits]--; // move one leaf down the tree + s.bl_count[bits+1]+=2; // move one overflow item as its brother + s.bl_count[max_length]--; + // The brother of the overflow item also moves one step up, + // but this does not affect bl_count[max_length] + overflow -= 2; + } + while (overflow > 0); + + for (bits = max_length; bits != 0; bits--) { + n = s.bl_count[bits]; + while (n != 0) { + m = s.heap[--h]; + if (m > max_code) continue; + if (tree[m*2+1] != bits) { + s.opt_len += ((long)bits - (long)tree[m*2+1])*(long)tree[m*2]; + tree[m*2+1] = (short)bits; + } + n--; + } + } + } + + // Construct one Huffman tree and assigns the code bit strings and lengths. + // Update the total bit length for the current block. + // IN assertion: the field freq is set for all tree elements. + // OUT assertions: the fields len and code are set to the optimal bit length + // and corresponding code. The length opt_len is updated; static_len is + // also updated if stree is not null. The field max_code is set. + void build_tree(Deflate s){ + short[] tree=dyn_tree; + short[] stree=stat_desc.static_tree; + int elems=stat_desc.elems; + int n, m; // iterate over heap elements + int max_code=-1; // largest code with non zero frequency + int node; // new node being created + + // Construct the initial heap, with least frequent element in + // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + // heap[0] is not used. + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + + for(n=0; n=1; n--) + s.pqdownheap(tree, n); + + // Construct the Huffman tree by repeatedly combining the least two + // frequent nodes. + + node=elems; // next internal node of the tree + do{ + // n = node of least frequency + n=s.heap[1]; + s.heap[1]=s.heap[s.heap_len--]; + s.pqdownheap(tree, 1); + m=s.heap[1]; // m = node of next least frequency + + s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency + s.heap[--s.heap_max] = m; + + // Create a new node father of n and m + tree[node*2] = (short)(tree[n*2] + tree[m*2]); + s.depth[node] = (byte)(Math.max(s.depth[n],s.depth[m])+1); + tree[n*2+1] = tree[m*2+1] = (short)node; + + // and insert the new node in the heap + s.heap[1] = node++; + s.pqdownheap(tree, 1); + } + while(s.heap_len>=2); + + s.heap[--s.heap_max] = s.heap[1]; + + // At this point, the fields freq and dad are set. We can now + // generate the bit lengths. + + gen_bitlen(s); + + // The field len is now set, we can generate the bit codes + gen_codes(tree, max_code, s.bl_count, s.next_code); + } + + // Generate the codes for a given tree and bit counts (which need not be + // optimal). + // IN assertion: the array bl_count contains the bit length statistics for + // the given tree and the field len is set for all tree elements. + // OUT assertion: the field code is set for all tree elements of non + // zero code length. + private final static void gen_codes( + short[] tree, // the tree to decorate + int max_code, // largest code with non zero frequency + short[] bl_count, // number of codes at each bit length + short[] next_code){ + short code = 0; // running code value + int bits; // bit index + int n; // code index + + // The distribution counts are first used to generate the code values + // without bit reversal. + next_code[0]=0; + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (short)((code + bl_count[bits-1]) << 1); + } + + // Check that the bit counts in bl_count are consistent. The last code + // must be all ones. + //Assert (code + bl_count[MAX_BITS]-1 == (1<>>=1; + res<<=1; + } + while(--len>0); + return res>>>1; + } +} + diff --git a/src/lwjgl/java/com/jcraft/jzlib/ZInputStream.java b/src/lwjgl/java/com/jcraft/jzlib/ZInputStream.java new file mode 100644 index 0000000..cbd38e1 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/ZInputStream.java @@ -0,0 +1,126 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jcraft.jzlib; +import java.io.*; + +/** + * ZInputStream + * + * @deprecated use DeflaterOutputStream or InflaterInputStream + */ +@Deprecated +public class ZInputStream extends FilterInputStream { + + protected int flush=JZlib.Z_NO_FLUSH; + protected boolean compress; + protected InputStream in=null; + + protected Deflater deflater; + protected InflaterInputStream iis; + + public ZInputStream(InputStream in) throws IOException { + this(in, false); + } + public ZInputStream(InputStream in, boolean nowrap) throws IOException { + super(in); + iis = new InflaterInputStream(in, nowrap); + compress=false; + } + + public ZInputStream(InputStream in, int level) throws IOException { + super(in); + this.in=in; + deflater = new Deflater(); + deflater.init(level); + compress=true; + } + + private byte[] buf1 = new byte[1]; + public int read() throws IOException { + if(read(buf1, 0, 1)==-1) return -1; + return(buf1[0]&0xFF); + } + + private byte[] buf = new byte[512]; + + public int read(byte[] b, int off, int len) throws IOException { + if(compress){ + deflater.setOutput(b, off, len); + while(true){ + int datalen = in.read(buf, 0, buf.length); + if(datalen == -1) return -1; + deflater.setInput(buf, 0, datalen, true); + int err = deflater.deflate(flush); + if(deflater.next_out_index>0) + return deflater.next_out_index; + if(err == JZlib.Z_STREAM_END) + return 0; + if(err == JZlib.Z_STREAM_ERROR || + err == JZlib.Z_DATA_ERROR){ + throw new ZStreamException("deflating: "+deflater.msg); + } + } + } + else{ + return iis.read(b, off, len); + } + } + + public long skip(long n) throws IOException { + int len=512; + if(n0){ + inflater.setOutput(buf, 0, buf.length); + err = inflater.inflate(flush); + if(inflater.next_out_index>0) + out.write(buf, 0, inflater.next_out_index); + if(err != JZlib.Z_OK) + break; + } + if(err != JZlib.Z_OK) + throw new ZStreamException("inflating: "+inflater.msg); + return; + } + } + + public int getFlushMode() { + return flush; + } + + public void setFlushMode(int flush) { + this.flush=flush; + } + + public void finish() throws IOException { + int err; + if(compress){ + int tmp = flush; + int flush = JZlib.Z_FINISH; + try{ + write("".getBytes(), 0, 0); + } + finally { flush = tmp; } + } + else{ + dos.finish(); + } + flush(); + } + public synchronized void end() { + if(end) return; + if(compress){ + try { dos.finish(); } catch(Exception e){} + } + else{ + inflater.end(); + } + end=true; + } + public void close() throws IOException { + try{ + try{finish();} + catch (IOException ignored) {} + } + finally{ + end(); + out.close(); + out=null; + } + } + + public long getTotalIn() { + if(compress) return dos.getTotalIn(); + else return inflater.total_in; + } + + public long getTotalOut() { + if(compress) return dos.getTotalOut(); + else return inflater.total_out; + } + + public void flush() throws IOException { + out.flush(); + } + +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/ZStream.java b/src/lwjgl/java/com/jcraft/jzlib/ZStream.java new file mode 100644 index 0000000..0afa4fd --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/ZStream.java @@ -0,0 +1,377 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +/** + * ZStream + * + * @deprecated Not for public use in the future. + */ +@Deprecated +public class ZStream{ + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_WBITS=MAX_WBITS; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + public byte[] next_in; // next input byte + public int next_in_index; + public int avail_in; // number of bytes available at next_in + public long total_in; // total nb of input bytes read so far + + public byte[] next_out; // next output byte should be put there + public int next_out_index; + public int avail_out; // remaining free space at next_out + public long total_out; // total nb of bytes output so far + + public String msg; + + Deflate dstate; + Inflate istate; + + int data_type; // best guess about the data type: ascii or binary + + Checksum adler; + + public ZStream(){ + this(new Adler32()); + } + + public ZStream(Checksum adler){ + this.adler=adler; + } + + public int inflateInit(){ + return inflateInit(DEF_WBITS); + } + public int inflateInit(boolean nowrap){ + return inflateInit(DEF_WBITS, nowrap); + } + public int inflateInit(int w){ + return inflateInit(w, false); + } + public int inflateInit(JZlib.WrapperType wrapperType) { + return inflateInit(DEF_WBITS, wrapperType); + } + public int inflateInit(int w, JZlib.WrapperType wrapperType) { + boolean nowrap = false; + if(wrapperType == JZlib.W_NONE){ + nowrap = true; + } + else if(wrapperType == JZlib.W_GZIP) { + w += 16; + } + else if(wrapperType == JZlib.W_ANY) { + w |= Inflate.INFLATE_ANY; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return inflateInit(w, nowrap); + } + public int inflateInit(int w, boolean nowrap){ + istate=new Inflate(this); + return istate.inflateInit(nowrap?-w:w); + } + + public int inflate(int f){ + if(istate==null) return Z_STREAM_ERROR; + return istate.inflate(f); + } + public int inflateEnd(){ + if(istate==null) return Z_STREAM_ERROR; + int ret=istate.inflateEnd(); +// istate = null; + return ret; + } + public int inflateSync(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSync(); + } + public int inflateSyncPoint(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSyncPoint(); + } + public int inflateSetDictionary(byte[] dictionary, int dictLength){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSetDictionary(dictionary, dictLength); + } + public boolean inflateFinished(){ + return istate.mode==12 /*DONE*/; + } + + public int deflateInit(int level){ + return deflateInit(level, MAX_WBITS); + } + public int deflateInit(int level, boolean nowrap){ + return deflateInit(level, MAX_WBITS, nowrap); + } + public int deflateInit(int level, int bits){ + return deflateInit(level, bits, false); + } + public int deflateInit(int level, int bits, int memlevel, JZlib.WrapperType wrapperType){ + if(bits < 9 || bits > 15){ + return Z_STREAM_ERROR; + } + if(wrapperType == JZlib.W_NONE) { + bits *= -1; + } + else if(wrapperType == JZlib.W_GZIP) { + bits += 16; + } + else if(wrapperType == JZlib.W_ANY) { + return Z_STREAM_ERROR; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return this.deflateInit(level, bits, memlevel); + } + public int deflateInit(int level, int bits, int memlevel){ + dstate=new Deflate(this); + return dstate.deflateInit(level, bits, memlevel); + } + public int deflateInit(int level, int bits, boolean nowrap){ + dstate=new Deflate(this); + return dstate.deflateInit(level, nowrap?-bits:bits); + } + public int deflate(int flush){ + if(dstate==null){ + return Z_STREAM_ERROR; + } + return dstate.deflate(flush); + } + public int deflateEnd(){ + if(dstate==null) return Z_STREAM_ERROR; + int ret=dstate.deflateEnd(); + dstate=null; + return ret; + } + public int deflateParams(int level, int strategy){ + if(dstate==null) return Z_STREAM_ERROR; + return dstate.deflateParams(level, strategy); + } + public int deflateSetDictionary (byte[] dictionary, int dictLength){ + if(dstate == null) + return Z_STREAM_ERROR; + return dstate.deflateSetDictionary(dictionary, dictLength); + } + + // Flush as much pending output as possible. All deflate() output goes + // through this function so some applications may wish to modify it + // to avoid allocating a large strm->next_out buffer and copying into it. + // (See also read_buf()). + void flush_pending(){ + int len=dstate.pending; + + if(len>avail_out) len=avail_out; + if(len==0) return; + + if(dstate.pending_buf.length<=dstate.pending_out || + next_out.length<=next_out_index || + dstate.pending_buf.length<(dstate.pending_out+len) || + next_out.length<(next_out_index+len)){ + //System.out.println(dstate.pending_buf.length+", "+dstate.pending_out+ + // ", "+next_out.length+", "+next_out_index+", "+len); + //System.out.println("avail_out="+avail_out); + } + + System.arraycopy(dstate.pending_buf, dstate.pending_out, + next_out, next_out_index, len); + + next_out_index+=len; + dstate.pending_out+=len; + total_out+=len; + avail_out-=len; + dstate.pending-=len; + if(dstate.pending==0){ + dstate.pending_out=0; + } + } + + // Read a new buffer from the current input stream, update the adler32 + // and total number of bytes read. All deflate() input goes through + // this function so some applications may wish to modify it to avoid + // allocating a large strm->next_in buffer and copying from it. + // (See also flush_pending()). + int read_buf(byte[] buf, int start, int size) { + int len=avail_in; + + if(len>size) len=size; + if(len==0) return 0; + + avail_in-=len; + + if(dstate.wrap!=0) { + adler.update(next_in, next_in_index, len); + } + System.arraycopy(next_in, next_in_index, buf, start, len); + next_in_index += len; + total_in += len; + return len; + } + + public long getAdler(){ + return adler.getValue(); + } + + public void free(){ + next_in=null; + next_out=null; + msg=null; + } + + public void setOutput(byte[] buf){ + setOutput(buf, 0, buf.length); + } + + public void setOutput(byte[] buf, int off, int len){ + next_out = buf; + next_out_index = off; + avail_out = len; + } + + public void setInput(byte[] buf){ + setInput(buf, 0, buf.length, false); + } + + public void setInput(byte[] buf, boolean append){ + setInput(buf, 0, buf.length, append); + } + + public void setInput(byte[] buf, int off, int len, boolean append){ + if(len<=0 && append && next_in!=null) return; + + if(avail_in>0 && append){ + byte[] tmp = new byte[avail_in+len]; + System.arraycopy(next_in, next_in_index, tmp, 0, avail_in); + System.arraycopy(buf, off, tmp, avail_in, len); + next_in=tmp; + next_in_index=0; + avail_in+=len; + } + else{ + next_in=buf; + next_in_index=off; + avail_in=len; + } + } + + public byte[] getNextIn(){ + return next_in; + } + + public void setNextIn(byte[] next_in){ + this.next_in = next_in; + } + + public int getNextInIndex(){ + return next_in_index; + } + + public void setNextInIndex(int next_in_index){ + this.next_in_index = next_in_index; + } + + public int getAvailIn(){ + return avail_in; + } + + public void setAvailIn(int avail_in){ + this.avail_in = avail_in; + } + + public byte[] getNextOut(){ + return next_out; + } + + public void setNextOut(byte[] next_out){ + this.next_out = next_out; + } + + public int getNextOutIndex(){ + return next_out_index; + } + + public void setNextOutIndex(int next_out_index){ + this.next_out_index = next_out_index; + } + + public int getAvailOut(){ + return avail_out; + + } + + public void setAvailOut(int avail_out){ + this.avail_out = avail_out; + } + + public long getTotalOut(){ + return total_out; + } + + public long getTotalIn(){ + return total_in; + } + + public String getMessage(){ + return msg; + } + + /** + * Those methods are expected to be override by Inflater and Deflater. + * In the future, they will become abstract methods. + */ + public int end(){ return Z_OK; } + public boolean finished(){ return false; } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/ZStreamException.java b/src/lwjgl/java/com/jcraft/jzlib/ZStreamException.java new file mode 100644 index 0000000..424b74b --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/ZStreamException.java @@ -0,0 +1,44 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +public class ZStreamException extends java.io.IOException { + public ZStreamException() { + super(); + } + public ZStreamException(String s) { + super(s); + } +} diff --git a/src/lwjgl/java/de/cuina/fireandfuel/CodecJLayerMP3.java b/src/lwjgl/java/de/cuina/fireandfuel/CodecJLayerMP3.java new file mode 100644 index 0000000..3049639 --- /dev/null +++ b/src/lwjgl/java/de/cuina/fireandfuel/CodecJLayerMP3.java @@ -0,0 +1,586 @@ +package de.cuina.fireandfuel; + +/* + * CodecJLayerMP3 - an ICodec interface for Paulscode Sound System + * Copyright (C) 2012 by fireandfuel from Cuina Team (http://www.cuina.byethost12.com/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 + * of the License, or (at your option) any later version. + * + * This program is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see http://www.gnu.org/licenses/lgpl.txt + */ + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.net.URL; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; + +import javazoom.jl.decoder.Bitstream; +import javazoom.jl.decoder.Decoder; +import javazoom.jl.decoder.Header; +import javazoom.jl.decoder.Obuffer; +import javazoom.mp3spi.DecodedMpegAudioInputStream; + +import paulscode.sound.ICodec; +import paulscode.sound.SoundBuffer; +import paulscode.sound.SoundSystemConfig; +import paulscode.sound.SoundSystemLogger; + +/** + * The CodecJLayer class provides an ICodec interface to the external JLayer + * library. + * + *
+ *
+ * This software is based on or using the JLayer and mp3spi library from + * http://www.javazoom.net/javalayer/javalayer.html and Tritonus library from + * http://www.tritonus.org/. + * + * JLayer, mp3spi and Tritonus library are released under the conditions of + * GNU Library General Public License version 2 or (at your option) + * any later version of the License. + *

+ */ + +public class CodecJLayerMP3 implements ICodec +{ + /** + * Used to return a current value from one of the synchronized + * boolean-interface methods. + */ + private static final boolean GET = false; + + /** + * Used to set the value in one of the synchronized boolean-interface + * methods. + */ + private static final boolean SET = true; + + /** + * Used when a parameter for one of the synchronized boolean-interface + * methods is not applicable. + */ + private static final boolean XXX = false; + + /** + * True if there is no more data to read in. + */ + private boolean endOfStream = false; + + /** + * True if the stream has finished initializing. + */ + private boolean initialized = false; + + private Decoder decoder; + private Bitstream bitstream; + private DMAISObuffer buffer; + + private Header mainHeader; + + /** + * Audio format to use when playing back the wave data. + */ + private AudioFormat myAudioFormat = null; + + /** + * Input stream to use for reading in pcm data. + */ + private DecodedMpegAudioInputStream myAudioInputStream = null; + + /** + * Processes status messages, warnings, and error messages. + */ + private SoundSystemLogger logger; + + public CodecJLayerMP3() + { + logger = SoundSystemConfig.getLogger(); + } + + @Override + public void reverseByteOrder(boolean b) + { + } + + @Override + public boolean initialize(URL url) + { + initialized(SET, false); + cleanup(); + if(url == null) + { + errorMessage("url null in method 'initialize'"); + cleanup(); + return false; + } + + try + { + bitstream = new Bitstream(new BufferedInputStream(url.openStream())); + decoder = new Decoder(); + + mainHeader = bitstream.readFrame(); + + buffer = new DMAISObuffer(2); + decoder.setOutputBuffer(buffer); + + int channels; + if(mainHeader.mode() < 3) + channels = 2; + else channels = 1; + + bitstream.closeFrame(); + bitstream.close(); + + myAudioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, + mainHeader.frequency(), 16, channels, channels * 2, mainHeader.frequency(), + false); + + AudioFormat mpegAudioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, -1.0f, + 16, channels, channels * 2, -1.0f, false); + + myAudioInputStream = new DecodedMpegAudioInputStream(myAudioFormat, + new AudioInputStream(new BufferedInputStream(url.openStream()), + mpegAudioFormat, -1)); + myAudioInputStream.skip((int)(myAudioInputStream.getFormat().getFrameRate() * 0.018f) * myAudioInputStream.getFormat().getFrameSize()); + } catch (Exception e) + { + errorMessage("Unable to set up input streams in method " + "'initialize'"); + printStackTrace(e); + cleanup(); + return false; + } + + if(myAudioInputStream == null) + { + errorMessage("Unable to set up audio input stream in method " + "'initialize'"); + cleanup(); + return false; + } + + endOfStream(SET, false); + initialized(SET, true); + return true; + } + + @Override + public boolean initialized() + { + return initialized(GET, XXX); + } + + @Override + public SoundBuffer read() + { + if(myAudioInputStream == null) + { + endOfStream(SET, true); + return null; + } + + // Get the format for the audio data: + AudioFormat audioFormat = myAudioInputStream.getFormat(); + + // Check to make sure there is an audio format: + if(audioFormat == null) + { + errorMessage("Audio Format null in method 'read'"); + endOfStream(SET, true); + return null; + } + + // Variables used when reading from the audio input stream: + int bytesRead = 0, cnt = 0; + + // Allocate memory for the audio data: + byte[] streamBuffer = new byte[SoundSystemConfig.getStreamingBufferSize()]; + + try + { + // Read until buffer is full or end of stream is reached: + while((!endOfStream(GET, XXX)) && (bytesRead < streamBuffer.length)) + { + myAudioInputStream.execute(); + if((cnt = myAudioInputStream.read(streamBuffer, bytesRead, streamBuffer.length + - bytesRead)) < 0) + { + endOfStream(SET, true); + break; + } + // keep track of how many bytes were read: + bytesRead += cnt; + } + } catch (IOException ioe) + { + + /* + * errorMessage( "Exception thrown while reading from the " + + * "AudioInputStream (location #3)." ); printStackTrace( e ); return + * null; + */// TODO: Figure out why this exceptions is being thrown at end of + // MP3 files! + endOfStream(SET, true); + return null; + } catch (ArrayIndexOutOfBoundsException e) + { + //this exception is thrown at the end of the mp3's + endOfStream(SET, true); + return null; + } + + // Return null if no data was read: + if(bytesRead <= 0) + { + endOfStream(SET, true); + return null; + } + + // Insert the converted data into a ByteBuffer: + // byte[] data = convertAudioBytes(streamBuffer, + // audioFormat.getSampleSizeInBits() == 16); + + // Wrap the data into a SoundBuffer: + SoundBuffer buffer = new SoundBuffer(streamBuffer, audioFormat); + + // Return the result: + return buffer; + } + + @Override + public SoundBuffer readAll() + { + // Check to make sure there is an audio format: + if(myAudioFormat == null) + { + errorMessage("Audio Format null in method 'readAll'"); + return null; + } + + // Array to contain the audio data: + byte[] fullBuffer = null; + + // Determine how much data will be read in: + int fileSize = myAudioFormat.getChannels() * (int) myAudioInputStream.getFrameLength() + * myAudioFormat.getSampleSizeInBits() / 8; + if(fileSize > 0) + { + // Allocate memory for the audio data: + fullBuffer = new byte[myAudioFormat.getChannels() + * (int) myAudioInputStream.getFrameLength() + * myAudioFormat.getSampleSizeInBits() / 8]; + int read = 0, total = 0; + try + { + // Read until the end of the stream is reached: + while((read = myAudioInputStream.read(fullBuffer, total, fullBuffer.length - total)) != -1 + && total < fullBuffer.length) + { + total += read; + } + } catch (IOException e) + { + errorMessage("Exception thrown while reading from the " + + "AudioInputStream (location #1)."); + printStackTrace(e); + return null; + } + } else + { + // Total file size unknown. + + // Variables used when reading from the audio input stream: + int totalBytes = 0, bytesRead = 0, cnt = 0; + byte[] smallBuffer = null; + + // Allocate memory for a chunk of data: + smallBuffer = new byte[SoundSystemConfig.getFileChunkSize()]; + + // Read until end of file or maximum file size is reached: + while((!endOfStream(GET, XXX)) && (totalBytes < SoundSystemConfig.getMaxFileSize())) + { + bytesRead = 0; + cnt = 0; + + try + { + // Read until small buffer is filled or end of file reached: + while(bytesRead < smallBuffer.length) + { + myAudioInputStream.execute(); + if((cnt = myAudioInputStream.read(smallBuffer, bytesRead, + smallBuffer.length - bytesRead)) < 0) + { + endOfStream(SET, true); + break; + } + bytesRead += cnt; + } + } catch (IOException e) + { + errorMessage("Exception thrown while reading from the " + + "AudioInputStream (location #2)."); + printStackTrace(e); + return null; + } + + // Reverse byte order if necessary: + // if( reverseBytes ) + // reverseBytes( smallBuffer, 0, bytesRead ); + + // Keep track of the total number of bytes read: + totalBytes += bytesRead; + + // Append the small buffer to the full buffer: + fullBuffer = appendByteArrays(fullBuffer, smallBuffer, bytesRead); + } + } + + // Insert the converted data into a ByteBuffer + // byte[] data = convertAudioBytes( fullBuffer, + // myAudioFormat.getSampleSizeInBits() == 16 ); + + // Wrap the data into an SoundBuffer: + SoundBuffer soundBuffer = new SoundBuffer(fullBuffer, myAudioFormat); + + // Close the audio input stream + try + { + myAudioInputStream.close(); + } catch (IOException e) + { + } + + // Return the result: + return soundBuffer; + } + + @Override + public boolean endOfStream() + { + return endOfStream(GET, XXX); + } + + @Override + public void cleanup() + { + if(myAudioInputStream != null) + try + { + myAudioInputStream.close(); + } catch (Exception e) + { + } + } + + @Override + public AudioFormat getAudioFormat() + { + return myAudioFormat; + } + + /** + * Internal method for synchronizing access to the boolean 'initialized'. + * + * @param action + * GET or SET. + * @param value + * New value if action == SET, or XXX if action == GET. + * @return True if steam is initialized. + */ + private synchronized boolean initialized(boolean action, boolean value) + { + if(action == SET) + initialized = value; + return initialized; + } + + /** + * Internal method for synchronizing access to the boolean 'endOfStream'. + * + * @param action + * GET or SET. + * @param value + * New value if action == SET, or XXX if action == GET. + * @return True if end of stream was reached. + */ + private synchronized boolean endOfStream(boolean action, boolean value) + { + if(action == SET) + endOfStream = value; + return endOfStream; + } + + /** + * Reverse-orders all bytes contained in the specified array. + * + * @param buffer + * Array containing audio data. + */ + public static void reverseBytes(byte[] buffer) + { + reverseBytes(buffer, 0, buffer.length); + } + + /** + * Reverse-orders the specified range of bytes contained in the specified + * array. + * + * @param buffer + * Array containing audio data. + * @param offset + * Array index to begin. + * @param size + * number of bytes to reverse-order. + */ + public static void reverseBytes(byte[] buffer, int offset, int size) + { + + byte b; + for(int i = offset; i < (offset + size); i += 2) + { + b = buffer[i]; + buffer[i] = buffer[i + 1]; + buffer[i + 1] = b; + } + } + + /** + * Prints an error message. + * + * @param message + * Message to print. + */ + private void errorMessage(String message) + { + logger.errorMessage("CodecJLayerMP3", message, 0); + } + + /** + * Prints an exception's error message followed by the stack trace. + * + * @param e + * Exception containing the information to print. + */ + private void printStackTrace(Exception e) + { + logger.printStackTrace(e, 1); + } + + /** + * Creates a new array with the second array appended to the end of the + * first array. + * + * @param arrayOne + * The first array. + * @param arrayTwo + * The second array. + * @param length + * How many bytes to append from the second array. + * @return Byte array containing information from both arrays. + */ + private static byte[] appendByteArrays(byte[] arrayOne, byte[] arrayTwo, int length) + { + byte[] newArray; + if(arrayOne == null && arrayTwo == null) + { + // no data, just return + return null; + } else if(arrayOne == null) + { + // create the new array, same length as arrayTwo: + newArray = new byte[length]; + // fill the new array with the contents of arrayTwo: + System.arraycopy(arrayTwo, 0, newArray, 0, length); + arrayTwo = null; + } else if(arrayTwo == null) + { + // create the new array, same length as arrayOne: + newArray = new byte[arrayOne.length]; + // fill the new array with the contents of arrayOne: + System.arraycopy(arrayOne, 0, newArray, 0, arrayOne.length); + arrayOne = null; + } else + { + // create the new array large enough to hold both arrays: + newArray = new byte[arrayOne.length + length]; + System.arraycopy(arrayOne, 0, newArray, 0, arrayOne.length); + // fill the new array with the contents of both arrays: + System.arraycopy(arrayTwo, 0, newArray, arrayOne.length, length); + arrayOne = null; + arrayTwo = null; + } + + return newArray; + } + + private static class DMAISObuffer extends Obuffer + { + private int m_nChannels; + private byte[] m_abBuffer; + private int[] m_anBufferPointers; + private boolean m_bIsBigEndian; + + public DMAISObuffer(int nChannels) + { + m_nChannels = nChannels; + m_abBuffer = new byte[OBUFFERSIZE * nChannels]; + m_anBufferPointers = new int[nChannels]; + reset(); + } + + public void append(int nChannel, short sValue) + { + byte bFirstByte; + byte bSecondByte; + if(m_bIsBigEndian) + { + bFirstByte = (byte) ((sValue >>> 8) & 0xFF); + bSecondByte = (byte) (sValue & 0xFF); + } else + // little endian + { + bFirstByte = (byte) (sValue & 0xFF); + bSecondByte = (byte) ((sValue >>> 8) & 0xFF); + } + m_abBuffer[m_anBufferPointers[nChannel]] = bFirstByte; + m_abBuffer[m_anBufferPointers[nChannel] + 1] = bSecondByte; + m_anBufferPointers[nChannel] += m_nChannels * 2; + } + + public void set_stop_flag() + { + } + + public void close() + { + } + + public void write_buffer(int nValue) + { + } + + public void clear_buffer() + { + } + + public void reset() + { + for(int i = 0; i < m_nChannels; i++) + { + /* + * Points to byte location, implicitly assuming 16 bit samples. + */ + m_anBufferPointers[i] = i * 2; + } + } + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/BitReserve.java b/src/lwjgl/java/javazoom/jl/decoder/BitReserve.java new file mode 100644 index 0000000..fa3deab --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/BitReserve.java @@ -0,0 +1,224 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 12/12/99 0.0.7 Implementation stores single bits + * as ints for better performance. mdm@techie.com. + * + * 02/28/99 0.0 Java Conversion by E.B, javalayer@javazoom.net + * + * Adapted from the public c code by Jeff Tsay. + * + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Implementation of Bit Reservoir for Layer III. + *

+ * The implementation stores single bits as a word in the buffer. If + * a bit is set, the corresponding word in the buffer will be non-zero. + * If a bit is clear, the corresponding word is zero. Although this + * may seem wasteful, this can be a factor of two quicker than + * packing 8 bits to a byte and extracting. + *

+ */ + +// REVIEW: there is no range checking, so buffer underflow or overflow +// can silently occur. +final class BitReserve +{ + /** + * Size of the internal buffer to store the reserved bits. + * Must be a power of 2. And x8, as each bit is stored as a single + * entry. + */ + private static final int BUFSIZE = 4096*8; + + /** + * Mask that can be used to quickly implement the + * modulus operation on BUFSIZE. + */ + private static final int BUFSIZE_MASK = BUFSIZE-1; + + private int offset, totbit, buf_byte_idx; + private final int[] buf = new int[BUFSIZE]; + private int buf_bit_idx; + + BitReserve() + { + + offset = 0; + totbit = 0; + buf_byte_idx = 0; + } + + + /** + * Return totbit Field. + */ + public int hsstell() + { + return(totbit); + } + + /** + * Read a number bits from the bit stream. + * @param N the number of + */ + public int hgetbits(int N) + { + totbit += N; + + int val = 0; + + int pos = buf_byte_idx; + if (pos+N < BUFSIZE) + { + while (N-- > 0) + { + val <<= 1; + val |= ((buf[pos++]!=0) ? 1 : 0); + } + } + else + { + while (N-- > 0) + { + val <<= 1; + val |= ((buf[pos]!=0) ? 1 : 0); + pos = (pos+1) & BUFSIZE_MASK; + } + } + buf_byte_idx = pos; + return val; + } + + + + /** + * Read 1 bit from the bit stream. + */ +/* + public int hget1bit_old() + { + int val; + totbit++; + if (buf_bit_idx == 0) + { + buf_bit_idx = 8; + buf_byte_idx++; + } + // BUFSIZE = 4096 = 2^12, so + // buf_byte_idx%BUFSIZE == buf_byte_idx & 0xfff + val = buf[buf_byte_idx & BUFSIZE_MASK] & putmask[buf_bit_idx]; + buf_bit_idx--; + val = val >>> buf_bit_idx; + return val; + } + */ + /** + * Returns next bit from reserve. + * + * @return 0 if next bit is reset, or 1 if next bit is set. + */ + public int hget1bit() + { + totbit++; + int val = buf[buf_byte_idx]; + buf_byte_idx = (buf_byte_idx+1) & BUFSIZE_MASK; + return val; + } + + /** + * Retrieves bits from the reserve. + */ +/* + public int readBits(int[] out, int len) + { + if (buf_bit_idx == 0) + { + buf_bit_idx = 8; + buf_byte_idx++; + current = buf[buf_byte_idx & BUFSIZE_MASK]; + } + + + + // save total number of bits returned + len = buf_bit_idx; + buf_bit_idx = 0; + + int b = current; + int count = len-1; + + while (count >= 0) + { + out[count--] = (b & 0x1); + b >>>= 1; + } + + totbit += len; + return len; + } + */ + + /** + * Write 8 bits into the bit stream. + */ + public void hputbuf(int val) + { + int ofs = offset; + buf[ofs++] = val & 0x80; + buf[ofs++] = val & 0x40; + buf[ofs++] = val & 0x20; + buf[ofs++] = val & 0x10; + buf[ofs++] = val & 0x08; + buf[ofs++] = val & 0x04; + buf[ofs++] = val & 0x02; + buf[ofs++] = val & 0x01; + + if (ofs==BUFSIZE) + offset = 0; + else + offset = ofs; + + } + + /** + * Rewind N bits in Stream. + */ + public void rewindNbits(int N) + { + totbit -= N; + buf_byte_idx -= N; + if (buf_byte_idx<0) + buf_byte_idx += BUFSIZE; + } + + /** + * Rewind N bytes in Stream. + */ + public void rewindNbytes(int N) + { + int bits = (N << 3); + totbit -= bits; + buf_byte_idx -= bits; + if (buf_byte_idx<0) + buf_byte_idx += BUFSIZE; + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/Bitstream.java b/src/lwjgl/java/javazoom/jl/decoder/Bitstream.java new file mode 100644 index 0000000..6286160 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/Bitstream.java @@ -0,0 +1,659 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 11/17/04 Uncomplete frames discarded. E.B, javalayer@javazoom.net + * + * 12/05/03 ID3v2 tag returned. E.B, javalayer@javazoom.net + * + * 12/12/99 Based on Ibitstream. Exceptions thrown on errors, + * Temporary removed seek functionality. mdm@techie.com + * + * 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net + * + * 04/14/97 : Added function prototypes for new syncing and seeking + * mechanisms. Also made this file portable. Changes made by Jeff Tsay + * + * @(#) ibitstream.h 1.5, last edit: 6/15/94 16:55:34 + * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de) + * @(#) Berlin University of Technology + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PushbackInputStream; + + +/** + * The Bistream class is responsible for parsing + * an MPEG audio bitstream. + * + * REVIEW: much of the parsing currently occurs in the + * various decoders. This should be moved into this class and associated + * inner classes. + */ +public final class Bitstream implements BitstreamErrors +{ + /** + * Synchronization control constant for the initial + * synchronization to the start of a frame. + */ + static byte INITIAL_SYNC = 0; + + /** + * Synchronization control constant for non-initial frame + * synchronizations. + */ + static byte STRICT_SYNC = 1; + + // max. 1730 bytes per frame: 144 * 384kbit/s / 32000 Hz + 2 Bytes CRC + /** + * Maximum size of the frame buffer. + */ + private static final int BUFFER_INT_SIZE = 433; + + /** + * The frame buffer that holds the data for the current frame. + */ + private final int[] framebuffer = new int[BUFFER_INT_SIZE]; + + /** + * Number of valid bytes in the frame buffer. + */ + private int framesize; + + /** + * The bytes read from the stream. + */ + private byte[] frame_bytes = new byte[BUFFER_INT_SIZE*4]; + + /** + * Index into framebuffer where the next bits are + * retrieved. + */ + private int wordpointer; + + /** + * Number (0-31, from MSB to LSB) of next bit for get_bits() + */ + private int bitindex; + + /** + * The current specified syncword + */ + private int syncword; + + /** + * Audio header position in stream. + */ + private int header_pos = 0; + + /** + * + */ + private boolean single_ch_mode; + //private int current_frame_number; + //private int last_frame_number; + + private final int bitmask[] = {0, // dummy + 0x00000001, 0x00000003, 0x00000007, 0x0000000F, + 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, + 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, + 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, + 0x0001FFFF }; + + private final PushbackInputStream source; + + private final Header header = new Header(); + + private final byte syncbuf[] = new byte[4]; + + private Crc16[] crc = new Crc16[1]; + + private byte[] rawid3v2 = null; + + private boolean firstframe = true; + + + /** + * Construct a IBitstream that reads data from a + * given InputStream. + * + * @param in The InputStream to read from. + */ + public Bitstream(InputStream in) + { + if (in==null) throw new NullPointerException("in"); + in = new BufferedInputStream(in); + loadID3v2(in); + firstframe = true; + //source = new PushbackInputStream(in, 1024); + source = new PushbackInputStream(in, BUFFER_INT_SIZE*4); + + closeFrame(); + //current_frame_number = -1; + //last_frame_number = -1; + } + + /** + * Return position of the first audio header. + * @return size of ID3v2 tag frames. + */ + public int header_pos() + { + return header_pos; + } + + /** + * Load ID3v2 frames. + * @param in MP3 InputStream. + * @author JavaZOOM + */ + private void loadID3v2(InputStream in) + { + int size = -1; + try + { + // Read ID3v2 header (10 bytes). + in.mark(10); + size = readID3v2Header(in); + header_pos = size; + } + catch (IOException e) + {} + finally + { + try + { + // Unread ID3v2 header (10 bytes). + in.reset(); + } + catch (IOException e) + {} + } + // Load ID3v2 tags. + try + { + if (size > 0) + { + rawid3v2 = new byte[size]; + in.read(rawid3v2,0,rawid3v2.length); + } + } + catch (IOException e) + {} + } + + /** + * Parse ID3v2 tag header to find out size of ID3v2 frames. + * @param in MP3 InputStream + * @return size of ID3v2 frames + header + * @throws IOException + * @author JavaZOOM + */ + private int readID3v2Header(InputStream in) throws IOException + { + byte[] id3header = new byte[4]; + int size = -10; + in.read(id3header,0,3); + // Look for ID3v2 + if ( (id3header[0]=='I') && (id3header[1]=='D') && (id3header[2]=='3')) + { + in.read(id3header,0,3); + int majorVersion = id3header[0]; + int revision = id3header[1]; + in.read(id3header,0,4); + size = (int) (id3header[0] << 21) + (id3header[1] << 14) + (id3header[2] << 7) + (id3header[3]); + } + return (size+10); + } + + /** + * Return raw ID3v2 frames + header. + * @return ID3v2 InputStream or null if ID3v2 frames are not available. + */ + public InputStream getRawID3v2() + { + if (rawid3v2 == null) return null; + else + { + ByteArrayInputStream bain = new ByteArrayInputStream(rawid3v2); + return bain; + } + } + + /** + * Close the Bitstream. + * @throws BitstreamException + */ + public void close() throws BitstreamException + { + try + { + source.close(); + } + catch (IOException ex) + { + throw newBitstreamException(STREAM_ERROR, ex); + } + } + + /** + * Reads and parses the next frame from the input source. + * + * @return the Header describing details of the frame read, + * or null if the end of the stream has been reached. + */ + public Header readFrame() throws BitstreamException + { + Header result = null; + try + { + result = readNextFrame(); + // E.B, Parse VBR (if any) first frame. + if (firstframe == true) + { + result.parseVBR(frame_bytes); + firstframe = false; + } + } + catch (BitstreamException ex) + { + if ((ex.getErrorCode()==INVALIDFRAME)) + { + // Try to skip this frame. + //System.out.println("INVALIDFRAME"); + try + { + closeFrame(); + result = readNextFrame(); + } + catch (BitstreamException e) + { + if ((e.getErrorCode()!=STREAM_EOF)) + { + // wrap original exception so stack trace is maintained. + throw newBitstreamException(e.getErrorCode(), e); + } + } + } + else if ((ex.getErrorCode()!=STREAM_EOF)) + { + // wrap original exception so stack trace is maintained. + throw newBitstreamException(ex.getErrorCode(), ex); + } + } + return result; + } + + /** + * Read next MP3 frame. + * + * @return MP3 frame header. + * @throws BitstreamException + */ + private Header readNextFrame() throws BitstreamException + { + if (framesize == -1) + { + nextFrame(); + } + return header; + } + + + /** + * Read next MP3 frame. + * + * @throws BitstreamException + */ + private void nextFrame() throws BitstreamException + { + // entire frame is read by the header class. + header.read_header(this, crc); + } + + /** + * Unreads the bytes read from the frame. + * + * @throws BitstreamException + */ + // REVIEW: add new error codes for this. + public void unreadFrame() throws BitstreamException + { + if (wordpointer==-1 && bitindex==-1 && (framesize>0)) + { + try + { + source.unread(frame_bytes, 0, framesize); + } + catch (IOException ex) + { + throw newBitstreamException(STREAM_ERROR); + } + } + } + + /** + * Close MP3 frame. + */ + public void closeFrame() + { + framesize = -1; + wordpointer = -1; + bitindex = -1; + } + + /** + * Determines if the next 4 bytes of the stream represent a + * frame header. + */ + public boolean isSyncCurrentPosition(int syncmode) throws BitstreamException + { + int read = readBytes(syncbuf, 0, 4); + int headerstring = ((syncbuf[0] << 24) & 0xFF000000) | ((syncbuf[1] << 16) & 0x00FF0000) | ((syncbuf[2] << 8) & 0x0000FF00) | ((syncbuf[3] << 0) & 0x000000FF); + + try + { + source.unread(syncbuf, 0, read); + } + catch (IOException ex) + { + } + + boolean sync = false; + switch (read) + { + case 0: + sync = true; + break; + case 4: + sync = isSyncMark(headerstring, syncmode, syncword); + break; + } + + return sync; + } + + + // REVIEW: this class should provide inner classes to + // parse the frame contents. Eventually, readBits will + // be removed. + public int readBits(int n) + { + return get_bits(n); + } + + public int readCheckedBits(int n) + { + // REVIEW: implement CRC check. + return get_bits(n); + } + + protected BitstreamException newBitstreamException(int errorcode) + { + return new BitstreamException(errorcode, null); + } + protected BitstreamException newBitstreamException(int errorcode, Throwable throwable) + { + return new BitstreamException(errorcode, throwable); + } + + /** + * Get next 32 bits from bitstream. + * They are stored in the headerstring. + * syncmod allows Synchro flag ID + * The returned value is False at the end of stream. + */ + + int syncHeader(byte syncmode) throws BitstreamException + { + boolean sync; + int headerstring; + // read additional 2 bytes + int bytesRead = readBytes(syncbuf, 0, 3); + + if (bytesRead!=3) throw newBitstreamException(STREAM_EOF, null); + + headerstring = ((syncbuf[0] << 16) & 0x00FF0000) | ((syncbuf[1] << 8) & 0x0000FF00) | ((syncbuf[2] << 0) & 0x000000FF); + + do + { + headerstring <<= 8; + + if (readBytes(syncbuf, 3, 1)!=1) + throw newBitstreamException(STREAM_EOF, null); + + headerstring |= (syncbuf[3] & 0x000000FF); + + sync = isSyncMark(headerstring, syncmode, syncword); + } + while (!sync); + + //current_frame_number++; + //if (last_frame_number < current_frame_number) last_frame_number = current_frame_number; + + return headerstring; + } + + public boolean isSyncMark(int headerstring, int syncmode, int word) + { + boolean sync = false; + + if (syncmode == INITIAL_SYNC) + { + //sync = ((headerstring & 0xFFF00000) == 0xFFF00000); + sync = ((headerstring & 0xFFE00000) == 0xFFE00000); // SZD: MPEG 2.5 + } + else + { + sync = ((headerstring & 0xFFF80C00) == word) && + (((headerstring & 0x000000C0) == 0x000000C0) == single_ch_mode); + } + + // filter out invalid sample rate + if (sync) + sync = (((headerstring >>> 10) & 3)!=3); + // filter out invalid layer + if (sync) + sync = (((headerstring >>> 17) & 3)!=0); + // filter out invalid version + if (sync) + sync = (((headerstring >>> 19) & 3)!=1); + + return sync; + } + + /** + * Reads the data for the next frame. The frame is not parsed + * until parse frame is called. + */ + int read_frame_data(int bytesize) throws BitstreamException + { + int numread = 0; + numread = readFully(frame_bytes, 0, bytesize); + framesize = bytesize; + wordpointer = -1; + bitindex = -1; + return numread; + } + + /** + * Parses the data previously read with read_frame_data(). + */ + void parse_frame() throws BitstreamException + { + // Convert Bytes read to int + int b=0; + byte[] byteread = frame_bytes; + int bytesize = framesize; + + // Check ID3v1 TAG (True only if last frame). + //for (int t=0;t<(byteread.length)-2;t++) + //{ + // if ((byteread[t]=='T') && (byteread[t+1]=='A') && (byteread[t+2]=='G')) + // { + // System.out.println("ID3v1 detected at offset "+t); + // throw newBitstreamException(INVALIDFRAME, null); + // } + //} + + for (int k=0;k>> (32 - sum)) & bitmask[number_of_bits]; + // returnvalue = (wordpointer[0] >> (32 - sum)) & bitmask[number_of_bits]; + if ((bitindex += number_of_bits) == 32) + { + bitindex = 0; + wordpointer++; // added by me! + } + return returnvalue; + } + + // E.B : Check that ? + //((short[])&returnvalue)[0] = ((short[])wordpointer + 1)[0]; + //wordpointer++; // Added by me! + //((short[])&returnvalue + 1)[0] = ((short[])wordpointer)[0]; + int Right = (framebuffer[wordpointer] & 0x0000FFFF); + wordpointer++; + int Left = (framebuffer[wordpointer] & 0xFFFF0000); + returnvalue = ((Right << 16) & 0xFFFF0000) | ((Left >>> 16)& 0x0000FFFF); + + returnvalue >>>= 48 - sum; // returnvalue >>= 16 - (number_of_bits - (32 - bitindex)) + returnvalue &= bitmask[number_of_bits]; + bitindex = sum - 32; + return returnvalue; +} + + /** + * Set the word we want to sync the header to. + * In Big-Endian byte order + */ + void set_syncword(int syncword0) + { + syncword = syncword0 & 0xFFFFFF3F; + single_ch_mode = ((syncword0 & 0x000000C0) == 0x000000C0); + } + /** + * Reads the exact number of bytes from the source + * input stream into a byte array. + * + * @param b The byte array to read the specified number + * of bytes into. + * @param offs The index in the array where the first byte + * read should be stored. + * @param len the number of bytes to read. + * + * @exception BitstreamException is thrown if the specified + * number of bytes could not be read from the stream. + */ + private int readFully(byte[] b, int offs, int len) + throws BitstreamException + { + int nRead = 0; + try + { + while (len > 0) + { + int bytesread = source.read(b, offs, len); + if (bytesread == -1) + { + while (len-->0) + { + b[offs++] = 0; + } + break; + //throw newBitstreamException(UNEXPECTED_EOF, new EOFException()); + } + nRead = nRead + bytesread; + offs += bytesread; + len -= bytesread; + } + } + catch (IOException ex) + { + throw newBitstreamException(STREAM_ERROR, ex); + } + return nRead; + } + + /** + * Similar to readFully, but doesn't throw exception when + * EOF is reached. + */ + private int readBytes(byte[] b, int offs, int len) + throws BitstreamException + { + int totalBytesRead = 0; + try + { + while (len > 0) + { + int bytesread = source.read(b, offs, len); + if (bytesread == -1) + { + break; + } + totalBytesRead += bytesread; + offs += bytesread; + len -= bytesread; + } + } + catch (IOException ex) + { + throw newBitstreamException(STREAM_ERROR, ex); + } + return totalBytesRead; + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/BitstreamErrors.java b/src/lwjgl/java/javazoom/jl/decoder/BitstreamErrors.java new file mode 100644 index 0000000..b5c3c93 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/BitstreamErrors.java @@ -0,0 +1,72 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 11/17/04 INVALIDFRAME code added. javalayer@javazoom.net + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * This interface describes all error codes that can be thrown + * in BistreamExceptions. + * + * @see BitstreamException + * + * @author MDM 12/12/99 + * @since 0.0.6 + */ + +public interface BitstreamErrors extends JavaLayerErrors +{ + + /** + * An undetermined error occurred. + */ + public static final int UNKNOWN_ERROR = BITSTREAM_ERROR + 0; + + /** + * The header describes an unknown sample rate. + */ + public static final int UNKNOWN_SAMPLE_RATE = BITSTREAM_ERROR + 1; + + /** + * A problem occurred reading from the stream. + */ + public static final int STREAM_ERROR = BITSTREAM_ERROR + 2; + + /** + * The end of the stream was reached prematurely. + */ + public static final int UNEXPECTED_EOF = BITSTREAM_ERROR + 3; + + /** + * The end of the stream was reached. + */ + public static final int STREAM_EOF = BITSTREAM_ERROR + 4; + + /** + * Frame data are missing. + */ + public static final int INVALIDFRAME = BITSTREAM_ERROR + 5; + + /** + * + */ + public static final int BITSTREAM_LAST = 0x1ff; + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/BitstreamException.java b/src/lwjgl/java/javazoom/jl/decoder/BitstreamException.java new file mode 100644 index 0000000..7aa0d6d --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/BitstreamException.java @@ -0,0 +1,71 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Instances of BitstreamException are thrown + * when operations on a Bitstream fail. + *

+ * The exception provides details of the exception condition + * in two ways: + *

  1. + * as an error-code describing the nature of the error + *


  2. + * as the Throwable instance, if any, that was thrown + * indicating that an exceptional condition has occurred. + *

+ * + * @since 0.0.6 + * @author MDM 12/12/99 + */ + +public class BitstreamException extends JavaLayerException + implements BitstreamErrors +{ + private int errorcode = UNKNOWN_ERROR; + + public BitstreamException(String msg, Throwable t) + { + super(msg, t); + } + + public BitstreamException(int errorcode, Throwable t) + { + this(getErrorString(errorcode), t); + this.errorcode = errorcode; + } + + public int getErrorCode() + { + return errorcode; + } + + + public static String getErrorString(int errorcode) + { + // REVIEW: use resource bundle to map error codes + // to locale-sensitive strings. + + return "Bitstream errorcode "+Integer.toHexString(errorcode); + } + + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/Control.java b/src/lwjgl/java/javazoom/jl/decoder/Control.java new file mode 100644 index 0000000..080ed52 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/Control.java @@ -0,0 +1,57 @@ +/* + * 11/19/04 1.0 moved to LGPL. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Work in progress. + */ + +public interface Control +{ + + /** + * Starts playback of the media presented by this control. + */ + public void start(); + + /** + * Stops playback of the media presented by this control. + */ + public void stop(); + + public boolean isPlaying(); + + public void pause(); + + + public boolean isRandomAccess(); + + /** + * Retrieves the current position. + */ + public double getPosition(); + + /** + * + */ + public void setPosition(double d); + + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/Crc16.java b/src/lwjgl/java/javazoom/jl/decoder/Crc16.java new file mode 100644 index 0000000..84760f2 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/Crc16.java @@ -0,0 +1,70 @@ +/* + * 11/19/04 : 1.0 moved to LGPL. + * + * 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net + * + * @(#) crc.h 1.5, last edit: 6/15/94 16:55:32 + * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de) + * @(#) Berlin University of Technology + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ +package javazoom.jl.decoder; + +/** + * 16-Bit CRC checksum + */ +public final class Crc16 +{ + private static short polynomial=(short)0x8005; + private short crc; + + /** + * Dummy Constructor + */ + public Crc16() + { + crc = (short) 0xFFFF; + } + + /** + * Feed a bitstring to the CRC calculation (0 < length <= 32). + */ + public void add_bits (int bitstring, int length) + { + int bitmask = 1 << (length - 1); + do + if (((crc & 0x8000) == 0) ^ ((bitstring & bitmask) == 0 )) + { + crc <<= 1; + crc ^= polynomial; + } + else + crc <<= 1; + while ((bitmask >>>= 1) != 0); + } + + /** + * Return the calculated checksum. + * Erase it for next calls to add_bits(). + */ + public short checksum() + { + short sum = crc; + crc = (short) 0xFFFF; + return sum; + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/Decoder.java b/src/lwjgl/java/javazoom/jl/decoder/Decoder.java new file mode 100644 index 0000000..dcd893b --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/Decoder.java @@ -0,0 +1,356 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 01/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * The Decoder class encapsulates the details of + * decoding an MPEG audio frame. + * + * @author MDM + * @version 0.0.7 12/12/99 + * @since 0.0.5 + */ +public class Decoder implements DecoderErrors +{ + private static final Params DEFAULT_PARAMS = new Params(); + + /** + * The Bitstream from which the MPEG audio frames are read. + */ + //private Bitstream stream; + + /** + * The Obuffer instance that will receive the decoded + * PCM samples. + */ + private Obuffer output; + + /** + * Synthesis filter for the left channel. + */ + private SynthesisFilter filter1; + + /** + * Synthesis filter for the right channel. + */ + private SynthesisFilter filter2; + + /** + * The decoder used to decode layer III frames. + */ + private LayerIIIDecoder l3decoder; + private LayerIIDecoder l2decoder; + private LayerIDecoder l1decoder; + + private int outputFrequency; + private int outputChannels; + + private Equalizer equalizer = new Equalizer(); + + private Params params; + + private boolean initialized; + + + /** + * Creates a new Decoder instance with default + * parameters. + */ + + public Decoder() + { + this(null); + } + + /** + * Creates a new Decoder instance with default + * parameters. + * + * @param params The Params instance that describes + * the customizable aspects of the decoder. + */ + public Decoder(Params params0) + { + if (params0==null) + params0 = DEFAULT_PARAMS; + + params = params0; + + Equalizer eq = params.getInitialEqualizerSettings(); + if (eq!=null) + { + equalizer.setFrom(eq); + } + } + + public static Params getDefaultParams() throws CloneNotSupportedException + { + return (Params)DEFAULT_PARAMS.clone(); + } + + public void setEqualizer(Equalizer eq) + { + if (eq==null) + eq = Equalizer.PASS_THRU_EQ; + + equalizer.setFrom(eq); + + float[] factors = equalizer.getBandFactors(); + + if (filter1!=null) + filter1.setEQ(factors); + + if (filter2!=null) + filter2.setEQ(factors); + } + + /** + * Decodes one frame from an MPEG audio bitstream. + * + * @param header The header describing the frame to decode. + * @param bitstream The bitstream that provides the bits for te body of the frame. + * + * @return A SampleBuffer containing the decoded samples. + */ + public Obuffer decodeFrame(Header header, Bitstream stream) + throws DecoderException + { + if (!initialized) + { + initialize(header); + } + + int layer = header.layer(); + + output.clear_buffer(); + + FrameDecoder decoder = retrieveDecoder(header, stream, layer); + + decoder.decodeFrame(); + + output.write_buffer(1); + + return output; + } + + /** + * Changes the output buffer. This will take effect the next time + * decodeFrame() is called. + */ + public void setOutputBuffer(Obuffer out) + { + output = out; + } + + /** + * Retrieves the sample frequency of the PCM samples output + * by this decoder. This typically corresponds to the sample + * rate encoded in the MPEG audio stream. + * + * @param the sample rate (in Hz) of the samples written to the + * output buffer when decoding. + */ + public int getOutputFrequency() + { + return outputFrequency; + } + + /** + * Retrieves the number of channels of PCM samples output by + * this decoder. This usually corresponds to the number of + * channels in the MPEG audio stream, although it may differ. + * + * @return The number of output channels in the decoded samples: 1 + * for mono, or 2 for stereo. + * + */ + public int getOutputChannels() + { + return outputChannels; + } + + /** + * Retrieves the maximum number of samples that will be written to + * the output buffer when one frame is decoded. This can be used to + * help calculate the size of other buffers whose size is based upon + * the number of samples written to the output buffer. NB: this is + * an upper bound and fewer samples may actually be written, depending + * upon the sample rate and number of channels. + * + * @return The maximum number of samples that are written to the + * output buffer when decoding a single frame of MPEG audio. + */ + public int getOutputBlockSize() + { + return Obuffer.OBUFFERSIZE; + } + + + protected DecoderException newDecoderException(int errorcode) + { + return new DecoderException(errorcode, null); + } + + protected DecoderException newDecoderException(int errorcode, Throwable throwable) + { + return new DecoderException(errorcode, throwable); + } + + protected FrameDecoder retrieveDecoder(Header header, Bitstream stream, int layer) + throws DecoderException + { + FrameDecoder decoder = null; + + // REVIEW: allow channel output selection type + // (LEFT, RIGHT, BOTH, DOWNMIX) + switch (layer) + { + case 3: + if (l3decoder==null) + { + l3decoder = new LayerIIIDecoder(stream, + header, filter1, filter2, + output, OutputChannels.BOTH_CHANNELS); + } + + decoder = l3decoder; + break; + case 2: + if (l2decoder==null) + { + l2decoder = new LayerIIDecoder(); + l2decoder.create(stream, + header, filter1, filter2, + output, OutputChannels.BOTH_CHANNELS); + } + decoder = l2decoder; + break; + case 1: + if (l1decoder==null) + { + l1decoder = new LayerIDecoder(); + l1decoder.create(stream, + header, filter1, filter2, + output, OutputChannels.BOTH_CHANNELS); + } + decoder = l1decoder; + break; + } + + if (decoder==null) + { + throw newDecoderException(UNSUPPORTED_LAYER, null); + } + + return decoder; + } + + private void initialize(Header header) + throws DecoderException + { + + // REVIEW: allow customizable scale factor + float scalefactor = 32700.0f; + + int mode = header.mode(); + int layer = header.layer(); + int channels = mode==Header.SINGLE_CHANNEL ? 1 : 2; + + + // set up output buffer if not set up by client. + if (output==null) + output = new SampleBuffer(header.frequency(), channels); + + float[] factors = equalizer.getBandFactors(); + filter1 = new SynthesisFilter(0, scalefactor, factors); + + // REVIEW: allow mono output for stereo + if (channels==2) + filter2 = new SynthesisFilter(1, scalefactor, factors); + + outputChannels = channels; + outputFrequency = header.frequency(); + + initialized = true; + } + + /** + * The Params class presents the customizable + * aspects of the decoder. + *

+ * Instances of this class are not thread safe. + */ + public static class Params implements Cloneable + { + private OutputChannels outputChannels = OutputChannels.BOTH; + + private Equalizer equalizer = new Equalizer(); + + public Params() + { + } + + public Object clone() throws CloneNotSupportedException { + try + { + return super.clone(); + } + catch (CloneNotSupportedException ex) + { + throw new InternalError(this+": "+ex); + } + } + + public void setOutputChannels(OutputChannels out) + { + if (out==null) + throw new NullPointerException("out"); + + outputChannels = out; + } + + public OutputChannels getOutputChannels() + { + return outputChannels; + } + + /** + * Retrieves the equalizer settings that the decoder's equalizer + * will be initialized from. + *

+ * The Equalizer instance returned + * cannot be changed in real time to affect the + * decoder output as it is used only to initialize the decoders + * EQ settings. To affect the decoder's output in realtime, + * use the Equalizer returned from the getEqualizer() method on + * the decoder. + * + * @return The Equalizer used to initialize the + * EQ settings of the decoder. + */ + public Equalizer getInitialEqualizerSettings() + { + return equalizer; + } + + }; +} + diff --git a/src/lwjgl/java/javazoom/jl/decoder/DecoderErrors.java b/src/lwjgl/java/javazoom/jl/decoder/DecoderErrors.java new file mode 100644 index 0000000..4cbbc81 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/DecoderErrors.java @@ -0,0 +1,45 @@ +/* + * 09/26/08 throw exception on subbband alloc error: Christopher G. Jennings (cjennings@acm.org) + * 11/19/04 1.0 moved to LGPL. + * 01/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * This interface provides constants describing the error + * codes used by the Decoder to indicate errors. + * + * @author MDM + */ +public interface DecoderErrors extends JavaLayerErrors +{ + + public static final int UNKNOWN_ERROR = DECODER_ERROR + 0; + + /** + * Layer not supported by the decoder. + */ + public static final int UNSUPPORTED_LAYER = DECODER_ERROR + 1; + + /** + * Illegal allocation in subband layer. Indicates a corrupt stream. + */ + public static final int ILLEGAL_SUBBAND_ALLOCATION = DECODER_ERROR + 2; + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/DecoderException.java b/src/lwjgl/java/javazoom/jl/decoder/DecoderException.java new file mode 100644 index 0000000..ce15c3d --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/DecoderException.java @@ -0,0 +1,59 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 01/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * The DecoderException represents the class of + * errors that can occur when decoding MPEG audio. + * + * @author MDM + */ +public class DecoderException extends JavaLayerException + implements DecoderErrors +{ + private int errorcode = UNKNOWN_ERROR; + + public DecoderException(String msg, Throwable t) + { + super(msg, t); + } + + public DecoderException(int errorcode, Throwable t) + { + this(getErrorString(errorcode), t); + this.errorcode = errorcode; + } + + public int getErrorCode() + { + return errorcode; + } + + + public static String getErrorString(int errorcode) + { + // REVIEW: use resource file to map error codes + // to locale-sensitive strings. + + return "Decoder errorcode "+Integer.toHexString(errorcode); + } +} + diff --git a/src/lwjgl/java/javazoom/jl/decoder/Equalizer.java b/src/lwjgl/java/javazoom/jl/decoder/Equalizer.java new file mode 100644 index 0000000..9d41047 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/Equalizer.java @@ -0,0 +1,227 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + + +package javazoom.jl.decoder; + +/** + * The Equalizer class can be used to specify + * equalization settings for the MPEG audio decoder. + *

+ * The equalizer consists of 32 band-pass filters. + * Each band of the equalizer can take on a fractional value between + * -1.0 and +1.0. + * At -1.0, the input signal is attenuated by 6dB, at +1.0 the signal is + * amplified by 6dB. + * + * @see Decoder + * + * @author MDM + */ +public final class Equalizer +{ + /** + * Equalizer setting to denote that a given band will not be + * present in the output signal. + */ + public static final float BAND_NOT_PRESENT = Float.NEGATIVE_INFINITY; + + public static final Equalizer PASS_THRU_EQ = new Equalizer(); + + private static final int BANDS = 32; + + private final float[] settings = new float[BANDS]; + + /** + * Creates a new Equalizer instance. + */ + public Equalizer() + { + } + +// private Equalizer(float b1, float b2, float b3, float b4, float b5, +// float b6, float b7, float b8, float b9, float b10, float b11, +// float b12, float b13, float b14, float b15, float b16, +// float b17, float b18, float b19, float b20); + + public Equalizer(float[] settings) + { + setFrom(settings); + } + + public Equalizer(EQFunction eq) + { + setFrom(eq); + } + + public void setFrom(float[] eq) + { + reset(); + int max = (eq.length > BANDS) ? BANDS : eq.length; + + for (int i=0; i=0) && (band=0) && (band 1.0f) + return 1.0f; + if (eq < -1.0f) + return -1.0f; + + return eq; + } + + /** + * Retrieves an array of floats whose values represent a + * scaling factor that can be applied to linear samples + * in each band to provide the equalization represented by + * this instance. + * + * @return an array of factors that can be applied to the + * subbands. + */ + float[] getBandFactors() + { + float[] factors = new float[BANDS]; + for (int i=0, maxCount=BANDS; i>> 19) & 1); + if (((headerstring >>> 20) & 1) == 0) // SZD: MPEG2.5 detection + if (h_version == MPEG2_LSF) + h_version = MPEG25_LSF; + else + throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR); + if ((h_sample_frequency = ((headerstring >>> 10) & 3)) == 3) + { + throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR); + } + } + h_layer = 4 - (headerstring >>> 17) & 3; + h_protection_bit = (headerstring >>> 16) & 1; + h_bitrate_index = (headerstring >>> 12) & 0xF; + h_padding_bit = (headerstring >>> 9) & 1; + h_mode = ((headerstring >>> 6) & 3); + h_mode_extension = (headerstring >>> 4) & 3; + if (h_mode == JOINT_STEREO) + h_intensity_stereo_bound = (h_mode_extension << 2) + 4; + else + h_intensity_stereo_bound = 0; // should never be used + if (((headerstring >>> 3) & 1) == 1) + h_copyright = true; + if (((headerstring >>> 2) & 1) == 1) + h_original = true; + // calculate number of subbands: + if (h_layer == 1) + h_number_of_subbands = 32; + else + { + channel_bitrate = h_bitrate_index; + // calculate bitrate per channel: + if (h_mode != SINGLE_CHANNEL) + if (channel_bitrate == 4) + channel_bitrate = 1; + else + channel_bitrate -= 4; + if ((channel_bitrate == 1) || (channel_bitrate == 2)) + if (h_sample_frequency == THIRTYTWO) + h_number_of_subbands = 12; + else + h_number_of_subbands = 8; + else if ((h_sample_frequency == FOURTYEIGHT) || ((channel_bitrate >= 3) && (channel_bitrate <= 5))) + h_number_of_subbands = 27; + else + h_number_of_subbands = 30; + } + if (h_intensity_stereo_bound > h_number_of_subbands) + h_intensity_stereo_bound = h_number_of_subbands; + // calculate framesize and nSlots + calculate_framesize(); + // read framedata: + int framesizeloaded = stream.read_frame_data(framesize); + if ((framesize >=0) && (framesizeloaded != framesize)) + { + // Data loaded does not match to expected framesize, + // it might be an ID3v1 TAG. (Fix 11/17/04). + throw stream.newBitstreamException(Bitstream.INVALIDFRAME); + } + if (stream.isSyncCurrentPosition(syncmode)) + { + if (syncmode == Bitstream.INITIAL_SYNC) + { + syncmode = Bitstream.STRICT_SYNC; + stream.set_syncword(headerstring & 0xFFF80CC0); + } + sync = true; + } + else + { + stream.unreadFrame(); + } + } + while (!sync); + stream.parse_frame(); + if (h_protection_bit == 0) + { + // frame contains a crc checksum + checksum = (short) stream.get_bits(16); + if (crc == null) + crc = new Crc16(); + crc.add_bits(headerstring, 16); + crcp[0] = crc; + } + else + crcp[0] = null; + if (h_sample_frequency == FOURTYFOUR_POINT_ONE) + { + /* + if (offset == null) + { + int max = max_number_of_frames(stream); + offset = new int[max]; + for(int i=0; i 0) && (cf == lf)) + { + offset[cf] = offset[cf-1] + h_padding_bit; + } + else + { + offset[0] = h_padding_bit; + } + */ + } + } + + /** + * Parse frame to extract optional VBR frame. + * + * @param firstframe + * @author E.B (javalayer@javazoom.net) + */ + void parseVBR(byte[] firstframe) throws BitstreamException + { + // Trying Xing header. + String xing = "Xing"; + byte tmp[] = new byte[4]; + int offset = 0; + // Compute "Xing" offset depending on MPEG version and channels. + if (h_version == MPEG1) + { + if (h_mode == SINGLE_CHANNEL) offset=21-4; + else offset=36-4; + } + else + { + if (h_mode == SINGLE_CHANNEL) offset=13-4; + else offset = 21-4; + } + try + { + System.arraycopy(firstframe, offset, tmp, 0, 4); + // Is "Xing" ? + if (xing.equals(new String(tmp))) + { + //Yes. + h_vbr = true; + h_vbr_frames = -1; + h_vbr_bytes = -1; + h_vbr_scale = -1; + h_vbr_toc = new byte[100]; + + int length = 4; + // Read flags. + byte flags[] = new byte[4]; + System.arraycopy(firstframe, offset + length, flags, 0, flags.length); + length += flags.length; + // Read number of frames (if available). + if ((flags[3] & (byte) (1 << 0)) != 0) + { + System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length); + h_vbr_frames = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF; + length += 4; + } + // Read size (if available). + if ((flags[3] & (byte) (1 << 1)) != 0) + { + System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length); + h_vbr_bytes = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF; + length += 4; + } + // Read TOC (if available). + if ((flags[3] & (byte) (1 << 2)) != 0) + { + System.arraycopy(firstframe, offset + length, h_vbr_toc, 0, h_vbr_toc.length); + length += h_vbr_toc.length; + } + // Read scale (if available). + if ((flags[3] & (byte) (1 << 3)) != 0) + { + System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length); + h_vbr_scale = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF; + length += 4; + } + //System.out.println("VBR:"+xing+" Frames:"+ h_vbr_frames +" Size:"+h_vbr_bytes); + } + } + catch (ArrayIndexOutOfBoundsException e) + { + throw new BitstreamException("XingVBRHeader Corrupted",e); + } + + // Trying VBRI header. + String vbri = "VBRI"; + offset = 36-4; + try + { + System.arraycopy(firstframe, offset, tmp, 0, 4); + // Is "VBRI" ? + if (vbri.equals(new String(tmp))) + { + //Yes. + h_vbr = true; + h_vbr_frames = -1; + h_vbr_bytes = -1; + h_vbr_scale = -1; + h_vbr_toc = new byte[100]; + // Bytes. + int length = 4 + 6; + System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length); + h_vbr_bytes = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF; + length += 4; + // Frames. + System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length); + h_vbr_frames = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF; + length += 4; + //System.out.println("VBR:"+vbri+" Frames:"+ h_vbr_frames +" Size:"+h_vbr_bytes); + // TOC + // TODO + } + } + catch (ArrayIndexOutOfBoundsException e) + { + throw new BitstreamException("VBRIVBRHeader Corrupted",e); + } + } + + // Functions to query header contents: + /** + * Returns version. + */ + public int version() { return h_version; } + + /** + * Returns Layer ID. + */ + public int layer() { return h_layer; } + + /** + * Returns bitrate index. + */ + public int bitrate_index() { return h_bitrate_index; } + + /** + * Returns Sample Frequency. + */ + public int sample_frequency() { return h_sample_frequency; } + + /** + * Returns Frequency. + */ + public int frequency() {return frequencies[h_version][h_sample_frequency];} + + /** + * Returns Mode. + */ + public int mode() { return h_mode; } + + /** + * Returns Protection bit. + */ + public boolean checksums() + { + if (h_protection_bit == 0) return true; + else return false; + } + + /** + * Returns Copyright. + */ + public boolean copyright() { return h_copyright; } + + /** + * Returns Original. + */ + public boolean original() { return h_original; } + + /** + * Return VBR. + * + * @return true if VBR header is found + */ + public boolean vbr() { return h_vbr; } + + /** + * Return VBR scale. + * + * @return scale of -1 if not available + */ + public int vbr_scale() { return h_vbr_scale; } + + /** + * Return VBR TOC. + * + * @return vbr toc ot null if not available + */ + public byte[] vbr_toc() { return h_vbr_toc; } + + /** + * Returns Checksum flag. + * Compares computed checksum with stream checksum. + */ + public boolean checksum_ok () { return (checksum == crc.checksum()); } + + // Seeking and layer III stuff + /** + * Returns Layer III Padding bit. + */ + public boolean padding() + { + if (h_padding_bit == 0) return false; + else return true; + } + + /** + * Returns Slots. + */ + public int slots() { return nSlots; } + + /** + * Returns Mode Extension. + */ + public int mode_extension() { return h_mode_extension; } + + // E.B -> private to public + public static final int bitrates[][][] = { + {{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000, + 112000, 128000, 144000, 160000, 176000, 192000 ,224000, 256000, 0}, + {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, + 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}, + {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, + 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}}, + + {{0 /*free format*/, 32000, 64000, 96000, 128000, 160000, 192000, + 224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000, 0}, + {0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000, + 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 0}, + {0 /*free format*/, 32000, 40000, 48000, 56000, 64000, 80000, + 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 0}}, + // SZD: MPEG2.5 + {{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000, + 112000, 128000, 144000, 160000, 176000, 192000 ,224000, 256000, 0}, + {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, + 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}, + {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, + 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}}, + + }; + + // E.B -> private to public + /** + * Calculate Frame size. + * + * Calculates framesize in bytes excluding header size. + */ + public int calculate_framesize() + { + + if (h_layer == 1) + { + framesize = (12 * bitrates[h_version][0][h_bitrate_index]) / + frequencies[h_version][h_sample_frequency]; + if (h_padding_bit != 0 ) framesize++; + framesize <<= 2; // one slot is 4 bytes long + nSlots = 0; + } + else + { + framesize = (144 * bitrates[h_version][h_layer - 1][h_bitrate_index]) / + frequencies[h_version][h_sample_frequency]; + if (h_version == MPEG2_LSF || h_version == MPEG25_LSF) framesize >>= 1; // SZD + if (h_padding_bit != 0) framesize++; + // Layer III slots + if (h_layer == 3) + { + if (h_version == MPEG1) + { + nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 17 : 32) // side info size + - ((h_protection_bit!=0) ? 0 : 2) // CRC size + - 4; // header size + } + else + { // MPEG-2 LSF, SZD: MPEG-2.5 LSF + nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 9 : 17) // side info size + - ((h_protection_bit!=0) ? 0 : 2) // CRC size + - 4; // header size + } + } + else + { + nSlots = 0; + } + } + framesize -= 4; // subtract header size + return framesize; + } + + /** + * Returns the maximum number of frames in the stream. + * + * @param streamsize + * @return number of frames + */ + public int max_number_of_frames(int streamsize) // E.B + { + if (h_vbr == true) return h_vbr_frames; + else + { + if ((framesize + 4 - h_padding_bit) == 0) return 0; + else return(streamsize / (framesize + 4 - h_padding_bit)); + } + } + + /** + * Returns the maximum number of frames in the stream. + * + * @param streamsize + * @return number of frames + */ + public int min_number_of_frames(int streamsize) // E.B + { + if (h_vbr == true) return h_vbr_frames; + else + { + if ((framesize + 5 - h_padding_bit) == 0) return 0; + else return(streamsize / (framesize + 5 - h_padding_bit)); + } + } + + + /** + * Returns ms/frame. + * + * @return milliseconds per frame + */ + public float ms_per_frame() // E.B + { + if (h_vbr == true) + { + double tpf = h_vbr_time_per_frame[layer()] / frequency(); + if ((h_version == MPEG2_LSF) || (h_version == MPEG25_LSF)) tpf /= 2; + return ((float) (tpf * 1000)); + } + else + { + float ms_per_frame_array[][] = {{8.707483f, 8.0f, 12.0f}, + {26.12245f, 24.0f, 36.0f}, + {26.12245f, 24.0f, 36.0f}}; + return(ms_per_frame_array[h_layer-1][h_sample_frequency]); + } + } + + /** + * Returns total ms. + * + * @param streamsize + * @return total milliseconds + */ + public float total_ms(int streamsize) // E.B + { + return(max_number_of_frames(streamsize) * ms_per_frame()); + } + + /** + * Returns synchronized header. + */ + public int getSyncHeader() // E.B + { + return _headerstring; + } + + // functions which return header informations as strings: + /** + * Return Layer version. + */ + public String layer_string() + { + switch (h_layer) + { + case 1: + return "I"; + case 2: + return "II"; + case 3: + return "III"; + } + return null; + } + + // E.B -> private to public + public static final String bitrate_str[][][] = { + {{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", + "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", + "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", + "forbidden"}, + {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", + "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", + "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", + "forbidden"}, + {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", + "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", + "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", + "forbidden"}}, + + {{"free format", "32 kbit/s", "64 kbit/s", "96 kbit/s", "128 kbit/s", + "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s", + "320 kbit/s", "352 kbit/s", "384 kbit/s", "416 kbit/s", "448 kbit/s", + "forbidden"}, + {"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", + "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", + "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s", "384 kbit/s", + "forbidden"}, + {"free format", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s", + "64 kbit/s", "80 kbit/s" , "96 kbit/s", "112 kbit/s", "128 kbit/s", + "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s", + "forbidden"}}, + // SZD: MPEG2.5 + {{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", + "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", + "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", + "forbidden"}, + {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", + "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", + "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", + "forbidden"}, + {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", + "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", + "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", + "forbidden"}}, + }; + + /** + * Return Bitrate. + * + * @return bitrate in bps + */ + public String bitrate_string() + { + if (h_vbr == true) + { + return Integer.toString(bitrate()/1000)+" kb/s"; + } + else return bitrate_str[h_version][h_layer - 1][h_bitrate_index]; + } + + /** + * Return Bitrate. + * + * @return bitrate in bps and average bitrate for VBR header + */ + public int bitrate() + { + if (h_vbr == true) + { + return ((int) ((h_vbr_bytes * 8) / (ms_per_frame() * h_vbr_frames)))*1000; + } + else return bitrates[h_version][h_layer - 1][h_bitrate_index]; + } + + /** + * Return Instant Bitrate. + * Bitrate for VBR is not constant. + * + * @return bitrate in bps + */ + public int bitrate_instant() + { + return bitrates[h_version][h_layer - 1][h_bitrate_index]; + } + + /** + * Returns Frequency + * + * @return frequency string in kHz + */ + public String sample_frequency_string() + { + switch (h_sample_frequency) + { + case THIRTYTWO: + if (h_version == MPEG1) + return "32 kHz"; + else if (h_version == MPEG2_LSF) + return "16 kHz"; + else // SZD + return "8 kHz"; + case FOURTYFOUR_POINT_ONE: + if (h_version == MPEG1) + return "44.1 kHz"; + else if (h_version == MPEG2_LSF) + return "22.05 kHz"; + else // SZD + return "11.025 kHz"; + case FOURTYEIGHT: + if (h_version == MPEG1) + return "48 kHz"; + else if (h_version == MPEG2_LSF) + return "24 kHz"; + else // SZD + return "12 kHz"; + } + return(null); + } + + /** + * Returns Mode. + */ + public String mode_string() + { + switch (h_mode) + { + case STEREO: + return "Stereo"; + case JOINT_STEREO: + return "Joint stereo"; + case DUAL_CHANNEL: + return "Dual channel"; + case SINGLE_CHANNEL: + return "Single channel"; + } + return null; + } + + /** + * Returns Version. + * + * @return MPEG-1 or MPEG-2 LSF or MPEG-2.5 LSF + */ + public String version_string() + { + switch (h_version) + { + case MPEG1: + return "MPEG-1"; + case MPEG2_LSF: + return "MPEG-2 LSF"; + case MPEG25_LSF: // SZD + return "MPEG-2.5 LSF"; + } + return(null); + } + + /** + * Returns the number of subbands in the current frame. + * + * @return number of subbands + */ + public int number_of_subbands() {return h_number_of_subbands;} + + /** + * Returns Intensity Stereo. + * (Layer II joint stereo only). + * Returns the number of subbands which are in stereo mode, + * subbands above that limit are in intensity stereo mode. + * + * @return intensity + */ + public int intensity_stereo_bound() {return h_intensity_stereo_bound;} +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/InputStreamSource.java b/src/lwjgl/java/javazoom/jl/decoder/InputStreamSource.java new file mode 100644 index 0000000..5c62947 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/InputStreamSource.java @@ -0,0 +1,80 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Work In Progress. + * + * An instance of InputStreamSource implements a + * Source that provides data from an InputStream + * . Seeking functionality is not supported. + * + * @author MDM + */ +public class InputStreamSource implements Source +{ + private final InputStream in; + + public InputStreamSource(InputStream in) + { + if (in==null) + throw new NullPointerException("in"); + + this.in = in; + } + + public int read(byte[] b, int offs, int len) + throws IOException + { + int read = in.read(b, offs, len); + return read; + } + + public boolean willReadBlock() + { + return true; + //boolean block = (in.available()==0); + //return block; + } + + public boolean isSeekable() + { + return false; + } + + public long tell() + { + return -1; + } + + public long seek(long to) + { + return -1; + } + + public long length() + { + return -1; + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/JavaLayerError.java b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerError.java new file mode 100644 index 0000000..d9910bc --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerError.java @@ -0,0 +1,31 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Work in progress. + * + * API usage errors may be handled by throwing an instance of this + * class, as per JMF 2.0. + */ +public class JavaLayerError extends Error +{ +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/JavaLayerErrors.java b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerErrors.java new file mode 100644 index 0000000..9050610 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerErrors.java @@ -0,0 +1,40 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Exception error codes for components of the JavaLayer API. + */ +public interface JavaLayerErrors +{ + /** + * The first bitstream error code. See the {@link DecoderErrors DecoderErrors} + * interface for other bitstream error codes. + */ + public static final int BITSTREAM_ERROR = 0x100; + + /** + * The first decoder error code. See the {@link DecoderErrors DecoderErrors} + * interface for other decoder error codes. + */ + public static final int DECODER_ERROR = 0x200; + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/JavaLayerException.java b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerException.java new file mode 100644 index 0000000..e432a68 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerException.java @@ -0,0 +1,78 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.PrintStream; + + +/** + * The JavaLayerException is the base class for all API-level + * exceptions thrown by JavaLayer. To facilitate conversion and + * common handling of exceptions from other domains, the class + * can delegate some functionality to a contained Throwable instance. + *

+ * + * @author MDM + */ +public class JavaLayerException extends Exception +{ + + private Throwable exception; + + + public JavaLayerException() + { + } + + public JavaLayerException(String msg) + { + super(msg); + } + + public JavaLayerException(String msg, Throwable t) + { + super(msg); + exception = t; + } + + public Throwable getException() + { + return exception; + } + + + public void printStackTrace() + { + printStackTrace(System.err); + } + + public void printStackTrace(PrintStream ps) + { + if (this.exception==null) + { + super.printStackTrace(ps); + } + else + { + exception.printStackTrace(); + } + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/JavaLayerHook.java b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerHook.java new file mode 100644 index 0000000..3520594 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerHook.java @@ -0,0 +1,36 @@ +/* + * 11/19/04 1.0 moved to LGPL. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.InputStream; + +/** + * The JavaLayerHooks class allows developers to change + * the way the JavaLayer library uses Resources. + */ + +public interface JavaLayerHook +{ + /** + * Retrieves the named resource. This allows resources to be + * obtained without specifying how they are retrieved. + */ + public InputStream getResourceAsStream(String name); +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/JavaLayerUtils.java b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerUtils.java new file mode 100644 index 0000000..5cfbd16 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerUtils.java @@ -0,0 +1,208 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.lang.reflect.Array; + +/** + * The JavaLayerUtils class is not strictly part of the JavaLayer API. + * It serves to provide useful methods and system-wide hooks. + * + * @author MDM + */ +public class JavaLayerUtils +{ + private static JavaLayerHook hook = null; + + /** + * Deserializes the object contained in the given input stream. + * + * @param in The input stream to deserialize an object from. + * @param cls The expected class of the deserialized object. + */ + public static Object deserialize(InputStream in, Class cls) + throws IOException + { + if (cls==null) + throw new NullPointerException("cls"); + + Object obj = deserialize(in, cls); + if (!cls.isInstance(obj)) + { + throw new InvalidObjectException("type of deserialized instance not of required class."); + } + + return obj; + } + + /** + * Deserializes an object from the given InputStream. + * The deserialization is delegated to an + * ObjectInputStream instance. + * + * @param in The InputStream to deserialize an object + * from. + * + * @return The object deserialized from the stream. + * @exception IOException is thrown if there was a problem reading + * the underlying stream, or an object could not be deserialized + * from the stream. + * + * @see java.io.ObjectInputStream + */ + public static Object deserialize(InputStream in) + throws IOException + { + if (in==null) + throw new NullPointerException("in"); + + ObjectInputStream objIn = new ObjectInputStream(in); + + Object obj; + + try + { + obj = objIn.readObject(); + } + catch (ClassNotFoundException ex) + { + throw new InvalidClassException(ex.toString()); + } + + return obj; + } + + /** + * Deserializes an array from a given InputStream. + * + * @param in The InputStream to + * deserialize an object from. + * + * @param elemType The class denoting the type of the array + * elements. + * @param length The expected length of the array, or -1 if + * any length is expected. + */ + public static Object deserializeArray(InputStream in, Class elemType, int length) + throws IOException + { + if (elemType==null) + throw new NullPointerException("elemType"); + + if (length<-1) + throw new IllegalArgumentException("length"); + + Object obj = deserialize(in); + + Class cls = obj.getClass(); + + + if (!cls.isArray()) + throw new InvalidObjectException("object is not an array"); + + Class arrayElemType = cls.getComponentType(); + if (arrayElemType!=elemType) + throw new InvalidObjectException("unexpected array component type"); + + if (length != -1) + { + int arrayLength = Array.getLength(obj); + if (arrayLength!=length) + throw new InvalidObjectException("array length mismatch"); + } + + return obj; + } + + public static Object deserializeArrayResource(String name, Class elemType, int length) + throws IOException + { + InputStream str = getResourceAsStream(name); + if (str==null) + throw new IOException("unable to load resource '"+name+"'"); + + Object obj = deserializeArray(str, elemType, length); + + return obj; + } + + public static void serialize(OutputStream out, Object obj) + throws IOException + { + if (out==null) + throw new NullPointerException("out"); + + if (obj==null) + throw new NullPointerException("obj"); + + ObjectOutputStream objOut = new ObjectOutputStream(out); + objOut.writeObject(obj); + + } + + /** + * Sets the system-wide JavaLayer hook. + */ + public static synchronized void setHook(JavaLayerHook hook0) + { + hook = hook0; + } + + public static synchronized JavaLayerHook getHook() + { + return hook; + } + + /** + * Retrieves an InputStream for a named resource. + * + * @param name The name of the resource. This must be a simple + * name, and not a qualified package name. + * + * @return The InputStream for the named resource, or null if + * the resource has not been found. If a hook has been + * provided, its getResourceAsStream() method is called + * to retrieve the resource. + */ + public static synchronized InputStream getResourceAsStream(String name) + { + InputStream is = null; + + if (hook!=null) + { + is = hook.getResourceAsStream(name); + } + else + { + Class cls = JavaLayerUtils.class; + is = cls.getResourceAsStream(name); + } + + return is; + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/LayerIDecoder.java b/src/lwjgl/java/javazoom/jl/decoder/LayerIDecoder.java new file mode 100644 index 0000000..5e3232c --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/LayerIDecoder.java @@ -0,0 +1,448 @@ +/* + * 09/26/08 throw exception on subbband alloc error: Christopher G. Jennings (cjennings@acm.org) + * + * 11/19/04 1.0 moved to LGPL. + * + * 12/12/99 Initial version. Adapted from javalayer.java + * and Subband*.java. mdm@techie.com + * + * 02/28/99 Initial version : javalayer.java by E.B + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Implements decoding of MPEG Audio Layer I frames. + */ +class LayerIDecoder implements FrameDecoder +{ + protected Bitstream stream; + protected Header header; + protected SynthesisFilter filter1, filter2; + protected Obuffer buffer; + protected int which_channels; + protected int mode; + + protected int num_subbands; + protected Subband[] subbands; + protected Crc16 crc = null; // new Crc16[1] to enable CRC checking. + + public LayerIDecoder() + { + crc = new Crc16(); + } + + public void create(Bitstream stream0, Header header0, + SynthesisFilter filtera, SynthesisFilter filterb, + Obuffer buffer0, int which_ch0) + { + stream = stream0; + header = header0; + filter1 = filtera; + filter2 = filterb; + buffer = buffer0; + which_channels = which_ch0; + + } + + public void decodeFrame() throws DecoderException + { + + num_subbands = header.number_of_subbands(); + subbands = new Subband[32]; + mode = header.mode(); + + createSubbands(); + + readAllocation(); + readScaleFactorSelection(); + + if ((crc != null) || header.checksum_ok()) + { + readScaleFactors(); + + readSampleData(); + } + + } + + protected void createSubbands() + { + int i; + if (mode == Header.SINGLE_CHANNEL) + for (i = 0; i < num_subbands; ++i) + subbands[i] = new SubbandLayer1(i); + else if (mode == Header.JOINT_STEREO) + { + for (i = 0; i < header.intensity_stereo_bound(); ++i) + subbands[i] = new SubbandLayer1Stereo(i); + for (; i < num_subbands; ++i) + subbands[i] = new SubbandLayer1IntensityStereo(i); + } + else + { + for (i = 0; i < num_subbands; ++i) + subbands[i] = new SubbandLayer1Stereo(i); + } + } + + protected void readAllocation() throws DecoderException + { + // start to read audio data: + for (int i = 0; i < num_subbands; ++i) + subbands[i].read_allocation(stream, header, crc); + + } + + protected void readScaleFactorSelection() + { + // scale factor selection not present for layer I. + } + + protected void readScaleFactors() + { + for (int i = 0; i < num_subbands; ++i) + subbands[i].read_scalefactor(stream, header); + } + + protected void readSampleData() + { + boolean read_ready = false; + boolean write_ready = false; + int mode = header.mode(); + int i; + do + { + for (i = 0; i < num_subbands; ++i) + read_ready = subbands[i].read_sampledata(stream); + do + { + for (i = 0; i < num_subbands; ++i) + write_ready = subbands[i].put_next_sample(which_channels,filter1, filter2); + + filter1.calculate_pcm_samples(buffer); + if ((which_channels == OutputChannels.BOTH_CHANNELS) && (mode != Header.SINGLE_CHANNEL)) + filter2.calculate_pcm_samples(buffer); + } while (!write_ready); + } while (!read_ready); + + } + + /** + * Abstract base class for subband classes of layer I and II + */ + abstract static class Subband + { + /* + * Changes from version 1.1 to 1.2: + * - array size increased by one, although a scalefactor with index 63 + * is illegal (to prevent segmentation faults) + */ + // Scalefactors for layer I and II, Annex 3-B.1 in ISO/IEC DIS 11172: + public static final float scalefactors[] = + { + 2.00000000000000f, 1.58740105196820f, 1.25992104989487f, 1.00000000000000f, + 0.79370052598410f, 0.62996052494744f, 0.50000000000000f, 0.39685026299205f, + 0.31498026247372f, 0.25000000000000f, 0.19842513149602f, 0.15749013123686f, + 0.12500000000000f, 0.09921256574801f, 0.07874506561843f, 0.06250000000000f, + 0.04960628287401f, 0.03937253280921f, 0.03125000000000f, 0.02480314143700f, + 0.01968626640461f, 0.01562500000000f, 0.01240157071850f, 0.00984313320230f, + 0.00781250000000f, 0.00620078535925f, 0.00492156660115f, 0.00390625000000f, + 0.00310039267963f, 0.00246078330058f, 0.00195312500000f, 0.00155019633981f, + 0.00123039165029f, 0.00097656250000f, 0.00077509816991f, 0.00061519582514f, + 0.00048828125000f, 0.00038754908495f, 0.00030759791257f, 0.00024414062500f, + 0.00019377454248f, 0.00015379895629f, 0.00012207031250f, 0.00009688727124f, + 0.00007689947814f, 0.00006103515625f, 0.00004844363562f, 0.00003844973907f, + 0.00003051757813f, 0.00002422181781f, 0.00001922486954f, 0.00001525878906f, + 0.00001211090890f, 0.00000961243477f, 0.00000762939453f, 0.00000605545445f, + 0.00000480621738f, 0.00000381469727f, 0.00000302772723f, 0.00000240310869f, + 0.00000190734863f, 0.00000151386361f, 0.00000120155435f, 0.00000000000000f /* illegal scalefactor */ + }; + + public abstract void read_allocation (Bitstream stream, Header header, Crc16 crc) throws DecoderException; + public abstract void read_scalefactor (Bitstream stream, Header header); + public abstract boolean read_sampledata (Bitstream stream); + public abstract boolean put_next_sample (int channels, SynthesisFilter filter1, SynthesisFilter filter2); + }; + + /** + * Class for layer I subbands in single channel mode. + * Used for single channel mode + * and in derived class for intensity stereo mode + */ + static class SubbandLayer1 extends Subband + { + + // Factors and offsets for sample re-quantization + public static final float table_factor[] = { + 0.0f, (1.0f/2.0f) * (4.0f/3.0f), (1.0f/4.0f) * (8.0f/7.0f), (1.0f/8.0f) * (16.0f/15.0f), + (1.0f/16.0f) * (32.0f/31.0f), (1.0f/32.0f) * (64.0f/63.0f), (1.0f/64.0f) * (128.0f/127.0f), + (1.0f/128.0f) * (256.0f/255.0f), (1.0f/256.0f) * (512.0f/511.0f), + (1.0f/512.0f) * (1024.0f/1023.0f), (1.0f/1024.0f) * (2048.0f/2047.0f), + (1.0f/2048.0f) * (4096.0f/4095.0f), (1.0f/4096.0f) * (8192.0f/8191.0f), + (1.0f/8192.0f) * (16384.0f/16383.0f), (1.0f/16384.0f) * (32768.0f/32767.0f) + }; + + public static final float table_offset[] = { + 0.0f, ((1.0f/2.0f)-1.0f) * (4.0f/3.0f), ((1.0f/4.0f)-1.0f) * (8.0f/7.0f), ((1.0f/8.0f)-1.0f) * (16.0f/15.0f), + ((1.0f/16.0f)-1.0f) * (32.0f/31.0f), ((1.0f/32.0f)-1.0f) * (64.0f/63.0f), ((1.0f/64.0f)-1.0f) * (128.0f/127.0f), + ((1.0f/128.0f)-1.0f) * (256.0f/255.0f), ((1.0f/256.0f)-1.0f) * (512.0f/511.0f), + ((1.0f/512.0f)-1.0f) * (1024.0f/1023.0f), ((1.0f/1024.0f)-1.0f) * (2048.0f/2047.0f), + ((1.0f/2048.0f)-1.0f) * (4096.0f/4095.0f), ((1.0f/4096.0f)-1.0f) * (8192.0f/8191.0f), + ((1.0f/8192.0f)-1.0f) * (16384.0f/16383.0f), ((1.0f/16384.0f)-1.0f) * (32768.0f/32767.0f) + }; + + protected int subbandnumber; + protected int samplenumber; + protected int allocation; + protected float scalefactor; + protected int samplelength; + protected float sample; + protected float factor, offset; + + /** + * Constructor. + */ + public SubbandLayer1(int subbandnumber) + { + this.subbandnumber = subbandnumber; + samplenumber = 0; + } + + /** + * + */ + public void read_allocation(Bitstream stream, Header header, Crc16 crc) throws DecoderException + { + if ((allocation = stream.get_bits (4)) == 15) + { + // CGJ: catch this condition and throw appropriate exception + throw new DecoderException(DecoderErrors.ILLEGAL_SUBBAND_ALLOCATION, null); + // cerr << "WARNING: stream contains an illegal allocation!\n"; + // MPEG-stream is corrupted! + } + + if (crc != null) crc.add_bits (allocation, 4); + if (allocation != 0) + { + samplelength = allocation + 1; + factor = table_factor[allocation]; + offset = table_offset[allocation]; + } + } + + /** + * + */ + public void read_scalefactor(Bitstream stream, Header header) + { + if (allocation != 0) scalefactor = scalefactors[stream.get_bits(6)]; + } + + /** + * + */ + public boolean read_sampledata(Bitstream stream) + { + if (allocation != 0) + { + sample = (float) (stream.get_bits(samplelength)); + } + if (++samplenumber == 12) + { + samplenumber = 0; + return true; + } + return false; + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) + { + if ((allocation !=0) && (channels != OutputChannels.RIGHT_CHANNEL)) + { + float scaled_sample = (sample * factor + offset) * scalefactor; + filter1.input_sample (scaled_sample, subbandnumber); + } + return true; + } + }; + + /** + * Class for layer I subbands in joint stereo mode. + */ + static class SubbandLayer1IntensityStereo extends SubbandLayer1 + { + protected float channel2_scalefactor; + + /** + * Constructor + */ + public SubbandLayer1IntensityStereo(int subbandnumber) + { + super(subbandnumber); + } + + /** + * + */ + public void read_allocation(Bitstream stream, Header header, Crc16 crc) throws DecoderException + { + super.read_allocation (stream, header, crc); + } + + /** + * + */ + public void read_scalefactor (Bitstream stream, Header header) + { + if (allocation != 0) + { + scalefactor = scalefactors[stream.get_bits(6)]; + channel2_scalefactor = scalefactors[stream.get_bits(6)]; + } + } + + /** + * + */ + public boolean read_sampledata(Bitstream stream) + { + return super.read_sampledata (stream); + } + + /** + * + */ + public boolean put_next_sample (int channels, SynthesisFilter filter1, SynthesisFilter filter2) + { + if (allocation !=0 ) + { + sample = sample * factor + offset; // re-quantization + if (channels == OutputChannels.BOTH_CHANNELS) + { + float sample1 = sample * scalefactor, + sample2 = sample * channel2_scalefactor; + filter1.input_sample(sample1, subbandnumber); + filter2.input_sample(sample2, subbandnumber); + } + else if (channels == OutputChannels.LEFT_CHANNEL) + { + float sample1 = sample * scalefactor; + filter1.input_sample(sample1, subbandnumber); + } + else + { + float sample2 = sample * channel2_scalefactor; + filter1.input_sample(sample2, subbandnumber); + } + } + return true; + } + }; + + /** + * Class for layer I subbands in stereo mode. + */ + static class SubbandLayer1Stereo extends SubbandLayer1 + { + protected int channel2_allocation; + protected float channel2_scalefactor; + protected int channel2_samplelength; + protected float channel2_sample; + protected float channel2_factor, channel2_offset; + + + /** + * Constructor + */ + public SubbandLayer1Stereo(int subbandnumber) + { + super(subbandnumber); + } + + /** + * + */ + public void read_allocation (Bitstream stream, Header header, Crc16 crc) throws DecoderException + { + allocation = stream.get_bits(4); + channel2_allocation = stream.get_bits(4); + if (crc != null) + { + crc.add_bits (allocation, 4); + crc.add_bits (channel2_allocation, 4); + } + if (allocation != 0) + { + samplelength = allocation + 1; + factor = table_factor[allocation]; + offset = table_offset[allocation]; + } + if (channel2_allocation != 0) + { + channel2_samplelength = channel2_allocation + 1; + channel2_factor = table_factor[channel2_allocation]; + channel2_offset = table_offset[channel2_allocation]; + } + } + + /** + * + */ + public void read_scalefactor(Bitstream stream, Header header) + { + if (allocation != 0) scalefactor = scalefactors[stream.get_bits(6)]; + if (channel2_allocation != 0) channel2_scalefactor = scalefactors[stream.get_bits(6)]; + } + + /** + * + */ + public boolean read_sampledata (Bitstream stream) + { + boolean returnvalue = super.read_sampledata(stream); + if (channel2_allocation != 0) + { + channel2_sample = (float) (stream.get_bits(channel2_samplelength)); + } + return(returnvalue); + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) + { + super.put_next_sample (channels, filter1, filter2); + if ((channel2_allocation != 0) && (channels != OutputChannels.LEFT_CHANNEL)) + { + float sample2 = (channel2_sample * channel2_factor + channel2_offset) * + channel2_scalefactor; + if (channels == OutputChannels.BOTH_CHANNELS) + filter2.input_sample (sample2, subbandnumber); + else + filter1.input_sample (sample2, subbandnumber); + } + return true; + } + }; + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/LayerIIDecoder.java b/src/lwjgl/java/javazoom/jl/decoder/LayerIIDecoder.java new file mode 100644 index 0000000..7265b1f --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/LayerIIDecoder.java @@ -0,0 +1,1064 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 29/05/01 Michael Scheerer, Fixed some C++ to Java porting bugs. + * + * 16/07/01 Michael Scheerer, Catched a bug in method + * read_sampledata, which causes an outOfIndexException. + * + * 12/12/99 Initial version. Adapted from javalayer.java + * and Subband*.java. mdm@techie.com + * + * 02/28/99 Initial version : javalayer.java by E.B + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Implements decoding of MPEG Audio Layer II frames. + */ +class LayerIIDecoder extends LayerIDecoder implements FrameDecoder +{ + + public LayerIIDecoder() + { + } + + + protected void createSubbands() + { + int i; + if (mode == Header.SINGLE_CHANNEL) + for (i = 0; i < num_subbands; ++i) + subbands[i] = new SubbandLayer2(i); + else if (mode == Header.JOINT_STEREO) + { + for (i = 0; i < header.intensity_stereo_bound(); ++i) + subbands[i] = new SubbandLayer2Stereo(i); + for (; i < num_subbands; ++i) + subbands[i] = new SubbandLayer2IntensityStereo(i); + } + else + { + for (i = 0; i < num_subbands; ++i) + subbands[i] = new SubbandLayer2Stereo(i); + } + + } + + protected void readScaleFactorSelection() + { + for (int i = 0; i < num_subbands; ++i) + ((SubbandLayer2)subbands[i]).read_scalefactor_selection(stream, crc); + } + + + + /** + * Class for layer II subbands in single channel mode. + */ + static class SubbandLayer2 extends Subband + { + // this table contains 3 requantized samples for each legal codeword + // when grouped in 5 bits, i.e. 3 quantizationsteps per sample + public static final float grouping_5bits[] = new float[] + { + -2.0f/3.0f, -2.0f/3.0f, -2.0f/3.0f, + 0.0f, -2.0f/3.0f, -2.0f/3.0f, + 2.0f/3.0f, -2.0f/3.0f, -2.0f/3.0f, + -2.0f/3.0f, 0.0f, -2.0f/3.0f, + 0.0f, 0.0f, -2.0f/3.0f, + 2.0f/3.0f, 0.0f, -2.0f/3.0f, + -2.0f/3.0f, 2.0f/3.0f, -2.0f/3.0f, + 0.0f, 2.0f/3.0f, -2.0f/3.0f, + 2.0f/3.0f, 2.0f/3.0f, -2.0f/3.0f, + -2.0f/3.0f, -2.0f/3.0f, 0.0f, + 0.0f, -2.0f/3.0f, 0.0f, + 2.0f/3.0f, -2.0f/3.0f, 0.0f, + -2.0f/3.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 2.0f/3.0f, 0.0f, 0.0f, + -2.0f/3.0f, 2.0f/3.0f, 0.0f, + 0.0f, 2.0f/3.0f, 0.0f, + 2.0f/3.0f, 2.0f/3.0f, 0.0f, + -2.0f/3.0f, -2.0f/3.0f, 2.0f/3.0f, + 0.0f, -2.0f/3.0f, 2.0f/3.0f, + 2.0f/3.0f, -2.0f/3.0f, 2.0f/3.0f, + -2.0f/3.0f, 0.0f, 2.0f/3.0f, + 0.0f, 0.0f, 2.0f/3.0f, + 2.0f/3.0f, 0.0f, 2.0f/3.0f, + -2.0f/3.0f, 2.0f/3.0f, 2.0f/3.0f, + 0.0f, 2.0f/3.0f, 2.0f/3.0f, + 2.0f/3.0f, 2.0f/3.0f, 2.0f/3.0f + }; + + // this table contains 3 requantized samples for each legal codeword + // when grouped in 7 bits, i.e. 5 quantizationsteps per sample + public static final float grouping_7bits[] = new float[] + { + -0.8f, -0.8f, -0.8f, -0.4f, -0.8f, -0.8f, 0.0f, -0.8f, -0.8f, 0.4f, -0.8f, -0.8f, 0.8f, -0.8f, -0.8f, + -0.8f, -0.4f, -0.8f, -0.4f, -0.4f, -0.8f, 0.0f, -0.4f, -0.8f, 0.4f, -0.4f, -0.8f, 0.8f, -0.4f, -0.8f, + -0.8f, 0.0f, -0.8f, -0.4f, 0.0f, -0.8f, 0.0f, 0.0f, -0.8f, 0.4f, 0.0f, -0.8f, 0.8f, 0.0f, -0.8f, + -0.8f, 0.4f, -0.8f, -0.4f, 0.4f, -0.8f, 0.0f, 0.4f, -0.8f, 0.4f, 0.4f, -0.8f, 0.8f, 0.4f, -0.8f, + -0.8f, 0.8f, -0.8f, -0.4f, 0.8f, -0.8f, 0.0f, 0.8f, -0.8f, 0.4f, 0.8f, -0.8f, 0.8f, 0.8f, -0.8f, + -0.8f, -0.8f, -0.4f, -0.4f, -0.8f, -0.4f, 0.0f, -0.8f, -0.4f, 0.4f, -0.8f, -0.4f, 0.8f, -0.8f, -0.4f, + -0.8f, -0.4f, -0.4f, -0.4f, -0.4f, -0.4f, 0.0f, -0.4f, -0.4f, 0.4f, -0.4f, -0.4f, 0.8f, -0.4f, -0.4f, + -0.8f, 0.0f, -0.4f, -0.4f, 0.0f, -0.4f, 0.0f, 0.0f, -0.4f, 0.4f, 0.0f, -0.4f, 0.8f, 0.0f, -0.4f, + -0.8f, 0.4f, -0.4f, -0.4f, 0.4f, -0.4f, 0.0f, 0.4f, -0.4f, 0.4f, 0.4f, -0.4f, 0.8f, 0.4f, -0.4f, + -0.8f, 0.8f, -0.4f, -0.4f, 0.8f, -0.4f, 0.0f, 0.8f, -0.4f, 0.4f, 0.8f, -0.4f, 0.8f, 0.8f, -0.4f, + -0.8f, -0.8f, 0.0f, -0.4f, -0.8f, 0.0f, 0.0f, -0.8f, 0.0f, 0.4f, -0.8f, 0.0f, 0.8f, -0.8f, 0.0f, + -0.8f, -0.4f, 0.0f, -0.4f, -0.4f, 0.0f, 0.0f, -0.4f, 0.0f, 0.4f, -0.4f, 0.0f, 0.8f, -0.4f, 0.0f, + -0.8f, 0.0f, 0.0f, -0.4f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.4f, 0.0f, 0.0f, 0.8f, 0.0f, 0.0f, + -0.8f, 0.4f, 0.0f, -0.4f, 0.4f, 0.0f, 0.0f, 0.4f, 0.0f, 0.4f, 0.4f, 0.0f, 0.8f, 0.4f, 0.0f, + -0.8f, 0.8f, 0.0f, -0.4f, 0.8f, 0.0f, 0.0f, 0.8f, 0.0f, 0.4f, 0.8f, 0.0f, 0.8f, 0.8f, 0.0f, + -0.8f, -0.8f, 0.4f, -0.4f, -0.8f, 0.4f, 0.0f, -0.8f, 0.4f, 0.4f, -0.8f, 0.4f, 0.8f, -0.8f, 0.4f, + -0.8f, -0.4f, 0.4f, -0.4f, -0.4f, 0.4f, 0.0f, -0.4f, 0.4f, 0.4f, -0.4f, 0.4f, 0.8f, -0.4f, 0.4f, + -0.8f, 0.0f, 0.4f, -0.4f, 0.0f, 0.4f, 0.0f, 0.0f, 0.4f, 0.4f, 0.0f, 0.4f, 0.8f, 0.0f, 0.4f, + -0.8f, 0.4f, 0.4f, -0.4f, 0.4f, 0.4f, 0.0f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.8f, 0.4f, 0.4f, + -0.8f, 0.8f, 0.4f, -0.4f, 0.8f, 0.4f, 0.0f, 0.8f, 0.4f, 0.4f, 0.8f, 0.4f, 0.8f, 0.8f, 0.4f, + -0.8f, -0.8f, 0.8f, -0.4f, -0.8f, 0.8f, 0.0f, -0.8f, 0.8f, 0.4f, -0.8f, 0.8f, 0.8f, -0.8f, 0.8f, + -0.8f, -0.4f, 0.8f, -0.4f, -0.4f, 0.8f, 0.0f, -0.4f, 0.8f, 0.4f, -0.4f, 0.8f, 0.8f, -0.4f, 0.8f, + -0.8f, 0.0f, 0.8f, -0.4f, 0.0f, 0.8f, 0.0f, 0.0f, 0.8f, 0.4f, 0.0f, 0.8f, 0.8f, 0.0f, 0.8f, + -0.8f, 0.4f, 0.8f, -0.4f, 0.4f, 0.8f, 0.0f, 0.4f, 0.8f, 0.4f, 0.4f, 0.8f, 0.8f, 0.4f, 0.8f, + -0.8f, 0.8f, 0.8f, -0.4f, 0.8f, 0.8f, 0.0f, 0.8f, 0.8f, 0.4f, 0.8f, 0.8f, 0.8f, 0.8f, 0.8f + }; + + // this table contains 3 requantized samples for each legal codeword + // when grouped in 10 bits, i.e. 9 quantizationsteps per sample + public static final float grouping_10bits[] = + { + -8.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, 0.0f, -8.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 0.0f, -6.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 0.0f, -4.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, 0.0f, -2.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, 0.0f, -8.0f/9.0f, -6.0f/9.0f, 0.0f, -8.0f/9.0f, -4.0f/9.0f, 0.0f, -8.0f/9.0f, + -2.0f/9.0f, 0.0f, -8.0f/9.0f, 0.0f, 0.0f, -8.0f/9.0f, 2.0f/9.0f, 0.0f, -8.0f/9.0f, + 4.0f/9.0f, 0.0f, -8.0f/9.0f, 6.0f/9.0f, 0.0f, -8.0f/9.0f, 8.0f/9.0f, 0.0f, -8.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 0.0f, 2.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, 0.0f, 4.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 0.0f, 6.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 0.0f, 8.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 0.0f, -8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 0.0f, -6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 0.0f, -4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 0.0f, -2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, 0.0f, -6.0f/9.0f, -6.0f/9.0f, 0.0f, -6.0f/9.0f, -4.0f/9.0f, 0.0f, -6.0f/9.0f, + -2.0f/9.0f, 0.0f, -6.0f/9.0f, 0.0f, 0.0f, -6.0f/9.0f, 2.0f/9.0f, 0.0f, -6.0f/9.0f, + 4.0f/9.0f, 0.0f, -6.0f/9.0f, 6.0f/9.0f, 0.0f, -6.0f/9.0f, 8.0f/9.0f, 0.0f, -6.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 0.0f, 2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 0.0f, 4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 0.0f, 6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 0.0f, 8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 0.0f, -8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 0.0f, -6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 0.0f, -4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 0.0f, -2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, 0.0f, -4.0f/9.0f, -6.0f/9.0f, 0.0f, -4.0f/9.0f, -4.0f/9.0f, 0.0f, -4.0f/9.0f, + -2.0f/9.0f, 0.0f, -4.0f/9.0f, 0.0f, 0.0f, -4.0f/9.0f, 2.0f/9.0f, 0.0f, -4.0f/9.0f, + 4.0f/9.0f, 0.0f, -4.0f/9.0f, 6.0f/9.0f, 0.0f, -4.0f/9.0f, 8.0f/9.0f, 0.0f, -4.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 0.0f, 2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 0.0f, 4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 0.0f, 6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 0.0f, 8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, 0.0f, -8.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 0.0f, -6.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 0.0f, -4.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, 0.0f, -2.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, 0.0f, -2.0f/9.0f, -6.0f/9.0f, 0.0f, -2.0f/9.0f, -4.0f/9.0f, 0.0f, -2.0f/9.0f, + -2.0f/9.0f, 0.0f, -2.0f/9.0f, 0.0f, 0.0f, -2.0f/9.0f, 2.0f/9.0f, 0.0f, -2.0f/9.0f, + 4.0f/9.0f, 0.0f, -2.0f/9.0f, 6.0f/9.0f, 0.0f, -2.0f/9.0f, 8.0f/9.0f, 0.0f, -2.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 0.0f, 2.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, 0.0f, 4.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 0.0f, 6.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 0.0f, 8.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, -8.0f/9.0f, 0.0f, -6.0f/9.0f, -8.0f/9.0f, 0.0f, -4.0f/9.0f, -8.0f/9.0f, 0.0f, + -2.0f/9.0f, -8.0f/9.0f, 0.0f, 0.0f, -8.0f/9.0f, 0.0f, 2.0f/9.0f, -8.0f/9.0f, 0.0f, + 4.0f/9.0f, -8.0f/9.0f, 0.0f, 6.0f/9.0f, -8.0f/9.0f, 0.0f, 8.0f/9.0f, -8.0f/9.0f, 0.0f, + -8.0f/9.0f, -6.0f/9.0f, 0.0f, -6.0f/9.0f, -6.0f/9.0f, 0.0f, -4.0f/9.0f, -6.0f/9.0f, 0.0f, + -2.0f/9.0f, -6.0f/9.0f, 0.0f, 0.0f, -6.0f/9.0f, 0.0f, 2.0f/9.0f, -6.0f/9.0f, 0.0f, + 4.0f/9.0f, -6.0f/9.0f, 0.0f, 6.0f/9.0f, -6.0f/9.0f, 0.0f, 8.0f/9.0f, -6.0f/9.0f, 0.0f, + -8.0f/9.0f, -4.0f/9.0f, 0.0f, -6.0f/9.0f, -4.0f/9.0f, 0.0f, -4.0f/9.0f, -4.0f/9.0f, 0.0f, + -2.0f/9.0f, -4.0f/9.0f, 0.0f, 0.0f, -4.0f/9.0f, 0.0f, 2.0f/9.0f, -4.0f/9.0f, 0.0f, + 4.0f/9.0f, -4.0f/9.0f, 0.0f, 6.0f/9.0f, -4.0f/9.0f, 0.0f, 8.0f/9.0f, -4.0f/9.0f, 0.0f, + -8.0f/9.0f, -2.0f/9.0f, 0.0f, -6.0f/9.0f, -2.0f/9.0f, 0.0f, -4.0f/9.0f, -2.0f/9.0f, 0.0f, + -2.0f/9.0f, -2.0f/9.0f, 0.0f, 0.0f, -2.0f/9.0f, 0.0f, 2.0f/9.0f, -2.0f/9.0f, 0.0f, + 4.0f/9.0f, -2.0f/9.0f, 0.0f, 6.0f/9.0f, -2.0f/9.0f, 0.0f, 8.0f/9.0f, -2.0f/9.0f, 0.0f, + -8.0f/9.0f, 0.0f, 0.0f, -6.0f/9.0f, 0.0f, 0.0f, -4.0f/9.0f, 0.0f, 0.0f, + -2.0f/9.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f/9.0f, 0.0f, 0.0f, + 4.0f/9.0f, 0.0f, 0.0f, 6.0f/9.0f, 0.0f, 0.0f, 8.0f/9.0f, 0.0f, 0.0f, + -8.0f/9.0f, 2.0f/9.0f, 0.0f, -6.0f/9.0f, 2.0f/9.0f, 0.0f, -4.0f/9.0f, 2.0f/9.0f, 0.0f, + -2.0f/9.0f, 2.0f/9.0f, 0.0f, 0.0f, 2.0f/9.0f, 0.0f, 2.0f/9.0f, 2.0f/9.0f, 0.0f, + 4.0f/9.0f, 2.0f/9.0f, 0.0f, 6.0f/9.0f, 2.0f/9.0f, 0.0f, 8.0f/9.0f, 2.0f/9.0f, 0.0f, + -8.0f/9.0f, 4.0f/9.0f, 0.0f, -6.0f/9.0f, 4.0f/9.0f, 0.0f, -4.0f/9.0f, 4.0f/9.0f, 0.0f, + -2.0f/9.0f, 4.0f/9.0f, 0.0f, 0.0f, 4.0f/9.0f, 0.0f, 2.0f/9.0f, 4.0f/9.0f, 0.0f, + 4.0f/9.0f, 4.0f/9.0f, 0.0f, 6.0f/9.0f, 4.0f/9.0f, 0.0f, 8.0f/9.0f, 4.0f/9.0f, 0.0f, + -8.0f/9.0f, 6.0f/9.0f, 0.0f, -6.0f/9.0f, 6.0f/9.0f, 0.0f, -4.0f/9.0f, 6.0f/9.0f, 0.0f, + -2.0f/9.0f, 6.0f/9.0f, 0.0f, 0.0f, 6.0f/9.0f, 0.0f, 2.0f/9.0f, 6.0f/9.0f, 0.0f, + 4.0f/9.0f, 6.0f/9.0f, 0.0f, 6.0f/9.0f, 6.0f/9.0f, 0.0f, 8.0f/9.0f, 6.0f/9.0f, 0.0f, + -8.0f/9.0f, 8.0f/9.0f, 0.0f, -6.0f/9.0f, 8.0f/9.0f, 0.0f, -4.0f/9.0f, 8.0f/9.0f, 0.0f, + -2.0f/9.0f, 8.0f/9.0f, 0.0f, 0.0f, 8.0f/9.0f, 0.0f, 2.0f/9.0f, 8.0f/9.0f, 0.0f, + 4.0f/9.0f, 8.0f/9.0f, 0.0f, 6.0f/9.0f, 8.0f/9.0f, 0.0f, 8.0f/9.0f, 8.0f/9.0f, 0.0f, + -8.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 0.0f, -8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 0.0f, -6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 0.0f, -4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 0.0f, -2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, 0.0f, 2.0f/9.0f, -6.0f/9.0f, 0.0f, 2.0f/9.0f, -4.0f/9.0f, 0.0f, 2.0f/9.0f, + -2.0f/9.0f, 0.0f, 2.0f/9.0f, 0.0f, 0.0f, 2.0f/9.0f, 2.0f/9.0f, 0.0f, 2.0f/9.0f, + 4.0f/9.0f, 0.0f, 2.0f/9.0f, 6.0f/9.0f, 0.0f, 2.0f/9.0f, 8.0f/9.0f, 0.0f, 2.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 0.0f, 2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 0.0f, 4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 0.0f, 6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 0.0f, 8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, 0.0f, -8.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 0.0f, -6.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 0.0f, -4.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, 0.0f, -2.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, 0.0f, 4.0f/9.0f, -6.0f/9.0f, 0.0f, 4.0f/9.0f, -4.0f/9.0f, 0.0f, 4.0f/9.0f, + -2.0f/9.0f, 0.0f, 4.0f/9.0f, 0.0f, 0.0f, 4.0f/9.0f, 2.0f/9.0f, 0.0f, 4.0f/9.0f, + 4.0f/9.0f, 0.0f, 4.0f/9.0f, 6.0f/9.0f, 0.0f, 4.0f/9.0f, 8.0f/9.0f, 0.0f, 4.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 0.0f, 2.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, 0.0f, 4.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 0.0f, 6.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 0.0f, 8.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 0.0f, -8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 0.0f, -6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 0.0f, -4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 0.0f, -2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, 0.0f, 6.0f/9.0f, -6.0f/9.0f, 0.0f, 6.0f/9.0f, -4.0f/9.0f, 0.0f, 6.0f/9.0f, + -2.0f/9.0f, 0.0f, 6.0f/9.0f, 0.0f, 0.0f, 6.0f/9.0f, 2.0f/9.0f, 0.0f, 6.0f/9.0f, + 4.0f/9.0f, 0.0f, 6.0f/9.0f, 6.0f/9.0f, 0.0f, 6.0f/9.0f, 8.0f/9.0f, 0.0f, 6.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 0.0f, 2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 0.0f, 4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 0.0f, 6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 0.0f, 8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 0.0f, -8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 0.0f, -6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 0.0f, -4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 0.0f, -2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, + -8.0f/9.0f, 0.0f, 8.0f/9.0f, -6.0f/9.0f, 0.0f, 8.0f/9.0f, -4.0f/9.0f, 0.0f, 8.0f/9.0f, + -2.0f/9.0f, 0.0f, 8.0f/9.0f, 0.0f, 0.0f, 8.0f/9.0f, 2.0f/9.0f, 0.0f, 8.0f/9.0f, + 4.0f/9.0f, 0.0f, 8.0f/9.0f, 6.0f/9.0f, 0.0f, 8.0f/9.0f, 8.0f/9.0f, 0.0f, 8.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 0.0f, 2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 0.0f, 4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 0.0f, 6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 0.0f, 8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f + }; + + // data taken from ISO/IEC DIS 11172, Annexes 3-B.2[abcd] and 3-B.4: + + // subbands 0-2 in tables 3-B.2a and 2b: (index is allocation) + public static final int table_ab1_codelength[] = + // bits per codeword + { 0, 5, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + + public static final float table_ab1_groupingtables[][] = + // pointer to sample grouping table, or NULL-pointer if ungrouped + { null, grouping_5bits, null, null, null, null, null, null, null, null, null, null, null, null, null, null }; + + public static final float table_ab1_factor[] = + // factor for requantization: (real)sample * factor - 1.0 gives requantized sample + { 0.0f, 1.0f/2.0f, 1.0f/4.0f, 1.0f/8.0f, 1.0f/16.0f, 1.0f/32.0f, 1.0f/64.0f, + 1.0f/128.0f, 1.0f/256.0f, 1.0f/512.0f, 1.0f/1024.0f, 1.0f/2048.0f, + 1.0f/4096.0f, 1.0f/8192.0f, 1.0f/16384.0f, 1.0f/32768.0f }; + + public static final float table_ab1_c[] = + // factor c for requantization from table 3-B.4 + { 0.0f, 1.33333333333f, 1.14285714286f, 1.06666666666f, 1.03225806452f, + 1.01587301587f, 1.00787401575f, 1.00392156863f, 1.00195694716f, 1.00097751711f, + 1.00048851979f, 1.00024420024f, 1.00012208522f, 1.00006103888f, 1.00003051851f, + 1.00001525902f }; + + public static final float table_ab1_d[] = + // addend d for requantization from table 3-B.4 + { 0.0f, 0.50000000000f, 0.25000000000f, 0.12500000000f, 0.06250000000f, + 0.03125000000f, 0.01562500000f, 0.00781250000f, 0.00390625000f, 0.00195312500f, + 0.00097656250f, 0.00048828125f, 0.00024414063f, 0.00012207031f, 0.00006103516f, + 0.00003051758f }; + + // subbands 3-... tables 3-B.2a and 2b: + public static final float[] table_ab234_groupingtables[] = + { null, grouping_5bits, grouping_7bits, null, grouping_10bits, null, null, null, null, null, null, null, null, null, null, null }; + + // subbands 3-10 in tables 3-B.2a and 2b: + public static final int table_ab2_codelength[] = + { 0, 5, 7, 3, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 }; + public static final float table_ab2_factor[] = + { 0.0f, 1.0f/2.0f, 1.0f/4.0f, 1.0f/4.0f, 1.0f/8.0f, 1.0f/8.0f, 1.0f/16.0f, + 1.0f/32.0f, 1.0f/64.0f, 1.0f/128.0f, 1.0f/256.0f, 1.0f/512.0f, + 1.0f/1024.0f, 1.0f/2048.0f, 1.0f/4096.0f, 1.0f/32768.0f }; + public static final float table_ab2_c[] = + { 0.0f, 1.33333333333f, 1.60000000000f, 1.14285714286f, 1.77777777777f, + 1.06666666666f, 1.03225806452f, 1.01587301587f, 1.00787401575f, 1.00392156863f, + 1.00195694716f, 1.00097751711f, 1.00048851979f, 1.00024420024f, 1.00012208522f, + 1.00001525902f }; + public static final float table_ab2_d[] = + { 0.0f, 0.50000000000f, 0.50000000000f, 0.25000000000f, 0.50000000000f, + 0.12500000000f, 0.06250000000f, 0.03125000000f, 0.01562500000f, 0.00781250000f, + 0.00390625000f, 0.00195312500f, 0.00097656250f, 0.00048828125f, 0.00024414063f, + 0.00003051758f }; + + // subbands 11-22 in tables 3-B.2a and 2b: + public static final int table_ab3_codelength[] = { 0, 5, 7, 3, 10, 4, 5, 16 }; + public static final float table_ab3_factor[] = + { 0.0f, 1.0f/2.0f, 1.0f/4.0f, 1.0f/4.0f, 1.0f/8.0f, 1.0f/8.0f, 1.0f/16.0f, 1.0f/32768.0f }; + public static final float table_ab3_c[] = + { 0.0f, 1.33333333333f, 1.60000000000f, 1.14285714286f, 1.77777777777f, + 1.06666666666f, 1.03225806452f, 1.00001525902f }; + public static final float table_ab3_d[] = + { 0.0f, 0.50000000000f, 0.50000000000f, 0.25000000000f, 0.50000000000f, + 0.12500000000f, 0.06250000000f, 0.00003051758f }; + + // subbands 23-... in tables 3-B.2a and 2b: + public static final int table_ab4_codelength[] = { 0, 5, 7, 16 }; + public static final float table_ab4_factor[] = { 0.0f, 1.0f/2.0f, 1.0f/4.0f, 1.0f/32768.0f }; + public static final float table_ab4_c[] = { 0.0f, 1.33333333333f, 1.60000000000f, 1.00001525902f }; + public static final float table_ab4_d[] = { 0.0f, 0.50000000000f, 0.50000000000f, 0.00003051758f }; + + // subbands in tables 3-B.2c and 2d: + public static final int table_cd_codelength[] = + { 0, 5, 7, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; + public static final float table_cd_groupingtables[][] = + { null, grouping_5bits, grouping_7bits, grouping_10bits, null, null, null, null, null, null, null, null, null, null, null, null }; + public static final float table_cd_factor[] = + { 0.0f, 1.0f/2.0f, 1.0f/4.0f, 1.0f/8.0f, 1.0f/8.0f, 1.0f/16.0f, 1.0f/32.0f, 1.0f/64.0f, + 1.0f/128.0f, 1.0f/256.0f, 1.0f/512.0f, 1.0f/1024.0f, 1.0f/2048.0f, 1.0f/4096.0f, + 1.0f/8192.0f, 1.0f/16384.0f }; + public static final float table_cd_c[] = + { 0.0f, 1.33333333333f, 1.60000000000f, 1.77777777777f, 1.06666666666f, + 1.03225806452f, 1.01587301587f, 1.00787401575f, 1.00392156863f, 1.00195694716f, + 1.00097751711f, 1.00048851979f, 1.00024420024f, 1.00012208522f, 1.00006103888f, + 1.00003051851f }; + public static final float table_cd_d[] = + { 0.0f, 0.50000000000f, 0.50000000000f, 0.50000000000f, 0.12500000000f, + 0.06250000000f, 0.03125000000f, 0.01562500000f, 0.00781250000f, 0.00390625000f, + 0.00195312500f, 0.00097656250f, 0.00048828125f, 0.00024414063f, 0.00012207031f, + 0.00006103516f }; + + + + protected int subbandnumber; + protected int allocation; + protected int scfsi; + protected float scalefactor1, scalefactor2, scalefactor3; + protected int[] codelength = {0}; + protected float groupingtable[][] = new float[2][]; + //protected float[][] groupingtable = {{0},{0}} ; + protected float[] factor = {0.0f}; + protected int groupnumber; + protected int samplenumber; + protected float[] samples = new float[3]; + protected float[] c = {0}; + protected float[] d = {0}; + /** + * Constructor + */ + public SubbandLayer2(int subbandnumber) + { + this.subbandnumber = subbandnumber; + groupnumber = samplenumber = 0; + } + + + /** + * + */ + protected int get_allocationlength (Header header) + { + if (header.version() == Header.MPEG1) + { + int channel_bitrate = header.bitrate_index(); + + // calculate bitrate per channel: + if (header.mode() != Header.SINGLE_CHANNEL) + if (channel_bitrate == 4) + channel_bitrate = 1; + else + channel_bitrate -= 4; + + if (channel_bitrate == 1 || channel_bitrate == 2) + // table 3-B.2c or 3-B.2d + if (subbandnumber <= 1) + return 4; + else + return 3; + else + // tables 3-B.2a or 3-B.2b + if (subbandnumber <= 10) + return 4; + else if (subbandnumber <= 22) + return 3; + else + return 2; + } + else + { // MPEG-2 LSF -- Jeff + + // table B.1 of ISO/IEC 13818-3 + if (subbandnumber <= 3) + return 4; + else if (subbandnumber <= 10) + return 3; + else + return 2; + } + } + + /** + * + */ + protected void prepare_sample_reading(Header header, int allocation, + //float[][] groupingtable, + int channel, + float[] factor, int[] codelength, + float[] c, float[] d) + { + int channel_bitrate = header.bitrate_index(); + // calculate bitrate per channel: + if (header.mode() != Header.SINGLE_CHANNEL) + if (channel_bitrate == 4) + channel_bitrate = 1; + else + channel_bitrate -= 4; + + if (channel_bitrate == 1 || channel_bitrate == 2) + { + // table 3-B.2c or 3-B.2d + groupingtable[channel] = table_cd_groupingtables[allocation]; + factor[0] = table_cd_factor[allocation]; + codelength[0] = table_cd_codelength[allocation]; + c[0] = table_cd_c[allocation]; + d[0] = table_cd_d[allocation]; + } + else + { + // tables 3-B.2a or 3-B.2b + if (subbandnumber <= 2) + { + groupingtable[channel] = table_ab1_groupingtables[allocation]; + factor[0] = table_ab1_factor[allocation]; + codelength[0] = table_ab1_codelength[allocation]; + c[0] = table_ab1_c[allocation]; + d[0] = table_ab1_d[allocation]; + } + else + { + groupingtable[channel] = table_ab234_groupingtables[allocation]; + if (subbandnumber <= 10) + { + factor[0] = table_ab2_factor[allocation]; + codelength[0] = table_ab2_codelength[allocation]; + c[0] = table_ab2_c[allocation]; + d[0] = table_ab2_d[allocation]; + } + else if (subbandnumber <= 22) + { + factor[0] = table_ab3_factor[allocation]; + codelength[0] = table_ab3_codelength[allocation]; + c[0] = table_ab3_c[allocation]; + d[0] = table_ab3_d[allocation]; + } + else + { + factor[0] = table_ab4_factor[allocation]; + codelength[0] = table_ab4_codelength[allocation]; + c[0] = table_ab4_c[allocation]; + d[0] = table_ab4_d[allocation]; + } + } + } + } + + + /** + * + */ + public void read_allocation(Bitstream stream, Header header, Crc16 crc) + { + int length = get_allocationlength(header); + allocation = stream.get_bits(length); + if (crc != null) + crc.add_bits(allocation, length); + } + + /** + * + */ + public void read_scalefactor_selection (Bitstream stream, Crc16 crc) + { + if (allocation != 0) + { + scfsi = stream.get_bits(2); + if (crc != null) crc.add_bits(scfsi, 2); + } + } + + /** + * + */ + public void read_scalefactor (Bitstream stream, Header header) + { + if (allocation != 0) + { + switch (scfsi) + { + case 0: + scalefactor1 = scalefactors[stream.get_bits(6)]; + scalefactor2 = scalefactors[stream.get_bits(6)]; + scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + case 1: + scalefactor1 = scalefactor2 = scalefactors[stream.get_bits(6)]; + scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + case 2: + scalefactor1 = scalefactor2 = scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + case 3: + scalefactor1 = scalefactors[stream.get_bits(6)]; + scalefactor2 = scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + } + prepare_sample_reading(header, allocation, 0, + factor, codelength, c, d); + } + } + + /** + * + */ + public boolean read_sampledata (Bitstream stream) + { + if (allocation != 0) + if (groupingtable[0] != null) + { + int samplecode = stream.get_bits(codelength[0]); + // create requantized samples: + samplecode += samplecode << 1; + float[] target = samples; + float[] source = groupingtable[0]; + /* + int tmp = 0; + int temp = 0; + target[tmp++] = source[samplecode + temp]; + temp++; + target[tmp++] = source[samplecode + temp]; + temp++; + target[tmp] = source[samplecode + temp]; + */ + //Bugfix: + int tmp = 0; + int temp = samplecode; + + if(temp > source.length - 3) temp = source.length - 3; + + target[tmp] = source[temp]; + temp++;tmp++; + target[tmp] = source[temp]; + temp++;tmp++; + target[tmp] = source[temp]; + + // memcpy (samples, groupingtable + samplecode, 3 * sizeof (real)); + } + else + { + samples[0] = (float) ((stream.get_bits(codelength[0])) * factor[0] - 1.0); + samples[1] = (float) ((stream.get_bits(codelength[0])) * factor[0] - 1.0); + samples[2] = (float) ((stream.get_bits(codelength[0])) * factor[0] - 1.0); + } + + samplenumber = 0; + if (++groupnumber == 12) + return true; + else + return false; + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) + { + if ((allocation != 0) && (channels != OutputChannels.RIGHT_CHANNEL)) + { + float sample = samples[samplenumber]; + + if (groupingtable[0] == null) + sample = (sample + d[0]) * c[0]; + if (groupnumber <= 4) + sample *= scalefactor1; + else if (groupnumber <= 8) + sample *= scalefactor2; + else + sample *= scalefactor3; + filter1.input_sample(sample, subbandnumber); + } + + if (++samplenumber == 3) + return true; + else + return false; + } + }; + + /** + * Class for layer II subbands in joint stereo mode. + */ + static class SubbandLayer2IntensityStereo extends SubbandLayer2 + { + protected int channel2_scfsi; + protected float channel2_scalefactor1, channel2_scalefactor2, channel2_scalefactor3; + + /** + * Constructor + */ + public SubbandLayer2IntensityStereo (int subbandnumber) + { + super(subbandnumber); + } + + /** + * + */ + public void read_allocation(Bitstream stream, Header header, Crc16 crc) + { + super.read_allocation (stream, header, crc); + } + + /** + * + */ + public void read_scalefactor_selection(Bitstream stream, Crc16 crc) + { + if (allocation != 0) + { + scfsi = stream.get_bits(2); + channel2_scfsi = stream.get_bits(2); + if (crc != null) + { + crc.add_bits(scfsi, 2); + crc.add_bits(channel2_scfsi, 2); + } + } + } + + /** + * + */ + public void read_scalefactor(Bitstream stream, Header header) + { + if (allocation != 0) + { + super.read_scalefactor(stream, header); + switch (channel2_scfsi) + { + case 0: + channel2_scalefactor1 = scalefactors[stream.get_bits(6)]; + channel2_scalefactor2 = scalefactors[stream.get_bits(6)]; + channel2_scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + + case 1: + channel2_scalefactor1 = channel2_scalefactor2 = scalefactors[stream.get_bits (6)]; + channel2_scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + + case 2: + channel2_scalefactor1 = channel2_scalefactor2 = + channel2_scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + + case 3: + channel2_scalefactor1 = scalefactors[stream.get_bits(6)]; + channel2_scalefactor2 = channel2_scalefactor3 = scalefactors[stream.get_bits (6)]; + break; + } + } + + } + + /** + * + */ + public boolean read_sampledata(Bitstream stream) + { + return super.read_sampledata (stream); + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) + { + if (allocation != 0) + { + float sample = samples[samplenumber]; + + if (groupingtable[0] == null) + sample = (sample + d[0]) * c[0]; + if (channels == OutputChannels.BOTH_CHANNELS) + { + float sample2 = sample; + if (groupnumber <= 4) + { + sample *= scalefactor1; + sample2 *= channel2_scalefactor1; + } + else if (groupnumber <= 8) + { + sample *= scalefactor2; + sample2 *= channel2_scalefactor2; + } + else + { + sample *= scalefactor3; + sample2 *= channel2_scalefactor3; + } + filter1.input_sample(sample, subbandnumber); + filter2.input_sample(sample2, subbandnumber); + } + else if (channels == OutputChannels.LEFT_CHANNEL) + { + if (groupnumber <= 4) + sample *= scalefactor1; + else if (groupnumber <= 8) + sample *= scalefactor2; + else + sample *= scalefactor3; + filter1.input_sample(sample, subbandnumber); + } + else + { + if (groupnumber <= 4) + sample *= channel2_scalefactor1; + else if (groupnumber <= 8) + sample *= channel2_scalefactor2; + else + sample *= channel2_scalefactor3; + filter1.input_sample(sample, subbandnumber); + } + } + + if (++samplenumber == 3) + return true; + else + return false; + } + }; + + /** + * Class for layer II subbands in stereo mode. + */ + static class SubbandLayer2Stereo extends SubbandLayer2 + { + protected int channel2_allocation; + protected int channel2_scfsi; + protected float channel2_scalefactor1, channel2_scalefactor2, channel2_scalefactor3; + //protected boolean channel2_grouping; ???? Never used! + protected int[] channel2_codelength = {0}; + //protected float[][] channel2_groupingtable = {{0},{0}}; + protected float[] channel2_factor = {0}; + protected float[] channel2_samples; + protected float[] channel2_c = {0}; + protected float[] channel2_d = {0}; + + /** + * Constructor + */ + public SubbandLayer2Stereo(int subbandnumber) + { + super(subbandnumber); + channel2_samples = new float[3]; + } + + /** + * + */ + public void read_allocation (Bitstream stream, Header header, Crc16 crc) + { + int length = get_allocationlength(header); + allocation = stream.get_bits(length); + channel2_allocation = stream.get_bits(length); + if (crc != null) + { + crc.add_bits(allocation, length); + crc.add_bits(channel2_allocation, length); + } + } + + /** + * + */ + public void read_scalefactor_selection(Bitstream stream, Crc16 crc) + { + if (allocation != 0) + { + scfsi = stream.get_bits(2); + if (crc != null) + crc.add_bits(scfsi, 2); + } + if (channel2_allocation != 0) + { + channel2_scfsi = stream.get_bits(2); + if (crc != null) + crc.add_bits(channel2_scfsi, 2); + } + } + + /** + * + */ + public void read_scalefactor(Bitstream stream, Header header) + { + super.read_scalefactor(stream, header); + if (channel2_allocation != 0) + { + switch (channel2_scfsi) + { + case 0: + channel2_scalefactor1 = scalefactors[stream.get_bits(6)]; + channel2_scalefactor2 = scalefactors[stream.get_bits(6)]; + channel2_scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + + case 1: + channel2_scalefactor1 = channel2_scalefactor2 = + scalefactors[stream.get_bits(6)]; + channel2_scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + + case 2: + channel2_scalefactor1 = channel2_scalefactor2 = + channel2_scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + + case 3: + channel2_scalefactor1 = scalefactors[stream.get_bits(6)]; + channel2_scalefactor2 = channel2_scalefactor3 = + scalefactors[stream.get_bits(6)]; + break; + } + prepare_sample_reading(header, channel2_allocation, 1, + channel2_factor, channel2_codelength, channel2_c, + channel2_d); + } + } + + /** + * + */ + public boolean read_sampledata (Bitstream stream) + { + boolean returnvalue = super.read_sampledata(stream); + + if (channel2_allocation != 0) + if (groupingtable[1] != null) + { + int samplecode = stream.get_bits(channel2_codelength[0]); + // create requantized samples: + samplecode += samplecode << 1; + /* + float[] target = channel2_samples; + float[] source = channel2_groupingtable[0]; + int tmp = 0; + int temp = 0; + target[tmp++] = source[samplecode + temp]; + temp++; + target[tmp++] = source[samplecode + temp]; + temp++; + target[tmp] = source[samplecode + temp]; + // memcpy (channel2_samples, channel2_groupingtable + samplecode, 3 * sizeof (real)); + */ + float[] target = channel2_samples; + float[] source = groupingtable[1]; + int tmp = 0; + int temp = samplecode; + target[tmp] = source[temp]; + temp++;tmp++; + target[tmp] = source[temp]; + temp++;tmp++; + target[tmp] = source[temp]; + + } + else + { + channel2_samples[0] = (float) ((stream.get_bits(channel2_codelength[0])) * + channel2_factor[0] - 1.0); + channel2_samples[1] = (float) ((stream.get_bits(channel2_codelength[0])) * + channel2_factor[0] - 1.0); + channel2_samples[2] = (float) ((stream.get_bits(channel2_codelength[0])) * + channel2_factor[0] - 1.0); + } + return returnvalue; + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) + { + boolean returnvalue = super.put_next_sample(channels, filter1, filter2); + if ((channel2_allocation != 0) && (channels != OutputChannels.LEFT_CHANNEL)) + { + float sample = channel2_samples[samplenumber - 1]; + + if (groupingtable[1] == null) + sample = (sample + channel2_d[0]) * channel2_c[0]; + + if (groupnumber <= 4) + sample *= channel2_scalefactor1; + else if (groupnumber <= 8) + sample *= channel2_scalefactor2; + else + sample *= channel2_scalefactor3; + if (channels == OutputChannels.BOTH_CHANNELS) + filter2.input_sample(sample, subbandnumber); + else + filter1.input_sample(sample, subbandnumber); + } + return returnvalue; + } + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/LayerIIIDecoder.java b/src/lwjgl/java/javazoom/jl/decoder/LayerIIIDecoder.java new file mode 100644 index 0000000..009e60d --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/LayerIIIDecoder.java @@ -0,0 +1,2436 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 18/06/01 Michael Scheerer, Fixed bugs which causes + * negative indexes in method huffmann_decode and in method + * dequanisize_sample. + * + * 16/07/01 Michael Scheerer, Catched a bug in method + * huffmann_decode, which causes an outOfIndexException. + * Cause : Indexnumber of 24 at SfBandIndex, + * which has only a length of 22. I have simply and dirty + * fixed the index to <= 22, because I'm not really be able + * to fix the bug. The Indexnumber is taken from the MP3 + * file and the origin Ma-Player with the same code works + * well. + * + * 02/19/99 Java Conversion by E.B, javalayer@javazoom.net + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Class Implementing Layer 3 Decoding. + * + * @since 0.0 + */ +final class LayerIIIDecoder implements FrameDecoder +{ + static final double d43 = (4.0/3.0); + + public int[] scalefac_buffer; + + // MDM: removed, as this wasn't being used. + //private float CheckSumOut1d = 0.0f; + private int CheckSumHuff = 0; + private int[] is_1d; + private float[][][] ro; + private float[][][] lr; + private float[] out_1d; + private float[][] prevblck; + private float[][] k; + private int[] nonzero; + private Bitstream stream; + private Header header; + private SynthesisFilter filter1, filter2; + private Obuffer buffer; + private int which_channels; + private BitReserve br; + private III_side_info_t si; + + private temporaire2[] III_scalefac_t; + private temporaire2[] scalefac; + // private III_scalefac_t scalefac; + + private int max_gr; + private int frame_start; + private int part2_start; + private int channels; + private int first_channel; + private int last_channel; + private int sfreq; + + + /** + * Constructor. + */ + // REVIEW: these constructor arguments should be moved to the + // decodeFrame() method, where possible, so that one + public LayerIIIDecoder(Bitstream stream0, Header header0, + SynthesisFilter filtera, SynthesisFilter filterb, + Obuffer buffer0, int which_ch0) + { + huffcodetab.inithuff(); + is_1d = new int[SBLIMIT*SSLIMIT+4]; + ro = new float[2][SBLIMIT][SSLIMIT]; + lr = new float[2][SBLIMIT][SSLIMIT]; + out_1d = new float[SBLIMIT*SSLIMIT]; + prevblck = new float[2][SBLIMIT*SSLIMIT]; + k = new float[2][SBLIMIT*SSLIMIT]; + nonzero = new int[2]; + + //III_scalefact_t + III_scalefac_t = new temporaire2[2]; + III_scalefac_t[0] = new temporaire2(); + III_scalefac_t[1] = new temporaire2(); + scalefac = III_scalefac_t; + // L3TABLE INIT + + sfBandIndex = new SBI[9]; // SZD: MPEG2.5 +3 indices + int[] l0 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}; + int[] s0 = {0,4,8,12,18,24,32,42,56,74,100,132,174,192}; + int[] l1 = {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576}; + int[] s1 = {0,4,8,12,18,26,36,48,62,80,104,136,180,192}; + int[] l2 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}; + int[] s2 = {0,4,8,12,18,26,36,48,62,80,104,134,174,192}; + + int[] l3 = {0,4,8,12,16,20,24,30,36,44,52,62,74,90,110,134,162,196,238,288,342,418,576}; + int[] s3 = {0,4,8,12,16,22,30,40,52,66,84,106,136,192}; + int[] l4 = {0,4,8,12,16,20,24,30,36,42,50,60,72,88,106,128,156,190,230,276,330,384,576}; + int[] s4 = {0,4,8,12,16,22,28,38,50,64,80,100,126,192}; + int[] l5 = {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576}; + int[] s5 = {0,4,8,12,16,22,30,42,58,78,104,138,180,192}; + // SZD: MPEG2.5 + int[] l6 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}; + int[] s6 = {0,4,8,12,18,26,36,48,62,80,104,134,174,192}; + int[] l7 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}; + int[] s7 = {0,4,8,12,18,26,36,48,62,80,104,134,174,192}; + int[] l8 = {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576}; + int[] s8 = {0,8,16,24,36,52,72,96,124,160,162,164,166,192}; + + sfBandIndex[0]= new SBI(l0,s0); + sfBandIndex[1]= new SBI(l1,s1); + sfBandIndex[2]= new SBI(l2,s2); + + sfBandIndex[3]= new SBI(l3,s3); + sfBandIndex[4]= new SBI(l4,s4); + sfBandIndex[5]= new SBI(l5,s5); + //SZD: MPEG2.5 + sfBandIndex[6]= new SBI(l6,s6); + sfBandIndex[7]= new SBI(l7,s7); + sfBandIndex[8]= new SBI(l8,s8); + // END OF L3TABLE INIT + + if(reorder_table == null) { // SZD: generate LUT + reorder_table = new int[9][]; + for(int i = 0; i < 9; i++) + reorder_table[i] = reorder(sfBandIndex[i].s); + } + + // Sftable + int[] ll0 = {0, 6, 11, 16, 21}; + int[] ss0 = {0, 6, 12}; + sftable = new Sftable(ll0,ss0); + // END OF Sftable + + // scalefac_buffer + scalefac_buffer = new int[54]; + // END OF scalefac_buffer + + stream = stream0; + header = header0; + filter1 = filtera; + filter2 = filterb; + buffer = buffer0; + which_channels = which_ch0; + + frame_start = 0; + channels = (header.mode() == Header.SINGLE_CHANNEL) ? 1 : 2; + max_gr = (header.version() == Header.MPEG1) ? 2 : 1; + + sfreq = header.sample_frequency() + + ((header.version() == Header.MPEG1) ? 3 : + (header.version() == Header.MPEG25_LSF) ? 6 : 0); // SZD + + if (channels == 2) + { + switch (which_channels) + { + case OutputChannels.LEFT_CHANNEL: + case OutputChannels.DOWNMIX_CHANNELS: + first_channel = last_channel = 0; + break; + + case OutputChannels.RIGHT_CHANNEL: + first_channel = last_channel = 1; + break; + + case OutputChannels.BOTH_CHANNELS: + default: + first_channel = 0; + last_channel = 1; + break; + } + } + else + { + first_channel = last_channel = 0; + } + + for(int ch=0;ch<2;ch++) + for (int j=0; j<576; j++) + prevblck[ch][j] = 0.0f; + + nonzero[0] = nonzero[1] = 576; + + br = new BitReserve(); + si = new III_side_info_t(); + } + + /** + * Notify decoder that a seek is being made. + */ + public void seek_notify() + { + frame_start = 0; + for(int ch=0;ch<2;ch++) + for (int j=0; j<576; j++) + prevblck[ch][j] = 0.0f; + br = new BitReserve(); + } + + public void decodeFrame() + { + decode(); + } + + /** + * Decode one frame, filling the buffer with the output samples. + */ + + // subband samples are buffered and passed to the + // SynthesisFilter in one go. + private float[] samples1 = new float[32]; + private float[] samples2 = new float[32]; + + public void decode() + { + int nSlots = header.slots(); + int flush_main; + int gr, ch, ss, sb, sb18; + int main_data_end; + int bytes_to_discard; + int i; + + get_side_info(); + + for (i=0; i>> 3; // of previous frame + + if ((flush_main = (br.hsstell() & 7)) != 0) { + br.hgetbits(8 - flush_main); + main_data_end++; + } + + bytes_to_discard = frame_start - main_data_end + - si.main_data_begin; + + frame_start += nSlots; + + if (bytes_to_discard < 0) + return; + + if (main_data_end > 4096) { + frame_start -= 4096; + br.rewindNbytes(4096); + } + + for (; bytes_to_discard > 0; bytes_to_discard--) + br.hgetbits(8); + + for (gr=0;gr>> 4) / 5 ; + new_slen[1] = (scalefac_comp >>> 4) % 5 ; + new_slen[2] = (scalefac_comp & 0xF) >>> 2 ; + new_slen[3] = (scalefac_comp & 3); + si.ch[ch].gr[gr].preflag = 0; + blocknumber = 0; + + } else if (scalefac_comp < 500) { + + new_slen[0] = ((scalefac_comp - 400) >>> 2) / 5 ; + new_slen[1] = ((scalefac_comp - 400) >>> 2) % 5 ; + new_slen[2] = (scalefac_comp - 400 ) & 3 ; + new_slen[3] = 0; + si.ch[ch].gr[gr].preflag = 0; + blocknumber = 1; + + } else if (scalefac_comp < 512) { + + new_slen[0] = (scalefac_comp - 500 ) / 3 ; + new_slen[1] = (scalefac_comp - 500) % 3 ; + new_slen[2] = 0; + new_slen[3] = 0; + si.ch[ch].gr[gr].preflag = 1; + blocknumber = 2; + } + } + + if((((mode_ext == 1) || (mode_ext == 3)) && (ch == 1))) + { + int_scalefac_comp = scalefac_comp >>> 1; + + if (int_scalefac_comp < 180) + { + new_slen[0] = int_scalefac_comp / 36 ; + new_slen[1] = (int_scalefac_comp % 36 ) / 6 ; + new_slen[2] = (int_scalefac_comp % 36) % 6; + new_slen[3] = 0; + si.ch[ch].gr[gr].preflag = 0; + blocknumber = 3; + } else if (int_scalefac_comp < 244) { + new_slen[0] = ((int_scalefac_comp - 180 ) & 0x3F) >>> 4 ; + new_slen[1] = ((int_scalefac_comp - 180) & 0xF) >>> 2 ; + new_slen[2] = (int_scalefac_comp - 180 ) & 3 ; + new_slen[3] = 0; + si.ch[ch].gr[gr].preflag = 0; + blocknumber = 4; + } else if (int_scalefac_comp < 255) { + new_slen[0] = (int_scalefac_comp - 244 ) / 3 ; + new_slen[1] = (int_scalefac_comp - 244 ) % 3 ; + new_slen[2] = 0 ; + new_slen[3] = 0; + si.ch[ch].gr[gr].preflag = 0; + blocknumber = 5; + } + } + + for (int x=0; x<45; x++) // why 45, not 54? + scalefac_buffer[x] = 0; + + m = 0; + for (int i=0; i<4;i++) { + for (int j = 0; j < nr_of_sfb_block[blocknumber][blocktypenumber][i]; + j++) + { + scalefac_buffer[m] = (new_slen[i] == 0) ? 0 : + br.hgetbits(new_slen[i]); + m++; + + } // for (unint32 j ... + } // for (uint32 i ... + } + + /** + * + */ + private void get_LSF_scale_factors(int ch, int gr) + { + int m = 0; + int sfb, window; + gr_info_s gr_info = (si.ch[ch].gr[gr]); + + get_LSF_scale_data(ch, gr); + + if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) { + if (gr_info.mixed_block_flag != 0) { // MIXED + for (sfb = 0; sfb < 8; sfb++) + { + scalefac[ch].l[sfb] = scalefac_buffer[m]; + m++; + } + for (sfb = 3; sfb < 12; sfb++) { + for (window=0; window<3; window++) + { + scalefac[ch].s[window][sfb] = scalefac_buffer[m]; + m++; + } + } + for (window=0; window<3; window++) + scalefac[ch].s[window][12] = 0; + + } else { // SHORT + + for (sfb = 0; sfb < 12; sfb++) { + for (window=0; window<3; window++) + { + scalefac[ch].s[window][sfb] = scalefac_buffer[m]; + m++; + } + } + + for (window=0; window<3; window++) + scalefac[ch].s[window][12] = 0; + } + } else { // LONG types 0,1,3 + + for (sfb = 0; sfb < 21; sfb++) { + scalefac[ch].l[sfb] = scalefac_buffer[m]; + m++; + } + scalefac[ch].l[21] = 0; // Jeff + scalefac[ch].l[22] = 0; + } + } + + /** + * + */ + int[] x = {0}; + int[] y = {0}; + int[] v = {0}; + int[] w = {0}; + private void huffman_decode(int ch, int gr) + { + x[0] = 0; + y[0] = 0; + v[0] = 0; + w[0] = 0; + + int part2_3_end = part2_start + si.ch[ch].gr[gr].part2_3_length; + int num_bits; + int region1Start; + int region2Start; + int index; + + int buf, buf1; + + huffcodetab h; + + // Find region boundary for short block case + + if ( ((si.ch[ch].gr[gr].window_switching_flag) != 0) && + (si.ch[ch].gr[gr].block_type == 2) ) { + + // Region2. + //MS: Extrahandling for 8KHZ + region1Start = (sfreq == 8) ? 72 : 36; // sfb[9/3]*3=36 or in case 8KHZ = 72 + region2Start = 576; // No Region2 for short block case + + } else { // Find region boundary for long block case + + buf = si.ch[ch].gr[gr].region0_count + 1; + buf1 = buf + si.ch[ch].gr[gr].region1_count + 1; + + if(buf1 > sfBandIndex[sfreq].l.length - 1) buf1 = sfBandIndex[sfreq].l.length - 1; + + region1Start = sfBandIndex[sfreq].l[buf]; + region2Start = sfBandIndex[sfreq].l[buf1]; /* MI */ + } + + index = 0; + // Read bigvalues area + for (int i=0; i<(si.ch[ch].gr[gr].big_values<<1); i+=2) { + if (i= is_1d.length) System.out.println("i0="+i+"/"+(si.ch[ch].gr[gr].big_values<<1)+" Index="+index+" is_1d="+is_1d.length); + + is_1d[index++] = x[0]; + is_1d[index++] = y[0]; + + CheckSumHuff = CheckSumHuff + x[0] + y[0]; + // System.out.println("x = "+x[0]+" y = "+y[0]); + } + + // Read count1 area + h = huffcodetab.ht[si.ch[ch].gr[gr].count1table_select+32]; + num_bits = br.hsstell(); + + while ((num_bits < part2_3_end) && (index < 576)) { + + huffcodetab.huffman_decoder(h, x, y, v, w, br); + + is_1d[index++] = v[0]; + is_1d[index++] = w[0]; + is_1d[index++] = x[0]; + is_1d[index++] = y[0]; + CheckSumHuff = CheckSumHuff + v[0] + w[0] + x[0] + y[0]; + // System.out.println("v = "+v[0]+" w = "+w[0]); + // System.out.println("x = "+x[0]+" y = "+y[0]); + num_bits = br.hsstell(); + } + + if (num_bits > part2_3_end) { + br.rewindNbits(num_bits - part2_3_end); + index-=4; + } + + num_bits = br.hsstell(); + + // Dismiss stuffing bits + if (num_bits < part2_3_end) + br.hgetbits(part2_3_end - num_bits); + + // Zero out rest + + if (index < 576) + nonzero[ch] = index; + else + nonzero[ch] = 576; + + if (index < 0) index = 0; + + // may not be necessary + for (; index<576; index++) + is_1d[index] = 0; + } + + /** + * + */ + private void i_stereo_k_values(int is_pos, int io_type, int i) + { + if (is_pos == 0) { + k[0][i] = 1.0f; + k[1][i] = 1.0f; + } else if ((is_pos & 1) != 0) { + k[0][i] = io[io_type][(is_pos + 1) >>> 1]; + k[1][i] = 1.0f; + } else { + k[0][i] = 1.0f; + k[1][i] = io[io_type][is_pos >>> 1]; + } + } + + /** + * + */ + private void dequantize_sample(float xr[][], int ch, int gr) + { + gr_info_s gr_info = (si.ch[ch].gr[gr]); + int cb=0; + int next_cb_boundary; + int cb_begin = 0; + int cb_width = 0; + int index=0, t_index, j; + float g_gain; + float[][] xr_1d = xr; + + // choose correct scalefactor band per block type, initalize boundary + + if ((gr_info.window_switching_flag !=0 ) && (gr_info.block_type == 2) ) { + if (gr_info.mixed_block_flag != 0) + next_cb_boundary=sfBandIndex[sfreq].l[1]; // LONG blocks: 0,1,3 + else { + cb_width = sfBandIndex[sfreq].s[1]; + next_cb_boundary = (cb_width << 2) - cb_width; + cb_begin = 0; + } + } else { + next_cb_boundary=sfBandIndex[sfreq].l[1]; // LONG blocks: 0,1,3 + } + + // Compute overall (global) scaling. + + g_gain = (float) Math.pow(2.0 , (0.25 * (gr_info.global_gain - 210.0))); + + for (j=0; j 0) xr_1d[quotien][reste] = g_gain * t_43[abv]; + else + { + if (-abv < t_43.length) xr_1d[quotien][reste] = -g_gain * t_43[-abv]; + else xr_1d[quotien][reste] = -g_gain * (float)Math.pow(-abv, d43); + } + } + else + { + if (is_1d[j] > 0) xr_1d[quotien][reste] = g_gain * (float)Math.pow(abv, d43); + else xr_1d[quotien][reste] = -g_gain * (float)Math.pow(-abv, d43); + } + } + } + + // apply formula per block type + for (j=0; j= 36)) )) + { + + t_index = (index - cb_begin) / cb_width; + /* xr[sb][ss] *= pow(2.0, ((-2.0 * gr_info.subblock_gain[t_index]) + -(0.5 * (1.0 + gr_info.scalefac_scale) + * scalefac[ch].s[t_index][cb]))); */ + int idx = scalefac[ch].s[t_index][cb] + << gr_info.scalefac_scale; + idx += (gr_info.subblock_gain[t_index] << 2); + + xr_1d[quotien][reste] *= two_to_negative_half_pow[idx]; + + } else { // LONG block types 0,1,3 & 1st 2 subbands of switched blocks + /* xr[sb][ss] *= pow(2.0, -0.5 * (1.0+gr_info.scalefac_scale) + * (scalefac[ch].l[cb] + + gr_info.preflag * pretab[cb])); */ + int idx = scalefac[ch].l[cb]; + + if (gr_info.preflag != 0) + idx += pretab[cb]; + + idx = idx << gr_info.scalefac_scale; + xr_1d[quotien][reste] *= two_to_negative_half_pow[idx]; + } + index++; + } + + for (j=nonzero[ch]; j<576; j++) + { + // Modif E.B 02/22/99 + int reste = j % SSLIMIT; + int quotien = (int) ((j-reste)/SSLIMIT); + if(reste < 0) reste = 0; + if(quotien < 0) quotien = 0; + xr_1d[quotien][reste] = 0.0f; + } + + return; + } + + /** + * + */ + private void reorder(float xr[][], int ch, int gr) + { + gr_info_s gr_info = (si.ch[ch].gr[gr]); + int freq, freq3; + int index; + int sfb, sfb_start, sfb_lines; + int src_line, des_line; + float[][] xr_1d = xr; + + if ((gr_info.window_switching_flag !=0) && (gr_info.block_type == 2)) { + + for(index=0; index<576; index++) + out_1d[index] = 0.0f; + + if (gr_info.mixed_block_flag !=0 ) { + // NO REORDER FOR LOW 2 SUBBANDS + for (index = 0; index < 36; index++) + { + // Modif E.B 02/22/99 + int reste = index % SSLIMIT; + int quotien = (int) ((index-reste)/SSLIMIT); + out_1d[index] = xr_1d[quotien][reste]; + } + // REORDERING FOR REST SWITCHED SHORT + /*for( sfb=3,sfb_start=sfBandIndex[sfreq].s[3], + sfb_lines=sfBandIndex[sfreq].s[4] - sfb_start; + sfb < 13; sfb++,sfb_start = sfBandIndex[sfreq].s[sfb], + sfb_lines = sfBandIndex[sfreq].s[sfb+1] - sfb_start ) + {*/ + for( sfb=3; sfb < 13; sfb++) + { + //System.out.println("sfreq="+sfreq+" sfb="+sfb+" sfBandIndex="+sfBandIndex.length+" sfBandIndex[sfreq].s="+sfBandIndex[sfreq].s.length); + sfb_start = sfBandIndex[sfreq].s[sfb]; + sfb_lines = sfBandIndex[sfreq].s[sfb+1] - sfb_start; + + int sfb_start3 = (sfb_start << 2) - sfb_start; + + for(freq=0, freq3=0; freq=3; sfb-- ) { + i = sfBandIndex[sfreq].s[sfb]; + lines = sfBandIndex[sfreq].s[sfb+1] - i; + i = (i << 2) - i + (j+1) * lines - 1; + + while (lines > 0) { + if (ro[1][i/18][i%18] != 0.0f) { + // MDM: in java, array access is very slow. + // Is quicker to compute div and mod values. + //if (ro[1][ss_div[i]][ss_mod[i]] != 0.0f) { + sfbcnt = sfb; + sfb = -10; + lines = -10; + } + + lines--; + i--; + + } // while (lines > 0) + + } // for (sfb=12 ... + sfb = sfbcnt + 1; + + if (sfb > max_sfb) + max_sfb = sfb; + + while(sfb < 12) { + temp = sfBandIndex[sfreq].s[sfb]; + sb = sfBandIndex[sfreq].s[sfb+1] - temp; + i = (temp << 2) - temp + j * sb; + + for ( ; sb > 0; sb--) { + is_pos[i] = scalefac[1].s[j][sfb]; + if (is_pos[i] != 7) + if (lsf) + i_stereo_k_values(is_pos[i], io_type, i); + else + is_ratio[i] = TAN12[is_pos[i]]; + + i++; + } // for (; sb>0... + sfb++; + } // while (sfb < 12) + sfb = sfBandIndex[sfreq].s[10]; + sb = sfBandIndex[sfreq].s[11] - sfb; + sfb = (sfb << 2) - sfb + j * sb; + temp = sfBandIndex[sfreq].s[11]; + sb = sfBandIndex[sfreq].s[12] - temp; + i = (temp << 2) - temp + j * sb; + + for (; sb > 0; sb--) { + is_pos[i] = is_pos[sfb]; + + if (lsf) { + k[0][i] = k[0][sfb]; + k[1][i] = k[1][sfb]; + } else { + is_ratio[i] = is_ratio[sfb]; + } + i++; + } // for (; sb > 0 ... + } + if (max_sfb <= 3) { + i = 2; + ss = 17; + sb = -1; + while (i >= 0) { + if (ro[1][i][ss] != 0.0f) { + sb = (i<<4) + (i<<1) + ss; + i = -1; + } else { + ss--; + if (ss < 0) { + i--; + ss = 17; + } + } // if (ro ... + } // while (i>=0) + i = 0; + while (sfBandIndex[sfreq].l[i] <= sb) + i++; + sfb = i; + i = sfBandIndex[sfreq].l[i]; + for (; sfb<8; sfb++) { + sb = sfBandIndex[sfreq].l[sfb+1]-sfBandIndex[sfreq].l[sfb]; + for (; sb>0; sb--) { + is_pos[i] = scalefac[1].l[sfb]; + if (is_pos[i] != 7) + if (lsf) + i_stereo_k_values(is_pos[i], io_type, i); + else + is_ratio[i] = TAN12[is_pos[i]]; + i++; + } // for (; sb>0 ... + } // for (; sfb<8 ... + } // for (j=0 ... + } else { // if (gr_info.mixed_block_flag) + for (int j=0; j<3; j++) { + int sfbcnt; + sfbcnt = -1; + for( sfb=12; sfb >=0; sfb-- ) + { + temp = sfBandIndex[sfreq].s[sfb]; + lines = sfBandIndex[sfreq].s[sfb+1] - temp; + i = (temp << 2) - temp + (j+1) * lines - 1; + + while (lines > 0) { + if (ro[1][i/18][i%18] != 0.0f) { + // MDM: in java, array access is very slow. + // Is quicker to compute div and mod values. + //if (ro[1][ss_div[i]][ss_mod[i]] != 0.0f) { + sfbcnt = sfb; + sfb = -10; + lines = -10; + } + lines--; + i--; + } // while (lines > 0) */ + + } // for (sfb=12 ... + sfb = sfbcnt + 1; + while(sfb<12) { + temp = sfBandIndex[sfreq].s[sfb]; + sb = sfBandIndex[sfreq].s[sfb+1] - temp; + i = (temp << 2) - temp + j * sb; + for ( ; sb > 0; sb--) { + is_pos[i] = scalefac[1].s[j][sfb]; + if (is_pos[i] != 7) + if (lsf) + i_stereo_k_values(is_pos[i], io_type, i); + else + is_ratio[i] = TAN12[is_pos[i]]; + i++; + } // for (; sb>0 ... + sfb++; + } // while (sfb<12) + + temp = sfBandIndex[sfreq].s[10]; + temp2= sfBandIndex[sfreq].s[11]; + sb = temp2 - temp; + sfb = (temp << 2) - temp + j * sb; + sb = sfBandIndex[sfreq].s[12] - temp2; + i = (temp2 << 2) - temp2 + j * sb; + + for (; sb>0; sb--) { + is_pos[i] = is_pos[sfb]; + + if (lsf) { + k[0][i] = k[0][sfb]; + k[1][i] = k[1][sfb]; + } else { + is_ratio[i] = is_ratio[sfb]; + } + i++; + } // for (; sb>0 ... + } // for (sfb=12 + } // for (j=0 ... + } else { // if (gr_info.window_switching_flag ... + i = 31; + ss = 17; + sb = 0; + while (i >= 0) { + if (ro[1][i][ss] != 0.0f) { + sb = (i<<4) + (i<<1) + ss; + i = -1; + } else { + ss--; + if (ss < 0) { + i--; + ss = 17; + } + } + } + i = 0; + while (sfBandIndex[sfreq].l[i] <= sb) + i++; + + sfb = i; + i = sfBandIndex[sfreq].l[i]; + for (; sfb<21; sfb++) { + sb = sfBandIndex[sfreq].l[sfb+1] - sfBandIndex[sfreq].l[sfb]; + for (; sb > 0; sb--) { + is_pos[i] = scalefac[1].l[sfb]; + if (is_pos[i] != 7) + if (lsf) + i_stereo_k_values(is_pos[i], io_type, i); + else + is_ratio[i] = TAN12[is_pos[i]]; + i++; + } + } + sfb = sfBandIndex[sfreq].l[20]; + for (sb = 576 - sfBandIndex[sfreq].l[21]; (sb > 0) && (i<576); sb--) + { + is_pos[i] = is_pos[sfb]; // error here : i >=576 + + if (lsf) { + k[0][i] = k[0][sfb]; + k[1][i] = k[1][sfb]; + } else { + is_ratio[i] = is_ratio[sfb]; + } + i++; + } // if (gr_info.mixed_block_flag) + } // if (gr_info.window_switching_flag ... + } // if (i_stereo) + + i = 0; + for(sb=0;sb 32767.0f) ? 32767 : + ((sample < -32768.0f) ? -32768 : + (short) sample)); + } + + /** + * Write the samples to the file or directly to the audio hardware. + */ + public abstract void write_buffer(int val); + public abstract void close(); + + /** + * Clears all data in the buffer (for seeking). + */ + public abstract void clear_buffer(); + + /** + * Notify the buffer that the user has stopped the stream. + */ + public abstract void set_stop_flag(); +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/OutputChannels.java b/src/lwjgl/java/javazoom/jl/decoder/OutputChannels.java new file mode 100644 index 0000000..7197306 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/OutputChannels.java @@ -0,0 +1,143 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial implementation. mdm@techie.com. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + + +/** + * A Type-safe representation of the the supported output channel + * constants. + * + * This class is immutable and, hence, is thread safe. + * + * @author Mat McGowan 12/12/99 + * @since 0.0.7 + */ +public class OutputChannels +{ + /** + * Flag to indicate output should include both channels. + */ + public static final int BOTH_CHANNELS = 0; + + /** + * Flag to indicate output should include the left channel only. + */ + public static final int LEFT_CHANNEL = 1; + + /** + * Flag to indicate output should include the right channel only. + */ + public static final int RIGHT_CHANNEL = 2; + + /** + * Flag to indicate output is mono. + */ + public static final int DOWNMIX_CHANNELS = 3; + + + public static final OutputChannels LEFT = new OutputChannels(LEFT_CHANNEL); + public static final OutputChannels RIGHT = new OutputChannels(RIGHT_CHANNEL); + public static final OutputChannels BOTH = new OutputChannels(BOTH_CHANNELS); + public static final OutputChannels DOWNMIX = new OutputChannels(DOWNMIX_CHANNELS); + + + private /*final*/ int outputChannels; + + /** + * Creates an OutputChannels instance + * corresponding to the given channel code. + * + * @param code one of the OutputChannels channel code constants. + * + * @throws IllegalArgumentException if code is not a valid + * channel code. + */ + public static OutputChannels fromInt(int code) + { + switch (code) + { + case LEFT_CHANNEL: + return LEFT; + case RIGHT_CHANNEL: + return RIGHT; + case BOTH_CHANNELS: + return BOTH; + case DOWNMIX_CHANNELS: + return DOWNMIX; + default: + throw new IllegalArgumentException("Invalid channel code: "+code); + } + } + + private OutputChannels(int channels) + { + outputChannels = channels; + + if (channels<0 || channels>3) + throw new IllegalArgumentException("channels"); + } + + /** + * Retrieves the code representing the desired output channels. + * Will be one of LEFT_CHANNEL, RIGHT_CHANNEL, BOTH_CHANNELS + * or DOWNMIX_CHANNELS. + * + * @return the channel code represented by this instance. + */ + public int getChannelsOutputCode() + { + return outputChannels; + } + + /** + * Retrieves the number of output channels represented + * by this channel output type. + * + * @return The number of output channels for this channel output + * type. This will be 2 for BOTH_CHANNELS only, and 1 + * for all other types. + */ + public int getChannelCount() + { + int count = (outputChannels==BOTH_CHANNELS) ? 2 : 1; + return count; + } + + + public boolean equals(Object o) + { + boolean equals = false; + + if (o instanceof OutputChannels) + { + OutputChannels oc = (OutputChannels)o; + equals = (oc.outputChannels == outputChannels); + } + + return equals; + } + + public int hashCode() + { + return outputChannels; + } + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/SampleBuffer.java b/src/lwjgl/java/javazoom/jl/decoder/SampleBuffer.java new file mode 100644 index 0000000..00b9f1b --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/SampleBuffer.java @@ -0,0 +1,132 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 12/12/99 Initial Version based on FileObuffer. mdm@techie.com. + * + * FileObuffer: + * 15/02/99 Java Conversion by E.B ,javalayer@javazoom.net + * + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * The SampleBuffer class implements an output buffer + * that provides storage for a fixed size block of samples. + */ +public class SampleBuffer extends Obuffer +{ + private short[] buffer; + private int[] bufferp; + private int channels; + private int frequency; + + /** + * Constructor + */ + public SampleBuffer(int sample_frequency, int number_of_channels) + { + buffer = new short[OBUFFERSIZE]; + bufferp = new int[MAXCHANNELS]; + channels = number_of_channels; + frequency = sample_frequency; + + for (int i = 0; i < number_of_channels; ++i) + bufferp[i] = (short)i; + + } + + public int getChannelCount() + { + return this.channels; + } + + public int getSampleFrequency() + { + return this.frequency; + } + + public short[] getBuffer() + { + return this.buffer; + } + + public int getBufferLength() + { + return bufferp[0]; + } + + /** + * Takes a 16 Bit PCM sample. + */ + public void append(int channel, short value) + { + buffer[bufferp[channel]] = value; + bufferp[channel] += channels; + } + + public void appendSamples(int channel, float[] f) + { + int pos = bufferp[channel]; + + short s; + float fs; + for (int i=0; i<32;) + { + fs = f[i++]; + fs = (fs>32767.0f ? 32767.0f + : (fs < -32767.0f ? -32767.0f : fs)); + + s = (short)fs; + buffer[pos] = s; + pos += channels; + } + + bufferp[channel] = pos; + } + + + /** + * Write the samples to the file (Random Access). + */ + public void write_buffer(int val) + { + + //for (int i = 0; i < channels; ++i) + // bufferp[i] = (short)i; + + } + + public void close() + {} + + /** + * + */ + public void clear_buffer() + { + for (int i = 0; i < channels; ++i) + bufferp[i] = (short)i; + } + + /** + * + */ + public void set_stop_flag() + {} +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/Source.java b/src/lwjgl/java/javazoom/jl/decoder/Source.java new file mode 100644 index 0000000..9d6a5d7 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/Source.java @@ -0,0 +1,49 @@ +/* + * 11/19/04 1.0 moved to LGPL. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.IOException; + +/** + * Work in progress. + * + * Class to describe a seekable data source. + * + */ +public interface Source +{ + + public static final long LENGTH_UNKNOWN = -1; + + public int read(byte[] b, int offs, int len) + throws IOException; + + + public boolean willReadBlock(); + + public boolean isSeekable(); + + public long length(); + + public long tell(); + + public long seek(long pos); + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/SynthesisFilter.java b/src/lwjgl/java/javazoom/jl/decoder/SynthesisFilter.java new file mode 100644 index 0000000..ea6e1a7 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/SynthesisFilter.java @@ -0,0 +1,1815 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 04/01/00 Fixes for running under build 23xx Microsoft JVM. mdm. + * + * 19/12/99 Performance improvements to compute_pcm_samples(). + * Mat McGowan. mdm@techie.com. + * + * 16/02/99 Java Conversion by E.B , javalayer@javazoom.net + * + * @(#) synthesis_filter.h 1.8, last edit: 6/15/94 16:52:00 + * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de) + * @(#) Berlin University of Technology + * + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ +package javazoom.jl.decoder; + +import java.io.IOException; + +/** + * A class for the synthesis filter bank. + * This class does a fast downsampling from 32, 44.1 or 48 kHz to 8 kHz, if ULAW is defined. + * Frequencies above 4 kHz are removed by ignoring higher subbands. + */ +final class SynthesisFilter +{ + private float[] v1; + private float[] v2; + private float[] actual_v; // v1 or v2 + private int actual_write_pos; // 0-15 + private float[] samples; // 32 new subband samples + private int channel; + private float scalefactor; + private float[] eq; + + /** + * Quality value for controlling CPU usage/quality tradeoff. + */ + /* + private int quality; + + private int v_inc; + + + + public static final int HIGH_QUALITY = 1; + public static final int MEDIUM_QUALITY = 2; + public static final int LOW_QUALITY = 4; + */ + + /** + * Constructor. + * + * The scalefactor scales the calculated float pcm samples to short values + * (raw pcm samples are in [-1.0, 1.0], if no violations occur). + */ + public SynthesisFilter(int channelnumber, float factor, float[] eq0) + { + if (d==null) + { + d = load_d(); + d16 = splitArray(d, 16); + } + + v1 = new float[512]; + v2 = new float[512]; + samples = new float[32]; + channel = channelnumber; + scalefactor = factor; + setEQ(eq); + //setQuality(HIGH_QUALITY); + + reset(); + } + + public void setEQ(float[] eq0) + { + this.eq = eq0; + if (eq==null) + { + eq = new float[32]; + for (int i=0; i<32; i++) + eq[i] = 1.0f; + } + if (eq.length<32) + { + throw new IllegalArgumentException("eq0"); + } + + } + + /* + private void setQuality(int quality0) + { + switch (quality0) + { + case HIGH_QUALITY: + case MEDIUM_QUALITY: + case LOW_QUALITY: + v_inc = 16 * quality0; + quality = quality0; + break; + default : + throw new IllegalArgumentException("Unknown quality value"); + } + } + + public int getQuality() + { + return quality; + } + */ + + /** + * Reset the synthesis filter. + */ + public void reset() + { + //float[] floatp; + // float[] floatp2; + + // initialize v1[] and v2[]: + //for (floatp = v1 + 512, floatp2 = v2 + 512; floatp > v1; ) + // *--floatp = *--floatp2 = 0.0; + for (int p=0;p<512;p++) + v1[p] = v2[p] = 0.0f; + + // initialize samples[]: + //for (floatp = samples + 32; floatp > samples; ) + // *--floatp = 0.0; + for (int p2=0;p2<32;p2++) + samples[p2] = 0.0f; + + actual_v = v1; + actual_write_pos = 15; + } + + + /** + * Inject Sample. + */ + public void input_sample(float sample, int subbandnumber) + { + samples[subbandnumber] = eq[subbandnumber]*sample; + } + + public void input_samples(float[] s) + { + for (int i=31; i>=0; i--) + { + samples[i] = s[i]*eq[i]; + } + } + + /** + * Compute new values via a fast cosine transform. + */ + private void compute_new_v() + { + // p is fully initialized from x1 + //float[] p = _p; + // pp is fully initialized from p + //float[] pp = _pp; + + //float[] new_v = _new_v; + + //float[] new_v = new float[32]; // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3 + //float[] p = new float[16]; + //float[] pp = new float[16]; + + /* + for (int i=31; i>=0; i--) + { + new_v[i] = 0.0f; + } + */ + + float new_v0, new_v1, new_v2, new_v3, new_v4, new_v5, new_v6, new_v7, new_v8, new_v9; + float new_v10, new_v11, new_v12, new_v13, new_v14, new_v15, new_v16, new_v17, new_v18, new_v19; + float new_v20, new_v21, new_v22, new_v23, new_v24, new_v25, new_v26, new_v27, new_v28, new_v29; + float new_v30, new_v31; + + new_v0 = new_v1 = new_v2 = new_v3 = new_v4 = new_v5 = new_v6 = new_v7 = new_v8 = new_v9 = + new_v10 = new_v11 = new_v12 = new_v13 = new_v14 = new_v15 = new_v16 = new_v17 = new_v18 = new_v19 = + new_v20 = new_v21 = new_v22 = new_v23 = new_v24 = new_v25 = new_v26 = new_v27 = new_v28 = new_v29 = + new_v30 = new_v31 = 0.0f; + + +// float[] new_v = new float[32]; // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3 +// float[] p = new float[16]; +// float[] pp = new float[16]; + + float[] s = samples; + + float s0 = s[0]; + float s1 = s[1]; + float s2 = s[2]; + float s3 = s[3]; + float s4 = s[4]; + float s5 = s[5]; + float s6 = s[6]; + float s7 = s[7]; + float s8 = s[8]; + float s9 = s[9]; + float s10 = s[10]; + float s11 = s[11]; + float s12 = s[12]; + float s13 = s[13]; + float s14 = s[14]; + float s15 = s[15]; + float s16 = s[16]; + float s17 = s[17]; + float s18 = s[18]; + float s19 = s[19]; + float s20 = s[20]; + float s21 = s[21]; + float s22 = s[22]; + float s23 = s[23]; + float s24 = s[24]; + float s25 = s[25]; + float s26 = s[26]; + float s27 = s[27]; + float s28 = s[28]; + float s29 = s[29]; + float s30 = s[30]; + float s31 = s[31]; + + float p0 = s0 + s31; + float p1 = s1 + s30; + float p2 = s2 + s29; + float p3 = s3 + s28; + float p4 = s4 + s27; + float p5 = s5 + s26; + float p6 = s6 + s25; + float p7 = s7 + s24; + float p8 = s8 + s23; + float p9 = s9 + s22; + float p10 = s10 + s21; + float p11 = s11 + s20; + float p12 = s12 + s19; + float p13 = s13 + s18; + float p14 = s14 + s17; + float p15 = s15 + s16; + + float pp0 = p0 + p15; + float pp1 = p1 + p14; + float pp2 = p2 + p13; + float pp3 = p3 + p12; + float pp4 = p4 + p11; + float pp5 = p5 + p10; + float pp6 = p6 + p9; + float pp7 = p7 + p8; + float pp8 = (p0 - p15) * cos1_32; + float pp9 = (p1 - p14) * cos3_32; + float pp10 = (p2 - p13) * cos5_32; + float pp11 = (p3 - p12) * cos7_32; + float pp12 = (p4 - p11) * cos9_32; + float pp13 = (p5 - p10) * cos11_32; + float pp14 = (p6 - p9) * cos13_32; + float pp15 = (p7 - p8) * cos15_32; + + p0 = pp0 + pp7; + p1 = pp1 + pp6; + p2 = pp2 + pp5; + p3 = pp3 + pp4; + p4 = (pp0 - pp7) * cos1_16; + p5 = (pp1 - pp6) * cos3_16; + p6 = (pp2 - pp5) * cos5_16; + p7 = (pp3 - pp4) * cos7_16; + p8 = pp8 + pp15; + p9 = pp9 + pp14; + p10 = pp10 + pp13; + p11 = pp11 + pp12; + p12 = (pp8 - pp15) * cos1_16; + p13 = (pp9 - pp14) * cos3_16; + p14 = (pp10 - pp13) * cos5_16; + p15 = (pp11 - pp12) * cos7_16; + + + pp0 = p0 + p3; + pp1 = p1 + p2; + pp2 = (p0 - p3) * cos1_8; + pp3 = (p1 - p2) * cos3_8; + pp4 = p4 + p7; + pp5 = p5 + p6; + pp6 = (p4 - p7) * cos1_8; + pp7 = (p5 - p6) * cos3_8; + pp8 = p8 + p11; + pp9 = p9 + p10; + pp10 = (p8 - p11) * cos1_8; + pp11 = (p9 - p10) * cos3_8; + pp12 = p12 + p15; + pp13 = p13 + p14; + pp14 = (p12 - p15) * cos1_8; + pp15 = (p13 - p14) * cos3_8; + + p0 = pp0 + pp1; + p1 = (pp0 - pp1) * cos1_4; + p2 = pp2 + pp3; + p3 = (pp2 - pp3) * cos1_4; + p4 = pp4 + pp5; + p5 = (pp4 - pp5) * cos1_4; + p6 = pp6 + pp7; + p7 = (pp6 - pp7) * cos1_4; + p8 = pp8 + pp9; + p9 = (pp8 - pp9) * cos1_4; + p10 = pp10 + pp11; + p11 = (pp10 - pp11) * cos1_4; + p12 = pp12 + pp13; + p13 = (pp12 - pp13) * cos1_4; + p14 = pp14 + pp15; + p15 = (pp14 - pp15) * cos1_4; + + // this is pretty insane coding + float tmp1; + new_v19/*36-17*/ = -(new_v4 = (new_v12 = p7) + p5) - p6; + new_v27/*44-17*/ = -p6 - p7 - p4; + new_v6 = (new_v10 = (new_v14 = p15) + p11) + p13; + new_v17/*34-17*/ = -(new_v2 = p15 + p13 + p9) - p14; + new_v21/*38-17*/ = (tmp1 = -p14 - p15 - p10 - p11) - p13; + new_v29/*46-17*/ = -p14 - p15 - p12 - p8; + new_v25/*42-17*/ = tmp1 - p12; + new_v31/*48-17*/ = -p0; + new_v0 = p1; + new_v23/*40-17*/ = -(new_v8 = p3) - p2; + + p0 = (s0 - s31) * cos1_64; + p1 = (s1 - s30) * cos3_64; + p2 = (s2 - s29) * cos5_64; + p3 = (s3 - s28) * cos7_64; + p4 = (s4 - s27) * cos9_64; + p5 = (s5 - s26) * cos11_64; + p6 = (s6 - s25) * cos13_64; + p7 = (s7 - s24) * cos15_64; + p8 = (s8 - s23) * cos17_64; + p9 = (s9 - s22) * cos19_64; + p10 = (s10 - s21) * cos21_64; + p11 = (s11 - s20) * cos23_64; + p12 = (s12 - s19) * cos25_64; + p13 = (s13 - s18) * cos27_64; + p14 = (s14 - s17) * cos29_64; + p15 = (s15 - s16) * cos31_64; + + + pp0 = p0 + p15; + pp1 = p1 + p14; + pp2 = p2 + p13; + pp3 = p3 + p12; + pp4 = p4 + p11; + pp5 = p5 + p10; + pp6 = p6 + p9; + pp7 = p7 + p8; + pp8 = (p0 - p15) * cos1_32; + pp9 = (p1 - p14) * cos3_32; + pp10 = (p2 - p13) * cos5_32; + pp11 = (p3 - p12) * cos7_32; + pp12 = (p4 - p11) * cos9_32; + pp13 = (p5 - p10) * cos11_32; + pp14 = (p6 - p9) * cos13_32; + pp15 = (p7 - p8) * cos15_32; + + + p0 = pp0 + pp7; + p1 = pp1 + pp6; + p2 = pp2 + pp5; + p3 = pp3 + pp4; + p4 = (pp0 - pp7) * cos1_16; + p5 = (pp1 - pp6) * cos3_16; + p6 = (pp2 - pp5) * cos5_16; + p7 = (pp3 - pp4) * cos7_16; + p8 = pp8 + pp15; + p9 = pp9 + pp14; + p10 = pp10 + pp13; + p11 = pp11 + pp12; + p12 = (pp8 - pp15) * cos1_16; + p13 = (pp9 - pp14) * cos3_16; + p14 = (pp10 - pp13) * cos5_16; + p15 = (pp11 - pp12) * cos7_16; + + + pp0 = p0 + p3; + pp1 = p1 + p2; + pp2 = (p0 - p3) * cos1_8; + pp3 = (p1 - p2) * cos3_8; + pp4 = p4 + p7; + pp5 = p5 + p6; + pp6 = (p4 - p7) * cos1_8; + pp7 = (p5 - p6) * cos3_8; + pp8 = p8 + p11; + pp9 = p9 + p10; + pp10 = (p8 - p11) * cos1_8; + pp11 = (p9 - p10) * cos3_8; + pp12 = p12 + p15; + pp13 = p13 + p14; + pp14 = (p12 - p15) * cos1_8; + pp15 = (p13 - p14) * cos3_8; + + + p0 = pp0 + pp1; + p1 = (pp0 - pp1) * cos1_4; + p2 = pp2 + pp3; + p3 = (pp2 - pp3) * cos1_4; + p4 = pp4 + pp5; + p5 = (pp4 - pp5) * cos1_4; + p6 = pp6 + pp7; + p7 = (pp6 - pp7) * cos1_4; + p8 = pp8 + pp9; + p9 = (pp8 - pp9) * cos1_4; + p10 = pp10 + pp11; + p11 = (pp10 - pp11) * cos1_4; + p12 = pp12 + pp13; + p13 = (pp12 - pp13) * cos1_4; + p14 = pp14 + pp15; + p15 = (pp14 - pp15) * cos1_4; + + + // manually doing something that a compiler should handle sucks + // coding like this is hard to read + float tmp2; + new_v5 = (new_v11 = (new_v13 = (new_v15 = p15) + p7) + p11) + + p5 + p13; + new_v7 = (new_v9 = p15 + p11 + p3) + p13; + new_v16/*33-17*/ = -(new_v1 = (tmp1 = p13 + p15 + p9) + p1) - p14; + new_v18/*35-17*/ = -(new_v3 = tmp1 + p5 + p7) - p6 - p14; + + new_v22/*39-17*/ = (tmp1 = -p10 - p11 - p14 - p15) + - p13 - p2 - p3; + new_v20/*37-17*/ = tmp1 - p13 - p5 - p6 - p7; + new_v24/*41-17*/ = tmp1 - p12 - p2 - p3; + new_v26/*43-17*/ = tmp1 - p12 - (tmp2 = p4 + p6 + p7); + new_v30/*47-17*/ = (tmp1 = -p8 - p12 - p14 - p15) - p0; + new_v28/*45-17*/ = tmp1 - tmp2; + + // insert V[0-15] (== new_v[0-15]) into actual v: + // float[] x2 = actual_v + actual_write_pos; + float dest[] = actual_v; + + int pos = actual_write_pos; + + dest[0 + pos] = new_v0; + dest[16 + pos] = new_v1; + dest[32 + pos] = new_v2; + dest[48 + pos] = new_v3; + dest[64 + pos] = new_v4; + dest[80 + pos] = new_v5; + dest[96 + pos] = new_v6; + dest[112 + pos] = new_v7; + dest[128 + pos] = new_v8; + dest[144 + pos] = new_v9; + dest[160 + pos] = new_v10; + dest[176 + pos] = new_v11; + dest[192 + pos] = new_v12; + dest[208 + pos] = new_v13; + dest[224 + pos] = new_v14; + dest[240 + pos] = new_v15; + + // V[16] is always 0.0: + dest[256 + pos] = 0.0f; + + // insert V[17-31] (== -new_v[15-1]) into actual v: + dest[272 + pos] = -new_v15; + dest[288 + pos] = -new_v14; + dest[304 + pos] = -new_v13; + dest[320 + pos] = -new_v12; + dest[336 + pos] = -new_v11; + dest[352 + pos] = -new_v10; + dest[368 + pos] = -new_v9; + dest[384 + pos] = -new_v8; + dest[400 + pos] = -new_v7; + dest[416 + pos] = -new_v6; + dest[432 + pos] = -new_v5; + dest[448 + pos] = -new_v4; + dest[464 + pos] = -new_v3; + dest[480 + pos] = -new_v2; + dest[496 + pos] = -new_v1; + + // insert V[32] (== -new_v[0]) into other v: + dest = (actual_v==v1) ? v2 : v1; + + dest[0 + pos] = -new_v0; + // insert V[33-48] (== new_v[16-31]) into other v: + dest[16 + pos] = new_v16; + dest[32 + pos] = new_v17; + dest[48 + pos] = new_v18; + dest[64 + pos] = new_v19; + dest[80 + pos] = new_v20; + dest[96 + pos] = new_v21; + dest[112 + pos] = new_v22; + dest[128 + pos] = new_v23; + dest[144 + pos] = new_v24; + dest[160 + pos] = new_v25; + dest[176 + pos] = new_v26; + dest[192 + pos] = new_v27; + dest[208 + pos] = new_v28; + dest[224 + pos] = new_v29; + dest[240 + pos] = new_v30; + dest[256 + pos] = new_v31; + + // insert V[49-63] (== new_v[30-16]) into other v: + dest[272 + pos] = new_v30; + dest[288 + pos] = new_v29; + dest[304 + pos] = new_v28; + dest[320 + pos] = new_v27; + dest[336 + pos] = new_v26; + dest[352 + pos] = new_v25; + dest[368 + pos] = new_v24; + dest[384 + pos] = new_v23; + dest[400 + pos] = new_v22; + dest[416 + pos] = new_v21; + dest[432 + pos] = new_v20; + dest[448 + pos] = new_v19; + dest[464 + pos] = new_v18; + dest[480 + pos] = new_v17; + dest[496 + pos] = new_v16; +/* + } + else + { + v1[0 + actual_write_pos] = -new_v0; + // insert V[33-48] (== new_v[16-31]) into other v: + v1[16 + actual_write_pos] = new_v16; + v1[32 + actual_write_pos] = new_v17; + v1[48 + actual_write_pos] = new_v18; + v1[64 + actual_write_pos] = new_v19; + v1[80 + actual_write_pos] = new_v20; + v1[96 + actual_write_pos] = new_v21; + v1[112 + actual_write_pos] = new_v22; + v1[128 + actual_write_pos] = new_v23; + v1[144 + actual_write_pos] = new_v24; + v1[160 + actual_write_pos] = new_v25; + v1[176 + actual_write_pos] = new_v26; + v1[192 + actual_write_pos] = new_v27; + v1[208 + actual_write_pos] = new_v28; + v1[224 + actual_write_pos] = new_v29; + v1[240 + actual_write_pos] = new_v30; + v1[256 + actual_write_pos] = new_v31; + + // insert V[49-63] (== new_v[30-16]) into other v: + v1[272 + actual_write_pos] = new_v30; + v1[288 + actual_write_pos] = new_v29; + v1[304 + actual_write_pos] = new_v28; + v1[320 + actual_write_pos] = new_v27; + v1[336 + actual_write_pos] = new_v26; + v1[352 + actual_write_pos] = new_v25; + v1[368 + actual_write_pos] = new_v24; + v1[384 + actual_write_pos] = new_v23; + v1[400 + actual_write_pos] = new_v22; + v1[416 + actual_write_pos] = new_v21; + v1[432 + actual_write_pos] = new_v20; + v1[448 + actual_write_pos] = new_v19; + v1[464 + actual_write_pos] = new_v18; + v1[480 + actual_write_pos] = new_v17; + v1[496 + actual_write_pos] = new_v16; + } +*/ + } + + /** + * Compute new values via a fast cosine transform. + */ + private void compute_new_v_old() + { + // p is fully initialized from x1 + //float[] p = _p; + // pp is fully initialized from p + //float[] pp = _pp; + + //float[] new_v = _new_v; + + float[] new_v = new float[32]; // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3 + float[] p = new float[16]; + float[] pp = new float[16]; + + + for (int i=31; i>=0; i--) + { + new_v[i] = 0.0f; + } + +// float[] new_v = new float[32]; // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3 +// float[] p = new float[16]; +// float[] pp = new float[16]; + + float[] x1 = samples; + + p[0] = x1[0] + x1[31]; + p[1] = x1[1] + x1[30]; + p[2] = x1[2] + x1[29]; + p[3] = x1[3] + x1[28]; + p[4] = x1[4] + x1[27]; + p[5] = x1[5] + x1[26]; + p[6] = x1[6] + x1[25]; + p[7] = x1[7] + x1[24]; + p[8] = x1[8] + x1[23]; + p[9] = x1[9] + x1[22]; + p[10] = x1[10] + x1[21]; + p[11] = x1[11] + x1[20]; + p[12] = x1[12] + x1[19]; + p[13] = x1[13] + x1[18]; + p[14] = x1[14] + x1[17]; + p[15] = x1[15] + x1[16]; + + pp[0] = p[0] + p[15]; + pp[1] = p[1] + p[14]; + pp[2] = p[2] + p[13]; + pp[3] = p[3] + p[12]; + pp[4] = p[4] + p[11]; + pp[5] = p[5] + p[10]; + pp[6] = p[6] + p[9]; + pp[7] = p[7] + p[8]; + pp[8] = (p[0] - p[15]) * cos1_32; + pp[9] = (p[1] - p[14]) * cos3_32; + pp[10] = (p[2] - p[13]) * cos5_32; + pp[11] = (p[3] - p[12]) * cos7_32; + pp[12] = (p[4] - p[11]) * cos9_32; + pp[13] = (p[5] - p[10]) * cos11_32; + pp[14] = (p[6] - p[9]) * cos13_32; + pp[15] = (p[7] - p[8]) * cos15_32; + + p[0] = pp[0] + pp[7]; + p[1] = pp[1] + pp[6]; + p[2] = pp[2] + pp[5]; + p[3] = pp[3] + pp[4]; + p[4] = (pp[0] - pp[7]) * cos1_16; + p[5] = (pp[1] - pp[6]) * cos3_16; + p[6] = (pp[2] - pp[5]) * cos5_16; + p[7] = (pp[3] - pp[4]) * cos7_16; + p[8] = pp[8] + pp[15]; + p[9] = pp[9] + pp[14]; + p[10] = pp[10] + pp[13]; + p[11] = pp[11] + pp[12]; + p[12] = (pp[8] - pp[15]) * cos1_16; + p[13] = (pp[9] - pp[14]) * cos3_16; + p[14] = (pp[10] - pp[13]) * cos5_16; + p[15] = (pp[11] - pp[12]) * cos7_16; + + + pp[0] = p[0] + p[3]; + pp[1] = p[1] + p[2]; + pp[2] = (p[0] - p[3]) * cos1_8; + pp[3] = (p[1] - p[2]) * cos3_8; + pp[4] = p[4] + p[7]; + pp[5] = p[5] + p[6]; + pp[6] = (p[4] - p[7]) * cos1_8; + pp[7] = (p[5] - p[6]) * cos3_8; + pp[8] = p[8] + p[11]; + pp[9] = p[9] + p[10]; + pp[10] = (p[8] - p[11]) * cos1_8; + pp[11] = (p[9] - p[10]) * cos3_8; + pp[12] = p[12] + p[15]; + pp[13] = p[13] + p[14]; + pp[14] = (p[12] - p[15]) * cos1_8; + pp[15] = (p[13] - p[14]) * cos3_8; + + p[0] = pp[0] + pp[1]; + p[1] = (pp[0] - pp[1]) * cos1_4; + p[2] = pp[2] + pp[3]; + p[3] = (pp[2] - pp[3]) * cos1_4; + p[4] = pp[4] + pp[5]; + p[5] = (pp[4] - pp[5]) * cos1_4; + p[6] = pp[6] + pp[7]; + p[7] = (pp[6] - pp[7]) * cos1_4; + p[8] = pp[8] + pp[9]; + p[9] = (pp[8] - pp[9]) * cos1_4; + p[10] = pp[10] + pp[11]; + p[11] = (pp[10] - pp[11]) * cos1_4; + p[12] = pp[12] + pp[13]; + p[13] = (pp[12] - pp[13]) * cos1_4; + p[14] = pp[14] + pp[15]; + p[15] = (pp[14] - pp[15]) * cos1_4; + + // this is pretty insane coding + float tmp1; + new_v[36-17] = -(new_v[4] = (new_v[12] = p[7]) + p[5]) - p[6]; + new_v[44-17] = -p[6] - p[7] - p[4]; + new_v[6] = (new_v[10] = (new_v[14] = p[15]) + p[11]) + p[13]; + new_v[34-17] = -(new_v[2] = p[15] + p[13] + p[9]) - p[14]; + new_v[38-17] = (tmp1 = -p[14] - p[15] - p[10] - p[11]) - p[13]; + new_v[46-17] = -p[14] - p[15] - p[12] - p[8]; + new_v[42-17] = tmp1 - p[12]; + new_v[48-17] = -p[0]; + new_v[0] = p[1]; + new_v[40-17] = -(new_v[8] = p[3]) - p[2]; + + p[0] = (x1[0] - x1[31]) * cos1_64; + p[1] = (x1[1] - x1[30]) * cos3_64; + p[2] = (x1[2] - x1[29]) * cos5_64; + p[3] = (x1[3] - x1[28]) * cos7_64; + p[4] = (x1[4] - x1[27]) * cos9_64; + p[5] = (x1[5] - x1[26]) * cos11_64; + p[6] = (x1[6] - x1[25]) * cos13_64; + p[7] = (x1[7] - x1[24]) * cos15_64; + p[8] = (x1[8] - x1[23]) * cos17_64; + p[9] = (x1[9] - x1[22]) * cos19_64; + p[10] = (x1[10] - x1[21]) * cos21_64; + p[11] = (x1[11] - x1[20]) * cos23_64; + p[12] = (x1[12] - x1[19]) * cos25_64; + p[13] = (x1[13] - x1[18]) * cos27_64; + p[14] = (x1[14] - x1[17]) * cos29_64; + p[15] = (x1[15] - x1[16]) * cos31_64; + + + pp[0] = p[0] + p[15]; + pp[1] = p[1] + p[14]; + pp[2] = p[2] + p[13]; + pp[3] = p[3] + p[12]; + pp[4] = p[4] + p[11]; + pp[5] = p[5] + p[10]; + pp[6] = p[6] + p[9]; + pp[7] = p[7] + p[8]; + pp[8] = (p[0] - p[15]) * cos1_32; + pp[9] = (p[1] - p[14]) * cos3_32; + pp[10] = (p[2] - p[13]) * cos5_32; + pp[11] = (p[3] - p[12]) * cos7_32; + pp[12] = (p[4] - p[11]) * cos9_32; + pp[13] = (p[5] - p[10]) * cos11_32; + pp[14] = (p[6] - p[9]) * cos13_32; + pp[15] = (p[7] - p[8]) * cos15_32; + + + p[0] = pp[0] + pp[7]; + p[1] = pp[1] + pp[6]; + p[2] = pp[2] + pp[5]; + p[3] = pp[3] + pp[4]; + p[4] = (pp[0] - pp[7]) * cos1_16; + p[5] = (pp[1] - pp[6]) * cos3_16; + p[6] = (pp[2] - pp[5]) * cos5_16; + p[7] = (pp[3] - pp[4]) * cos7_16; + p[8] = pp[8] + pp[15]; + p[9] = pp[9] + pp[14]; + p[10] = pp[10] + pp[13]; + p[11] = pp[11] + pp[12]; + p[12] = (pp[8] - pp[15]) * cos1_16; + p[13] = (pp[9] - pp[14]) * cos3_16; + p[14] = (pp[10] - pp[13]) * cos5_16; + p[15] = (pp[11] - pp[12]) * cos7_16; + + + pp[0] = p[0] + p[3]; + pp[1] = p[1] + p[2]; + pp[2] = (p[0] - p[3]) * cos1_8; + pp[3] = (p[1] - p[2]) * cos3_8; + pp[4] = p[4] + p[7]; + pp[5] = p[5] + p[6]; + pp[6] = (p[4] - p[7]) * cos1_8; + pp[7] = (p[5] - p[6]) * cos3_8; + pp[8] = p[8] + p[11]; + pp[9] = p[9] + p[10]; + pp[10] = (p[8] - p[11]) * cos1_8; + pp[11] = (p[9] - p[10]) * cos3_8; + pp[12] = p[12] + p[15]; + pp[13] = p[13] + p[14]; + pp[14] = (p[12] - p[15]) * cos1_8; + pp[15] = (p[13] - p[14]) * cos3_8; + + + p[0] = pp[0] + pp[1]; + p[1] = (pp[0] - pp[1]) * cos1_4; + p[2] = pp[2] + pp[3]; + p[3] = (pp[2] - pp[3]) * cos1_4; + p[4] = pp[4] + pp[5]; + p[5] = (pp[4] - pp[5]) * cos1_4; + p[6] = pp[6] + pp[7]; + p[7] = (pp[6] - pp[7]) * cos1_4; + p[8] = pp[8] + pp[9]; + p[9] = (pp[8] - pp[9]) * cos1_4; + p[10] = pp[10] + pp[11]; + p[11] = (pp[10] - pp[11]) * cos1_4; + p[12] = pp[12] + pp[13]; + p[13] = (pp[12] - pp[13]) * cos1_4; + p[14] = pp[14] + pp[15]; + p[15] = (pp[14] - pp[15]) * cos1_4; + + + // manually doing something that a compiler should handle sucks + // coding like this is hard to read + float tmp2; + new_v[5] = (new_v[11] = (new_v[13] = (new_v[15] = p[15]) + p[7]) + p[11]) + + p[5] + p[13]; + new_v[7] = (new_v[9] = p[15] + p[11] + p[3]) + p[13]; + new_v[33-17] = -(new_v[1] = (tmp1 = p[13] + p[15] + p[9]) + p[1]) - p[14]; + new_v[35-17] = -(new_v[3] = tmp1 + p[5] + p[7]) - p[6] - p[14]; + + new_v[39-17] = (tmp1 = -p[10] - p[11] - p[14] - p[15]) + - p[13] - p[2] - p[3]; + new_v[37-17] = tmp1 - p[13] - p[5] - p[6] - p[7]; + new_v[41-17] = tmp1 - p[12] - p[2] - p[3]; + new_v[43-17] = tmp1 - p[12] - (tmp2 = p[4] + p[6] + p[7]); + new_v[47-17] = (tmp1 = -p[8] - p[12] - p[14] - p[15]) - p[0]; + new_v[45-17] = tmp1 - tmp2; + + // insert V[0-15] (== new_v[0-15]) into actual v: + x1 = new_v; + // float[] x2 = actual_v + actual_write_pos; + float[] dest = actual_v; + + dest[0 + actual_write_pos] = x1[0]; + dest[16 + actual_write_pos] = x1[1]; + dest[32 + actual_write_pos] = x1[2]; + dest[48 + actual_write_pos] = x1[3]; + dest[64 + actual_write_pos] = x1[4]; + dest[80 + actual_write_pos] = x1[5]; + dest[96 + actual_write_pos] = x1[6]; + dest[112 + actual_write_pos] = x1[7]; + dest[128 + actual_write_pos] = x1[8]; + dest[144 + actual_write_pos] = x1[9]; + dest[160 + actual_write_pos] = x1[10]; + dest[176 + actual_write_pos] = x1[11]; + dest[192 + actual_write_pos] = x1[12]; + dest[208 + actual_write_pos] = x1[13]; + dest[224 + actual_write_pos] = x1[14]; + dest[240 + actual_write_pos] = x1[15]; + + // V[16] is always 0.0: + dest[256 + actual_write_pos] = 0.0f; + + // insert V[17-31] (== -new_v[15-1]) into actual v: + dest[272 + actual_write_pos] = -x1[15]; + dest[288 + actual_write_pos] = -x1[14]; + dest[304 + actual_write_pos] = -x1[13]; + dest[320 + actual_write_pos] = -x1[12]; + dest[336 + actual_write_pos] = -x1[11]; + dest[352 + actual_write_pos] = -x1[10]; + dest[368 + actual_write_pos] = -x1[9]; + dest[384 + actual_write_pos] = -x1[8]; + dest[400 + actual_write_pos] = -x1[7]; + dest[416 + actual_write_pos] = -x1[6]; + dest[432 + actual_write_pos] = -x1[5]; + dest[448 + actual_write_pos] = -x1[4]; + dest[464 + actual_write_pos] = -x1[3]; + dest[480 + actual_write_pos] = -x1[2]; + dest[496 + actual_write_pos] = -x1[1]; + + // insert V[32] (== -new_v[0]) into other v: + + } + + /** + * Compute PCM Samples. + */ + + private float[] _tmpOut = new float[32]; + + + private void compute_pcm_samples0(Obuffer buffer) + { + final float[] vp = actual_v; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + float pcm_sample; + final float[] dp = d16[i]; + pcm_sample = (float)(((vp[0 + dvp] * dp[0]) + + (vp[15 + dvp] * dp[1]) + + (vp[14 + dvp] * dp[2]) + + (vp[13 + dvp] * dp[3]) + + (vp[12 + dvp] * dp[4]) + + (vp[11 + dvp] * dp[5]) + + (vp[10 + dvp] * dp[6]) + + (vp[9 + dvp] * dp[7]) + + (vp[8 + dvp] * dp[8]) + + (vp[7 + dvp] * dp[9]) + + (vp[6 + dvp] * dp[10]) + + (vp[5 + dvp] * dp[11]) + + (vp[4 + dvp] * dp[12]) + + (vp[3 + dvp] * dp[13]) + + (vp[2 + dvp] * dp[14]) + + (vp[1 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples1(Obuffer buffer) + { + final float[] vp = actual_v; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[1 + dvp] * dp[0]) + + (vp[0 + dvp] * dp[1]) + + (vp[15 + dvp] * dp[2]) + + (vp[14 + dvp] * dp[3]) + + (vp[13 + dvp] * dp[4]) + + (vp[12 + dvp] * dp[5]) + + (vp[11 + dvp] * dp[6]) + + (vp[10 + dvp] * dp[7]) + + (vp[9 + dvp] * dp[8]) + + (vp[8 + dvp] * dp[9]) + + (vp[7 + dvp] * dp[10]) + + (vp[6 + dvp] * dp[11]) + + (vp[5 + dvp] * dp[12]) + + (vp[4 + dvp] * dp[13]) + + (vp[3 + dvp] * dp[14]) + + (vp[2 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + private void compute_pcm_samples2(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[2 + dvp] * dp[0]) + + (vp[1 + dvp] * dp[1]) + + (vp[0 + dvp] * dp[2]) + + (vp[15 + dvp] * dp[3]) + + (vp[14 + dvp] * dp[4]) + + (vp[13 + dvp] * dp[5]) + + (vp[12 + dvp] * dp[6]) + + (vp[11 + dvp] * dp[7]) + + (vp[10 + dvp] * dp[8]) + + (vp[9 + dvp] * dp[9]) + + (vp[8 + dvp] * dp[10]) + + (vp[7 + dvp] * dp[11]) + + (vp[6 + dvp] * dp[12]) + + (vp[5 + dvp] * dp[13]) + + (vp[4 + dvp] * dp[14]) + + (vp[3 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples3(Obuffer buffer) + { + final float[] vp = actual_v; + + int idx = 0; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[3 + dvp] * dp[0]) + + (vp[2 + dvp] * dp[1]) + + (vp[1 + dvp] * dp[2]) + + (vp[0 + dvp] * dp[3]) + + (vp[15 + dvp] * dp[4]) + + (vp[14 + dvp] * dp[5]) + + (vp[13 + dvp] * dp[6]) + + (vp[12 + dvp] * dp[7]) + + (vp[11 + dvp] * dp[8]) + + (vp[10 + dvp] * dp[9]) + + (vp[9 + dvp] * dp[10]) + + (vp[8 + dvp] * dp[11]) + + (vp[7 + dvp] * dp[12]) + + (vp[6 + dvp] * dp[13]) + + (vp[5 + dvp] * dp[14]) + + (vp[4 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples4(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[4 + dvp] * dp[0]) + + (vp[3 + dvp] * dp[1]) + + (vp[2 + dvp] * dp[2]) + + (vp[1 + dvp] * dp[3]) + + (vp[0 + dvp] * dp[4]) + + (vp[15 + dvp] * dp[5]) + + (vp[14 + dvp] * dp[6]) + + (vp[13 + dvp] * dp[7]) + + (vp[12 + dvp] * dp[8]) + + (vp[11 + dvp] * dp[9]) + + (vp[10 + dvp] * dp[10]) + + (vp[9 + dvp] * dp[11]) + + (vp[8 + dvp] * dp[12]) + + (vp[7 + dvp] * dp[13]) + + (vp[6 + dvp] * dp[14]) + + (vp[5 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples5(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[5 + dvp] * dp[0]) + + (vp[4 + dvp] * dp[1]) + + (vp[3 + dvp] * dp[2]) + + (vp[2 + dvp] * dp[3]) + + (vp[1 + dvp] * dp[4]) + + (vp[0 + dvp] * dp[5]) + + (vp[15 + dvp] * dp[6]) + + (vp[14 + dvp] * dp[7]) + + (vp[13 + dvp] * dp[8]) + + (vp[12 + dvp] * dp[9]) + + (vp[11 + dvp] * dp[10]) + + (vp[10 + dvp] * dp[11]) + + (vp[9 + dvp] * dp[12]) + + (vp[8 + dvp] * dp[13]) + + (vp[7 + dvp] * dp[14]) + + (vp[6 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples6(Obuffer buffer) + { + final float[] vp = actual_v; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[6 + dvp] * dp[0]) + + (vp[5 + dvp] * dp[1]) + + (vp[4 + dvp] * dp[2]) + + (vp[3 + dvp] * dp[3]) + + (vp[2 + dvp] * dp[4]) + + (vp[1 + dvp] * dp[5]) + + (vp[0 + dvp] * dp[6]) + + (vp[15 + dvp] * dp[7]) + + (vp[14 + dvp] * dp[8]) + + (vp[13 + dvp] * dp[9]) + + (vp[12 + dvp] * dp[10]) + + (vp[11 + dvp] * dp[11]) + + (vp[10 + dvp] * dp[12]) + + (vp[9 + dvp] * dp[13]) + + (vp[8 + dvp] * dp[14]) + + (vp[7 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples7(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[7 + dvp] * dp[0]) + + (vp[6 + dvp] * dp[1]) + + (vp[5 + dvp] * dp[2]) + + (vp[4 + dvp] * dp[3]) + + (vp[3 + dvp] * dp[4]) + + (vp[2 + dvp] * dp[5]) + + (vp[1 + dvp] * dp[6]) + + (vp[0 + dvp] * dp[7]) + + (vp[15 + dvp] * dp[8]) + + (vp[14 + dvp] * dp[9]) + + (vp[13 + dvp] * dp[10]) + + (vp[12 + dvp] * dp[11]) + + (vp[11 + dvp] * dp[12]) + + (vp[10 + dvp] * dp[13]) + + (vp[9 + dvp] * dp[14]) + + (vp[8 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + private void compute_pcm_samples8(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[8 + dvp] * dp[0]) + + (vp[7 + dvp] * dp[1]) + + (vp[6 + dvp] * dp[2]) + + (vp[5 + dvp] * dp[3]) + + (vp[4 + dvp] * dp[4]) + + (vp[3 + dvp] * dp[5]) + + (vp[2 + dvp] * dp[6]) + + (vp[1 + dvp] * dp[7]) + + (vp[0 + dvp] * dp[8]) + + (vp[15 + dvp] * dp[9]) + + (vp[14 + dvp] * dp[10]) + + (vp[13 + dvp] * dp[11]) + + (vp[12 + dvp] * dp[12]) + + (vp[11 + dvp] * dp[13]) + + (vp[10 + dvp] * dp[14]) + + (vp[9 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples9(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[9 + dvp] * dp[0]) + + (vp[8 + dvp] * dp[1]) + + (vp[7 + dvp] * dp[2]) + + (vp[6 + dvp] * dp[3]) + + (vp[5 + dvp] * dp[4]) + + (vp[4 + dvp] * dp[5]) + + (vp[3 + dvp] * dp[6]) + + (vp[2 + dvp] * dp[7]) + + (vp[1 + dvp] * dp[8]) + + (vp[0 + dvp] * dp[9]) + + (vp[15 + dvp] * dp[10]) + + (vp[14 + dvp] * dp[11]) + + (vp[13 + dvp] * dp[12]) + + (vp[12 + dvp] * dp[13]) + + (vp[11 + dvp] * dp[14]) + + (vp[10 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples10(Obuffer buffer) + { + final float[] vp = actual_v; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[10 + dvp] * dp[0]) + + (vp[9 + dvp] * dp[1]) + + (vp[8 + dvp] * dp[2]) + + (vp[7 + dvp] * dp[3]) + + (vp[6 + dvp] * dp[4]) + + (vp[5 + dvp] * dp[5]) + + (vp[4 + dvp] * dp[6]) + + (vp[3 + dvp] * dp[7]) + + (vp[2 + dvp] * dp[8]) + + (vp[1 + dvp] * dp[9]) + + (vp[0 + dvp] * dp[10]) + + (vp[15 + dvp] * dp[11]) + + (vp[14 + dvp] * dp[12]) + + (vp[13 + dvp] * dp[13]) + + (vp[12 + dvp] * dp[14]) + + (vp[11 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + private void compute_pcm_samples11(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[11 + dvp] * dp[0]) + + (vp[10 + dvp] * dp[1]) + + (vp[9 + dvp] * dp[2]) + + (vp[8 + dvp] * dp[3]) + + (vp[7 + dvp] * dp[4]) + + (vp[6 + dvp] * dp[5]) + + (vp[5 + dvp] * dp[6]) + + (vp[4 + dvp] * dp[7]) + + (vp[3 + dvp] * dp[8]) + + (vp[2 + dvp] * dp[9]) + + (vp[1 + dvp] * dp[10]) + + (vp[0 + dvp] * dp[11]) + + (vp[15 + dvp] * dp[12]) + + (vp[14 + dvp] * dp[13]) + + (vp[13 + dvp] * dp[14]) + + (vp[12 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + private void compute_pcm_samples12(Obuffer buffer) + { + final float[] vp = actual_v; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[12 + dvp] * dp[0]) + + (vp[11 + dvp] * dp[1]) + + (vp[10 + dvp] * dp[2]) + + (vp[9 + dvp] * dp[3]) + + (vp[8 + dvp] * dp[4]) + + (vp[7 + dvp] * dp[5]) + + (vp[6 + dvp] * dp[6]) + + (vp[5 + dvp] * dp[7]) + + (vp[4 + dvp] * dp[8]) + + (vp[3 + dvp] * dp[9]) + + (vp[2 + dvp] * dp[10]) + + (vp[1 + dvp] * dp[11]) + + (vp[0 + dvp] * dp[12]) + + (vp[15 + dvp] * dp[13]) + + (vp[14 + dvp] * dp[14]) + + (vp[13 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + private void compute_pcm_samples13(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[13 + dvp] * dp[0]) + + (vp[12 + dvp] * dp[1]) + + (vp[11 + dvp] * dp[2]) + + (vp[10 + dvp] * dp[3]) + + (vp[9 + dvp] * dp[4]) + + (vp[8 + dvp] * dp[5]) + + (vp[7 + dvp] * dp[6]) + + (vp[6 + dvp] * dp[7]) + + (vp[5 + dvp] * dp[8]) + + (vp[4 + dvp] * dp[9]) + + (vp[3 + dvp] * dp[10]) + + (vp[2 + dvp] * dp[11]) + + (vp[1 + dvp] * dp[12]) + + (vp[0 + dvp] * dp[13]) + + (vp[15 + dvp] * dp[14]) + + (vp[14 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + private void compute_pcm_samples14(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[14 + dvp] * dp[0]) + + (vp[13 + dvp] * dp[1]) + + (vp[12 + dvp] * dp[2]) + + (vp[11 + dvp] * dp[3]) + + (vp[10 + dvp] * dp[4]) + + (vp[9 + dvp] * dp[5]) + + (vp[8 + dvp] * dp[6]) + + (vp[7 + dvp] * dp[7]) + + (vp[6 + dvp] * dp[8]) + + (vp[5 + dvp] * dp[9]) + + (vp[4 + dvp] * dp[10]) + + (vp[3 + dvp] * dp[11]) + + (vp[2 + dvp] * dp[12]) + + (vp[1 + dvp] * dp[13]) + + (vp[0 + dvp] * dp[14]) + + (vp[15 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + private void compute_pcm_samples15(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + float pcm_sample; + final float dp[] = d16[i]; + pcm_sample = (float)(((vp[15 + dvp] * dp[0]) + + (vp[14 + dvp] * dp[1]) + + (vp[13 + dvp] * dp[2]) + + (vp[12 + dvp] * dp[3]) + + (vp[11 + dvp] * dp[4]) + + (vp[10 + dvp] * dp[5]) + + (vp[9 + dvp] * dp[6]) + + (vp[8 + dvp] * dp[7]) + + (vp[7 + dvp] * dp[8]) + + (vp[6 + dvp] * dp[9]) + + (vp[5 + dvp] * dp[10]) + + (vp[4 + dvp] * dp[11]) + + (vp[3 + dvp] * dp[12]) + + (vp[2 + dvp] * dp[13]) + + (vp[1 + dvp] * dp[14]) + + (vp[0 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + dvp += 16; + } // for + } + +private void compute_pcm_samples(Obuffer buffer) +{ + + switch (actual_write_pos) + { + case 0: + compute_pcm_samples0(buffer); + break; + case 1: + compute_pcm_samples1(buffer); + break; + case 2: + compute_pcm_samples2(buffer); + break; + case 3: + compute_pcm_samples3(buffer); + break; + case 4: + compute_pcm_samples4(buffer); + break; + case 5: + compute_pcm_samples5(buffer); + break; + case 6: + compute_pcm_samples6(buffer); + break; + case 7: + compute_pcm_samples7(buffer); + break; + case 8: + compute_pcm_samples8(buffer); + break; + case 9: + compute_pcm_samples9(buffer); + break; + case 10: + compute_pcm_samples10(buffer); + break; + case 11: + compute_pcm_samples11(buffer); + break; + case 12: + compute_pcm_samples12(buffer); + break; + case 13: + compute_pcm_samples13(buffer); + break; + case 14: + compute_pcm_samples14(buffer); + break; + case 15: + compute_pcm_samples15(buffer); + break; + } + + if (buffer!=null) + { + buffer.appendSamples(channel, _tmpOut); + } + +/* + // MDM: I was considering putting in quality control for + // low-spec CPUs, but the performance gain (about 10-15%) + // did not justify the considerable drop in audio quality. + switch (inc) + { + case 16: + buffer.appendSamples(channel, tmpOut); + break; + case 32: + for (int i=0; i<16; i++) + { + buffer.append(channel, (short)tmpOut[i]); + buffer.append(channel, (short)tmpOut[i]); + } + break; + case 64: + for (int i=0; i<8; i++) + { + buffer.append(channel, (short)tmpOut[i]); + buffer.append(channel, (short)tmpOut[i]); + buffer.append(channel, (short)tmpOut[i]); + buffer.append(channel, (short)tmpOut[i]); + } + break; + + } +*/ + } + + /** + * Calculate 32 PCM samples and put the into the Obuffer-object. + */ + + public void calculate_pcm_samples(Obuffer buffer) + { + compute_new_v(); + compute_pcm_samples(buffer); + + actual_write_pos = (actual_write_pos + 1) & 0xf; + actual_v = (actual_v == v1) ? v2 : v1; + + // initialize samples[]: + //for (register float *floatp = samples + 32; floatp > samples; ) + // *--floatp = 0.0f; + + // MDM: this may not be necessary. The Layer III decoder always + // outputs 32 subband samples, but I haven't checked layer I & II. + for (int p=0;p<32;p++) + samples[p] = 0.0f; + } + + + private static final double MY_PI = 3.14159265358979323846; + private static final float cos1_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI / 64.0))); + private static final float cos3_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 64.0))); + private static final float cos5_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 5.0 / 64.0))); + private static final float cos7_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 7.0 / 64.0))); + private static final float cos9_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 9.0 / 64.0))); + private static final float cos11_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 11.0 / 64.0))); + private static final float cos13_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 13.0 / 64.0))); + private static final float cos15_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 15.0 / 64.0))); + private static final float cos17_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 17.0 / 64.0))); + private static final float cos19_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 19.0 / 64.0))); + private static final float cos21_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 21.0 / 64.0))); + private static final float cos23_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 23.0 / 64.0))); + private static final float cos25_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 25.0 / 64.0))); + private static final float cos27_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 27.0 / 64.0))); + private static final float cos29_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 29.0 / 64.0))); + private static final float cos31_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 31.0 / 64.0))); + private static final float cos1_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI / 32.0))); + private static final float cos3_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 32.0))); + private static final float cos5_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 5.0 / 32.0))); + private static final float cos7_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 7.0 / 32.0))); + private static final float cos9_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 9.0 / 32.0))); + private static final float cos11_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 11.0 / 32.0))); + private static final float cos13_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 13.0 / 32.0))); + private static final float cos15_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 15.0 / 32.0))); + private static final float cos1_16 =(float) (1.0 / (2.0 * Math.cos(MY_PI / 16.0))); + private static final float cos3_16 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 16.0))); + private static final float cos5_16 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 5.0 / 16.0))); + private static final float cos7_16 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 7.0 / 16.0))); + private static final float cos1_8 =(float) (1.0 / (2.0 * Math.cos(MY_PI / 8.0))); + private static final float cos3_8 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 8.0))); + private static final float cos1_4 =(float) (1.0 / (2.0 * Math.cos(MY_PI / 4.0))); + + // Note: These values are not in the same order + // as in Annex 3-B.3 of the ISO/IEC DIS 11172-3 + // private float d[] = {0.000000000, -4.000442505}; + + private static float d[] = null; + + /** + * d[] split into subarrays of length 16. This provides for + * more faster access by allowing a block of 16 to be addressed + * with constant offset. + **/ + private static float d16[][] = null; + + /** + * Loads the data for the d[] from the resource SFd.ser. + * @return the loaded values for d[]. + */ + static private float[] load_d() + { + try + { + Class elemType = Float.TYPE; + Object o = JavaLayerUtils.deserializeArrayResource("sfd.ser", elemType, 512); + return (float[])o; + } + catch (IOException ex) + { + throw new ExceptionInInitializerError(ex); + } + } + + /** + * Converts a 1D array into a number of smaller arrays. This is used + * to achieve offset + constant indexing into an array. Each sub-array + * represents a block of values of the original array. + * @param array The array to split up into blocks. + * @param blockSize The size of the blocks to split the array + * into. This must be an exact divisor of + * the length of the array, or some data + * will be lost from the main array. + * + * @return An array of arrays in which each element in the returned + * array will be of length blockSize. + */ + static private float[][] splitArray(final float[] array, final int blockSize) + { + int size = array.length / blockSize; + float[][] split = new float[size][]; + for (int i=0; i array.length) + { + len = array.length-offs; + } + + if (len < 0) + len = 0; + + float[] subarray = new float[len]; + System.arraycopy(array, offs + 0, subarray, 0, len); + + return subarray; + } + + // The original data for d[]. This data is loaded from a file + // to reduce the overall package size and to improve performance. +/* + static final float d_data[] = { + 0.000000000f, -0.000442505f, 0.003250122f, -0.007003784f, + 0.031082153f, -0.078628540f, 0.100311279f, -0.572036743f, + 1.144989014f, 0.572036743f, 0.100311279f, 0.078628540f, + 0.031082153f, 0.007003784f, 0.003250122f, 0.000442505f, + -0.000015259f, -0.000473022f, 0.003326416f, -0.007919312f, + 0.030517578f, -0.084182739f, 0.090927124f, -0.600219727f, + 1.144287109f, 0.543823242f, 0.108856201f, 0.073059082f, + 0.031478882f, 0.006118774f, 0.003173828f, 0.000396729f, + -0.000015259f, -0.000534058f, 0.003387451f, -0.008865356f, + 0.029785156f, -0.089706421f, 0.080688477f, -0.628295898f, + 1.142211914f, 0.515609741f, 0.116577148f, 0.067520142f, + 0.031738281f, 0.005294800f, 0.003082275f, 0.000366211f, + -0.000015259f, -0.000579834f, 0.003433228f, -0.009841919f, + 0.028884888f, -0.095169067f, 0.069595337f, -0.656219482f, + 1.138763428f, 0.487472534f, 0.123474121f, 0.061996460f, + 0.031845093f, 0.004486084f, 0.002990723f, 0.000320435f, + -0.000015259f, -0.000625610f, 0.003463745f, -0.010848999f, + 0.027801514f, -0.100540161f, 0.057617188f, -0.683914185f, + 1.133926392f, 0.459472656f, 0.129577637f, 0.056533813f, + 0.031814575f, 0.003723145f, 0.002899170f, 0.000289917f, + -0.000015259f, -0.000686646f, 0.003479004f, -0.011886597f, + 0.026535034f, -0.105819702f, 0.044784546f, -0.711318970f, + 1.127746582f, 0.431655884f, 0.134887695f, 0.051132202f, + 0.031661987f, 0.003005981f, 0.002792358f, 0.000259399f, + -0.000015259f, -0.000747681f, 0.003479004f, -0.012939453f, + 0.025085449f, -0.110946655f, 0.031082153f, -0.738372803f, + 1.120223999f, 0.404083252f, 0.139450073f, 0.045837402f, + 0.031387329f, 0.002334595f, 0.002685547f, 0.000244141f, + -0.000030518f, -0.000808716f, 0.003463745f, -0.014022827f, + 0.023422241f, -0.115921021f, 0.016510010f, -0.765029907f, + 1.111373901f, 0.376800537f, 0.143264771f, 0.040634155f, + 0.031005859f, 0.001693726f, 0.002578735f, 0.000213623f, + -0.000030518f, -0.000885010f, 0.003417969f, -0.015121460f, + 0.021575928f, -0.120697021f, 0.001068115f, -0.791213989f, + 1.101211548f, 0.349868774f, 0.146362305f, 0.035552979f, + 0.030532837f, 0.001098633f, 0.002456665f, 0.000198364f, + -0.000030518f, -0.000961304f, 0.003372192f, -0.016235352f, + 0.019531250f, -0.125259399f, -0.015228271f, -0.816864014f, + 1.089782715f, 0.323318481f, 0.148773193f, 0.030609131f, + 0.029937744f, 0.000549316f, 0.002349854f, 0.000167847f, + -0.000030518f, -0.001037598f, 0.003280640f, -0.017349243f, + 0.017257690f, -0.129562378f, -0.032379150f, -0.841949463f, + 1.077117920f, 0.297210693f, 0.150497437f, 0.025817871f, + 0.029281616f, 0.000030518f, 0.002243042f, 0.000152588f, + -0.000045776f, -0.001113892f, 0.003173828f, -0.018463135f, + 0.014801025f, -0.133590698f, -0.050354004f, -0.866363525f, + 1.063217163f, 0.271591187f, 0.151596069f, 0.021179199f, + 0.028533936f, -0.000442505f, 0.002120972f, 0.000137329f, + -0.000045776f, -0.001205444f, 0.003051758f, -0.019577026f, + 0.012115479f, -0.137298584f, -0.069168091f, -0.890090942f, + 1.048156738f, 0.246505737f, 0.152069092f, 0.016708374f, + 0.027725220f, -0.000869751f, 0.002014160f, 0.000122070f, + -0.000061035f, -0.001296997f, 0.002883911f, -0.020690918f, + 0.009231567f, -0.140670776f, -0.088775635f, -0.913055420f, + 1.031936646f, 0.221984863f, 0.151962280f, 0.012420654f, + 0.026840210f, -0.001266479f, 0.001907349f, 0.000106812f, + -0.000061035f, -0.001388550f, 0.002700806f, -0.021789551f, + 0.006134033f, -0.143676758f, -0.109161377f, -0.935195923f, + 1.014617920f, 0.198059082f, 0.151306152f, 0.008316040f, + 0.025909424f, -0.001617432f, 0.001785278f, 0.000106812f, + -0.000076294f, -0.001480103f, 0.002487183f, -0.022857666f, + 0.002822876f, -0.146255493f, -0.130310059f, -0.956481934f, + 0.996246338f, 0.174789429f, 0.150115967f, 0.004394531f, + 0.024932861f, -0.001937866f, 0.001693726f, 0.000091553f, + -0.000076294f, -0.001586914f, 0.002227783f, -0.023910522f, + -0.000686646f, -0.148422241f, -0.152206421f, -0.976852417f, + 0.976852417f, 0.152206421f, 0.148422241f, 0.000686646f, + 0.023910522f, -0.002227783f, 0.001586914f, 0.000076294f, + -0.000091553f, -0.001693726f, 0.001937866f, -0.024932861f, + -0.004394531f, -0.150115967f, -0.174789429f, -0.996246338f, + 0.956481934f, 0.130310059f, 0.146255493f, -0.002822876f, + 0.022857666f, -0.002487183f, 0.001480103f, 0.000076294f, + -0.000106812f, -0.001785278f, 0.001617432f, -0.025909424f, + -0.008316040f, -0.151306152f, -0.198059082f, -1.014617920f, + 0.935195923f, 0.109161377f, 0.143676758f, -0.006134033f, + 0.021789551f, -0.002700806f, 0.001388550f, 0.000061035f, + -0.000106812f, -0.001907349f, 0.001266479f, -0.026840210f, + -0.012420654f, -0.151962280f, -0.221984863f, -1.031936646f, + 0.913055420f, 0.088775635f, 0.140670776f, -0.009231567f, + 0.020690918f, -0.002883911f, 0.001296997f, 0.000061035f, + -0.000122070f, -0.002014160f, 0.000869751f, -0.027725220f, + -0.016708374f, -0.152069092f, -0.246505737f, -1.048156738f, + 0.890090942f, 0.069168091f, 0.137298584f, -0.012115479f, + 0.019577026f, -0.003051758f, 0.001205444f, 0.000045776f, + -0.000137329f, -0.002120972f, 0.000442505f, -0.028533936f, + -0.021179199f, -0.151596069f, -0.271591187f, -1.063217163f, + 0.866363525f, 0.050354004f, 0.133590698f, -0.014801025f, + 0.018463135f, -0.003173828f, 0.001113892f, 0.000045776f, + -0.000152588f, -0.002243042f, -0.000030518f, -0.029281616f, + -0.025817871f, -0.150497437f, -0.297210693f, -1.077117920f, + 0.841949463f, 0.032379150f, 0.129562378f, -0.017257690f, + 0.017349243f, -0.003280640f, 0.001037598f, 0.000030518f, + -0.000167847f, -0.002349854f, -0.000549316f, -0.029937744f, + -0.030609131f, -0.148773193f, -0.323318481f, -1.089782715f, + 0.816864014f, 0.015228271f, 0.125259399f, -0.019531250f, + 0.016235352f, -0.003372192f, 0.000961304f, 0.000030518f, + -0.000198364f, -0.002456665f, -0.001098633f, -0.030532837f, + -0.035552979f, -0.146362305f, -0.349868774f, -1.101211548f, + 0.791213989f, -0.001068115f, 0.120697021f, -0.021575928f, + 0.015121460f, -0.003417969f, 0.000885010f, 0.000030518f, + -0.000213623f, -0.002578735f, -0.001693726f, -0.031005859f, + -0.040634155f, -0.143264771f, -0.376800537f, -1.111373901f, + 0.765029907f, -0.016510010f, 0.115921021f, -0.023422241f, + 0.014022827f, -0.003463745f, 0.000808716f, 0.000030518f, + -0.000244141f, -0.002685547f, -0.002334595f, -0.031387329f, + -0.045837402f, -0.139450073f, -0.404083252f, -1.120223999f, + 0.738372803f, -0.031082153f, 0.110946655f, -0.025085449f, + 0.012939453f, -0.003479004f, 0.000747681f, 0.000015259f, + -0.000259399f, -0.002792358f, -0.003005981f, -0.031661987f, + -0.051132202f, -0.134887695f, -0.431655884f, -1.127746582f, + 0.711318970f, -0.044784546f, 0.105819702f, -0.026535034f, + 0.011886597f, -0.003479004f, 0.000686646f, 0.000015259f, + -0.000289917f, -0.002899170f, -0.003723145f, -0.031814575f, + -0.056533813f, -0.129577637f, -0.459472656f, -1.133926392f, + 0.683914185f, -0.057617188f, 0.100540161f, -0.027801514f, + 0.010848999f, -0.003463745f, 0.000625610f, 0.000015259f, + -0.000320435f, -0.002990723f, -0.004486084f, -0.031845093f, + -0.061996460f, -0.123474121f, -0.487472534f, -1.138763428f, + 0.656219482f, -0.069595337f, 0.095169067f, -0.028884888f, + 0.009841919f, -0.003433228f, 0.000579834f, 0.000015259f, + -0.000366211f, -0.003082275f, -0.005294800f, -0.031738281f, + -0.067520142f, -0.116577148f, -0.515609741f, -1.142211914f, + 0.628295898f, -0.080688477f, 0.089706421f, -0.029785156f, + 0.008865356f, -0.003387451f, 0.000534058f, 0.000015259f, + -0.000396729f, -0.003173828f, -0.006118774f, -0.031478882f, + -0.073059082f, -0.108856201f, -0.543823242f, -1.144287109f, + 0.600219727f, -0.090927124f, 0.084182739f, -0.030517578f, + 0.007919312f, -0.003326416f, 0.000473022f, 0.000015259f + }; + */ + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/au2lin.ser b/src/lwjgl/java/javazoom/jl/decoder/au2lin.ser new file mode 100644 index 0000000..0b20bc8 Binary files /dev/null and b/src/lwjgl/java/javazoom/jl/decoder/au2lin.ser differ diff --git a/src/lwjgl/java/javazoom/jl/decoder/huffcodetab.java b/src/lwjgl/java/javazoom/jl/decoder/huffcodetab.java new file mode 100644 index 0000000..3d80f17 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/huffcodetab.java @@ -0,0 +1,600 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 16/11/99 Renamed class, added javadoc, and changed table + * name from String to 3 chars. mdm@techie.com + * 02/15/99 Java Conversion by E.B, javalayer@javazoom.net + * + * 04/19/97 : Adapted from the ISO MPEG Audio Subgroup Software Simulation + * Group's public c source for its MPEG audio decoder. Miscellaneous + * changes by Jeff Tsay (ctsay@pasteur.eecs.berkeley.edu). + *----------------------------------------------------------------------- + * Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reserved + * MPEG/audio coding/decoding software, work in progress + * NOT for public distribution until verified and approved by the + * MPEG/audio committee. For further information, please contact + * Davis Pan, 508-493-2241, e-mail: pan@3d.enet.dec.com + * + * VERSION 4.1 + * changes made since last update: + * date programmers comment + * 27.2.92 F.O.Witte (ITT Intermetall) + * 8/24/93 M. Iwadare Changed for 1 pass decoding. + * 7/14/94 J. Koller useless 'typedef' before huffcodetab removed + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Class that implements a Huffman decoder. + */ +final class huffcodetab +{ + private static final int MXOFF=250; + private static final int HTN=34; + + private char tablename0 = ' '; /* string, containing table_description */ + private char tablename1 = ' '; /* string, containing table_description */ + private char tablename2 = ' '; /* string, containing table_description */ + + private int xlen; /* max. x-index+ */ + private int ylen; /* max. y-index+ */ + private int linbits; /* number of linbits */ + private int linmax; /* max number to be stored in linbits */ + private int ref; /* a positive value indicates a reference */ + private int[] table=null; /* pointer to array[xlen][ylen] */ + private int[] hlen=null; /* pointer to array[xlen][ylen] */ + private int[][] val=null; /* decoder tree */ + private int treelen; /* length of decoder tree */ + + private static int ValTab0[][] = { + {0,0} // dummy + }; + + private static int ValTab1[][] = { + {2,1},{0,0},{2,1},{0,16},{2,1},{0,1},{0,17}, + }; + + private static int ValTab2[][] = { + {2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{2,1},{0,17},{4,1},{2,1}, + {0,32},{0,33},{2,1},{0,18},{2,1},{0,2},{0,34}, + }; + + private static int ValTab3[][] = { + {4,1},{2,1},{0,0},{0,1},{2,1},{0,17},{2,1},{0,16},{4,1},{2,1}, + {0,32},{0,33},{2,1},{0,18},{2,1},{0,2},{0,34}, + }; + + private static int ValTab4[][] = {{0,0}}; // dummy + + private static int ValTab5[][] = { + {2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{2,1},{0,17},{8,1},{4,1}, + {2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{8,1},{4,1},{2,1},{0,34}, + {0,48},{2,1},{0,3},{0,19},{2,1},{0,49},{2,1},{0,50},{2,1},{0,35}, + {0,51}, + }; + + private static int ValTab6[][] = { + {6,1},{4,1},{2,1},{0,0},{0,16},{0,17},{6,1},{2,1},{0,1},{2,1}, + {0,32},{0,33},{6,1},{2,1},{0,18},{2,1},{0,2},{0,34},{4,1},{2,1}, + {0,49},{0,19},{4,1},{2,1},{0,48},{0,50},{2,1},{0,35},{2,1},{0,3}, + {0,51}, + }; + + private static int ValTab7[][] = { + {2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{8,1},{2,1},{0,17},{4,1}, + {2,1},{0,32},{0,2},{0,33},{18,1},{6,1},{2,1},{0,18},{2,1},{0,34}, + {0,48},{4,1},{2,1},{0,49},{0,19},{4,1},{2,1},{0,3},{0,50},{2,1}, + {0,35},{0,4},{10,1},{4,1},{2,1},{0,64},{0,65},{2,1},{0,20},{2,1}, + {0,66},{0,36},{12,1},{6,1},{4,1},{2,1},{0,51},{0,67},{0,80},{4,1}, + {2,1},{0,52},{0,5},{0,81},{6,1},{2,1},{0,21},{2,1},{0,82},{0,37}, + {4,1},{2,1},{0,68},{0,53},{4,1},{2,1},{0,83},{0,84},{2,1},{0,69}, + {0,85}, + }; + + private static int ValTab8[][] = { + {6,1},{2,1},{0,0},{2,1},{0,16},{0,1},{2,1},{0,17},{4,1},{2,1}, + {0,33},{0,18},{14,1},{4,1},{2,1},{0,32},{0,2},{2,1},{0,34},{4,1}, + {2,1},{0,48},{0,3},{2,1},{0,49},{0,19},{14,1},{8,1},{4,1},{2,1}, + {0,50},{0,35},{2,1},{0,64},{0,4},{2,1},{0,65},{2,1},{0,20},{0,66}, + {12,1},{6,1},{2,1},{0,36},{2,1},{0,51},{0,80},{4,1},{2,1},{0,67}, + {0,52},{0,81},{6,1},{2,1},{0,21},{2,1},{0,5},{0,82},{6,1},{2,1}, + {0,37},{2,1},{0,68},{0,53},{2,1},{0,83},{2,1},{0,69},{2,1},{0,84}, + {0,85}, + }; + + private static int ValTab9[][] = { + {8,1},{4,1},{2,1},{0,0},{0,16},{2,1},{0,1},{0,17},{10,1},{4,1}, + {2,1},{0,32},{0,33},{2,1},{0,18},{2,1},{0,2},{0,34},{12,1},{6,1}, + {4,1},{2,1},{0,48},{0,3},{0,49},{2,1},{0,19},{2,1},{0,50},{0,35}, + {12,1},{4,1},{2,1},{0,65},{0,20},{4,1},{2,1},{0,64},{0,51},{2,1}, + {0,66},{0,36},{10,1},{6,1},{4,1},{2,1},{0,4},{0,80},{0,67},{2,1}, + {0,52},{0,81},{8,1},{4,1},{2,1},{0,21},{0,82},{2,1},{0,37},{0,68}, + {6,1},{4,1},{2,1},{0,5},{0,84},{0,83},{2,1},{0,53},{2,1},{0,69}, + {0,85}, + }; + + private static int ValTab10[][] = { + {2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{10,1},{2,1},{0,17},{4,1}, + {2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{28,1},{8,1},{4,1},{2,1}, + {0,34},{0,48},{2,1},{0,49},{0,19},{8,1},{4,1},{2,1},{0,3},{0,50}, + {2,1},{0,35},{0,64},{4,1},{2,1},{0,65},{0,20},{4,1},{2,1},{0,4}, + {0,51},{2,1},{0,66},{0,36},{28,1},{10,1},{6,1},{4,1},{2,1},{0,80}, + {0,5},{0,96},{2,1},{0,97},{0,22},{12,1},{6,1},{4,1},{2,1},{0,67}, + {0,52},{0,81},{2,1},{0,21},{2,1},{0,82},{0,37},{4,1},{2,1},{0,38}, + {0,54},{0,113},{20,1},{8,1},{2,1},{0,23},{4,1},{2,1},{0,68},{0,83}, + {0,6},{6,1},{4,1},{2,1},{0,53},{0,69},{0,98},{2,1},{0,112},{2,1}, + {0,7},{0,100},{14,1},{4,1},{2,1},{0,114},{0,39},{6,1},{2,1},{0,99}, + {2,1},{0,84},{0,85},{2,1},{0,70},{0,115},{8,1},{4,1},{2,1},{0,55}, + {0,101},{2,1},{0,86},{0,116},{6,1},{2,1},{0,71},{2,1},{0,102},{0,117}, + {4,1},{2,1},{0,87},{0,118},{2,1},{0,103},{0,119}, + }; + + private static int ValTab11[][] = { + {6,1},{2,1},{0,0},{2,1},{0,16},{0,1},{8,1},{2,1},{0,17},{4,1}, + {2,1},{0,32},{0,2},{0,18},{24,1},{8,1},{2,1},{0,33},{2,1},{0,34}, + {2,1},{0,48},{0,3},{4,1},{2,1},{0,49},{0,19},{4,1},{2,1},{0,50}, + {0,35},{4,1},{2,1},{0,64},{0,4},{2,1},{0,65},{0,20},{30,1},{16,1}, + {10,1},{4,1},{2,1},{0,66},{0,36},{4,1},{2,1},{0,51},{0,67},{0,80}, + {4,1},{2,1},{0,52},{0,81},{0,97},{6,1},{2,1},{0,22},{2,1},{0,6}, + {0,38},{2,1},{0,98},{2,1},{0,21},{2,1},{0,5},{0,82},{16,1},{10,1}, + {6,1},{4,1},{2,1},{0,37},{0,68},{0,96},{2,1},{0,99},{0,54},{4,1}, + {2,1},{0,112},{0,23},{0,113},{16,1},{6,1},{4,1},{2,1},{0,7},{0,100}, + {0,114},{2,1},{0,39},{4,1},{2,1},{0,83},{0,53},{2,1},{0,84},{0,69}, + {10,1},{4,1},{2,1},{0,70},{0,115},{2,1},{0,55},{2,1},{0,101},{0,86}, + {10,1},{6,1},{4,1},{2,1},{0,85},{0,87},{0,116},{2,1},{0,71},{0,102}, + {4,1},{2,1},{0,117},{0,118},{2,1},{0,103},{0,119}, + }; + + private static int ValTab12[][] = { + {12,1},{4,1},{2,1},{0,16},{0,1},{2,1},{0,17},{2,1},{0,0},{2,1}, + {0,32},{0,2},{16,1},{4,1},{2,1},{0,33},{0,18},{4,1},{2,1},{0,34}, + {0,49},{2,1},{0,19},{2,1},{0,48},{2,1},{0,3},{0,64},{26,1},{8,1}, + {4,1},{2,1},{0,50},{0,35},{2,1},{0,65},{0,51},{10,1},{4,1},{2,1}, + {0,20},{0,66},{2,1},{0,36},{2,1},{0,4},{0,80},{4,1},{2,1},{0,67}, + {0,52},{2,1},{0,81},{0,21},{28,1},{14,1},{8,1},{4,1},{2,1},{0,82}, + {0,37},{2,1},{0,83},{0,53},{4,1},{2,1},{0,96},{0,22},{0,97},{4,1}, + {2,1},{0,98},{0,38},{6,1},{4,1},{2,1},{0,5},{0,6},{0,68},{2,1}, + {0,84},{0,69},{18,1},{10,1},{4,1},{2,1},{0,99},{0,54},{4,1},{2,1}, + {0,112},{0,7},{0,113},{4,1},{2,1},{0,23},{0,100},{2,1},{0,70},{0,114}, + {10,1},{6,1},{2,1},{0,39},{2,1},{0,85},{0,115},{2,1},{0,55},{0,86}, + {8,1},{4,1},{2,1},{0,101},{0,116},{2,1},{0,71},{0,102},{4,1},{2,1}, + {0,117},{0,87},{2,1},{0,118},{2,1},{0,103},{0,119}, + }; + + private static int ValTab13[][] = { + {2,1},{0,0},{6,1},{2,1},{0,16},{2,1},{0,1},{0,17},{28,1},{8,1}, + {4,1},{2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{8,1},{4,1},{2,1}, + {0,34},{0,48},{2,1},{0,3},{0,49},{6,1},{2,1},{0,19},{2,1},{0,50}, + {0,35},{4,1},{2,1},{0,64},{0,4},{0,65},{70,1},{28,1},{14,1},{6,1}, + {2,1},{0,20},{2,1},{0,51},{0,66},{4,1},{2,1},{0,36},{0,80},{2,1}, + {0,67},{0,52},{4,1},{2,1},{0,81},{0,21},{4,1},{2,1},{0,5},{0,82}, + {2,1},{0,37},{2,1},{0,68},{0,83},{14,1},{8,1},{4,1},{2,1},{0,96}, + {0,6},{2,1},{0,97},{0,22},{4,1},{2,1},{0,128},{0,8},{0,129},{16,1}, + {8,1},{4,1},{2,1},{0,53},{0,98},{2,1},{0,38},{0,84},{4,1},{2,1}, + {0,69},{0,99},{2,1},{0,54},{0,112},{6,1},{4,1},{2,1},{0,7},{0,85}, + {0,113},{2,1},{0,23},{2,1},{0,39},{0,55},{72,1},{24,1},{12,1},{4,1}, + {2,1},{0,24},{0,130},{2,1},{0,40},{4,1},{2,1},{0,100},{0,70},{0,114}, + {8,1},{4,1},{2,1},{0,132},{0,72},{2,1},{0,144},{0,9},{2,1},{0,145}, + {0,25},{24,1},{14,1},{8,1},{4,1},{2,1},{0,115},{0,101},{2,1},{0,86}, + {0,116},{4,1},{2,1},{0,71},{0,102},{0,131},{6,1},{2,1},{0,56},{2,1}, + {0,117},{0,87},{2,1},{0,146},{0,41},{14,1},{8,1},{4,1},{2,1},{0,103}, + {0,133},{2,1},{0,88},{0,57},{2,1},{0,147},{2,1},{0,73},{0,134},{6,1}, + {2,1},{0,160},{2,1},{0,104},{0,10},{2,1},{0,161},{0,26},{68,1},{24,1}, + {12,1},{4,1},{2,1},{0,162},{0,42},{4,1},{2,1},{0,149},{0,89},{2,1}, + {0,163},{0,58},{8,1},{4,1},{2,1},{0,74},{0,150},{2,1},{0,176},{0,11}, + {2,1},{0,177},{0,27},{20,1},{8,1},{2,1},{0,178},{4,1},{2,1},{0,118}, + {0,119},{0,148},{6,1},{4,1},{2,1},{0,135},{0,120},{0,164},{4,1},{2,1}, + {0,105},{0,165},{0,43},{12,1},{6,1},{4,1},{2,1},{0,90},{0,136},{0,179}, + {2,1},{0,59},{2,1},{0,121},{0,166},{6,1},{4,1},{2,1},{0,106},{0,180}, + {0,192},{4,1},{2,1},{0,12},{0,152},{0,193},{60,1},{22,1},{10,1},{6,1}, + {2,1},{0,28},{2,1},{0,137},{0,181},{2,1},{0,91},{0,194},{4,1},{2,1}, + {0,44},{0,60},{4,1},{2,1},{0,182},{0,107},{2,1},{0,196},{0,76},{16,1}, + {8,1},{4,1},{2,1},{0,168},{0,138},{2,1},{0,208},{0,13},{2,1},{0,209}, + {2,1},{0,75},{2,1},{0,151},{0,167},{12,1},{6,1},{2,1},{0,195},{2,1}, + {0,122},{0,153},{4,1},{2,1},{0,197},{0,92},{0,183},{4,1},{2,1},{0,29}, + {0,210},{2,1},{0,45},{2,1},{0,123},{0,211},{52,1},{28,1},{12,1},{4,1}, + {2,1},{0,61},{0,198},{4,1},{2,1},{0,108},{0,169},{2,1},{0,154},{0,212}, + {8,1},{4,1},{2,1},{0,184},{0,139},{2,1},{0,77},{0,199},{4,1},{2,1}, + {0,124},{0,213},{2,1},{0,93},{0,224},{10,1},{4,1},{2,1},{0,225},{0,30}, + {4,1},{2,1},{0,14},{0,46},{0,226},{8,1},{4,1},{2,1},{0,227},{0,109}, + {2,1},{0,140},{0,228},{4,1},{2,1},{0,229},{0,186},{0,240},{38,1},{16,1}, + {4,1},{2,1},{0,241},{0,31},{6,1},{4,1},{2,1},{0,170},{0,155},{0,185}, + {2,1},{0,62},{2,1},{0,214},{0,200},{12,1},{6,1},{2,1},{0,78},{2,1}, + {0,215},{0,125},{2,1},{0,171},{2,1},{0,94},{0,201},{6,1},{2,1},{0,15}, + {2,1},{0,156},{0,110},{2,1},{0,242},{0,47},{32,1},{16,1},{6,1},{4,1}, + {2,1},{0,216},{0,141},{0,63},{6,1},{2,1},{0,243},{2,1},{0,230},{0,202}, + {2,1},{0,244},{0,79},{8,1},{4,1},{2,1},{0,187},{0,172},{2,1},{0,231}, + {0,245},{4,1},{2,1},{0,217},{0,157},{2,1},{0,95},{0,232},{30,1},{12,1}, + {6,1},{2,1},{0,111},{2,1},{0,246},{0,203},{4,1},{2,1},{0,188},{0,173}, + {0,218},{8,1},{2,1},{0,247},{4,1},{2,1},{0,126},{0,127},{0,142},{6,1}, + {4,1},{2,1},{0,158},{0,174},{0,204},{2,1},{0,248},{0,143},{18,1},{8,1}, + {4,1},{2,1},{0,219},{0,189},{2,1},{0,234},{0,249},{4,1},{2,1},{0,159}, + {0,235},{2,1},{0,190},{2,1},{0,205},{0,250},{14,1},{4,1},{2,1},{0,221}, + {0,236},{6,1},{4,1},{2,1},{0,233},{0,175},{0,220},{2,1},{0,206},{0,251}, + {8,1},{4,1},{2,1},{0,191},{0,222},{2,1},{0,207},{0,238},{4,1},{2,1}, + {0,223},{0,239},{2,1},{0,255},{2,1},{0,237},{2,1},{0,253},{2,1},{0,252}, + {0,254}, + }; + + private static int ValTab14[][] = { + {0,0} // dummy + }; + + private static int ValTab15[][] = { + {16,1},{6,1},{2,1},{0,0},{2,1},{0,16},{0,1},{2,1},{0,17},{4,1}, + {2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{50,1},{16,1},{6,1},{2,1}, + {0,34},{2,1},{0,48},{0,49},{6,1},{2,1},{0,19},{2,1},{0,3},{0,64}, + {2,1},{0,50},{0,35},{14,1},{6,1},{4,1},{2,1},{0,4},{0,20},{0,65}, + {4,1},{2,1},{0,51},{0,66},{2,1},{0,36},{0,67},{10,1},{6,1},{2,1}, + {0,52},{2,1},{0,80},{0,5},{2,1},{0,81},{0,21},{4,1},{2,1},{0,82}, + {0,37},{4,1},{2,1},{0,68},{0,83},{0,97},{90,1},{36,1},{18,1},{10,1}, + {6,1},{2,1},{0,53},{2,1},{0,96},{0,6},{2,1},{0,22},{0,98},{4,1}, + {2,1},{0,38},{0,84},{2,1},{0,69},{0,99},{10,1},{6,1},{2,1},{0,54}, + {2,1},{0,112},{0,7},{2,1},{0,113},{0,85},{4,1},{2,1},{0,23},{0,100}, + {2,1},{0,114},{0,39},{24,1},{16,1},{8,1},{4,1},{2,1},{0,70},{0,115}, + {2,1},{0,55},{0,101},{4,1},{2,1},{0,86},{0,128},{2,1},{0,8},{0,116}, + {4,1},{2,1},{0,129},{0,24},{2,1},{0,130},{0,40},{16,1},{8,1},{4,1}, + {2,1},{0,71},{0,102},{2,1},{0,131},{0,56},{4,1},{2,1},{0,117},{0,87}, + {2,1},{0,132},{0,72},{6,1},{4,1},{2,1},{0,144},{0,25},{0,145},{4,1}, + {2,1},{0,146},{0,118},{2,1},{0,103},{0,41},{92,1},{36,1},{18,1},{10,1}, + {4,1},{2,1},{0,133},{0,88},{4,1},{2,1},{0,9},{0,119},{0,147},{4,1}, + {2,1},{0,57},{0,148},{2,1},{0,73},{0,134},{10,1},{6,1},{2,1},{0,104}, + {2,1},{0,160},{0,10},{2,1},{0,161},{0,26},{4,1},{2,1},{0,162},{0,42}, + {2,1},{0,149},{0,89},{26,1},{14,1},{6,1},{2,1},{0,163},{2,1},{0,58}, + {0,135},{4,1},{2,1},{0,120},{0,164},{2,1},{0,74},{0,150},{6,1},{4,1}, + {2,1},{0,105},{0,176},{0,177},{4,1},{2,1},{0,27},{0,165},{0,178},{14,1}, + {8,1},{4,1},{2,1},{0,90},{0,43},{2,1},{0,136},{0,151},{2,1},{0,179}, + {2,1},{0,121},{0,59},{8,1},{4,1},{2,1},{0,106},{0,180},{2,1},{0,75}, + {0,193},{4,1},{2,1},{0,152},{0,137},{2,1},{0,28},{0,181},{80,1},{34,1}, + {16,1},{6,1},{4,1},{2,1},{0,91},{0,44},{0,194},{6,1},{4,1},{2,1}, + {0,11},{0,192},{0,166},{2,1},{0,167},{0,122},{10,1},{4,1},{2,1},{0,195}, + {0,60},{4,1},{2,1},{0,12},{0,153},{0,182},{4,1},{2,1},{0,107},{0,196}, + {2,1},{0,76},{0,168},{20,1},{10,1},{4,1},{2,1},{0,138},{0,197},{4,1}, + {2,1},{0,208},{0,92},{0,209},{4,1},{2,1},{0,183},{0,123},{2,1},{0,29}, + {2,1},{0,13},{0,45},{12,1},{4,1},{2,1},{0,210},{0,211},{4,1},{2,1}, + {0,61},{0,198},{2,1},{0,108},{0,169},{6,1},{4,1},{2,1},{0,154},{0,184}, + {0,212},{4,1},{2,1},{0,139},{0,77},{2,1},{0,199},{0,124},{68,1},{34,1}, + {18,1},{10,1},{4,1},{2,1},{0,213},{0,93},{4,1},{2,1},{0,224},{0,14}, + {0,225},{4,1},{2,1},{0,30},{0,226},{2,1},{0,170},{0,46},{8,1},{4,1}, + {2,1},{0,185},{0,155},{2,1},{0,227},{0,214},{4,1},{2,1},{0,109},{0,62}, + {2,1},{0,200},{0,140},{16,1},{8,1},{4,1},{2,1},{0,228},{0,78},{2,1}, + {0,215},{0,125},{4,1},{2,1},{0,229},{0,186},{2,1},{0,171},{0,94},{8,1}, + {4,1},{2,1},{0,201},{0,156},{2,1},{0,241},{0,31},{6,1},{4,1},{2,1}, + {0,240},{0,110},{0,242},{2,1},{0,47},{0,230},{38,1},{18,1},{8,1},{4,1}, + {2,1},{0,216},{0,243},{2,1},{0,63},{0,244},{6,1},{2,1},{0,79},{2,1}, + {0,141},{0,217},{2,1},{0,187},{0,202},{8,1},{4,1},{2,1},{0,172},{0,231}, + {2,1},{0,126},{0,245},{8,1},{4,1},{2,1},{0,157},{0,95},{2,1},{0,232}, + {0,142},{2,1},{0,246},{0,203},{34,1},{18,1},{10,1},{6,1},{4,1},{2,1}, + {0,15},{0,174},{0,111},{2,1},{0,188},{0,218},{4,1},{2,1},{0,173},{0,247}, + {2,1},{0,127},{0,233},{8,1},{4,1},{2,1},{0,158},{0,204},{2,1},{0,248}, + {0,143},{4,1},{2,1},{0,219},{0,189},{2,1},{0,234},{0,249},{16,1},{8,1}, + {4,1},{2,1},{0,159},{0,220},{2,1},{0,205},{0,235},{4,1},{2,1},{0,190}, + {0,250},{2,1},{0,175},{0,221},{14,1},{6,1},{4,1},{2,1},{0,236},{0,206}, + {0,251},{4,1},{2,1},{0,191},{0,237},{2,1},{0,222},{0,252},{6,1},{4,1}, + {2,1},{0,207},{0,253},{0,238},{4,1},{2,1},{0,223},{0,254},{2,1},{0,239}, + {0,255}, + }; + + private static int ValTab16[][] = { + {2,1},{0,0},{6,1},{2,1},{0,16},{2,1},{0,1},{0,17},{42,1},{8,1}, + {4,1},{2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{10,1},{6,1},{2,1}, + {0,34},{2,1},{0,48},{0,3},{2,1},{0,49},{0,19},{10,1},{4,1},{2,1}, + {0,50},{0,35},{4,1},{2,1},{0,64},{0,4},{0,65},{6,1},{2,1},{0,20}, + {2,1},{0,51},{0,66},{4,1},{2,1},{0,36},{0,80},{2,1},{0,67},{0,52}, + {138,1},{40,1},{16,1},{6,1},{4,1},{2,1},{0,5},{0,21},{0,81},{4,1}, + {2,1},{0,82},{0,37},{4,1},{2,1},{0,68},{0,53},{0,83},{10,1},{6,1}, + {4,1},{2,1},{0,96},{0,6},{0,97},{2,1},{0,22},{0,98},{8,1},{4,1}, + {2,1},{0,38},{0,84},{2,1},{0,69},{0,99},{4,1},{2,1},{0,54},{0,112}, + {0,113},{40,1},{18,1},{8,1},{2,1},{0,23},{2,1},{0,7},{2,1},{0,85}, + {0,100},{4,1},{2,1},{0,114},{0,39},{4,1},{2,1},{0,70},{0,101},{0,115}, + {10,1},{6,1},{2,1},{0,55},{2,1},{0,86},{0,8},{2,1},{0,128},{0,129}, + {6,1},{2,1},{0,24},{2,1},{0,116},{0,71},{2,1},{0,130},{2,1},{0,40}, + {0,102},{24,1},{14,1},{8,1},{4,1},{2,1},{0,131},{0,56},{2,1},{0,117}, + {0,132},{4,1},{2,1},{0,72},{0,144},{0,145},{6,1},{2,1},{0,25},{2,1}, + {0,9},{0,118},{2,1},{0,146},{0,41},{14,1},{8,1},{4,1},{2,1},{0,133}, + {0,88},{2,1},{0,147},{0,57},{4,1},{2,1},{0,160},{0,10},{0,26},{8,1}, + {2,1},{0,162},{2,1},{0,103},{2,1},{0,87},{0,73},{6,1},{2,1},{0,148}, + {2,1},{0,119},{0,134},{2,1},{0,161},{2,1},{0,104},{0,149},{220,1},{126,1}, + {50,1},{26,1},{12,1},{6,1},{2,1},{0,42},{2,1},{0,89},{0,58},{2,1}, + {0,163},{2,1},{0,135},{0,120},{8,1},{4,1},{2,1},{0,164},{0,74},{2,1}, + {0,150},{0,105},{4,1},{2,1},{0,176},{0,11},{0,177},{10,1},{4,1},{2,1}, + {0,27},{0,178},{2,1},{0,43},{2,1},{0,165},{0,90},{6,1},{2,1},{0,179}, + {2,1},{0,166},{0,106},{4,1},{2,1},{0,180},{0,75},{2,1},{0,12},{0,193}, + {30,1},{14,1},{6,1},{4,1},{2,1},{0,181},{0,194},{0,44},{4,1},{2,1}, + {0,167},{0,195},{2,1},{0,107},{0,196},{8,1},{2,1},{0,29},{4,1},{2,1}, + {0,136},{0,151},{0,59},{4,1},{2,1},{0,209},{0,210},{2,1},{0,45},{0,211}, + {18,1},{6,1},{4,1},{2,1},{0,30},{0,46},{0,226},{6,1},{4,1},{2,1}, + {0,121},{0,152},{0,192},{2,1},{0,28},{2,1},{0,137},{0,91},{14,1},{6,1}, + {2,1},{0,60},{2,1},{0,122},{0,182},{4,1},{2,1},{0,76},{0,153},{2,1}, + {0,168},{0,138},{6,1},{2,1},{0,13},{2,1},{0,197},{0,92},{4,1},{2,1}, + {0,61},{0,198},{2,1},{0,108},{0,154},{88,1},{86,1},{36,1},{16,1},{8,1}, + {4,1},{2,1},{0,139},{0,77},{2,1},{0,199},{0,124},{4,1},{2,1},{0,213}, + {0,93},{2,1},{0,224},{0,14},{8,1},{2,1},{0,227},{4,1},{2,1},{0,208}, + {0,183},{0,123},{6,1},{4,1},{2,1},{0,169},{0,184},{0,212},{2,1},{0,225}, + {2,1},{0,170},{0,185},{24,1},{10,1},{6,1},{4,1},{2,1},{0,155},{0,214}, + {0,109},{2,1},{0,62},{0,200},{6,1},{4,1},{2,1},{0,140},{0,228},{0,78}, + {4,1},{2,1},{0,215},{0,229},{2,1},{0,186},{0,171},{12,1},{4,1},{2,1}, + {0,156},{0,230},{4,1},{2,1},{0,110},{0,216},{2,1},{0,141},{0,187},{8,1}, + {4,1},{2,1},{0,231},{0,157},{2,1},{0,232},{0,142},{4,1},{2,1},{0,203}, + {0,188},{0,158},{0,241},{2,1},{0,31},{2,1},{0,15},{0,47},{66,1},{56,1}, + {2,1},{0,242},{52,1},{50,1},{20,1},{8,1},{2,1},{0,189},{2,1},{0,94}, + {2,1},{0,125},{0,201},{6,1},{2,1},{0,202},{2,1},{0,172},{0,126},{4,1}, + {2,1},{0,218},{0,173},{0,204},{10,1},{6,1},{2,1},{0,174},{2,1},{0,219}, + {0,220},{2,1},{0,205},{0,190},{6,1},{4,1},{2,1},{0,235},{0,237},{0,238}, + {6,1},{4,1},{2,1},{0,217},{0,234},{0,233},{2,1},{0,222},{4,1},{2,1}, + {0,221},{0,236},{0,206},{0,63},{0,240},{4,1},{2,1},{0,243},{0,244},{2,1}, + {0,79},{2,1},{0,245},{0,95},{10,1},{2,1},{0,255},{4,1},{2,1},{0,246}, + {0,111},{2,1},{0,247},{0,127},{12,1},{6,1},{2,1},{0,143},{2,1},{0,248}, + {0,249},{4,1},{2,1},{0,159},{0,250},{0,175},{8,1},{4,1},{2,1},{0,251}, + {0,191},{2,1},{0,252},{0,207},{4,1},{2,1},{0,253},{0,223},{2,1},{0,254}, + {0,239}, + }; + + private static int ValTab24[][] = { + {60,1},{8,1},{4,1},{2,1},{0,0},{0,16},{2,1},{0,1},{0,17},{14,1}, + {6,1},{4,1},{2,1},{0,32},{0,2},{0,33},{2,1},{0,18},{2,1},{0,34}, + {2,1},{0,48},{0,3},{14,1},{4,1},{2,1},{0,49},{0,19},{4,1},{2,1}, + {0,50},{0,35},{4,1},{2,1},{0,64},{0,4},{0,65},{8,1},{4,1},{2,1}, + {0,20},{0,51},{2,1},{0,66},{0,36},{6,1},{4,1},{2,1},{0,67},{0,52}, + {0,81},{6,1},{4,1},{2,1},{0,80},{0,5},{0,21},{2,1},{0,82},{0,37}, + {250,1},{98,1},{34,1},{18,1},{10,1},{4,1},{2,1},{0,68},{0,83},{2,1}, + {0,53},{2,1},{0,96},{0,6},{4,1},{2,1},{0,97},{0,22},{2,1},{0,98}, + {0,38},{8,1},{4,1},{2,1},{0,84},{0,69},{2,1},{0,99},{0,54},{4,1}, + {2,1},{0,113},{0,85},{2,1},{0,100},{0,70},{32,1},{14,1},{6,1},{2,1}, + {0,114},{2,1},{0,39},{0,55},{2,1},{0,115},{4,1},{2,1},{0,112},{0,7}, + {0,23},{10,1},{4,1},{2,1},{0,101},{0,86},{4,1},{2,1},{0,128},{0,8}, + {0,129},{4,1},{2,1},{0,116},{0,71},{2,1},{0,24},{0,130},{16,1},{8,1}, + {4,1},{2,1},{0,40},{0,102},{2,1},{0,131},{0,56},{4,1},{2,1},{0,117}, + {0,87},{2,1},{0,132},{0,72},{8,1},{4,1},{2,1},{0,145},{0,25},{2,1}, + {0,146},{0,118},{4,1},{2,1},{0,103},{0,41},{2,1},{0,133},{0,88},{92,1}, + {34,1},{16,1},{8,1},{4,1},{2,1},{0,147},{0,57},{2,1},{0,148},{0,73}, + {4,1},{2,1},{0,119},{0,134},{2,1},{0,104},{0,161},{8,1},{4,1},{2,1}, + {0,162},{0,42},{2,1},{0,149},{0,89},{4,1},{2,1},{0,163},{0,58},{2,1}, + {0,135},{2,1},{0,120},{0,74},{22,1},{12,1},{4,1},{2,1},{0,164},{0,150}, + {4,1},{2,1},{0,105},{0,177},{2,1},{0,27},{0,165},{6,1},{2,1},{0,178}, + {2,1},{0,90},{0,43},{2,1},{0,136},{0,179},{16,1},{10,1},{6,1},{2,1}, + {0,144},{2,1},{0,9},{0,160},{2,1},{0,151},{0,121},{4,1},{2,1},{0,166}, + {0,106},{0,180},{12,1},{6,1},{2,1},{0,26},{2,1},{0,10},{0,176},{2,1}, + {0,59},{2,1},{0,11},{0,192},{4,1},{2,1},{0,75},{0,193},{2,1},{0,152}, + {0,137},{67,1},{34,1},{16,1},{8,1},{4,1},{2,1},{0,28},{0,181},{2,1}, + {0,91},{0,194},{4,1},{2,1},{0,44},{0,167},{2,1},{0,122},{0,195},{10,1}, + {6,1},{2,1},{0,60},{2,1},{0,12},{0,208},{2,1},{0,182},{0,107},{4,1}, + {2,1},{0,196},{0,76},{2,1},{0,153},{0,168},{16,1},{8,1},{4,1},{2,1}, + {0,138},{0,197},{2,1},{0,92},{0,209},{4,1},{2,1},{0,183},{0,123},{2,1}, + {0,29},{0,210},{9,1},{4,1},{2,1},{0,45},{0,211},{2,1},{0,61},{0,198}, + {85,250},{4,1},{2,1},{0,108},{0,169},{2,1},{0,154},{0,212},{32,1},{16,1}, + {8,1},{4,1},{2,1},{0,184},{0,139},{2,1},{0,77},{0,199},{4,1},{2,1}, + {0,124},{0,213},{2,1},{0,93},{0,225},{8,1},{4,1},{2,1},{0,30},{0,226}, + {2,1},{0,170},{0,185},{4,1},{2,1},{0,155},{0,227},{2,1},{0,214},{0,109}, + {20,1},{10,1},{6,1},{2,1},{0,62},{2,1},{0,46},{0,78},{2,1},{0,200}, + {0,140},{4,1},{2,1},{0,228},{0,215},{4,1},{2,1},{0,125},{0,171},{0,229}, + {10,1},{4,1},{2,1},{0,186},{0,94},{2,1},{0,201},{2,1},{0,156},{0,110}, + {8,1},{2,1},{0,230},{2,1},{0,13},{2,1},{0,224},{0,14},{4,1},{2,1}, + {0,216},{0,141},{2,1},{0,187},{0,202},{74,1},{2,1},{0,255},{64,1},{58,1}, + {32,1},{16,1},{8,1},{4,1},{2,1},{0,172},{0,231},{2,1},{0,126},{0,217}, + {4,1},{2,1},{0,157},{0,232},{2,1},{0,142},{0,203},{8,1},{4,1},{2,1}, + {0,188},{0,218},{2,1},{0,173},{0,233},{4,1},{2,1},{0,158},{0,204},{2,1}, + {0,219},{0,189},{16,1},{8,1},{4,1},{2,1},{0,234},{0,174},{2,1},{0,220}, + {0,205},{4,1},{2,1},{0,235},{0,190},{2,1},{0,221},{0,236},{8,1},{4,1}, + {2,1},{0,206},{0,237},{2,1},{0,222},{0,238},{0,15},{4,1},{2,1},{0,240}, + {0,31},{0,241},{4,1},{2,1},{0,242},{0,47},{2,1},{0,243},{0,63},{18,1}, + {8,1},{4,1},{2,1},{0,244},{0,79},{2,1},{0,245},{0,95},{4,1},{2,1}, + {0,246},{0,111},{2,1},{0,247},{2,1},{0,127},{0,143},{10,1},{4,1},{2,1}, + {0,248},{0,249},{4,1},{2,1},{0,159},{0,175},{0,250},{8,1},{4,1},{2,1}, + {0,251},{0,191},{2,1},{0,252},{0,207},{4,1},{2,1},{0,253},{0,223},{2,1}, + {0,254},{0,239}, + }; + + private static int ValTab32[][] = { + {2,1},{0,0},{8,1},{4,1},{2,1},{0,8},{0,4},{2,1},{0,1},{0,2}, + {8,1},{4,1},{2,1},{0,12},{0,10},{2,1},{0,3},{0,6},{6,1},{2,1}, + {0,9},{2,1},{0,5},{0,7},{4,1},{2,1},{0,14},{0,13},{2,1},{0,15}, + {0,11}, + }; + + private static int ValTab33[][] = { + {16,1},{8,1},{4,1},{2,1},{0,0},{0,1},{2,1},{0,2},{0,3},{4,1}, + {2,1},{0,4},{0,5},{2,1},{0,6},{0,7},{8,1},{4,1},{2,1},{0,8}, + {0,9},{2,1},{0,10},{0,11},{4,1},{2,1},{0,12},{0,13},{2,1},{0,14}, + {0,15}, + }; + + + public static huffcodetab[] ht = null; /* Simulate extern struct */ + + private static int[] bitbuf = new int[32]; + + /** + * Big Constructor : Computes all Huffman Tables. + */ + private huffcodetab(String S,int XLEN, int YLEN, int LINBITS, int LINMAX, int REF, + int[] TABLE, int[] HLEN, int[][] VAL, int TREELEN) + { + tablename0 = S.charAt(0); + tablename1 = S.charAt(1); + tablename2 = S.charAt(2); + xlen = XLEN; + ylen = YLEN; + linbits = LINBITS; + linmax = LINMAX; + ref = REF; + table = TABLE; + hlen = HLEN; + val = VAL; + treelen = TREELEN; + } + + + + /** + * Do the Huffman decoding. + * note! for counta,countb -the 4 bit value is returned in y, + * discard x. + */ + public static int huffman_decoder(huffcodetab h, int[] x, int[] y, int[] v, int[] w, BitReserve br) + { + // array of all huffcodtable headers + // 0..31 Huffman code table 0..31 + // 32,33 count1-tables + + int dmask = 1 << ((4 * 8) - 1); + int hs = 4 * 8; + int level; + int point = 0; + int error = 1; + level = dmask; + + if (h.val == null) return 2; + + /* table 0 needs no bits */ + if ( h.treelen == 0) + { + x[0] = y[0] = 0; + return 0; + } + + /* Lookup in Huffman table. */ + + /*int bitsAvailable = 0; + int bitIndex = 0; + + int bits[] = bitbuf;*/ + do + { + if (h.val[point][0]==0) + { /*end of tree*/ + x[0] = h.val[point][1] >>> 4; + y[0] = h.val[point][1] & 0xf; + error = 0; + break; + } + + // hget1bit() is called thousands of times, and so needs to be + // ultra fast. + /* + if (bitIndex==bitsAvailable) + { + bitsAvailable = br.readBits(bits, 32); + bitIndex = 0; + } + */ + //if (bits[bitIndex++]!=0) + if (br.hget1bit()!=0) + { + while (h.val[point][1] >= MXOFF) point += h.val[point][1]; + point += h.val[point][1]; + } + else + { + while (h.val[point][0] >= MXOFF) point += h.val[point][0]; + point += h.val[point][0]; + } + level >>>= 1; + // MDM: ht[0] is always 0; + } while ((level !=0 ) || (point < 0 /*ht[0].treelen*/) ); + + // put back any bits not consumed + /* + int unread = (bitsAvailable-bitIndex); + if (unread>0) + br.rewindNbits(unread); + */ + /* Process sign encodings for quadruples tables. */ + // System.out.println(h.tablename); + if (h.tablename0 == '3' && (h.tablename1 == '2' || h.tablename1 == '3')) + { + v[0] = (y[0]>>3) & 1; + w[0] = (y[0]>>2) & 1; + x[0] = (y[0]>>1) & 1; + y[0] = y[0] & 1; + + /* v, w, x and y are reversed in the bitstream. + switch them around to make test bistream work. */ + + if (v[0]!=0) + if (br.hget1bit() != 0) v[0] = -v[0]; + if (w[0]!=0) + if (br.hget1bit() != 0) w[0] = -w[0]; + if (x[0]!=0) + if (br.hget1bit() != 0) x[0] = -x[0]; + if (y[0]!=0) + if (br.hget1bit() != 0) y[0] = -y[0]; + } + else + { + // Process sign and escape encodings for dual tables. + // x and y are reversed in the test bitstream. + // Reverse x and y here to make test bitstream work. + + if (h.linbits != 0) + if ((h.xlen-1) == x[0]) + x[0] += br.hgetbits(h.linbits); + if (x[0] != 0) + if (br.hget1bit() != 0) x[0] = -x[0]; + if (h.linbits != 0) + if ((h.ylen-1) == y[0]) + y[0] += br.hgetbits(h.linbits); + if (y[0] != 0) + if (br.hget1bit() != 0) y[0] = -y[0]; + } + return error; + } + + public static void inithuff() + { + + if (ht!=null) + return; + + ht = new huffcodetab[HTN]; + ht[0] = new huffcodetab("0 ",0,0,0,0,-1,null,null,ValTab0,0); + ht[1] = new huffcodetab("1 ",2,2,0,0,-1,null,null,ValTab1,7); + ht[2] = new huffcodetab("2 ",3,3,0,0,-1,null,null,ValTab2,17); + ht[3] = new huffcodetab("3 ",3,3,0,0,-1,null,null,ValTab3,17); + ht[4] = new huffcodetab("4 ",0,0,0,0,-1,null,null,ValTab4,0); + ht[5] = new huffcodetab("5 ",4,4,0,0,-1,null,null,ValTab5,31); + ht[6] = new huffcodetab("6 ",4,4,0,0,-1,null,null,ValTab6,31); + ht[7] = new huffcodetab("7 ",6,6,0,0,-1,null,null,ValTab7,71); + ht[8] = new huffcodetab("8 ",6,6,0,0,-1,null,null,ValTab8,71); + ht[9] = new huffcodetab("9 ",6,6,0,0,-1,null,null,ValTab9,71); + ht[10] = new huffcodetab("10 ",8,8,0,0,-1,null,null,ValTab10,127); + ht[11] = new huffcodetab("11 ",8,8,0,0,-1,null,null,ValTab11,127); + ht[12] = new huffcodetab("12 ",8,8,0,0,-1,null,null,ValTab12,127); + ht[13] = new huffcodetab("13 ",16,16,0,0,-1,null,null,ValTab13,511); + ht[14] = new huffcodetab("14 ",0,0,0,0,-1,null,null,ValTab14,0); + ht[15] = new huffcodetab("15 ",16,16,0,0,-1,null,null,ValTab15,511); + ht[16] = new huffcodetab("16 ",16,16,1,1,-1,null,null,ValTab16,511); + ht[17] = new huffcodetab("17 ",16,16,2,3,16,null,null,ValTab16,511); + ht[18] = new huffcodetab("18 ",16,16,3,7,16,null,null,ValTab16,511); + ht[19] = new huffcodetab("19 ",16,16,4,15,16,null,null,ValTab16,511); + ht[20] = new huffcodetab("20 ",16,16,6,63,16,null,null,ValTab16,511); + ht[21] = new huffcodetab("21 ",16,16,8,255,16,null,null,ValTab16,511); + ht[22] = new huffcodetab("22 ",16,16,10,1023,16,null,null,ValTab16,511); + ht[23] = new huffcodetab("23 ",16,16,13,8191,16,null,null,ValTab16,511); + ht[24] = new huffcodetab("24 ",16,16,4,15,-1,null,null,ValTab24,512); + ht[25] = new huffcodetab("25 ",16,16,5,31,24,null,null,ValTab24,512); + ht[26] = new huffcodetab("26 ",16,16,6,63,24,null,null,ValTab24,512); + ht[27] = new huffcodetab("27 ",16,16,7,127,24,null,null,ValTab24,512); + ht[28] = new huffcodetab("28 ",16,16,8,255,24,null,null,ValTab24,512); + ht[29] = new huffcodetab("29 ",16,16,9,511,24,null,null,ValTab24,512); + ht[30] = new huffcodetab("30 ",16,16,11,2047,24,null,null,ValTab24,512); + ht[31] = new huffcodetab("31 ",16,16,13,8191,24,null,null,ValTab24,512); + ht[32] = new huffcodetab("32 ",1,16,0,0,-1,null,null,ValTab32,31); + ht[33] = new huffcodetab("33 ",1,16,0,0,-1,null,null,ValTab33,31); + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/l3reorder.ser b/src/lwjgl/java/javazoom/jl/decoder/l3reorder.ser new file mode 100644 index 0000000..da216fc Binary files /dev/null and b/src/lwjgl/java/javazoom/jl/decoder/l3reorder.ser differ diff --git a/src/lwjgl/java/javazoom/jl/decoder/lin2au.ser b/src/lwjgl/java/javazoom/jl/decoder/lin2au.ser new file mode 100644 index 0000000..ec1c83d Binary files /dev/null and b/src/lwjgl/java/javazoom/jl/decoder/lin2au.ser differ diff --git a/src/lwjgl/java/javazoom/jl/decoder/readme.txt b/src/lwjgl/java/javazoom/jl/decoder/readme.txt new file mode 100644 index 0000000..7a765ec --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/readme.txt @@ -0,0 +1,15 @@ + +TODO: + + +Implement high-level Player and Converter classes. + +Add MP1 and MP2 support and test. + +Add option to run each "stage" on own thread. +E.g. read & parse input, decode subbands, subband synthesis, audio output. + +Retrofit seek support (temporarily removed when reworking classes.) + + +Document and give example code. \ No newline at end of file diff --git a/src/lwjgl/java/javazoom/jl/decoder/sfd.ser b/src/lwjgl/java/javazoom/jl/decoder/sfd.ser new file mode 100644 index 0000000..440c7c6 Binary files /dev/null and b/src/lwjgl/java/javazoom/jl/decoder/sfd.ser differ diff --git a/src/lwjgl/java/javazoom/mp3spi/DecodedMpegAudioInputStream.java b/src/lwjgl/java/javazoom/mp3spi/DecodedMpegAudioInputStream.java new file mode 100644 index 0000000..b908f49 --- /dev/null +++ b/src/lwjgl/java/javazoom/mp3spi/DecodedMpegAudioInputStream.java @@ -0,0 +1,265 @@ +/* + * DecodedMpegAudioInputStream. + * + * JavaZOOM : mp3spi@javazoom.net + * http://www.javazoom.net + * + * Copyright (c) 2012 by fireandfuel from Cuina Team (http://www.cuina.byethost12.com/) + * + *----------------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *------------------------------------------------------------------------ + */ + +package javazoom.mp3spi; + +import java.io.IOException; +import java.io.InputStream; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; + +import tritonus.TAsynchronousFilteredAudioInputStream; + +import javazoom.jl.decoder.Bitstream; +import javazoom.jl.decoder.BitstreamException; +import javazoom.jl.decoder.Decoder; +import javazoom.jl.decoder.DecoderException; +import javazoom.jl.decoder.Header; +import javazoom.jl.decoder.Obuffer; + +/** + * Main decoder. + */ +public class DecodedMpegAudioInputStream extends TAsynchronousFilteredAudioInputStream +{ + private InputStream m_encodedStream; + private Bitstream m_bitstream; + private Decoder m_decoder; + private Header m_header; + private DMAISObuffer m_oBuffer; + + // Bytes info. + private long byteslength = -1; + private long currentByte = 0; + // Frame info. + private int frameslength = -1; + private long currentFrame = 0; + private int currentFramesize = 0; + + public DecodedMpegAudioInputStream(AudioFormat outputFormat, + AudioInputStream bufferedInputStream) + { + super(outputFormat, -1); + + try + { + // Try to find out inputstream length to allow skip. + byteslength = bufferedInputStream.available(); + } catch (IOException e) + { + byteslength = -1; + } + m_encodedStream = bufferedInputStream; + m_bitstream = new Bitstream(bufferedInputStream); + m_decoder = new Decoder(null); + // m_equalizer = new Equalizer(); + // m_equalizer_values = new float[32]; + // for (int b=0;b 0)) + frameslength = m_header.max_number_of_frames((int) byteslength); + } catch (BitstreamException e) + { + + byteslength = -1; + } + } + + public void execute()// if( reverseBytes ) + // reverseBytes( smallBuffer, 0, bytesRead ); + { + + try + { + // Following line hangs when FrameSize is available in AudioFormat. + Header header = null; + if(m_header == null) + header = m_bitstream.readFrame(); + else header = m_header; + + if(header == null) + { + + getCircularBuffer().close(); + return; + } + currentFrame++; + currentFramesize = header.calculate_framesize(); + currentByte = currentByte + currentFramesize; + // Obuffer decoderOutput = + m_decoder.decodeFrame(header, m_bitstream); + m_bitstream.closeFrame(); + getCircularBuffer().write(m_oBuffer.getBuffer(), 0, m_oBuffer.getCurrentBufferSize()); + m_oBuffer.reset(); + if(m_header != null) + m_header = null; + } catch (BitstreamException e) + { + + } catch (DecoderException e) + { + + } + + } + + public long skip(long bytes) + { + if((byteslength > 0) && (frameslength > 0)) + { + float ratio = bytes * 1.0f / byteslength * 1.0f; + long bytesread = skipFrames((long) (ratio * frameslength)); + currentByte = currentByte + bytesread; + m_header = null; + return bytesread; + } else return -1; + } + + /** + * Skip frames. You don't need to call it severals times, it will exactly + * skip given frames number. + * + * @param frames + * @return bytes length skipped matching to frames skipped. + */ + public long skipFrames(long frames) + { + + int framesRead = 0; + int bytesReads = 0; + try + { + for(int i = 0; i < frames; i++) + { + Header header = m_bitstream.readFrame(); + if(header != null) + { + int fsize = header.calculate_framesize(); + bytesReads = bytesReads + fsize; + } + m_bitstream.closeFrame(); + framesRead++; + } + } catch (BitstreamException e) + { + + } + + currentFrame = currentFrame + framesRead; + return bytesReads; + } + + private boolean isBigEndian() + { + return getFormat().isBigEndian(); + } + + public void close() throws IOException + { + super.close(); + m_encodedStream.close(); + } + + private class DMAISObuffer extends Obuffer + { + private int m_nChannels; + private byte[] m_abBuffer; + private int[] m_anBufferPointers; + private boolean m_bIsBigEndian; + + public DMAISObuffer(int nChannels) + { + m_nChannels = nChannels; + m_abBuffer = new byte[OBUFFERSIZE * nChannels]; + m_anBufferPointers = new int[nChannels]; + reset(); + m_bIsBigEndian = DecodedMpegAudioInputStream.this.isBigEndian(); + } + + public void append(int nChannel, short sValue) + { + byte bFirstByte; + byte bSecondByte; + if(m_bIsBigEndian) + { + bFirstByte = (byte) ((sValue >>> 8) & 0xFF); + bSecondByte = (byte) (sValue & 0xFF); + } else + // little endian + { + bFirstByte = (byte) (sValue & 0xFF); + bSecondByte = (byte) ((sValue >>> 8) & 0xFF); + } + m_abBuffer[m_anBufferPointers[nChannel]] = bFirstByte; + m_abBuffer[m_anBufferPointers[nChannel] + 1] = bSecondByte; + m_anBufferPointers[nChannel] += m_nChannels * 2; + } + + public void set_stop_flag() + { + } + + public void close() + { + } + + public void write_buffer(int nValue) + { + } + + public void clear_buffer() + { + } + + public byte[] getBuffer() + { + return m_abBuffer; + } + + public int getCurrentBufferSize() + { + return m_anBufferPointers[0]; + } + + public void reset() + { + for(int i = 0; i < m_nChannels; i++) + { + /* + * Points to byte location, implicitely assuming 16 bit samples. + */ + m_anBufferPointers[i] = i * 2; + } + } + } +} diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/MinecraftMain.java b/src/lwjgl/java/net/lax1dude/eaglercraft/MinecraftMain.java new file mode 100644 index 0000000..aa47616 --- /dev/null +++ b/src/lwjgl/java/net/lax1dude/eaglercraft/MinecraftMain.java @@ -0,0 +1,24 @@ +package net.lax1dude.eaglercraft; + +import java.util.Arrays; + +import org.lwjgl.input.Keyboard; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.LocalStorageManager; +import net.minecraft.client.Minecraft; +import net.minecraft.src.ServerList; + +public class MinecraftMain { + + public static void main(String[] par0ArrayOfStr) { + + EaglerAdapter.initializeContext(); + LocalStorageManager.loadStorage(); + ServerList.loadDefaultServers(Base64.encodeBase64String(EaglerAdapter.loadLocalStorage("forced"))); + + Minecraft mc = new Minecraft(); + mc.run(); + + } +} diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/EaglerAdapterImpl2.java b/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/EaglerAdapterImpl2.java new file mode 100644 index 0000000..6d8fa32 --- /dev/null +++ b/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/EaglerAdapterImpl2.java @@ -0,0 +1,1157 @@ +package net.lax1dude.eaglercraft.adapter; + +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.charset.Charset; +import java.util.LinkedList; +import java.util.concurrent.TimeUnit; + +import javax.swing.JFileChooser; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.filechooser.FileFilter; + +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.handshake.ServerHandshake; +import org.lwjgl.LWJGLException; +import org.lwjgl.Sys; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.ARBDebugOutput; +import org.lwjgl.opengl.ARBDebugOutputCallback; +import org.lwjgl.opengl.ARBOcclusionQuery2; +import org.lwjgl.opengl.ContextAttribs; +import org.lwjgl.opengl.Display; +import org.lwjgl.opengl.DisplayMode; +import org.lwjgl.opengl.EXTTextureFilterAnisotropic; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; +import org.lwjgl.opengl.GL13; +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GL32; +import org.lwjgl.opengl.PixelFormat; +import org.lwjgl.util.glu.GLU; + +import de.cuina.fireandfuel.CodecJLayerMP3; +import net.lax1dude.eaglercraft.AssetRepository; +import net.lax1dude.eaglercraft.EarlyLoadScreen; +import net.lax1dude.eaglercraft.adapter.lwjgl.GameWindowListener; +import net.minecraft.src.MathHelper; +import paulscode.sound.SoundSystem; +import paulscode.sound.SoundSystemConfig; +import paulscode.sound.libraries.LibraryLWJGLOpenAL; + +public class EaglerAdapterImpl2 { + + public static final boolean _wisWebGL() { + return false; + } + public static final boolean _wisAnisotropicPatched() { + return true; + } + public static final String _wgetShaderHeader() { + return "#version 150"; + } + + public static final InputStream loadResource(String path) { + byte[] file = loadResourceBytes(path); + if (file != null) { + return new ByteArrayInputStream(file); + } else { + return null; + } + } + + private static final boolean useEPKTest = false; + + public static final byte[] loadResourceBytes(String path) { + if(useEPKTest) { + return AssetRepository.getResource(path); + }else { + try { + InputStream stream; + try { + stream = new FileInputStream(new File("resources", path)); + } catch (FileNotFoundException e) { + return null; + } + byte[] targetArray = new byte[stream.available()]; + stream.read(targetArray); + stream.close(); + return targetArray; + } catch (IOException e) { + return null; + } + } + } + + public static final String fileContents(String path) { + byte[] contents = loadResourceBytes(path); + if(contents == null) { + return null; + }else { + return new String(contents, Charset.forName("UTF-8")); + } + } + + public static final String[] fileContentsLines(String path) { + String contents = fileContents(path); + if(contents == null) { + return null; + }else { + return contents.replace("\r\n", "\n").split("[\r\n]"); + } + } + + public static final void setDebugVar(String v, String s) { + + } + + public static final int _wGL_TEXTURE_2D = GL11.GL_TEXTURE_2D; + public static final int _wGL_DEPTH_TEST = GL11.GL_DEPTH_TEST; + public static final int _wGL_LEQUAL = GL11.GL_LEQUAL; + public static final int _wGL_GEQUAL = GL11.GL_GEQUAL; + public static final int _wGL_GREATER = GL11.GL_GREATER; + public static final int _wGL_LESS = GL11.GL_LESS; + public static final int _wGL_BACK = GL11.GL_BACK; + public static final int _wGL_FRONT = GL11.GL_FRONT; + public static final int _wGL_FRONT_AND_BACK = GL11.GL_FRONT_AND_BACK; + public static final int _wGL_COLOR_BUFFER_BIT = GL11.GL_COLOR_BUFFER_BIT; + public static final int _wGL_DEPTH_BUFFER_BIT = GL11.GL_DEPTH_BUFFER_BIT; + public static final int _wGL_BLEND = GL11.GL_BLEND; + public static final int _wGL_RGBA = GL11.GL_RGBA; + public static final int _wGL_RGB = GL11.GL_RGB; + public static final int _wGL_RGB8 = GL11.GL_RGB8; + public static final int _wGL_RGBA8 = GL11.GL_RGBA8; + public static final int _wGL_UNSIGNED_BYTE = GL11.GL_UNSIGNED_BYTE; + public static final int _wGL_UNSIGNED_SHORT = GL11.GL_UNSIGNED_SHORT; + public static final int _wGL_TEXTURE_WIDTH = GL11.GL_TEXTURE_WIDTH; + public static final int _wGL_SRC_ALPHA = GL11.GL_SRC_ALPHA; + public static final int _wGL_ONE_MINUS_SRC_ALPHA = GL11.GL_ONE_MINUS_SRC_ALPHA; + public static final int _wGL_ONE_MINUS_DST_COLOR = GL11.GL_ONE_MINUS_DST_COLOR; + public static final int _wGL_ONE_MINUS_SRC_COLOR = GL11.GL_ONE_MINUS_SRC_COLOR; + public static final int _wGL_ZERO = GL11.GL_ZERO; + public static final int _wGL_CULL_FACE = GL11.GL_CULL_FACE; + public static final int _wGL_TEXTURE_MIN_FILTER = GL11.GL_TEXTURE_MIN_FILTER; + public static final int _wGL_TEXTURE_MAG_FILTER = GL11.GL_TEXTURE_MAG_FILTER; + public static final int _wGL_LINEAR = GL11.GL_LINEAR; + public static final int _wGL_NEAREST_MIPMAP_LINEAR = GL11.GL_NEAREST_MIPMAP_LINEAR; + public static final int _wGL_LINEAR_MIPMAP_LINEAR = GL11.GL_LINEAR_MIPMAP_LINEAR; + public static final int _wGL_LINEAR_MIPMAP_NEAREST = GL11.GL_LINEAR_MIPMAP_NEAREST; + public static final int _wGL_NEAREST_MIPMAP_NEAREST = GL11.GL_NEAREST_MIPMAP_NEAREST; + public static final int _wGL_EQUAL = GL11.GL_EQUAL; + public static final int _wGL_SRC_COLOR = GL11.GL_SRC_COLOR; + public static final int _wGL_ONE = GL11.GL_ONE; + public static final int _wGL_NEAREST = GL11.GL_NEAREST; + public static final int _wGL_CLAMP = GL11.GL_CLAMP; + public static final int _wGL_TEXTURE_WRAP_S = GL11.GL_TEXTURE_WRAP_S; + public static final int _wGL_TEXTURE_WRAP_T = GL11.GL_TEXTURE_WRAP_T; + public static final int _wGL_TEXTURE_MAX_LEVEL = GL12.GL_TEXTURE_MAX_LEVEL; + public static final int _wGL_REPEAT = GL11.GL_REPEAT; + public static final int _wGL_DST_COLOR = GL11.GL_DST_COLOR; + public static final int _wGL_DST_ALPHA = GL11.GL_DST_ALPHA; + public static final int _wGL_FLOAT = GL11.GL_FLOAT; + public static final int _wGL_SHORT = GL11.GL_SHORT; + public static final int _wGL_TRIANGLES = GL11.GL_TRIANGLES; + public static final int _wGL_TRIANGLE_STRIP = GL11.GL_TRIANGLE_STRIP; + public static final int _wGL_TRIANGLE_FAN = GL11.GL_TRIANGLE_FAN; + public static final int _wGL_LINE_STRIP = GL11.GL_LINE_STRIP; + public static final int _wGL_LINES = GL11.GL_LINES; + public static final int _wGL_PACK_ALIGNMENT = GL11.GL_PACK_ALIGNMENT; + public static final int _wGL_UNPACK_ALIGNMENT = GL11.GL_UNPACK_ALIGNMENT; + public static final int _wGL_TEXTURE0 = GL13.GL_TEXTURE0; + public static final int _wGL_TEXTURE1 = GL13.GL_TEXTURE1; + public static final int _wGL_TEXTURE2 = GL13.GL_TEXTURE2; + public static final int _wGL_TEXTURE3 = GL13.GL_TEXTURE3; + public static final int _wGL_VIEWPORT = GL11.GL_VIEWPORT; + public static final int _wGL_VERTEX_SHADER = GL20.GL_VERTEX_SHADER; + public static final int _wGL_FRAGMENT_SHADER = GL20.GL_FRAGMENT_SHADER; + public static final int _wGL_ARRAY_BUFFER = GL15.GL_ARRAY_BUFFER; + public static final int _wGL_ELEMENT_ARRAY_BUFFER = GL15.GL_ELEMENT_ARRAY_BUFFER; + public static final int _wGL_STATIC_DRAW = GL15.GL_STATIC_DRAW; + public static final int _wGL_DYNAMIC_DRAW = GL15.GL_DYNAMIC_DRAW; + public static final int _wGL_INVALID_ENUM = GL11.GL_INVALID_ENUM; + public static final int _wGL_INVALID_VALUE= GL11.GL_INVALID_VALUE; + public static final int _wGL_INVALID_OPERATION = GL11.GL_INVALID_OPERATION; + public static final int _wGL_OUT_OF_MEMORY = GL11.GL_OUT_OF_MEMORY; + public static final int _wGL_CONTEXT_LOST_WEBGL = -1; + public static final int _wGL_FRAMEBUFFER_COMPLETE = GL30.GL_FRAMEBUFFER_COMPLETE; + public static final int _wGL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = GL30.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + public static final int _wGL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL30.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; + public static final int _wGL_COLOR_ATTACHMENT0 = GL30.GL_COLOR_ATTACHMENT0; + public static final int _wGL_DEPTH_STENCIL_ATTACHMENT = GL30.GL_DEPTH_STENCIL_ATTACHMENT; + public static final int _wGL_DEPTH_ATTACHMENT = GL30.GL_DEPTH_ATTACHMENT; + public static final int _wGL_DEPTH_COMPONENT32F = GL30.GL_DEPTH_COMPONENT32F; + public static final int _wGL_DEPTH_STENCIL = GL30.GL_DEPTH_STENCIL; + public static final int _wGL_DEPTH24_STENCIL8 = GL30.GL_DEPTH24_STENCIL8; + public static final int _wGL_UNSIGNED_INT_24_8 = GL30.GL_UNSIGNED_INT_24_8; + public static final int _wGL_UNSIGNED_INT = GL11.GL_UNSIGNED_INT; + public static int _wGL_ANY_SAMPLES_PASSED = -1; + public static final int _wGL_QUERY_RESULT = GL15.GL_QUERY_RESULT; + public static final int _wGL_QUERY_RESULT_AVAILABLE = GL15.GL_QUERY_RESULT_AVAILABLE; + public static int _wGL_TEXTURE_MAX_ANISOTROPY = -1; + public static final int _wGL_R8 = GL30.GL_R8; + public static final int _wGL_R32UI = GL30.GL_R32UI; + public static final int _wGL_RED = GL11.GL_RED; + public static final int _wGL_RENDERBUFFER = GL30.GL_RENDERBUFFER; + public static final int _wGL_MULTISAMPLE = GL13.GL_MULTISAMPLE; + public static final int _wGL_LINE_SMOOTH = GL11.GL_LINE_SMOOTH; + public static final int _wGL_DRAW_FRAMEBUFFER = GL30.GL_DRAW_FRAMEBUFFER; + public static final int _wGL_READ_FRAMEBUFFER = GL30.GL_READ_FRAMEBUFFER; + public static final int _wGL_FRAMEBUFFER = GL30.GL_FRAMEBUFFER; + + public static final class TextureGL { + protected final int obj; + protected TextureGL(int obj) { + this.obj = obj; + } + } + public static final class BufferGL { + protected final int obj; + protected BufferGL(int obj) { + this.obj = obj; + } + } + public static final class ShaderGL { + protected final int obj; + protected ShaderGL(int obj) { + this.obj = obj; + } + } + public static final class ProgramGL { + protected final int obj; + protected ProgramGL(int obj) { + this.obj = obj; + } + } + public static final class UniformGL { + protected final int obj; + protected UniformGL(int obj) { + this.obj = obj; + } + } + public static final class BufferArrayGL { + protected final int obj; + public boolean isQuadBufferBound; + protected BufferArrayGL(int obj) { + this.obj = obj; + this.isQuadBufferBound = false; + } + } + public static final class FramebufferGL { + protected final int obj; + protected FramebufferGL(int obj) { + this.obj = obj; + } + } + public static final class RenderbufferGL { + protected final int obj; + protected RenderbufferGL(int obj) { + this.obj = obj; + } + } + public static final class QueryGL { + protected final int obj; + protected QueryGL(int obj) { + this.obj = obj; + } + } + + public static final void _wglEnable(int p1) { + GL11.glEnable(p1); + } + public static final void _wglClearDepth(float p1) { + GL11.glClearDepth(p1); + } + public static final void _wglDepthFunc(int p1) { + GL11.glDepthFunc(p1); + } + public static final void _wglCullFace(int p1) { + GL11.glCullFace(p1); + } + private static final int[] viewport = new int[4]; + public static final void _wglViewport(int p1, int p2, int p3, int p4) { + viewport[0] = p1; viewport[1] = p2; + viewport[2] = p3; viewport[3] = p4; + GL11.glViewport(p1, p2, p3, p4); + } + public static final void _wglClear(int p1) { + GL11.glClear(p1); + } + public static final void _wglClearColor(float p1, float p2, float p3, float p4) { + GL11.glClearColor(p1, p2, p3, p4); + } + public static final void _wglDisable(int p1) { + GL11.glDisable(p1); + } + public static final int _wglGetError() { + return GL11.glGetError(); + } + public static final void _wglFlush() { + + } + public static final void _wglTexImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, ByteBuffer p9) { + GL11.glTexImage2D(p1, p2, p3, p4, p5, p6, p7, p8, p9); + } + + public static final void _wglBlendFunc(int p1, int p2) { + GL11.glBlendFunc(p1, p2); + } + public static final void _wglDepthMask(boolean p1) { + GL11.glDepthMask(p1); + } + public static final void _wglColorMask(boolean p1, boolean p2, boolean p3, boolean p4) { + GL11.glColorMask(p1, p2, p3, p4); + } + public static final void _wglBindTexture(int p1, TextureGL p2) { + GL11.glBindTexture(p1, p2 == null ? 0 : p2.obj); + } + public static final void _wglCopyTexSubImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) { + GL11.glCopyTexSubImage2D(p1, p2, p3, p4, p5, p6, p7, p8); + } + public static final void _wglTexParameteri(int p1, int p2, int p3) { + GL11.glTexParameteri(p1, p2, p3); + } + public static final void _wglTexParameterf(int p1, int p2, int p3) { + GL11.glTexParameterf(p1, p2, p3); + } + public static final void _wglTexImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, IntBuffer p9) { + GL11.glTexImage2D(p1, p2, p3, p4, p5, p6, p7, p8, p9); + } + public static final void _wglTexSubImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, IntBuffer p9) { + GL11.glTexSubImage2D(p1, p2, p3, p4, p5, p6, p7, p8, p9); + } + public static final void _wglDeleteTextures(TextureGL p1) { + GL11.glDeleteTextures(p1.obj); + } + public static final void _wglDrawArrays(int p1, int p2, int p3) { + GL11.glDrawArrays(p1, p2, p3); + } + public static final void _wglDrawElements(int p1, int p2, int p3, int p4) { + GL11.glDrawElements(p1, p2, p3, p4); + } + public static final TextureGL _wglGenTextures() { + return new TextureGL(GL11.glGenTextures()); + } + public static final void _wglTexSubImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, ByteBuffer p9) { + GL11.glTexSubImage2D(p1, p2, p3, p4, p5, p6, p7, p8, p9); + } + public static final void _wglTexImage3D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9, ByteBuffer p10) { + GL12.glTexImage3D(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + } + public static final void _wglTexParameterf(int p1, int p2, float p3) { + GL11.glTexParameterf(p1, p2, p3); + } + public static final void _wglActiveTexture(int p1) { + GL13.glActiveTexture(p1); + } + public static final String _wgluErrorString(int p1) { + return GLU.gluErrorString(p1); + } + public static final ProgramGL _wglCreateProgram() { + return new ProgramGL(GL20.glCreateProgram()); + } + public static final ShaderGL _wglCreateShader(int p1) { + return new ShaderGL(GL20.glCreateShader(p1)); + } + public static final void _wglAttachShader(ProgramGL p1, ShaderGL p2) { + GL20.glAttachShader(p1.obj, p2.obj); + } + public static final void _wglDetachShader(ProgramGL p1, ShaderGL p2) { + GL20.glDetachShader(p1.obj, p2.obj); + } + public static final void _wglCompileShader(ShaderGL p1) { + GL20.glCompileShader(p1.obj); + } + public static final void _wglLinkProgram(ProgramGL p1) { + GL20.glLinkProgram(p1.obj); + } + public static final void _wglShaderSource(ShaderGL p1, String p2) { + GL20.glShaderSource(p1.obj, p2); + } + public static final String _wglGetShaderInfoLog(ShaderGL p1) { + return GL20.glGetShaderInfoLog(p1.obj, 8192); + } + public static final String _wglGetProgramInfoLog(ProgramGL p1) { + return GL20.glGetProgramInfoLog(p1.obj, 8192); + } + public static final boolean _wglGetShaderCompiled(ShaderGL p1) { + return GL20.glGetShaderi(p1.obj, GL20.GL_COMPILE_STATUS) == GL11.GL_TRUE; + } + public static final boolean _wglGetProgramLinked(ProgramGL p1) { + return GL20.glGetProgrami(p1.obj, GL20.GL_LINK_STATUS) == GL11.GL_TRUE; + } + public static final void _wglDeleteShader(ShaderGL p1) { + GL20.glDeleteShader(p1.obj); + } + public static final void _wglDeleteProgram(ProgramGL p1) { + GL20.glDeleteProgram(p1.obj); + } + public static final BufferArrayGL _wglCreateVertexArray() { + return new BufferArrayGL(GL30.glGenVertexArrays()); + } + public static final void _wglDeleteVertexArray(BufferArrayGL p1) { + GL30.glDeleteVertexArrays(p1.obj); + } + public static final void _wglBindVertexArray(BufferArrayGL p1) { + GL30.glBindVertexArray(p1 == null ? 0 : p1.obj); + } + public static final BufferGL _wglCreateBuffer() { + return new BufferGL(GL15.glGenBuffers()); + } + public static final void _wglDeleteBuffer(BufferGL p1) { + GL15.glDeleteBuffers(p1.obj); + } + public static final void _wglBindBuffer(int p1, BufferGL p2) { + GL15.glBindBuffer(p1, p2 == null ? 0 : p2.obj); + } + public static final void _wglBufferData(int p1, Object p2, int p3) { + GL15.glBufferData(p1, (IntBuffer)p2, p3); + } + public static final void _wglBufferSubData(int p1, int p2, Object p3) { + GL15.glBufferSubData(p1, p2, (IntBuffer)p3); + } + public static final void _wglBufferData0(int p1, IntBuffer p2, int p3) { + GL15.glBufferData(p1, p2, p3); + } + public static final void _wglBufferSubData0(int p1, int p2, IntBuffer p3) { + GL15.glBufferSubData(p1, p2, p3); + } + public static final void _wglBindAttribLocation(int p1, int p2, String p3) { + GL20.glBindAttribLocation(p1, p2, p3); + } + public static final void _wglEnableVertexAttribArray(int p1) { + GL20.glEnableVertexAttribArray(p1); + } + public static final void _wglDisableVertexAttribArray(int p1) { + GL20.glDisableVertexAttribArray(p1); + } + public static final UniformGL _wglGetUniformLocation(ProgramGL p1, String p2) { + int u = GL20.glGetUniformLocation(p1.obj, p2); + return u == -1 ? null : new UniformGL(u); + } + public static final void _wglBindAttributeLocation(ProgramGL p1, int p2, String p3) { + GL20.glBindAttribLocation(p1.obj, p2, p3); + } + public static final void _wglUniform1f(UniformGL p1, float p2) { + if(p1 != null) GL20.glUniform1f(p1.obj, p2); + } + public static final void _wglUniform2f(UniformGL p1, float p2, float p3) { + if(p1 != null) GL20.glUniform2f(p1.obj, p2, p3); + } + public static final void _wglUniform3f(UniformGL p1, float p2, float p3, float p4) { + if(p1 != null) GL20.glUniform3f(p1.obj, p2, p3, p4); + } + public static final void _wglUniform4f(UniformGL p1, float p2, float p3, float p4, float p5) { + if(p1 != null) GL20.glUniform4f(p1.obj, p2, p3, p4, p5); + } + public static final void _wglUniform1i(UniformGL p1, int p2) { + if(p1 != null) GL20.glUniform1i(p1.obj, p2); + } + public static final void _wglUniform2i(UniformGL p1, int p2, int p3) { + if(p1 != null) GL20.glUniform2i(p1.obj, p2, p3); + } + public static final void _wglUniform3i(UniformGL p1, int p2, int p3, int p4) { + if(p1 != null) GL20.glUniform3i(p1.obj, p2, p3, p4); + } + public static final void _wglUniform4i(UniformGL p1, int p2, int p3, int p4, int p5) { + if(p1 != null) GL20.glUniform4i(p1.obj, p2, p3, p4, p5); + } + private static final FloatBuffer matUpload = ByteBuffer.allocateDirect(16 << 2).order(ByteOrder.nativeOrder()).asFloatBuffer(); + public static final void _wglUniformMat2fv(UniformGL p1, float[] mat) { + matUpload.clear(); + matUpload.put(mat); + matUpload.flip(); + if(p1 != null) GL20.glUniformMatrix2(p1.obj, false, matUpload); + } + public static final void _wglUniformMat3fv(UniformGL p1, float[] mat) { + matUpload.clear(); + matUpload.put(mat); + matUpload.flip(); + if(p1 != null) GL20.glUniformMatrix3(p1.obj, false, matUpload); + } + public static final void _wglUniformMat4fv(UniformGL p1, float[] mat) { + matUpload.clear(); + matUpload.put(mat); + matUpload.flip(); + if(p1 != null) GL20.glUniformMatrix4(p1.obj, false, matUpload); + } + private static int currentProgram = 0; + public static final void _wglUseProgram(ProgramGL p1) { + int i = p1 == null ? 0 : p1.obj; + if(i != currentProgram) { + currentProgram = i; + GL20.glUseProgram(i); + } + } + public static final void _wglGetParameter(int p1, int size, int[] p3) { + if(p1 == _wGL_VIEWPORT) { + p3[0] = viewport[0]; p3[1] = viewport[1]; + p3[2] = viewport[2]; p3[3] = viewport[3]; + } + } + public static final void _wglPolygonOffset(float p1, float p2) { + GL11.glPolygonOffset(p1, p2); + } + public static final void _wglVertexAttribPointer(int p1, int p2, int p3, boolean p4, int p5, int p6) { + GL20.glVertexAttribPointer(p1, p2, p3, p4, p5, p6); + } + public static final void _wglBindFramebuffer(int p1, FramebufferGL p2) { + GL30.glBindFramebuffer(p1, p2 == null ? 0 : p2.obj); + } + public static final void _wglDrawBuffer(int p1) { + GL11.glDrawBuffer(p1); + } + public static final void _wglBlitFramebuffer(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9, int p10) { + GL30.glBlitFramebuffer(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + } + public static final FramebufferGL _wglCreateFramebuffer() { + return new FramebufferGL(GL30.glGenFramebuffers()); + } + public static final void _wglDeleteFramebuffer(FramebufferGL p1) { + GL30.glDeleteFramebuffers(p1.obj); + } + public static final void _wglFramebufferTexture2D(int p1, TextureGL p2) { + GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, p1, GL11.GL_TEXTURE_2D, p2.obj, 0); + } + public static final RenderbufferGL _wglCreateRenderBuffer() { + return new RenderbufferGL(GL30.glGenRenderbuffers()); + } + public static final void _wglDeleteRenderbuffer(RenderbufferGL p1) { + GL30.glDeleteRenderbuffers(p1.obj); + } + public static final void _wglBindRenderbuffer(RenderbufferGL p1) { + GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, p1 == null ? 0 : p1.obj); + } + public static final void _wglRenderbufferStorage(int p1, int p2, int p3) { + GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, p1, p2, p3); + } + public static final void _wglRenderbufferStorageMultisample(int p1, int p2, int p3, int p4) { + GL30.glRenderbufferStorageMultisample(GL30.GL_RENDERBUFFER, p1, p2, p3, p4); + } + public static final void _wglFramebufferRenderbuffer(int p1, RenderbufferGL p2) { + GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, p1, GL30.GL_RENDERBUFFER, p2.obj); + } + public static final QueryGL _wglCreateQuery() { + return new QueryGL(GL15.glGenQueries()); + } + public static final void _wglBeginQuery(int p1, QueryGL p2) { + GL15.glBeginQuery(p1, p2.obj); + } + public static final void _wglEndQuery(int p1) { + GL15.glEndQuery(p1); + } + public static final void _wglDeleteQuery(QueryGL p1) { + GL15.glDeleteQueries(p1.obj); + } + public static final int _wglGetQueryObjecti(QueryGL p1, int p2) { + return GL15.glGetQueryObjecti(p1.obj, p2); + } + public static final void _wglLineWidth(float p1) { + GL11.glLineWidth(p1); + } + + + // ======================================================================================= + // ======================================================================================= + // ======================================================================================= + // ======================================================================================= + // ======================================================================================= + + private static Canvas daCanvas = null; + private static Frame eagler = null; + private static SoundSystem ss = null; + public static final void initializeContext() { + daCanvas = new Canvas(); + eagler = new Frame(); + eagler.setTitle("eaglercraft desktop runtime"); + eagler.setBackground(Color.BLACK); + JPanel var16 = new JPanel(); + eagler.setLayout(new BorderLayout()); + var16.setPreferredSize(new Dimension(854, 480)); + eagler.add(var16, "Center"); + eagler.pack(); + eagler.setLocationRelativeTo((Component) null); + eagler.setVisible(true); + eagler.addWindowListener(new GameWindowListener()); + eagler.removeAll(); + eagler.setLayout(new BorderLayout()); + eagler.add(daCanvas, "Center"); + eagler.validate(); + eagler.setVisible(true); + + try { + ContextAttribs contextAtrributes = new ContextAttribs(3, 2).withForwardCompatible(true).withProfileCore(true).withDebug(true); + Display.setParent(daCanvas); + Display.create((new PixelFormat()).withDepthBits(24), contextAtrributes); + } catch (LWJGLException var5) { + var5.printStackTrace(); + + try { + Thread.sleep(1000L); + } catch (InterruptedException var4) { + ; + } + + try { + Display.create(); + } catch (LWJGLException e) { + e.printStackTrace(); + } + } + + //if(!_wisWebGL()) { + // GL30.glBindVertexArray(GL30.glGenVertexArrays()); + //} + + EarlyLoadScreen.paintScreen(); + + try { + Mouse.create(); + Keyboard.create(); + } catch (LWJGLException var5) { + var5.printStackTrace(); + } + + if(useEPKTest) { + try { + InputStream stream = new FileInputStream(new File("out.epk")); + byte[] targetArray = new byte[stream.available()]; + stream.read(targetArray); + stream.close(); + AssetRepository.install(targetArray); + } catch(IOException e) { + e.printStackTrace(); + } + } + + Display.setTitle("eaglercraft desktop runtime"); + System.out.println("LWJGL Version: " + Sys.getVersion()); + + _wGL_ANY_SAMPLES_PASSED = ARBOcclusionQuery2.GL_ANY_SAMPLES_PASSED; + _wGL_TEXTURE_MAX_ANISOTROPY = EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT; + + GL11.glEnable(ARBDebugOutput.GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); + ARBDebugOutput.glDebugMessageCallbackARB(new ARBDebugOutputCallback(new ARBDebugOutputCallback.Handler() { + + @Override + public void handleMessage(int arg0, int arg1, int arg2, int arg3, String arg4) { + if(arg3 == ARBDebugOutput.GL_DEBUG_SEVERITY_MEDIUM_ARB || arg3 == ARBDebugOutput.GL_DEBUG_SEVERITY_HIGH_ARB) { + StringBuilder b = new StringBuilder(); + b.append("[KHR DEBUG #"); b.append(arg2); b.append("] "); + switch(arg0) { + case ARBDebugOutput.GL_DEBUG_SOURCE_API_ARB: b.append("[API - "); break; + case ARBDebugOutput.GL_DEBUG_SOURCE_APPLICATION_ARB: b.append("[APPLICATION - "); break; + default: + case ARBDebugOutput.GL_DEBUG_SOURCE_OTHER_ARB: b.append("[OTHER - "); break; + case ARBDebugOutput.GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: b.append("[SHADER COMPILER - "); break; + case ARBDebugOutput.GL_DEBUG_SOURCE_THIRD_PARTY_ARB: b.append("[THIRD PARTY - "); break; + } + switch(arg1) { + case ARBDebugOutput.GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: b.append("DEPRECATED BEHAVIOR] "); break; + case ARBDebugOutput.GL_DEBUG_TYPE_ERROR_ARB: b.append("ERROR] "); break; + default: + case ARBDebugOutput.GL_DEBUG_TYPE_OTHER_ARB: b.append("OTHER] "); break; + case ARBDebugOutput.GL_DEBUG_TYPE_PERFORMANCE_ARB: b.append("PERFORMANCE] "); break; + case ARBDebugOutput.GL_DEBUG_TYPE_PORTABILITY_ARB: b.append("PORTABILITY] "); break; + case ARBDebugOutput.GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: b.append("UNDEFINED BEHAVIOR] "); break; + } + switch(arg3) { + default: + case ARBDebugOutput.GL_DEBUG_SEVERITY_LOW_ARB: b.append("[LOW Severity] "); break; + case ARBDebugOutput.GL_DEBUG_SEVERITY_MEDIUM_ARB: b.append("[MEDIUM Severity] "); break; + case ARBDebugOutput.GL_DEBUG_SEVERITY_HIGH_ARB: b.append("[SEVERE] "); break; + } + b.append(arg4); + System.err.println(b.toString()); + if(arg3 == ARBDebugOutput.GL_DEBUG_SEVERITY_HIGH_ARB) { + throw new RuntimeException("GL_DEBUG_SEVERITY_HIGH_ARB was thrown"); + } + } + } + + })); + + try { + SoundSystemConfig.addLibrary(LibraryLWJGLOpenAL.class); + SoundSystemConfig.setCodec("mp3", CodecJLayerMP3.class); + ss = new SoundSystem(); + }catch(Throwable t) { + t.printStackTrace(); + } + } + public static final void destroyContext() { + Display.destroy(); + Keyboard.destroy(); + Mouse.destroy(); + eagler.dispose(); + if(ss != null) { + ss.cleanup(); + } + } + public static final boolean mouseNext() { + return Mouse.next(); + } + public static final int mouseGetEventButton() { + return Mouse.getEventButton(); + } + public static final boolean mouseGetEventButtonState() { + return Mouse.getEventButtonState(); + } + public static final boolean mouseIsButtonDown(int p1) { + return Mouse.isButtonDown(p1); + } + public static final int mouseGetEventDWheel() { + return Mouse.getDWheel(); + } + public static final void mouseSetCursorPosition(int x, int y) { + Mouse.setCursorPosition(x, y); + } + public static final void mouseSetGrabbed(boolean grabbed) { + Mouse.setGrabbed(grabbed); + } + public static final int mouseGetDX() { + return Mouse.getDX(); + } + public static final int mouseGetDY() { + return Mouse.getDY(); + } + public static final int mouseGetX() { + return Mouse.getX(); + } + public static final int mouseGetY() { + return Mouse.getY(); + } + public static final int mouseGetEventX() { + return Mouse.getEventX(); + } + public static final int mouseGetEventY() { + return Mouse.getEventY(); + } + public static final boolean keysNext() { + return Keyboard.next(); + } + public static final int getEventKey() { + return Keyboard.getEventKey(); + } + public static final char getEventChar() { + return Keyboard.getEventCharacter(); + } + public static final boolean getEventKeyState() { + return Keyboard.getEventKeyState(); + } + public static final boolean isKeyDown(int p1) { + return Keyboard.isKeyDown(p1); + } + public static final String getKeyName(int p1) { + return Keyboard.getKeyName(p1); + } + public static final void setFullscreen(boolean p1) { + try { + Display.setFullscreen(p1); + } catch (LWJGLException e) { + e.printStackTrace(); + } + } + public static final boolean shouldShutdown() { + return Display.isCloseRequested(); + } + public static final void updateDisplay() { + Display.update(); + } + public static final void setVSyncEnabled(boolean p1) { + Display.setVSyncEnabled(p1); + } + public static final void enableRepeatEvents(boolean b) { + Keyboard.enableRepeatEvents(b); + } + public static final boolean isFocused() { + return Display.isActive(); + } + public static final int getScreenWidth() { + return Display.getDisplayMode().getWidth(); + } + public static final int getScreenHeight() { + return Display.getDisplayMode().getHeight(); + } + public static final int getCanvasWidth() { + return daCanvas.getWidth(); + } + public static final int getCanvasHeight() { + return daCanvas.getHeight(); + } + public static final void setDisplaySize(int x, int y) { + try { + Display.setDisplayMode(new DisplayMode(x, y)); + } catch (LWJGLException e) { + e.printStackTrace(); + } + } + public static final void syncDisplay(int performanceToFps) { + Display.sync(performanceToFps); + } + + private static WebSocketClient clientSocket = null; + private static final Object socketSync = new Object(); + + private static LinkedList readPackets = new LinkedList(); + + private static class EaglerSocketClient extends WebSocketClient { + + private Exception currentException = null; + + public EaglerSocketClient(URI serverUri) throws IOException, InterruptedException { + super(serverUri); + this.setTcpNoDelay(true); + this.setConnectionLostTimeout(5); + System.out.println("[ws] connecting to "+serverUri.toString()); + if(!this.connectBlocking(5, TimeUnit.SECONDS)) { + throw new IOException("could not connect socket", currentException); + } + } + + @Override + public void onClose(int arg0, String arg1, boolean arg2) { + synchronized(socketSync) { + readPackets.clear(); + System.out.println("[ws] disconnecting - " + currentException); + currentException = null; + } + } + + @Override + public void onError(Exception arg0) { + currentException = arg0; + } + + @Override + public void onMessage(String arg0) { + System.out.println("[ws] " + arg0); + currentException = null; + } + + @Override + public void onMessage(ByteBuffer arg0) { + synchronized(socketSync) { + readPackets.add(arg0.array()); + } + currentException = null; + } + + @Override + public void onOpen(ServerHandshake arg0) { + System.out.println("[ws] connected."); + } + + } + + public static final boolean startConnection(String uri) { + if(clientSocket == null) { + try { + clientSocket = new EaglerSocketClient(new URI(uri)); + return true; + }catch(InterruptedException e) { + clientSocket = null; + } catch (URISyntaxException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return false; + } + public static final void endConnection() { + synchronized(socketSync) { + if(clientSocket.isOpen()) { + clientSocket.close(); + } + clientSocket = null; + readPackets.clear(); + } + } + public static final boolean connectionOpen() { + return clientSocket != null && clientSocket.isOpen(); + } + public static final void writePacket(byte[] packet) { + if(clientSocket != null && clientSocket.isOpen()) { + clientSocket.send(ByteBuffer.wrap(packet)); + } + } + public static final byte[] readPacket() { + synchronized(socketSync) { + if(!readPackets.isEmpty()) { + return readPackets.remove(0); + } + } + return null; + } + public static final byte[] loadLocalStorage(String key) { + try { + File f = new File("_eagstorage."+key+".dat"); + byte[] b = new byte[(int)f.length()]; + FileInputStream s = new FileInputStream(f); + s.read(b); + s.close(); + return b; + } catch (IOException e) { + return null; + } + } + public static final void saveLocalStorage(String key, byte[] data) { + try { + FileOutputStream f = new FileOutputStream(new File("_eagstorage."+key+".dat")); + f.write(data); + f.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + public static final void openLink(String url) { + try { + Class var3 = Class.forName("java.awt.Desktop"); + Object var4 = var3.getMethod("getDesktop", new Class[0]).invoke((Object) null, new Object[0]); + var3.getMethod("browse", new Class[] { URI.class }).invoke(var4, new Object[] { new URI(url) }); + } catch (Throwable var5) { + var5.printStackTrace(); + } + } + private static volatile boolean fileChooserOpen = false; + private static volatile byte[] fileChooserFile = null; + private static volatile String fileChooserName = null; + public static final void openFileChooser(final String ext, final String mime) { + EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + if(!fileChooserOpen) { + fileChooserOpen = true; + try { + JFileChooser yee = new JFileChooser(new File(System.getProperty("user.home"))); + yee.setDialogTitle("select a file"); + yee.setFileSelectionMode(JFileChooser.FILES_ONLY); + yee.setMultiSelectionEnabled(false); + yee.setFileFilter(new FileFilter() { + + @Override + public String getDescription() { + return ext+" files"; + } + + @Override + public boolean accept(File f) { + return f.isDirectory() || f.getName().endsWith("."+ext); + } + }); + if(yee.showOpenDialog(eagler) == JFileChooser.APPROVE_OPTION) { + File f = yee.getSelectedFile(); + fileChooserName = f.getName(); + try { + byte[] b = new byte[(int)f.length()]; + FileInputStream s = new FileInputStream(f); + s.read(b); + s.close(); + fileChooserFile = b; + } catch (IOException e) { + fileChooserFile = new byte[0]; + } + }else { + fileChooserFile = new byte[0]; + } + }catch(Throwable t) { + fileChooserFile = new byte[0]; + } + fileChooserOpen = false; + } + } + + }); + } + public static final byte[] getFileChooserResult() { + byte[] b = fileChooserFile; + fileChooserFile = null; + return b; + } + public static final String getFileChooserResultName() { + String s = fileChooserName; + fileChooserName = null; + return s; + } + public static final void setListenerPos(float x, float y, float z, float vx, float vy, float vz, float pitch, float yaw) { + float var11 = MathHelper.cos(-yaw * 0.017453292F - (float) Math.PI); + float var12 = MathHelper.sin(-yaw * 0.017453292F - (float) Math.PI); + float var13 = -var12; + float var14 = -MathHelper.sin(-pitch * 0.017453292F - (float) Math.PI); + float var15 = -var11; + float var16 = 0.0F; + float var17 = 1.0F; + float var18 = 0.0F; + ss.setListenerPosition(x, y, z); + ss.setListenerOrientation(var13, var14, var15, var16, var17, var18); + ss.setListenerVelocity(vx, vy, vz); + } + private static int playbackId = 0; + public static final int beginPlayback(String fileName, float x, float y, float z, float volume, float pitch) { + int id = ++playbackId; + URL loc = null; + if((loc = getResourceURL(fileName)) != null) { + String name = "sound_"+id; + float var8 = 16.0F; + if (volume > 1.0F) { + var8 *= volume; + } + ss.newSource(false, name, loc, fileName, false, x, y, z, 2, var8); + ss.setTemporary(name, true); + ss.setPitch(name, pitch); + ss.setVolume(name, volume); + ss.play(name); + }else { + System.err.println("unknown sound event "+fileName); + } + return id; + } + public static final int beginPlaybackStatic(String fileName, float volume, float pitch) { + int id = ++playbackId; + URL loc = null; + if((loc = getResourceURL(fileName)) != null) { + String name = "sound_"+id; + ss.newSource(false, name, loc, fileName, false, 0f, 0f, 0f, 0, 0f); + ss.setTemporary(name, true); + ss.setPitch(name, pitch); + ss.setVolume(name, volume); + ss.play(name); + }else { + System.err.println("unknown sound event "+fileName); + } + return id; + } + private static URL getResourceURL(String path) { + try { + File f = new File("resources", path); + if(f.exists()) { + return f.toURI().toURL(); + } + } catch (MalformedURLException e) { + e.printStackTrace(); + } + return null; + } + public static final void setPitch(int id, float pitch) { + String name = "sound_"+id; + if(ss.playing(name)) { + ss.setPitch(name, pitch); + } + } + public static final void setVolume(int id, float volume) { + String name = "sound_"+id; + if(ss.playing(name)) { + ss.setVolume(name, volume); + } + } + public static final void moveSound(int id, float x, float y, float z, float vx, float vy, float vz) { + String name = "sound_"+id; + if(ss.playing(name)) { + ss.setPosition(name, x, y, z); + ss.setVelocity(name, vx, vy, vz); + } + } + public static final void endSound(int id) { + String name = "sound_"+id; + if(ss.playing(name)) { + ss.stop(name); + } + } + public static final boolean isPlaying(int id) { + return ss.playing("sound_"+id); + } + public static final void openConsole() { + EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + JOptionPane.showMessageDialog(eagler, "not supported in lwjgl runtime", "eaglercraft", JOptionPane.ERROR_MESSAGE); + } + + }); + } + private static boolean connected = false; + public static final void voiceConnect(String channel) { + connected = true; + } + public static final void voiceVolume(float volume) { + + } + public static final boolean voiceActive() { + return connected; + } + public static final boolean voiceRelayed() { + return connected; + } + public static final String[] voiceUsers() { + return new String[0]; + } + public static final String[] voiceUsersTalking() { + return new String[0]; + } + public static final void voiceEnd() { + connected = false; + } + public static final void doJavascriptCoroutines() { + + } + public static final long maxMemory() { + return Runtime.getRuntime().maxMemory(); + } + public static final long totalMemory() { + return Runtime.getRuntime().totalMemory(); + } + public static final long freeMemory() { + return Runtime.getRuntime().freeMemory(); + } + public static final void exit() { + System.exit(0); + } + public static final int _wArrayByteLength(Object obj) { + return ((IntBuffer)obj).remaining() * 4; + } + public static final Object _wCreateLowLevelIntBuffer(int len) { + return ByteBuffer.allocateDirect(len*4).order(ByteOrder.nativeOrder()).asIntBuffer(); + } + + private static final IntBuffer appendbuffer = (IntBuffer) _wCreateLowLevelIntBuffer(525000); + + public static final void _wAppendLowLevelBuffer(Object arr) { + if(appendbuffer.limit() != appendbuffer.capacity()) appendbuffer.clear(); + IntBuffer a = (IntBuffer)arr; + if(appendbuffer.remaining() >= a.remaining()) { + appendbuffer.put(a); + } + } + + public static final Object _wGetLowLevelBuffersAppended() { + appendbuffer.flip(); + return appendbuffer; + } + +} diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/Tessellator.java b/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/Tessellator.java new file mode 100644 index 0000000..6970565 --- /dev/null +++ b/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/Tessellator.java @@ -0,0 +1,384 @@ +package net.lax1dude.eaglercraft.adapter; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.IntBuffer; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.minecraft.src.MathHelper; + +public class Tessellator { + + /** The byte buffer used for GL allocation. */ + private ByteBuffer byteBuffer; + private IntBuffer intBuffer; + + /** Raw integer array. */ + private int[] rawBuffer; + + /** + * The number of vertices to be drawn in the next draw call. Reset to 0 between + * draw calls. + */ + private int vertexCount = 0; + + /** The first coordinate to be used for the texture. */ + private double textureU; + + /** The second coordinate to be used for the texture. */ + private double textureV; + private int brightness; + + /** The color (RGBA) value to be used for the following draw call. */ + private int color; + + /** + * Whether the current draw object for this tessellator has color values. + */ + private boolean hasColor = false; + + /** + * Whether the current draw object for this tessellator has texture coordinates. + */ + private boolean hasTexture = false; + private boolean hasBrightness = false; + + /** + * Whether the current draw object for this tessellator has normal values. + */ + private boolean hasNormals = false; + + /** The index into the raw buffer to be used for the next data. */ + private int rawBufferIndex = 0; + + /** + * The number of vertices manually added to the given draw call. This differs + * from vertexCount because it adds extra vertices when converting quads to + * triangles. + */ + private int addedVertices = 0; + + /** Disables all color information for the following draw call. */ + private boolean isColorDisabled = false; + + /** The draw mode currently being used by the tessellator. */ + private int drawMode; + + /** + * An offset to be applied along the x-axis for all vertices in this draw call. + */ + private double xOffset; + + /** + * An offset to be applied along the y-axis for all vertices in this draw call. + */ + private double yOffset; + + /** + * An offset to be applied along the z-axis for all vertices in this draw call. + */ + private double zOffset; + + /** The normal to be applied to the face being drawn. */ + private int normal; + + /** The static instance of the Tessellator. */ + public static final Tessellator instance = new Tessellator(525000); + + /** Whether this tessellator is currently in draw mode. */ + private boolean isDrawing = false; + + /** Whether we are currently using VBO or not. */ + private boolean useVBO = false; + + /** The size of the buffers used (in integers). */ + private int bufferSize; + + private Tessellator(int par1) { + this.bufferSize = par1; + this.byteBuffer = ByteBuffer.allocateDirect(par1 * 4).order(ByteOrder.nativeOrder()); + this.intBuffer = this.byteBuffer.asIntBuffer(); + this.rawBuffer = new int[par1]; + this.useVBO = false;// tryVBO && GLContext.getCapabilities().GL_ARB_vertex_buffer_object; + + //if (this.useVBO) { + //this.vertexBuffers = GLAllocation.createDirectIntBuffer(this.vboCount); + //ARBVertexBufferObject.glGenBuffersARB(this.vertexBuffers); + //} + } + + /** + * Draws the data set up in this tessellator and resets the state to prepare for + * new drawing. + */ + public int draw() { + if (!this.isDrawing) { + return 0; + } else { + this.isDrawing = false; + + if (this.vertexCount > 0) { + IntBuffer up = null; + this.intBuffer.clear(); + this.intBuffer.put(rawBuffer, 0, this.rawBufferIndex); + this.intBuffer.flip(); + up = this.intBuffer; + + if (this.hasTexture) { + EaglerAdapter.glEnableVertexAttrib(EaglerAdapter.GL_TEXTURE_COORD_ARRAY); + } + + if (this.hasColor) { + EaglerAdapter.glEnableVertexAttrib(EaglerAdapter.GL_COLOR_ARRAY); + } + + if (this.hasNormals) { + EaglerAdapter.glEnableVertexAttrib(EaglerAdapter.GL_NORMAL_ARRAY); + } + + if (this.hasBrightness) { + EaglerAdapter.glClientActiveTexture(EaglerAdapter.GL_TEXTURE1); + EaglerAdapter.glEnableVertexAttrib(EaglerAdapter.GL_TEXTURE_COORD_ARRAY); + EaglerAdapter.glClientActiveTexture(EaglerAdapter.GL_TEXTURE0); + } + + EaglerAdapter.glDrawArrays(this.drawMode, 0, this.vertexCount, up); + + if (this.hasTexture) { + EaglerAdapter.glDisableVertexAttrib(EaglerAdapter.GL_TEXTURE_COORD_ARRAY); + } + + if (this.hasColor) { + EaglerAdapter.glDisableVertexAttrib(EaglerAdapter.GL_COLOR_ARRAY); + } + + if (this.hasNormals) { + EaglerAdapter.glDisableVertexAttrib(EaglerAdapter.GL_NORMAL_ARRAY); + } + + if (this.hasBrightness) { + EaglerAdapter.glClientActiveTexture(EaglerAdapter.GL_TEXTURE1); + EaglerAdapter.glDisableVertexAttrib(EaglerAdapter.GL_TEXTURE_COORD_ARRAY); + EaglerAdapter.glClientActiveTexture(EaglerAdapter.GL_TEXTURE0); + } + } + + int var1 = this.rawBufferIndex * 4; + this.reset(); + return var1; + } + } + + /** + * Clears the tessellator state in preparation for new drawing. + */ + private void reset() { + this.vertexCount = 0; + this.rawBufferIndex = 0; + this.addedVertices = 0; + } + + /** + * Sets draw mode in the tessellator to draw quads. + */ + public void startDrawingQuads() { + this.startDrawing(EaglerAdapter.GL_QUADS); + } + + /** + * Resets tessellator state and prepares for drawing (with the specified draw + * mode). + */ + public void startDrawing(int par1) { + if (this.isDrawing) { + this.draw(); + } + this.isDrawing = true; + this.reset(); + this.drawMode = par1; + this.hasNormals = false; + this.hasColor = false; + this.hasTexture = false; + this.hasBrightness = false; + this.isColorDisabled = false; + } + + /** + * Sets the texture coordinates. + */ + public void setTextureUV(double par1, double par3) { + this.hasTexture = true; + this.textureU = par1; + this.textureV = par3; + } + + public void setBrightness(int par1) { + this.hasBrightness = true; + this.brightness = par1; + } + + /** + * Sets the RGB values as specified, converting from floats between 0 and 1 to + * integers from 0-255. + */ + public void setColorOpaque_F(float par1, float par2, float par3) { + this.setColorOpaque((int) (par1 * 255.0F), (int) (par2 * 255.0F), (int) (par3 * 255.0F)); + } + + /** + * Sets the RGBA values for the color, converting from floats between 0 and 1 to + * integers from 0-255. + */ + public void setColorRGBA_F(float par1, float par2, float par3, float par4) { + this.setColorRGBA((int) (par1 * 255.0F), (int) (par2 * 255.0F), (int) (par3 * 255.0F), (int) (par4 * 255.0F)); + } + + /** + * Sets the RGB values as specified, and sets alpha to opaque. + */ + public void setColorOpaque(int par1, int par2, int par3) { + this.setColorRGBA(par1, par2, par3, 255); + } + + /** + * Sets the RGBA values for the color. Also clamps them to 0-255. + */ + public void setColorRGBA(int par1, int par2, int par3, int par4) { + if (!this.isColorDisabled) { + if (par1 > 255) { + par1 = 255; + } + + if (par2 > 255) { + par2 = 255; + } + + if (par3 > 255) { + par3 = 255; + } + + if (par4 > 255) { + par4 = 255; + } + + if (par1 < 0) { + par1 = 0; + } + + if (par2 < 0) { + par2 = 0; + } + + if (par3 < 0) { + par3 = 0; + } + + if (par4 < 0) { + par4 = 0; + } + + this.hasColor = true; + this.color = par4 << 24 | par3 << 16 | par2 << 8 | par1; + } + } + + /** + * Adds a vertex specifying both x,y,z and the texture u,v for it. + */ + public void addVertexWithUV(double par1, double par3, double par5, double par7, double par9) { + this.setTextureUV(par7, par9); + this.addVertex(par1, par3, par5); + } + + /** + * Adds a vertex with the specified x,y,z to the current draw call. It will + * trigger a draw() if the buffer gets full. + */ + public void addVertex(double par1, double par3, double par5) { + if(this.addedVertices > 65534) return; + ++this.addedVertices; + + this.rawBuffer[this.rawBufferIndex + 0] = Float.floatToRawIntBits((float) (par1 + this.xOffset)); + this.rawBuffer[this.rawBufferIndex + 1] = Float.floatToRawIntBits((float) (par3 + this.yOffset)); + this.rawBuffer[this.rawBufferIndex + 2] = Float.floatToRawIntBits((float) (par5 + this.zOffset)); + + if (this.hasTexture) { + this.rawBuffer[this.rawBufferIndex + 3] = Float.floatToRawIntBits((float) this.textureU); + this.rawBuffer[this.rawBufferIndex + 4] = Float.floatToRawIntBits((float) this.textureV); + } + + if (this.hasColor) { + this.rawBuffer[this.rawBufferIndex + 5] = this.color; + } + + if (this.hasNormals) { + this.rawBuffer[this.rawBufferIndex + 6] = this.normal; + } + + if (this.hasBrightness) { + this.rawBuffer[this.rawBufferIndex + 7] = this.brightness; + } + + this.rawBufferIndex += 8; + ++this.vertexCount; + } + + /** + * Sets the color to the given opaque value (stored as byte values packed in an + * integer). + */ + public void setColorOpaque_I(int par1) { + int var2 = par1 >> 16 & 255; + int var3 = par1 >> 8 & 255; + int var4 = par1 & 255; + this.setColorOpaque(var2, var3, var4); + } + + /** + * Sets the color to the given color (packed as bytes in integer) and alpha + * values. + */ + public void setColorRGBA_I(int par1, int par2) { + int var3 = par1 >> 16 & 255; + int var4 = par1 >> 8 & 255; + int var5 = par1 & 255; + this.setColorRGBA(var3, var4, var5, par2); + } + + /** + * Disables colors for the current draw call. + */ + public void disableColor() { + this.isColorDisabled = true; + } + + /** + * Sets the normal for the current draw call. + */ + public void setNormal(float par1, float par2, float par3) { + this.hasNormals = true; + float len = (float) Math.sqrt(par1 * par1 + par2 * par2 + par3 * par3); + int var4 = (int)((par1 / len) * 128.0F) + 127; + int var5 = (int)((par2 / len) * 128.0F) + 127; + int var6 = (int)((par3 / len) * 128.0F) + 127; + this.normal = var4 & 255 | (var5 & 255) << 8 | (var6 & 255) << 16; + } + + /** + * Sets the translation for all vertices in the current draw call. + */ + public void setTranslation(double par1, double par3, double par5) { + this.xOffset = par1; + this.yOffset = par3; + this.zOffset = par5; + } + + /** + * Offsets the translation for all vertices in the current draw call. + */ + public void addTranslation(float par1, float par2, float par3) { + this.xOffset += (double) par1; + this.yOffset += (double) par2; + this.zOffset += (double) par3; + } +} diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/lwjgl/GameWindowListener.java b/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/lwjgl/GameWindowListener.java new file mode 100644 index 0000000..9206a5e --- /dev/null +++ b/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/lwjgl/GameWindowListener.java @@ -0,0 +1,12 @@ +package net.lax1dude.eaglercraft.adapter.lwjgl; + +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import net.minecraft.client.Minecraft; + +public final class GameWindowListener extends WindowAdapter { + public void windowClosing(WindowEvent par1WindowEvent) { + Minecraft.getMinecraft().shutdown(); + } +} diff --git a/src/lwjgl/java/paulscode/sound/Channel.java b/src/lwjgl/java/paulscode/sound/Channel.java new file mode 100644 index 0000000..af0efa4 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/Channel.java @@ -0,0 +1,270 @@ +package paulscode.sound; + +import java.util.LinkedList; +import javax.sound.sampled.AudioFormat; + +/** + * The Channel class is the base class which can be extended for + * library-specific channels. It is also used in the "no-sound" library. + * A channel is a reserved sound-card voice through which sources are played + * back. Channels can be either streaming channels or normal (non-streaming) + * ones. For consistant naming conventions, each sub-class should have the + * name prefix "Channel". + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class Channel +{ +/** + * The library class associated with this type of channel. + */ + protected Class libraryType = Library.class; + +/** + * Global identifier for the type of channel (normal or streaming). Possible + * values for this varriable can be found in the + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} class. + */ + public int channelType; + +/** + * Processes status messages, warnings, and error messages. + */ + private SoundSystemLogger logger; + +/** + * Whatever source is attached to this channel. + */ + public Source attachedSource = null; + +/** + * Cumulative counter of the buffers played then unqued. + */ + public int buffersUnqueued = 0; + +/** + * Constructor: Takes channelType identifier as a paramater. Possible values + * for channel type can be found in the + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} class. + * @param type Type of channel (normal or streaming). + */ + public Channel( int type ) + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + channelType = type; + } + +/** + * Shuts the channel down and removes references to all instantiated objects. + */ + public void cleanup() + { + logger = null; + } + +/** + * Queues up the initial byte[] buffers of data to be streamed. + * @param bufferList List of the first buffers to be played for a streaming source. + * @return False if an error occurred or if end of stream was reached. + */ + public boolean preLoadBuffers( LinkedList bufferList ) + { + return true; + } + +/** + * Queues up a byte[] buffer of data to be streamed. + * @param buffer The next buffer to be played for a streaming source. + * @return False if an error occurred or if the channel is shutting down. + */ + public boolean queueBuffer( byte[] buffer ) + { + return false; + } + +/** + * Feeds raw data to the stream. + * @param buffer Buffer containing raw audio data to stream. + * @return Number of prior buffers that have been processed. + */ + public int feedRawAudioData( byte[] buffer ) + { + return 1; + } + +/** + * Returns the number of queued byte[] buffers that have finished playing. + * @return Number of buffers processed. + */ + public int buffersProcessed() + { + return 0; + } + +/** + * Calculates the number of milliseconds since the channel began playing. + * @return Milliseconds, or -1 if unable to calculate. + */ + public float millisecondsPlayed() + { + return -1; + } +/** + * Plays the next queued byte[] buffer. This method is run from the seperate + * {@link paulscode.sound.StreamThread StreamThread}. + * @return False when no more buffers are left to process. + */ + public boolean processBuffer() + { + return false; + } + +/** + * Sets the channel up to receive the specified audio format. + */ + public void setAudioFormat( AudioFormat audioFormat ) + {} + +/** + * Dequeues all previously queued data. + */ + public void flush() + {} + +/** + * Stops the channel, dequeues any queued data, and closes the channel. + */ + public void close() + {} + +/** + * Plays the currently attached normal source, opens this channel up for + * streaming, or resumes playback if this channel was paused. + */ + public void play() + {} + +/** + * Temporarily stops playback for this channel. + */ + public void pause() + {} + +/** + * Stops playback for this channel and rewinds the attached source to the + * beginning. + */ + public void stop() + {} + +/** + * Rewinds the attached source to the beginning. Stops the source if it was + * paused. + */ + public void rewind() + {} + +/** + * Used to determine if a channel is actively playing a source. This method + * will return false if the channel is paused or stopped and when no data is + * queued to be streamed. + * @return True if this channel is playing a source. + */ + public boolean playing() + { + return false; + } + +/** + * Returns the name of the class. + * @return "Channel" + library title. + */ + public String getClassName() + { + String libTitle = SoundSystemConfig.getLibraryTitle( libraryType ); + + if( libTitle.equals( "No Sound" ) ) + return "Channel"; + else + return "Channel" + libTitle; + } + +/** + * Prints a message. + * @param message Message to print. + */ + protected void message( String message ) + { + logger.message( message, 0 ); + } + +/** + * Prints an important message. + * @param message Message to print. + */ + protected void importantMessage( String message ) + { + logger.importantMessage( message, 0 ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param message Message to print if error is true. + * @return True if error is true. + */ + protected boolean errorCheck( boolean error, String message ) + { + return logger.errorCheck( error, getClassName(), message, 0 ); + } + +/** + * Prints an error message. + * @param message Message to print. + */ + protected void errorMessage( String message ) + { + logger.errorMessage( getClassName(), message, 0 ); + } + +/** + * Prints an exception's error message followed by the stack trace. + * @param e Exception containing the information to print. + */ + protected void printStackTrace( Exception e ) + { + logger.printStackTrace( e, 1 ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/CommandObject.java b/src/lwjgl/java/paulscode/sound/CommandObject.java new file mode 100644 index 0000000..11107af --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/CommandObject.java @@ -0,0 +1,603 @@ +package paulscode.sound; + +/** + * The CommandObject class is used to store arguments in the SoundSystem's + * Command Queue. Queued CommandObjects are then processed by the + * {@link paulscode.sound.CommandThread CommandThread}. Commands are queued + * and executed in the background, so it is unlikely that the user will ever + * need to use this class. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class CommandObject +{ +/** + * Global identifier for the command to initialize the current sound library. + */ + public static final int INITIALIZE = 1; +/** + * Global identifier for the command to pre-load a sound file. + */ + public static final int LOAD_SOUND = 2; +/** + * Global identifier for the command to pre-load a sound file. + */ + public static final int LOAD_DATA = 3; +/** + * Global identifier for the command to remove a sound file from memory. + */ + public static final int UNLOAD_SOUND = 4; +/** + * Global identifier for the command to queue a sound file. + */ + public static final int QUEUE_SOUND = 5; +/** + * Global identifier for the command to dequeue a sound file. + */ + public static final int DEQUEUE_SOUND = 6; +/** + * Global identifier for the command to fade-out transition a source. + */ + public static final int FADE_OUT = 7; +/** + * Global identifier for the command to fade-out/in transition a source. + */ + public static final int FADE_OUT_IN = 8; +/** + * Global identifier for the command to check volume levels of fading sources. + */ + public static final int CHECK_FADE_VOLUMES = 9; +/** + * Global identifier for the command to create a new source. + */ + public static final int NEW_SOURCE = 10; +/** + * Global identifier for the command to create a new raw data stream. + */ + public static final int RAW_DATA_STREAM = 11; +/** + * Global identifier for the command to create a source and immediately play it. + */ + public static final int QUICK_PLAY = 12; +/** + * Global identifier for the command to set a source's position in 3D space. + */ + public static final int SET_POSITION = 13; +/** + * Global identifier for the command to change a source's volume. + */ + public static final int SET_VOLUME = 14; +/** + * Global identifier for the command to change a source's pitch. + */ + public static final int SET_PITCH = 15; +/** + * Global identifier for the command to change a source's priority. + */ + public static final int SET_PRIORITY = 16; +/** + * Global identifier for the command to tell a source whether or not to loop. + */ + public static final int SET_LOOPING = 17; +/** + * Global identifier for the command to set a source's attenuation model. + */ + public static final int SET_ATTENUATION = 18; +/** + * Global identifier for the command to set a source's fade distance or rolloff + * factor. + */ + public static final int SET_DIST_OR_ROLL = 19; +/** + * Global identifier for the command to change the Doppler factor. + */ + public static final int CHANGE_DOPPLER_FACTOR = 20; +/** + * Global identifier for the command to change the Doppler velocity. + */ + public static final int CHANGE_DOPPLER_VELOCITY = 21; +/** + * Global identifier for the command to set a source's velocity. + */ + public static final int SET_VELOCITY = 22; +/** + * Global identifier for the command to set a source's velocity. + */ + public static final int SET_LISTENER_VELOCITY = 23; +/** + * Global identifier for the command to play a source. + */ + public static final int PLAY = 24; +/** + * Global identifier for the command to play a source. + */ + public static final int FEED_RAW_AUDIO_DATA = 25; +/** + * Global identifier for the command to pause a source. + */ + public static final int PAUSE = 26; +/** + * Global identifier for the command to stop a source. + */ + public static final int STOP = 27; +/** + * Global identifier for the command to rewind a source. + */ + public static final int REWIND = 28; +/** + * Global identifier for the command to flush all queued data. + */ + public static final int FLUSH = 29; +/** + * Global identifier for the command to cull a source. + */ + public static final int CULL = 30; +/** + * Global identifier for the command to activate a source. + */ + public static final int ACTIVATE = 31; +/** + * Global identifier for the command to set a source as permanant or temporary. + */ + public static final int SET_TEMPORARY = 32; +/** + * Global identifier for the command to delete a source. + */ + public static final int REMOVE_SOURCE = 33; +/** + * Global identifier for the command to move the listner. + */ + public static final int MOVE_LISTENER = 34; +/** + * Global identifier for the command to set the listener's position. + */ + public static final int SET_LISTENER_POSITION = 35; +/** + * Global identifier for the command to turn the listener. + */ + public static final int TURN_LISTENER = 36; +/** + * Global identifier for the command to set the listener's turn angle. + */ + public static final int SET_LISTENER_ANGLE = 37; +/** + * Global identifier for the command to change the listener's orientation. + */ + public static final int SET_LISTENER_ORIENTATION = 38; +/** + * Global identifier for the command to change the master volume. + */ + public static final int SET_MASTER_VOLUME = 39; +/** + * Global identifier for the command to create a new library. + */ + public static final int NEW_LIBRARY = 40; + +/** + * Any buffer required for a command. + */ + public byte[] buffer; +/** + * Any int arguments required for a command. + */ + public int[] intArgs; +/** + * Any float arguments required for a command. + */ + public float[] floatArgs; +/** + * Any long arguments required for a command. + */ + public long[] longArgs; +/** + * Any boolean arguments required for a command. + */ + public boolean[] boolArgs; +/** + * Any String arguments required for a command. + */ + public String[] stringArgs; + +/** + * Any Class arguments required for a command. + */ + public Class[] classArgs; + +/** + * Any Object arguments required for a command. + */ + public Object[] objectArgs; + +/** + * Which command to execute. + */ + public int Command; + +/** + * Constructor used to create a command which doesn't require any arguments. + * @param cmd Which command to execute. + */ + public CommandObject( int cmd ) + { + Command = cmd; + } +/** + * Constructor used to create a command which requires one integer argument. + * @param cmd Which command to execute. + * @param i The integer argument needed to execute this command. + */ + public CommandObject( int cmd, int i ) + { + Command = cmd; + intArgs = new int[1]; + intArgs[0] = i; + } +/** + * Constructor used to create a command which requires one Library Class + * argument. + * @param cmd Which command to execute. + * @param c The Library Class argument needed to execute this command. + */ + public CommandObject( int cmd, Class c ) + { + Command = cmd; + classArgs = new Class[1]; + classArgs[0] = c; + } +/** + * Constructor used to create a command which requires one float argument. + * @param cmd Which command to execute. + * @param f The float argument needed to execute this command. + */ + public CommandObject( int cmd, float f ) + { + Command = cmd; + floatArgs = new float[1]; + floatArgs[0] = f; + } +/** + * Constructor used to create a command which requires one String argument. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + */ + public CommandObject( int cmd, String s ) + { + Command = cmd; + stringArgs = new String[1]; + stringArgs[0] = s; + } +/** + * Constructor used to create a command which requires one Object argument. + * @param cmd Which command to execute. + * @param o The Object argument needed to execute this command. + */ + public CommandObject( int cmd, Object o ) + { + Command = cmd; + objectArgs = new Object[1]; + objectArgs[0] = o; + } +/** + * Constructor used to create a command which requires one String argument and + * one Object argument. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param o The Object argument needed to execute this command. + */ + public CommandObject( int cmd, String s, Object o ) + { + Command = cmd; + stringArgs = new String[1]; + stringArgs[0] = s; + objectArgs = new Object[1]; + objectArgs[0] = o; + } +/** + * Constructor used to create a command which requires one String argument and + * one byte buffer argument. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param buff The byte buffer argument needed to execute this command. + */ + public CommandObject( int cmd, String s, byte[] buff ) + { + Command = cmd; + stringArgs = new String[1]; + stringArgs[0] = s; + buffer = buff; + } +/** + * Constructor used to create a command which requires one String argument, one + * Object argument, and one long argument. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param o The Object argument needed to execute this command. + * @param l The long argument needed to execute this command. + */ + public CommandObject( int cmd, String s, Object o, long l ) + { + Command = cmd; + stringArgs = new String[1]; + stringArgs[0] = s; + objectArgs = new Object[1]; + objectArgs[0] = o; + longArgs = new long[1]; + longArgs[0] = l; + } +/** + * Constructor used to create a command which requires one String argument, one + * Object argument, and two long arguments. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param o The Object argument needed to execute this command. + * @param l1 The first long argument needed to execute this command. + * @param l2 The second long argument needed to execute this command. + */ + public CommandObject( int cmd, String s, Object o, long l1, long l2 ) + { + Command = cmd; + stringArgs = new String[1]; + stringArgs[0] = s; + objectArgs = new Object[1]; + objectArgs[0] = o; + longArgs = new long[2]; + longArgs[0] = l1; + longArgs[1] = l2; + } +/** + * Constructor used to create a command which requires two String arguments. + * @param cmd Which command to execute. + * @param s1 The first String argument needed to execute this command. + * @param s2 The second String argument needed to execute this command. + */ + public CommandObject( int cmd, String s1, String s2 ) + { + Command = cmd; + stringArgs = new String[2]; + stringArgs[0] = s1; + stringArgs[1] = s2; + } +/** + * Constructor used to create a command which requires a String and an int as + * arguments. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param i The integer argument needed to execute this command. + */ + public CommandObject( int cmd, String s, int i ) + { + Command = cmd; + intArgs = new int[1]; + stringArgs = new String[1]; + intArgs[0] = i; + stringArgs[0] = s; + } +/** + * Constructor used to create a command which requires a String and a float as + * arguments. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param f The float argument needed to execute this command. + */ + public CommandObject( int cmd, String s, float f ) + { + Command = cmd; + floatArgs = new float[1]; + stringArgs = new String[1]; + floatArgs[0] = f; + stringArgs[0] = s; + } +/** + * Constructor used to create a command which requires a String and a boolean + * as arguments. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param b The boolean argument needed to execute this command. + */ + public CommandObject( int cmd, String s, boolean b ) + { + Command = cmd; + boolArgs = new boolean[1]; + stringArgs = new String[1]; + boolArgs[0] = b; + stringArgs[0] = s; + } +/** + * Constructor used to create a command which requires three float arguments. + * @param cmd Which command to execute. + * @param f1 The first float argument needed to execute this command. + * @param f2 The second float argument needed to execute this command. + * @param f3 The third float argument needed to execute this command. + */ + public CommandObject( int cmd, float f1, float f2, float f3 ) + { + Command = cmd; + floatArgs = new float[3]; + floatArgs[0] = f1; + floatArgs[1] = f2; + floatArgs[2] = f3; + } +/** + * Constructor used to create a command which a String and three float + * arguments. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param f1 The first float argument needed to execute this command. + * @param f2 The second float argument needed to execute this command. + * @param f3 The third float argument needed to execute this command. + */ + public CommandObject( int cmd, String s, float f1, float f2, float f3 ) + { + Command = cmd; + floatArgs = new float[3]; + stringArgs = new String[1]; + floatArgs[0] = f1; + floatArgs[1] = f2; + floatArgs[2] = f3; + stringArgs[0] = s; + } +/** + * Constructor used to create a command which requires six float arguments. + * @param cmd Which command to execute. + * @param f1 The first float argument needed to execute this command. + * @param f2 The second float argument needed to execute this command. + * @param f3 The third float argument needed to execute this command. + * @param f4 The fourth float argument needed to execute this command. + * @param f5 The fifth float argument needed to execute this command. + * @param f6 The sixth float argument needed to execute this command. + */ + public CommandObject( int cmd, float f1, float f2, float f3, float f4, + float f5, float f6 ) + { + Command = cmd; + floatArgs = new float[6]; + floatArgs[0] = f1; + floatArgs[1] = f2; + floatArgs[2] = f3; + floatArgs[3] = f4; + floatArgs[4] = f5; + floatArgs[5] = f6; + } +/** + * Constructor used to create a command which requires several arguments. + * @param cmd Which command to execute. + * @param b1 The first boolean argument needed to execute this command. + * @param b2 The second boolean argument needed to execute this command. + * @param b3 The third boolean argument needed to execute this command. + * @param s The String argument needed to execute this command. + * @param o The Object argument needed to execute this command. + * @param f1 The first float argument needed to execute this command. + * @param f2 The second float argument needed to execute this command. + * @param f3 The third float argument needed to execute this command. + * @param i The integer argument needed to execute this command. + * @param f4 The fourth float argument needed to execute this command. + */ + public CommandObject( int cmd, + boolean b1, boolean b2, boolean b3, + String s, Object o, + float f1, float f2, float f3, + int i, float f4 ) + { + Command = cmd; + intArgs = new int[1]; + floatArgs = new float[4]; + boolArgs = new boolean[3]; + stringArgs = new String[1]; + objectArgs = new Object[1]; + intArgs[0] = i; + floatArgs[0] = f1; + floatArgs[1] = f2; + floatArgs[2] = f3; + floatArgs[3] = f4; + boolArgs[0] = b1; + boolArgs[1] = b2; + boolArgs[2] = b3; + stringArgs[0] = s; + objectArgs[0] = o; + } +/** + * Constructor used to create a command which requires several arguments. + * @param cmd Which command to execute. + * @param b1 The first boolean argument needed to execute this command. + * @param b2 The second boolean argument needed to execute this command. + * @param b3 The third boolean argument needed to execute this command. + * @param s The String argument needed to execute this command. + * @param o The Object argument needed to execute this command. + * @param f1 The first float argument needed to execute this command. + * @param f2 The second float argument needed to execute this command. + * @param f3 The third float argument needed to execute this command. + * @param i The integer argument needed to execute this command. + * @param f4 The fourth float argument needed to execute this command. + * @param b4 The fourth boolean argument needed to execute this command. + */ + public CommandObject( int cmd, + boolean b1, boolean b2, boolean b3, + String s, + Object o, + float f1, float f2, float f3, + int i, float f4, boolean b4 ) + { + Command = cmd; + intArgs = new int[1]; + floatArgs = new float[4]; + boolArgs = new boolean[4]; + stringArgs = new String[1]; + objectArgs = new Object[1]; + intArgs[0] = i; + floatArgs[0] = f1; + floatArgs[1] = f2; + floatArgs[2] = f3; + floatArgs[3] = f4; + boolArgs[0] = b1; + boolArgs[1] = b2; + boolArgs[2] = b3; + boolArgs[3] = b4; + stringArgs[0] = s; + objectArgs[0] = o; + } +/** + * Constructor used to create a command which requires several arguments. + * @param cmd Which command to execute. + * @param o The Object argument needed to execute this command. + * @param b The first boolean argument needed to execute this command. + * @param s The String argument needed to execute this command. + * @param f1 The first float argument needed to execute this command. + * @param f2 The second float argument needed to execute this command. + * @param f3 The third float argument needed to execute this command. + * @param i The integer argument needed to execute this command. + * @param f4 The fourth float argument needed to execute this command. + */ + public CommandObject( int cmd, + Object o, + boolean b, + String s, + float f1, float f2, float f3, + int i, + float f4 ) + { + Command = cmd; + intArgs = new int[1]; + floatArgs = new float[4]; + boolArgs = new boolean[1]; + stringArgs = new String[1]; + objectArgs = new Object[1]; + intArgs[0] = i; + floatArgs[0] = f1; + floatArgs[1] = f2; + floatArgs[2] = f3; + floatArgs[3] = f4; + boolArgs[0] = b; + stringArgs[0] = s; + objectArgs[0] = o; + } +} diff --git a/src/lwjgl/java/paulscode/sound/CommandThread.java b/src/lwjgl/java/paulscode/sound/CommandThread.java new file mode 100644 index 0000000..982e6fa --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/CommandThread.java @@ -0,0 +1,176 @@ +package paulscode.sound; + +/** + * The CommandThread class is designed to move all command processing into a + * single thread to be run in the background and avoid conflicts between + * threads. Commands are processed in the order that they were queued. The + * arguements for each command are stored in a + * {@link paulscode.sound.CommandObject CommandObject}. The Command Queue is + * located in the {@link paulscode.sound.SoundSystem SoundSystem} class. + * Calling kill() stops the thread, and this should be immediatly followed + * by a call to interrupt() to wake up the thread so it may end. This class + * also checks for temporary sources that are finished playing, and removes + * them. + * + * NOTE: The command thread is created automatically by the sound system, so it + * is unlikely that the user would ever need to use this class. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class CommandThread extends SimpleThread +{ +/** + * Processes status messages, warnings, and error messages. + */ + protected SoundSystemLogger logger; + +/** + * Handle to the Sound System. This is where the Command Queue is located. + */ + private SoundSystem soundSystem; + +/** + * Name of this class. + */ + protected String className = "CommandThread"; + +/** + * Constructor: Takes a handle to the SoundSystem object as a parameter. + * @param s Handle to the SoundSystem. +*/ + public CommandThread( SoundSystem s ) + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + soundSystem = s; + } + +/** + * Shuts the thread down and removes references to all instantiated objects. + * NOTE: Method alive() will return false when cleanup() has finished. + */ + @Override + protected void cleanup() + { + kill(); + + logger = null; + soundSystem = null; + + super.cleanup(); // Important! + } + +/** + * The main loop for processing commands. The Command Thread starts out + * asleep, and it sleeps again after it finishes processing commands, so it + * must be interrupted when commands are queued for processing. + */ + @Override + public void run() + { + long previousTime = System.currentTimeMillis(); + long currentTime = previousTime; + + if( soundSystem == null ) + { + errorMessage( "SoundSystem was null in method run().", 0 ); + cleanup(); + return; + } + + // Start out asleep: + snooze( 3600000 ); + + while( !dying() ) + { + // Perform user-specific source management: + soundSystem.ManageSources(); + + // Process all queued commands: + soundSystem.CommandQueue( null ); + + // Remove temporary sources every ten seconds: + currentTime = System.currentTimeMillis(); + if( (!dying()) && ((currentTime - previousTime) > 10000) ) + { + previousTime = currentTime; + soundSystem.removeTemporarySources(); + } + + // Wait for more commands: + if( !dying() ) + snooze( 3600000 ); + } + + cleanup(); // Important! + } + +/** + * Prints a message. + * @param message Message to print. + */ + protected void message( String message, int indent ) + { + logger.message( message, indent ); + } + +/** + * Prints an important message. + * @param message Message to print. + */ + protected void importantMessage( String message, int indent ) + { + logger.importantMessage( message, indent ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param message Message to print if error is true. + * @return True if error is true. + */ + protected boolean errorCheck( boolean error, String message ) + { + return logger.errorCheck( error, className, message, 0 ); + } + +/** + * Prints an error message. + * @param message Message to print. + */ + protected void errorMessage( String message, int indent ) + { + logger.errorMessage( className, message, indent ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/FilenameURL.java b/src/lwjgl/java/paulscode/sound/FilenameURL.java new file mode 100644 index 0000000..96b48dc --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/FilenameURL.java @@ -0,0 +1,153 @@ +package paulscode.sound; + +import java.net.URL; + +/** + * The FilenameURL class is designed to associate a String filename/identifier + * with a URL. Handles either case where user supplies a String path or user + * supplies a URL instance. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class FilenameURL +{ +/** + * Processes status messages, warnings, and error messages. + */ + private SoundSystemLogger logger; + +/** + * Filename or identifier for the file. + */ + private String filename = null; + +/** + * URL interface to the file. + */ + private URL url = null; + +/** + * Constructor: Saves handles to the url and identifier. The identifier should + * look like a filename, and it must have the correct extension so SoundSystem + * knows what format to use for the file referenced by the URL instance. + * @param url URL interface to a file. + * @param identifier Identifier (filename) for the file. + */ + public FilenameURL( URL url, String identifier ) + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + filename = identifier; + this.url = url; + } + +/** + * Constructor: Saves a handle to the filename (used later to generate a URL + * instance). The file may either be located within the + * JAR or at an online location. If the file is online, filename must begin + * with "http://", since that is how SoundSystem recognizes URL names. + * @param filename Name of the file. + */ + public FilenameURL( String filename ) + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + this.filename = filename; + url = null; + } + +/** + * Returns the filename/identifier. + * @return Filename or identifier for the file. + */ + public String getFilename() + { + return filename; + } + +/** + * Returns the URL interface to the file. If a URL was not originally specified + * in the constructor, then the first time this method is called it creates a + * URL instance using the previously specified filename. + * @return URL interface to the file. + */ + public URL getURL() + { + if( url == null ) + { + // Check if the file is online or inside the JAR: + if( filename.matches( SoundSystemConfig.PREFIX_URL ) ) + { + // Online + try + { + url = new URL( filename ); + } + catch( Exception e ) + { + errorMessage( "Unable to access online URL in " + + "method 'getURL'" ); + printStackTrace( e ); + return null; + } + } + else + { + // Inside the JAR + url = getClass().getClassLoader().getResource( + SoundSystemConfig.getSoundFilesPackage() + filename ); + } + } + return url; + } + +/** + * Prints an error message. + * @param message Message to print. + */ + private void errorMessage( String message ) + { + logger.errorMessage( "MidiChannel", message, 0 ); + } + +/** + * Prints an exception's error message followed by the stack trace. + * @param e Exception containing the information to print. + */ + private void printStackTrace( Exception e ) + { + logger.printStackTrace( e, 1 ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/ICodec.java b/src/lwjgl/java/paulscode/sound/ICodec.java new file mode 100644 index 0000000..9385445 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/ICodec.java @@ -0,0 +1,119 @@ +package paulscode.sound; + +import java.net.URL; +import javax.sound.sampled.AudioFormat; + +/** + * The ICodec interface provides a common interface for SoundSystem to use + * for accessing external codec libraries. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public interface ICodec +{ +/** + * Should tell derived classes when they may need to reverse the byte order of + * the data before returning it in the read() and readAll() methods. The + * reason for the reversBytOrder method is because some external codec + * libraries produce audio data in a format that some external audio libraries + * require to be reversed. Derivatives of the Library and Source classes for + * audio libraries which require this type of data to be reversed should call + * the reverseByteOrder() method for all instances of ICodec that they use. + * Derivatives of the ICodec interface for codec libraries which which produce + * this type of data should use the reverseByteOrder() method to know when the + * data needs to be reversed before returning it in the read() and readAll() + * methods. If a particular codec library does not produce this type of data, + * its derived ICodec class may disregard any calls to the reverseByteOrder() + * method. + * @param b True if the calling audio library requires byte-reversal by some codec libraries. + */ + public void reverseByteOrder( boolean b ); + +/** + * Should make any preperations required before reading from the audio stream. + * If another stream is already opened, it should be closed and a new audio + * stream opened in its place. This method is used internally by SoundSystem + * not only to initialize a stream, but also to rewind streams and to switch + * stream sources on the fly. + * @return False if an error occurred or if end of stream was reached. + */ + public boolean initialize( URL url ); + +/** + * Should return false if the stream is busy initializing. To prevent bad + * data from being returned by this method, derived classes should internally + * synchronize with any elements used by both the initialized() and initialize() + * methods. + * @return True if steam is initialized. + */ + public boolean initialized(); + +/** + * Should read in one stream buffer worth of audio data. See + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about accessing and changing default settings. + * @return The audio data wrapped into a SoundBuffer context. + */ + public SoundBuffer read(); + +/** + * Should read in all the audio data from the stream (up to the default + * "maximum file size". See + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about accessing and changing default settings. + * @return the audio data wrapped into a SoundBuffer context. + */ + public SoundBuffer readAll(); + +/** + * Should return false if there is still more data available to be read in. To + * prevent bad data from being returned by this method, derived classes should + * internally synchronize with any elements used in both the endOfStream() and + * the read() or readAll() methods. + * @return True if end of stream was reached. + */ + public boolean endOfStream(); + +/** + * Should close any open streams and remove references to all instantiated + * objects. + */ + public void cleanup(); + +/** + * Should return the audio format of the data being returned by the read() and + * readAll() methods. + * @return Information wrapped into an AudioFormat context. + */ + public AudioFormat getAudioFormat(); +} diff --git a/src/lwjgl/java/paulscode/sound/IStreamListener.java b/src/lwjgl/java/paulscode/sound/IStreamListener.java new file mode 100644 index 0000000..6f767f4 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/IStreamListener.java @@ -0,0 +1,11 @@ +package paulscode.sound; + +public interface IStreamListener +{ + /** + * Notifies implementation that an End Of Stream was reached. + * @param sourcename String identifier of the source which reached the EOS. + * @param queueSize Number of items left the the stream's play queue, or zero if none. + */ + public void endOfStream( String sourcename, int queueSize ); +} diff --git a/src/lwjgl/java/paulscode/sound/Library.java b/src/lwjgl/java/paulscode/sound/Library.java new file mode 100644 index 0000000..79011db --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/Library.java @@ -0,0 +1,1615 @@ +package paulscode.sound; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import javax.sound.sampled.AudioFormat; + +/** + * The Library class is the class from which all library types are extended. + * It provides generic methods for interfacing with the audio libraries + * supported by the SoundSystem. Specific libraries should extend this class + * and override the necessary methods. For consistant naming conventions, each + * sub-class should have the name prefix "Library". + * + * This class may also be used as the "No Sound Library" (i.e. silent mode) if + * no other audio libraries are supported by the host machine, or to mute all + * sound. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class Library +{ +/** + * Processes status messages, warnings, and error messages. + */ + private SoundSystemLogger logger; + +/** + * Position and orientation of the listener. + */ + protected ListenerData listener; + +/** + * Map containing sound file data for easy lookup by filename / identifier. + */ + protected HashMap bufferMap = null; + +/** + * Map containing all created sources for easy look-up by name. + */ + protected HashMap sourceMap; // (name, source data) pairs + +/** + * Interface through which MIDI files can be played. + */ + private MidiChannel midiChannel; + +/** + * Array containing maximum number of non-streaming audio channels. + */ + protected List streamingChannels; + +/** + * Array containing maximum number of non-streaming audio channels. + */ + protected List normalChannels; + +/** + * Source name last played on each streaming channel. + */ + private String[] streamingChannelSourceNames; + +/** + * Source name last played on each non-streaming channel. + */ + private String[] normalChannelSourceNames; + +/** + * Increments through the steaming channel list as new sources are played. + */ + private int nextStreamingChannel = 0; + +/** + * Increments through the non-steaming channel list as new sources are played. + */ + private int nextNormalChannel = 0; + +/** + * Handles processing for all streaming sources. + */ + protected StreamThread streamThread; + +/** + * Whether or not the library requires reversal of audio data byte order. + */ + protected boolean reverseByteOrder = false; + +/** + * Constructor: Instantiates the source map and listener information. NOTES: + * The 'super()' method should be at the top of constructors for all extended + * classes. The varriable 'libraryType' should be given a new value in the + * constructors for all extended classes. + */ + public Library() throws SoundSystemException + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + // instantiate the buffer map: + bufferMap = new HashMap(); + + // instantiate the source map: + sourceMap = new HashMap(); + + listener = new ListenerData( 0.0f, 0.0f, 0.0f, // position + 0.0f, 0.0f, -1.0f, // look-at direction + 0.0f, 1.0f, 0.0f, // up direction + 0.0f ); // angle + + streamingChannels = new LinkedList(); + normalChannels = new LinkedList(); + streamingChannelSourceNames = new String[ + SoundSystemConfig.getNumberStreamingChannels() ]; + normalChannelSourceNames = new String[ + SoundSystemConfig.getNumberNormalChannels() ]; + + streamThread = new StreamThread(); + streamThread.start(); + } + + +/* ########################################################################## */ +/* BEGIN OVERRIDE METHODS */ +/* */ +/* The following methods should be overrided as required */ +/* ########################################################################## */ + +/** + * Stops all sources, shuts down sound library, and removes references to all + * instantiated objects. + */ + public void cleanup() + { + streamThread.kill(); + streamThread.interrupt(); + + // wait up to 5 seconds for stream thread to end: + for( int i = 0; i < 50; i++ ) + { + if( !streamThread.alive() ) + break; + try + { + Thread.sleep(100); + } + catch(Exception e) + {} + } + + if( streamThread.alive() ) + { + errorMessage( "Stream thread did not die!" ); + message( "Ignoring errors... continuing clean-up." ); + } + + if( midiChannel != null ) + { + midiChannel.cleanup(); + midiChannel = null; + } + + Channel channel = null; + if( streamingChannels != null ) + { + while( !streamingChannels.isEmpty() ) + { + channel = streamingChannels.remove(0); + channel.close(); + channel.cleanup(); + channel = null; + } + streamingChannels.clear(); + streamingChannels = null; + } + if( normalChannels != null ) + { + while( !normalChannels.isEmpty() ) + { + channel = normalChannels.remove(0); + channel.close(); + channel.cleanup(); + channel = null; + } + normalChannels.clear(); + normalChannels = null; + } + + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // loop through and cleanup all the sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + source.cleanup(); + } + sourceMap.clear(); + sourceMap = null; + + listener = null; + streamThread = null; + } + +/** + * Initializes the sound library. + */ + public void init() throws SoundSystemException + { + Channel channel = null; + + // create the streaming channels: + for( int x = 0; x < SoundSystemConfig.getNumberStreamingChannels(); x++ ) + { + channel = createChannel( SoundSystemConfig.TYPE_STREAMING ); + if( channel == null ) + break; + streamingChannels.add( channel ); + } + // create the non-streaming channels: + for( int x = 0; x < SoundSystemConfig.getNumberNormalChannels(); x++ ) + { + channel = createChannel( SoundSystemConfig.TYPE_NORMAL ); + if( channel == null ) + break; + normalChannels.add( channel ); + } + } + +/** + * Checks if the no-sound library type is compatible. + * @return True or false. + */ + public static boolean libraryCompatible() + { + return true; // the no-sound library is always compatible. + } + +/** + * Creates a new channel of the specified type (normal or streaming). Possible + * values for channel type can be found in the + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} class. + * @param type Type of channel. + * @return The new channel. + */ + protected Channel createChannel( int type ) + { + return new Channel( type ); + } + +/** + * Pre-loads a sound into memory. + * @param filenameURL Filename/URL of the sound file to load. + * @return True if the sound loaded properly. + */ + public boolean loadSound( FilenameURL filenameURL ) + { + return true; + } + +/** + * Saves the specified sample data, under the specified identifier. This + * identifier can be later used in place of 'filename' parameters to reference + * the sample data. + * @param buffer the sample data and audio format to save. + * @param identifier What to call the sample. + * @return True if there weren't any problems. + */ + public boolean loadSound( SoundBuffer buffer, String identifier ) + { + return true; + } + +/** + * Returns the filenames of all previously loaded sounds. + * @return LinkedList of String filenames. + */ + public LinkedList getAllLoadedFilenames() + { + LinkedList filenames = new LinkedList(); + Set keys = bufferMap.keySet(); + Iterator iter = keys.iterator(); + + // loop through and update the volume of all sources: + while( iter.hasNext() ) + { + filenames.add( iter.next() ); + } + + return filenames; + } + +/** + * Returns the sourcenames of all sources. + * @return LinkedList of String sourcenames. + */ + public LinkedList getAllSourcenames() + { + LinkedList sourcenames = new LinkedList(); + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + + if( midiChannel != null ) + sourcenames.add( midiChannel.getSourcename() ); + + // loop through and update the volume of all sources: + while( iter.hasNext() ) + { + sourcenames.add( iter.next() ); + } + + return sourcenames; + } + +/** + * Removes a pre-loaded sound from memory. This is a good method to use for + * freeing up memory after a large sound file is no longer needed. NOTE: the + * source will remain in memory after this method has been called, for as long + * as the sound is attached to an existing source. + * @param filename Filename/identifier of the sound file to unload. + */ + public void unloadSound( String filename ) + { + bufferMap.remove( filename ); + } + +/** + * Opens a direct line for streaming audio data. + * @param audioFormat Format that the data will be in. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param posX X position for this source. + * @param posY Y position for this source. + * @param posZ Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void rawDataStream( AudioFormat audioFormat, boolean priority, + String sourcename, float posX, float posY, + float posZ, int attModel, float distOrRoll ) + { + sourceMap.put( sourcename, + new Source( audioFormat, priority, sourcename, posX, + posY, posZ, attModel, distOrRoll ) ); + } + +/** + * Creates a new source using the specified information. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will load the sound in pieces rather than all at once. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param posX X position for this source. + * @param posY Y position for this source. + * @param posZ Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void newSource( boolean priority, boolean toStream, boolean toLoop, + String sourcename, FilenameURL filenameURL, + float posX, float posY, float posZ, int attModel, + float distOrRoll ) + { + sourceMap.put( sourcename, + new Source( priority, toStream, toLoop, sourcename, + filenameURL, null, posX, posY, posZ, + attModel, distOrRoll, false ) ); + } + +/** + * Creates and immediately plays a new source that will be removed when it + * finishes playing. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will load the sound in pieces rather than all at once. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL The filename/URL of the sound file to play at this source. + * @param posX X position for this source. + * @param posY Y position for this source. + * @param posZ Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void quickPlay( boolean priority, boolean toStream, boolean toLoop, + String sourcename, FilenameURL filenameURL, + float posX, float posY, float posZ, int attModel, + float distOrRoll, boolean tmp ) + { + sourceMap.put( sourcename, + new Source( priority, toStream, toLoop, sourcename, + filenameURL, null, posX, posY, posZ, + attModel, distOrRoll, tmp ) ); + } + +/** + * + * Defines whether or not the source should be removed after it finishes + * playing. + * @param sourcename The source's name. + * @param temporary True or False. + */ + public void setTemporary( String sourcename, boolean temporary ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.setTemporary( temporary ); + } + +/** + * Changes the specified source's position. + * @param sourcename The source's name. + * @param x Destination X coordinate. + * @param y Destination Y coordinate. + * @param z Destination Z coordinate. + */ + public void setPosition( String sourcename, float x, float y, float z ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.setPosition( x, y, z ); + } + +/** + * Sets the specified source's priority factor. A priority source will not be + * overriden if there are too many sources playing at once. + * @param sourcename The source's name. + * @param pri True or False. + */ + public void setPriority( String sourcename, boolean pri ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.setPriority( pri ); + } + +/** + * Sets the specified source's looping parameter. If parameter lp is false, + * the source will play once and stop. + * @param sourcename The source's name. + * @param lp True or False. + */ + public void setLooping( String sourcename, boolean lp ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.setLooping( lp ); + } + +/** + * Sets the specified source's attenuation model. + * @param sourcename The source's name. + * @param model Attenuation model to use. + */ + public void setAttenuation( String sourcename, int model ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.setAttenuation( model ); + } + +/** + * Sets the specified source's fade distance or rolloff factor. + * @param sourcename The source's name. + * @param dr Fade distance or rolloff factor. + */ + public void setDistOrRoll( String sourcename, float dr) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.setDistOrRoll( dr ); + } + +/** + * Sets the specified source's velocity, for use in Doppler effect. + * @param sourcename The source's name. + * @param x Velocity along world x-axis. + * @param y Velocity along world y-axis. + * @param z Velocity along world z-axis. + */ + public void setVelocity( String sourcename, float x, float y, float z ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.setVelocity( x, y, z ); + } + +/** + * Sets the listener's velocity, for use in Doppler effect. + * @param x Velocity along world x-axis. + * @param y Velocity along world y-axis. + * @param z Velocity along world z-axis. + */ + public void setListenerVelocity( float x, float y, float z ) + { + listener.setVelocity( x, y, z ); + } + +/** + * Notifies the underlying library that the Doppler parameters have changed. + */ + public void dopplerChanged() + {} + +/** + * Returns the number of miliseconds since the specified source began playing. + * @return miliseconds, or -1 if not playing or unable to calculate + */ + public float millisecondsPlayed( String sourcename ) + { + if( sourcename == null || sourcename.equals( "" ) ) + { + errorMessage( "Sourcename not specified in method " + + "'millisecondsPlayed'" ); + return -1; + } + + if( midiSourcename( sourcename ) ) + { + errorMessage( "Unable to calculate milliseconds for MIDI source." ); + return -1; + } + else + { + Source source = sourceMap.get( sourcename ); + if( source == null ) + { + errorMessage( "Source '" + sourcename + "' not found in " + + "method 'millisecondsPlayed'" ); + } + return source.millisecondsPlayed(); + } + } +/** + * Feeds raw data through the specified source. The source must be a + * streaming source and it can not be already associated with a file or URL to + * stream from. + * @param sourcename Name of the streaming source to play from. + * @param buffer Byte buffer containing raw audio data to stream. + * @return Number of prior buffers that have been processed, or -1 if unable to queue the buffer (if the source was culled, for example). + */ + public int feedRawAudioData( String sourcename, byte[] buffer ) + { + if( sourcename == null || sourcename.equals( "" ) ) + { + errorMessage( "Sourcename not specified in method " + + "'feedRawAudioData'" ); + return -1; + } + + if( midiSourcename( sourcename ) ) + { + errorMessage( "Raw audio data can not be fed to the " + + "MIDI channel." ); + return -1; + } + else + { + Source source = sourceMap.get( sourcename ); + if( source == null ) + { + errorMessage( "Source '" + sourcename + "' not found in " + + "method 'feedRawAudioData'" ); + } + return feedRawAudioData( source, buffer ); + } + } + +/** + * Feeds raw data through the specified source. The source must be a + * streaming source and it can not be already associated with a file or URL to + * stream from. + * @param source Streaming source to play from. + * @param buffer Byte buffer containing raw audio data to stream. + * @return Number of prior buffers that have been processed, or -1 if unable to queue the buffer (if the source was culled, for example). + */ + public int feedRawAudioData( Source source, byte[] buffer ) + { + if( source == null ) + { + errorMessage( "Source parameter null in method " + + "'feedRawAudioData'" ); + return -1; + } + if( !source.toStream ) + { + errorMessage( "Only a streaming source may be specified in " + + "method 'feedRawAudioData'" ); + return -1; + } + if( !source.rawDataStream ) + { + errorMessage( "Streaming source already associated with a " + + "file or URL in method'feedRawAudioData'" ); + return -1; + } + + if( !source.playing() || source.channel == null ) + { + Channel channel; + if( source.channel != null && ( source.channel.attachedSource == + source ) ) + channel = source.channel; + else + channel = getNextChannel( source ); + + int processed = source.feedRawAudioData( channel, buffer ); + channel.attachedSource = source; + streamThread.watch( source ); + streamThread.interrupt(); + return processed; + } + + return( source.feedRawAudioData( source.channel, buffer ) ); + } + +/** + * Looks up the specified source and plays it. + * @param sourcename Name of the source to play. + */ + public void play( String sourcename ) + { + if( sourcename == null || sourcename.equals( "" ) ) + { + errorMessage( "Sourcename not specified in method 'play'" ); + return; + } + + if( midiSourcename( sourcename ) ) + { + midiChannel.play(); + } + else + { + Source source = sourceMap.get( sourcename ); + if( source == null ) + { + errorMessage( "Source '" + sourcename + "' not found in " + + "method 'play'" ); + } + play( source ); + } + } + +/** + * Plays the specified source. + * @param source The source to play. + */ + public void play( Source source ) + { + if( source == null ) + return; + + // raw data streams will automatically play when data is sent to them, + // so no need to do anything here. + if( source.rawDataStream ) + return; + + if( !source.active() ) + return; + + if( !source.playing() ) + { + Channel channel = getNextChannel( source ); + + if( source != null && channel != null ) + { + if( source.channel != null && + source.channel.attachedSource != source ) + source.channel = null; + channel.attachedSource = source; + source.play( channel ); + if( source.toStream ) + { + streamThread.watch( source ); + streamThread.interrupt(); + } + } + } + } + +/** + * Stops the specified source. + * @param sourcename The source's name. + */ + public void stop( String sourcename ) + { + if( sourcename == null || sourcename.equals( "" ) ) + { + errorMessage( "Sourcename not specified in method 'stop'" ); + return; + } + if( midiSourcename( sourcename ) ) + { + midiChannel.stop(); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.stop(); + } + } + +/** + * Pauses the specified source. + * @param sourcename The source's name. + */ + public void pause( String sourcename ) + { + if( sourcename == null || sourcename.equals( "" ) ) + { + errorMessage( "Sourcename not specified in method 'stop'" ); + return; + } + if( midiSourcename( sourcename ) ) + { + midiChannel.pause(); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.pause(); + } + } + +/** + * Rewinds the specified source. + * @param sourcename The source's name. + */ + public void rewind( String sourcename ) + { + if( midiSourcename( sourcename ) ) + { + midiChannel.rewind(); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.rewind(); + } + } + +/** + * Clears all previously queued data from a stream. + * @param sourcename The source's name. + */ + public void flush( String sourcename ) + { + if( midiSourcename( sourcename ) ) + errorMessage( "You can not flush the MIDI channel" ); + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.flush(); + } + } + +/** + * Culls the specified source. A culled source will not play until it has been + * activated again. + * @param sourcename The source's name. + */ + public void cull( String sourcename ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.cull(); + } + +/** + * Activates a previously culled source, so it can be played again. + * @param sourcename The source's name. + */ + public void activate( String sourcename ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + { + mySource.activate(); + if( mySource.toPlay ) + play( mySource ); + } + } + +/** + * Sets the overall volume to the specified value, affecting all sources. + * @param value New volume, float value ( 0.0f - 1.0f ). + */ + public void setMasterVolume( float value ) + { + SoundSystemConfig.setMasterGain( value ); + if( midiChannel != null ) + midiChannel.resetGain(); + } + +/** + * Manually sets the specified source's volume. + * @param sourcename The source's name. + * @param value A float value ( 0.0f - 1.0f ). + */ + public void setVolume( String sourcename, float value ) + { + if( midiSourcename( sourcename ) ) + { + midiChannel.setVolume( value ); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + { + float newVolume = value; + if( newVolume < 0.0f ) + newVolume = 0.0f; + else if( newVolume > 1.0f ) + newVolume = 1.0f; + + mySource.sourceVolume = newVolume; + mySource.positionChanged(); + } + } + } + +/** + * Returns the current volume of the specified source, or zero if the specified + * source was not found. + * @param sourcename Source to read volume from. + * @return Float value representing the source volume (0.0f - 1.0f). + */ + public float getVolume( String sourcename ) + { + if( midiSourcename( sourcename ) ) + { + return midiChannel.getVolume(); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + return mySource.sourceVolume; + else + return 0.0f; + } + } + +/** + * Manually sets the specified source's pitch. + * @param sourcename The source's name. + * @param value A float value ( 0.5f - 2.0f ). + */ + public void setPitch( String sourcename, float value ) + { + if( !midiSourcename( sourcename ) ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + { + float newPitch = value; + if( newPitch < 0.5f ) + newPitch = 0.5f; + else if( newPitch > 2.0f ) + newPitch = 2.0f; + + mySource.setPitch( newPitch ); + mySource.positionChanged(); + } + } + } + +/** + * Returns the pitch of the specified source. + * @param sourcename The source's name. + * @return Float value representing the source pitch (0.5f - 2.0f). + */ + public float getPitch( String sourcename ) + { + if( !midiSourcename( sourcename ) ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + return mySource.getPitch(); + } + return 1.0f; + } + +/** + * Moves the listener relative to the current position. + * @param x X offset. + * @param y Y offset. + * @param z Z offset. + */ + public void moveListener( float x, float y, float z ) + { + setListenerPosition( listener.position.x + x, listener.position.y + y, + listener.position.z + z ); + } + +/** + * Changes the listener's position. + * @param x Destination X coordinate. + * @param y Destination Y coordinate. + * @param z Destination Z coordinate. + */ + public void setListenerPosition( float x, float y, float z ) + { + // update listener's position + listener.setPosition( x, y, z ); + + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // loop through and update the volume of all sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + source.positionChanged(); + } + } + +/** + * Turn the listener 'angle' radians counterclockwise around the y-Axis, + * relative to the current angle. + * @param angle Angle in radians. + */ + public void turnListener( float angle ) + { + setListenerAngle( listener.angle + angle ); + + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // loop through and update the volume of all sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + source.positionChanged(); + } + } + +/** + * Changes the listeners orientation to the specified 'angle' radians + * counterclockwise around the y-Axis. + * @param angle Angle in radians. + */ + public void setListenerAngle( float angle ) + { + listener.setAngle( angle ); + + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // loop through and update the volume of all sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + source.positionChanged(); + } + } + +/** + * Changes the listeners orientation using the specified coordinates. + * @param lookX X element of the look-at direction. + * @param lookY Y element of the look-at direction. + * @param lookZ Z element of the look-at direction. + * @param upX X element of the up direction. + * @param upY Y element of the up direction. + * @param upZ Z element of the up direction. + */ + public void setListenerOrientation( float lookX, float lookY, float lookZ, + float upX, float upY, float upZ ) + { + listener.setOrientation( lookX, lookY, lookZ, upX, upY, upZ ); + + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // loop through and update the volume of all sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + source.positionChanged(); + } + } + +/** + * Changes the listeners position and orientation using the specified listener + * data. + * @param l Listener data to use. + */ + public void setListenerData( ListenerData l ) + { + listener.setData( l ); + } + +/** + * Creates sources based on the source map provided. + * @param srcMap Sources to copy. + */ + public void copySources( HashMap srcMap ) + { + if( srcMap == null ) + return; + Set keys = srcMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source srcData; + + // remove any existing sources before starting: + sourceMap.clear(); + + // loop through and copy all the sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + srcData = srcMap.get( sourcename ); + if( srcData != null ) + { + loadSound( srcData.filenameURL ); + sourceMap.put( sourcename, new Source( srcData, null ) ); + } + } + } + +/** + * Stops and deletes the specified source. + * @param sourcename The source's name. + */ + public void removeSource( String sourcename ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) { + // if this is a streaming source just mark it removed - https://github.com/MinecraftForge/MinecraftForge/pull/4765 + if ( mySource.toStream ) + mySource.removed = true; + else + mySource.cleanup(); // end the source, free memory + } + sourceMap.remove( sourcename ); + } + +/** + * Searches for and removes all temporary sources that have finished playing. + */ + public void removeTemporarySources() + { + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source srcData; + + // loop through and cleanup all the sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + srcData = sourceMap.get( sourcename ); + if( (srcData != null) && (srcData.temporary) + && (!srcData.playing()) ) + { + srcData.cleanup(); // end the source, free memory + iter.remove(); + } + } + } + +/* ########################################################################## */ +/* END OVERRIDE METHODS */ +/* ########################################################################## */ + +/** + * Returns a handle to the next available channel. If the specified + * source is a normal source, a normal channel is returned, and if it is a + * streaming source, then a streaming channel is returned. If all channels of + * the required type are currently playing, then the next channel playing a + * non-priority source is returned. If no channels are available (i.e. they + * are all playing priority sources) then getNextChannel returns null. + * @param source Source to find a channel for. + * @return The next available channel, or null. + */ + private Channel getNextChannel( Source source ) + { + if( source == null ) + return null; + + String sourcename = source.sourcename; + if( sourcename == null ) + return null; + + int x; + int channels; + int nextChannel; + List channelList; + String[] sourceNames; + String name; + + if( source.toStream ) + { + nextChannel = nextStreamingChannel; + channelList = streamingChannels; + sourceNames = streamingChannelSourceNames; + } + else + { + nextChannel = nextNormalChannel; + channelList = normalChannels; + sourceNames = normalChannelSourceNames; + } + + channels = channelList.size(); + + // Check if this source is already on a channel: + for( x = 0; x < channels; x++ ) + { + if( sourcename.equals( sourceNames[x] ) ) + return channelList.get( x ); + } + + int n = nextChannel; + Source src; + // Play on the next new or non-playing channel: + for( x = 0; x < channels; x++ ) + { + name = sourceNames[n]; + if( name == null ) + src = null; + else + src = sourceMap.get( name ); + + if( src == null || !src.playing() ) + { + if( source.toStream ) + { + nextStreamingChannel = n + 1; + if( nextStreamingChannel >= channels ) + nextStreamingChannel = 0; + } + else + { + nextNormalChannel = n + 1; + if( nextNormalChannel >= channels ) + nextNormalChannel = 0; + } + sourceNames[n] = sourcename; + return channelList.get( n ); + } + n++; + if( n >= channels ) + n = 0; + } + + n = nextChannel; + // Play on the next non-priority channel: + for( x = 0; x < channels; x++ ) + { + name = sourceNames[n]; + if( name == null ) + src = null; + else + src = sourceMap.get( name ); + + if( src == null || !src.playing() || !src.priority ) + { + if( source.toStream ) + { + nextStreamingChannel = n + 1; + if( nextStreamingChannel >= channels ) + nextStreamingChannel = 0; + } + else + { + nextNormalChannel = n + 1; + if( nextNormalChannel >= channels ) + nextNormalChannel = 0; + } + sourceNames[n] = sourcename; + return channelList.get( n ); + } + n++; + if( n >= channels ) + n = 0; + } + + return null; + } + +/** + * Plays all sources whose 'toPlay' varriable is true but are not currently + * playing (such as sources which were culled while looping and then + * reactivated). + */ + public void replaySources() + { + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // loop through and cleanup all the sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + { + if( source.toPlay && !source.playing() ) + { + play( sourcename ); + source.toPlay = false; + } + } + } + } + +/** + * If the specified source is a streaming source or MIDI source, this method + * queues up the next sound to play when the previous playback ends. This + * method has no effect on non-streaming sources. + * @param sourcename Source identifier. + * @param filenameURL Filename/URL of the sound file to play next. + */ + public void queueSound( String sourcename, FilenameURL filenameURL ) + { + if( midiSourcename( sourcename ) ) + { + midiChannel.queueSound( filenameURL ); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.queueSound( filenameURL ); + } + } + +/** + * Removes the first occurrence of the specified filename from the specified + * source's list of sounds to play when previous playback ends. This method + * has no effect on non-streaming sources. + * @param sourcename Source identifier. + * @param filename Filename/identifier of the sound file to remove from the queue. + */ + public void dequeueSound( String sourcename, String filename ) + { + if( midiSourcename( sourcename ) ) + { + midiChannel.dequeueSound( filename ); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.dequeueSound( filename ); + } + } + +/** + * Fades out the volume of whatever the specified source is currently playing, + * then begins playing the specified file at the source's previously + * assigned volume level. If the filenameURL parameter is null or empty, the + * specified source will simply fade out and stop. The miliseconds parameter + * must be non-negative or zero. This method will remove anything that is + * currently in the specified source's list of queued sounds that would have + * played next when the current sound finished playing. This method may only + * be used for streaming and MIDI sources. + * @param sourcename Name of the source to fade out. + * @param filenameURL Filename/URL of the sound file to play next, or null for none. + * @param milis Number of miliseconds the fadeout should take. + */ + public void fadeOut( String sourcename, FilenameURL filenameURL, + long milis ) + { + if( midiSourcename( sourcename ) ) + { + midiChannel.fadeOut( filenameURL, milis ); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.fadeOut( filenameURL, milis ); + } + } + +/** + * Fades out the volume of whatever the specified source is currently playing, + * then fades the volume back in playing the specified file. Final volume + * after fade-in completes will be equal to the source's previously assigned + * volume level. The filenameURL parameter may not be null or empty. The + * miliseconds parameters must be non-negative or zero. This method will + * remove anything that is currently in the specified source's list of queued + * sounds that would have played next when the current sound finished playing. + * This method may only be used for streaming and MIDI sources. + * @param sourcename Name of the source to fade out/in. + * @param filenameURL Filename/URL of the sound file to play next, or null for none. + * @param milisOut Number of miliseconds the fadeout should take. + * @param milisIn Number of miliseconds the fadein should take. + */ + public void fadeOutIn( String sourcename, FilenameURL filenameURL, + long milisOut, long milisIn ) + { + if( midiSourcename( sourcename ) ) + { + midiChannel.fadeOutIn( filenameURL, milisOut, milisIn ); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.fadeOutIn( filenameURL, milisOut, milisIn ); + } + } + +/** + * Makes sure the current volume levels of streaming sources and MIDI are + * correct. This method is designed to help reduce the "jerky" fading behavior + * that happens when using some library and codec pluggins (such as + * LibraryJavaSound and CodecJOrbis). This method has no effect on normal + * "non-streaming" sources. It would normally be called somewhere in the main + * "game loop". IMPORTANT: To optimize frame-rates, do not call this method + * for every frame. It is better to just call this method at some acceptable + * "granularity" (play around with different granularities to find what sounds + * acceptable for a particular situation). + */ + public void checkFadeVolumes() + { + if( midiChannel != null ) + midiChannel.resetGain(); + Channel c; + Source s; + for( int x = 0; x < streamingChannels.size(); x++ ) + { + c = streamingChannels.get( x ); + if( c != null ) + { + s = c.attachedSource; + if( s != null ) + s.checkFadeOut(); + } + } + c = null; + s = null; + } + +/** + * Loads the specified MIDI file, and saves the source information about it. + * @param toLoop Midi file should loop or play once. + * @param sourcename Source identifier. + * @param filenameURL Filename/URL of the MIDI file to load. + */ + public void loadMidi( boolean toLoop, String sourcename, + FilenameURL filenameURL ) + { + if( filenameURL == null ) + { + errorMessage( "Filename/URL not specified in method 'loadMidi'." ); + return; + } + + if( !filenameURL.getFilename().matches( + SoundSystemConfig.EXTENSION_MIDI ) ) + { + errorMessage( "Filename/identifier doesn't end in '.mid' or" + + "'.midi' in method loadMidi." ); + return; + } + + if( midiChannel == null ) + { + midiChannel = new MidiChannel( toLoop, sourcename, filenameURL ); + } + else + { + midiChannel.switchSource( toLoop, sourcename, filenameURL ); + } + } + +/** + * Unloads the current Midi file. + */ + public void unloadMidi() + { + if( midiChannel != null ) + midiChannel.cleanup(); + midiChannel = null; + } + +/** + * Checks if the sourcename matches the midi source. + * @param sourcename Source identifier. + * @return True if sourcename and midi sourcename match. + */ + public boolean midiSourcename( String sourcename ) + { + if( midiChannel == null || sourcename == null ) + return false; + + if( midiChannel.getSourcename() == null || sourcename.equals( "" ) ) + return false; + + if( sourcename.equals( midiChannel.getSourcename() ) ) + return true; + + return false; + } + +/** + * + * Returns the Source object identified by the specified name. + * @param sourcename The source's name. + * @return The source, or null if not found. + */ + public Source getSource( String sourcename ) + { + return sourceMap.get( sourcename ); + } + +/** + * + * Returns a handle to the MIDI channel, or null if one does not exist. + * @return The MIDI channel. + */ + public MidiChannel getMidiChannel() + { + return midiChannel; + } + +/** + * + * Specifies the MIDI channel to use. + * @param c New MIDI channel. + */ + public void setMidiChannel( MidiChannel c ) + { + if( midiChannel != null && midiChannel != c ) + midiChannel.cleanup(); + + midiChannel = c; + } + +/** + * Tells all the sources that the listener has moved. + */ + public void listenerMoved() + { + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source srcData; + + // loop through and copy all the sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + srcData = sourceMap.get( sourcename ); + if( srcData != null ) + { + srcData.listenerMoved(); + } + } + } + +/** + * Returns the sources map. + * @return Map of all sources. + */ + public HashMap getSources() + { + return sourceMap; + } + +/** + * Returns information about the listener. + * @return A ListenerData object. + */ + public ListenerData getListenerData() + { + return listener; + } + +/** + * Indicates whether or not this library requires some codecs to reverse-order + * the audio data they generate. + * @return True if audio data should be reverse-ordered. + */ + public boolean reverseByteOrder() + { + return reverseByteOrder; + } +/** + * Returns the short title of this library type. + * @return A short title. + */ + public static String getTitle() + { + return "No Sound"; + } + +/** + * Returns a longer description of this library type. + * @return A longer description. + */ + public static String getDescription() + { + return "Silent Mode"; + } + +/** + * Returns the name of the class. + * @return "Library" + library title. + */ + public String getClassName() + { + return "Library"; + } + +/** + * Prints a message. + * @param message Message to print. + */ + protected void message( String message ) + { + logger.message( message, 0 ); + } + +/** + * Prints an important message. + * @param message Message to print. + */ + protected void importantMessage( String message ) + { + logger.importantMessage( message, 0 ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param message Message to print if error is true. + * @return True if error is true. + */ + protected boolean errorCheck( boolean error, String message ) + { + return logger.errorCheck( error, getClassName(), message, 0 ); + } + +/** + * Prints an error message. + * @param message Message to print. + */ + protected void errorMessage( String message ) + { + logger.errorMessage( getClassName(), message, 0 ); + } + +/** + * Prints an exception's error message followed by the stack trace. + * @param e Exception containing the information to print. + */ + protected void printStackTrace( Exception e ) + { + logger.printStackTrace( e, 1 ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/ListenerData.java b/src/lwjgl/java/paulscode/sound/ListenerData.java new file mode 100644 index 0000000..af24b3c --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/ListenerData.java @@ -0,0 +1,282 @@ +package paulscode.sound; + +/** + * The listenerData class is used to store information about the + * listener's position and orientation. A ListenerData object can be obtained + * using SoundSystem's getListenerData() method. See + * {@link paulscode.sound.Vector3D Vector3D} for more information about 3D + * coordinates and vectors. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class ListenerData +{ +/** + * Listener's position in 3D space + */ + public Vector3D position; +/** + * A normalized vector indicating the direction the listener is facing + */ + public Vector3D lookAt; +/** + * A normalized vector indicating the up direction + */ + public Vector3D up; +/** + * Listener's velocity in world-space + */ + public Vector3D velocity; + +/** + * Used for easy rotation along the x/z plane (for use in a first-person + * shooter type of application). + */ + public float angle = 0.0f; + +/** + * Constructor: Set this listener data to the origin facing along the z-axis + */ + public ListenerData() + { + position = new Vector3D( 0.0f, 0.0f, 0.0f ); + lookAt = new Vector3D( 0.0f, 0.0f, -1.0f ); + up = new Vector3D( 0.0f, 1.0f, 0.0f ); + velocity = new Vector3D( 0.0f, 0.0f, 0.0f ); + angle = 0.0f; + } + +/** + * Constructor: Set this listener data to the specified values for position and + * orientation. + * @param pX Listener's X coordinate. + * @param pY Listener's Y coordinate. + * @param pZ Listener's Z coordinate. + * @param lX X element of the look-at direction. + * @param lY Y element of the look-at direction. + * @param lZ Z element of the look-at direction. + * @param uX X element of the up direction. + * @param uY Y element of the up direction. + * @param uZ Z element of the up direction. + * @param a Angle in radians that the listener is turned counterclockwise around the y-axis. + */ + public ListenerData( float pX, float pY, float pZ, float lX, float lY, + float lZ, float uX, float uY, float uZ, float a ) + { + position = new Vector3D( pX, pY, pZ ); + lookAt = new Vector3D( lX, lY, lZ ); + up = new Vector3D( uX, uY, uZ ); + velocity = new Vector3D( 0.0f, 0.0f, 0.0f ); + angle = a; + } + +/** + * Constructor: Set this listener data to the specified values for position and + * orientation. + * @param p Position of the listener in 3D space. + * @param l Normalized vector indicating the direction which the listener is facing. + * @param u Normalized vector indicating the up direction. + * @param a Angle in radians that the listener is turned counterclockwise around the y-axis. + */ + public ListenerData( Vector3D p, Vector3D l, Vector3D u, float a ) + { + position = p.clone(); + lookAt = l.clone(); + up = u.clone(); + velocity = new Vector3D( 0.0f, 0.0f, 0.0f ); + angle = a; + } + +/** + * Change this listener data using the specified coordinates for position and + * orientation. + * @param pX Listener's X coordinate. + * @param pY Listener's Y coordinate. + * @param pZ Listener's Z coordinate. + * @param lX X element of the look-at direction. + * @param lY Y element of the look-at direction. + * @param lZ Z element of the look-at direction. + * @param uX X element of the up direction. + * @param uY Y element of the up direction. + * @param uZ Z element of the up direction. + * @param a Angle in radians that the listener is turned counterclockwise around the y-axis. + */ + public void setData( float pX, float pY, float pZ, float lX, float lY, + float lZ, float uX, float uY, float uZ, float a ) + { + position.x = pX; + position.y = pY; + position.z = pZ; + lookAt.x = lX; + lookAt.y = lY; + lookAt.z = lZ; + up.x = uX; + up.y = uY; + up.z = uZ; + angle = a; + } + +/** + * Change this listener data using the specified 3D vectors for position and + * orientation. + * @param p Position of the listener in 3D space. + * @param l Normalized vector indicating the direction which the listener is facing. + * @param u Normalized vector indicating the up direction. + * @param a Angle in radians that the listener is turned counterclockwise around the y-axis. + */ + public void setData( Vector3D p, Vector3D l, Vector3D u, float a ) + { + position.x = p.x; + position.y = p.y; + position.z = p.z; + lookAt.x = l.x; + lookAt.y = l.y; + lookAt.z = l.z; + up.x = u.x; + up.y = u.y; + up.z = u.z; + angle = a; + } + +/** + * Change this listener data to match the specified listener data. + * @param l Listener data to use. + */ + public void setData( ListenerData l ) + { + position.x = l.position.x; + position.y = l.position.y; + position.z = l.position.z; + lookAt.x = l.lookAt.x; + lookAt.y = l.lookAt.y; + lookAt.z = l.lookAt.z; + up.x = l.up.x; + up.y = l.up.y; + up.z = l.up.z; + angle = l.angle; + } + +/** + * Change this listener's position using the specified coordinates. + * @param x Listener's X coordinate. + * @param y Listener's Y coordinate. + * @param z Listener's Z coordinate. + */ + public void setPosition( float x, float y, float z ) + { + position.x = x; + position.y = y; + position.z = z; + } + +/** + * Change this listener's position using the specified vector. + * @param p New position. + */ + public void setPosition( Vector3D p ) + { + position.x = p.x; + position.y = p.y; + position.z = p.z; + } + +/** + * Changes the listeners orientation using the specified coordinates. + * @param lX X element of the look-at direction. + * @param lY Y element of the look-at direction. + * @param lZ Z element of the look-at direction. + * @param uX X element of the up direction. + * @param uY Y element of the up direction. + * @param uZ Z element of the up direction. + */ + public void setOrientation( float lX, float lY, float lZ, + float uX, float uY, float uZ ) + { + lookAt.x = lX; + lookAt.y = lY; + lookAt.z = lZ; + up.x = uX; + up.y = uY; + up.z = uZ; + } + +/** + * Changes the listeners orientation using the specified vectors. + * @param l Normalized vector representing the look-at direction. + * @param u Normalized vector representing the up direction. + */ + public void setOrientation( Vector3D l, Vector3D u ) + { + lookAt.x = l.x; + lookAt.y = l.y; + lookAt.z = l.z; + up.x = u.x; + up.y = u.y; + up.z = u.z; + } + +/** + * Change this listener's velocity in world-space. + * @param v New velocity. + */ + public void setVelocity( Vector3D v ) + { + velocity.x = v.x; + velocity.y = v.y; + velocity.z = v.z; + } + +/** + * Change this listener's velocity in world-space. + * @param x New velocity along world x-axis. + * @param y New velocity along world y-axis. + * @param z New velocity along world z-axis. + */ + public void setVelocity( float x, float y, float z ) + { + velocity.x = x; + velocity.y = y; + velocity.z = z; + } + +/** + * Sets the listener's angle counterclockwise around the y-axis. + * @param a Angle in radians. + */ + public void setAngle( float a ) + { + angle = a; + lookAt.x = -1.0f * (float) Math.sin( angle ); + lookAt.z = -1.0f * (float) Math.cos( angle ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/MidiChannel.java b/src/lwjgl/java/paulscode/sound/MidiChannel.java new file mode 100644 index 0000000..aedf033 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/MidiChannel.java @@ -0,0 +1,1601 @@ +package paulscode.sound; + +import java.io.IOException; +import java.net.URL; +import java.util.LinkedList; +import java.util.ListIterator; + +import javax.sound.midi.InvalidMidiDataException; +import javax.sound.midi.MetaEventListener; +import javax.sound.midi.MetaMessage; +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Sequence; +import javax.sound.midi.Sequencer; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Synthesizer; + +/** + * The MidiChannel class provides an interface for playing MIDI files, using + * the JavaSound API. For more information about the JavaSound API, visit + * http://java.sun.com/products/java-media/sound/ + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class MidiChannel implements MetaEventListener +{ +/** + * Processes status messages, warnings, and error messages. + */ + private SoundSystemLogger logger; + +/** + * Filename/URL to the file: + */ + private FilenameURL filenameURL; + +/** + * Unique source identifier for this MIDI source. + */ + private String sourcename; + +/** + * Global identifier for the MIDI "change volume" event. + */ + private static final int CHANGE_VOLUME = 7; + +/** + * Global identifier for the MIDI "end of track" event. + */ + private static final int END_OF_TRACK = 47; + +/** + * Used to return a current value from one of the synchronized + * boolean-interface methods. + */ + private static final boolean GET = false; + +/** + * Used to set the value in one of the synchronized boolean-interface methods. + */ + private static final boolean SET = true; + +/** + * Used when a parameter for one of the synchronized boolean-interface methods + * is not aplicable. + */ + private static final boolean XXX = false; + +/** + * Runs the assigned sequence, passing information on to the synthesizer for + * playback. + */ + private Sequencer sequencer = null; + +/** + * Converts MIDI events into audio. + */ + private Synthesizer synthesizer = null; + +/** + * Converts MIDI events into audio if there is no default Synthesizer. + */ + private MidiDevice synthDevice = null; + +/** + * Sequence of MIDI events defining sound. + */ + private Sequence sequence = null; + +/** + * Should playback loop or play only once. + */ + private boolean toLoop = true; + +/** + * Playback volume, float value (0.0f - 1.0f). + */ + private float gain = 1.0f; + +/** + * True while sequencer is busy being set up. + */ + private boolean loading = true; + +/** + * The list of MIDI files to play when the current sequence finishes. + */ + private LinkedList sequenceQueue = null; + +/** + * Ensures that only one thread accesses the sequenceQueue at a time. + */ + private final Object sequenceQueueLock = new Object(); + +/** + * Specifies the gain factor used for the fade-out effect, or -1 when + * playback is not currently fading out. + */ + protected float fadeOutGain = -1.0f; + +/** + * Specifies the gain factor used for the fade-in effect, or 1 when + * playback is not currently fading in. + */ + protected float fadeInGain = 1.0f; + +/** + * Specifies the number of miliseconds it should take to fade out. + */ + protected long fadeOutMilis = 0; + +/** + * Specifies the number of miliseconds it should take to fade in. + */ + protected long fadeInMilis = 0; + +/** + * System time in miliseconds when the last fade in/out volume check occurred. + */ + protected long lastFadeCheck = 0; + +/** + * Used for fading in and out effects. + */ + private FadeThread fadeThread = null; + +/** + * Constructor: Defines the basic source information. + * @param toLoop Should playback loop or play only once? + * @param sourcename Unique identifier for this source. + * @param filename Name of the MIDI file to play. + */ + public MidiChannel( boolean toLoop, String sourcename, String filename ) + { + // let others know we are busy loading: + loading( SET, true ); + + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + // save information about the source: + filenameURL( SET, new FilenameURL( filename ) ); + sourcename( SET, sourcename ); + setLooping( toLoop ); + + // initialize the MIDI channel: + init(); + + // finished loading: + loading( SET, false ); + } + +/** + * Constructor: Defines the basic source information. The fourth parameter, + * 'identifier' should look like a filename, and it must have the correct + * extension (.mid or .midi). + * @param toLoop Should playback loop or play only once? + * @param sourcename Unique identifier for this source. + * @param midiFile URL to the MIDI file to play. + * @param identifier Filename/identifier for the MIDI file. + */ + public MidiChannel( boolean toLoop, String sourcename, URL midiFile, + String identifier ) + { + // let others know we are busy loading + loading( SET, true ); + + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + // save information about the source: + filenameURL( SET, new FilenameURL( midiFile, identifier ) ); + sourcename( SET, sourcename ); + setLooping( toLoop ); + + // initialize the MIDI channel: + init(); + + // finished loading: + loading( SET, false ); + } + +/** + * Constructor: Defines the basic source information. + * @param toLoop Should playback loop or play only once? + * @param sourcename Unique identifier for this source. + * @param midiFilenameURL Filename/URL to the MIDI file to play. + */ + public MidiChannel( boolean toLoop, String sourcename, + FilenameURL midiFilenameURL ) + { + // let others know we are busy loading + loading( SET, true ); + + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + // save information about the source: + filenameURL( SET, midiFilenameURL ); + sourcename( SET, sourcename ); + setLooping( toLoop ); + + // initialize the MIDI channel: + init(); + + // finished loading: + loading( SET, false ); + } + +/** + * Initializes the sequencer, loads the sequence, and sets up the synthesizer. + */ + private void init() + { + // Load a sequencer: + getSequencer(); + + // Load the sequence to play: + setSequence( filenameURL( GET, null).getURL() ); + + // Load a synthesizer to play the sequence on: + getSynthesizer(); + + // Ensure the initial volume is correct: + // (TODO: doesn't always work??) + resetGain(); + } + +/** + * Shuts the channel down and removes references to all instantiated objects. + */ + public void cleanup() + { + loading( SET, true ); + setLooping( true ); + + if( sequencer != null ) + { + try + { + sequencer.stop(); + sequencer.close(); + sequencer.removeMetaEventListener( this ); + } + catch( Exception e ) + {} + } + + logger = null; + sequencer = null; + synthesizer = null; + sequence = null; + + synchronized( sequenceQueueLock ) + { + if( sequenceQueue != null ) + sequenceQueue.clear(); + sequenceQueue = null; + } + + // End the fade effects thread if it exists: + if( fadeThread != null ) + { + boolean killException = false; + try + { + fadeThread.kill(); // end the fade effects thread. + fadeThread.interrupt(); // wake the thread up so it can end. + } + catch( Exception e ) + { + killException = true; + } + + if( !killException ) + { + // wait up to 5 seconds for fade effects thread to end: + for( int i = 0; i < 50; i++ ) + { + if( !fadeThread.alive() ) + break; + try{Thread.sleep( 100 );}catch(InterruptedException e){} + } + } + + // Let user know if there was a problem ending the fade thread + if( killException || fadeThread.alive() ) + { + errorMessage( "MIDI fade effects thread did not die!" ); + message( "Ignoring errors... continuing clean-up." ); + } + } + + fadeThread = null; + + loading( SET, false ); + } + +/** + * Queues up the next MIDI sequence to play when the previous sequence ends. + * @param filenameURL MIDI sequence to play next. + */ + public void queueSound( FilenameURL filenameURL ) + { + if( filenameURL == null ) + { + errorMessage( "Filename/URL not specified in method 'queueSound'" ); + return; + } + + synchronized( sequenceQueueLock ) + { + if( sequenceQueue == null ) + sequenceQueue = new LinkedList(); + sequenceQueue.add( filenameURL ); + } + } + +/** + * Removes the first occurrence of the specified filename/identifier from the + * list of MIDI sequences to play when the previous sequence ends. + * @param filename Filename or identifier of a MIDI sequence to remove from the + * queue. + */ + public void dequeueSound( String filename ) + { + if( filename == null || filename.equals( "" ) ) + { + errorMessage( "Filename not specified in method 'dequeueSound'" ); + return; + } + + synchronized( sequenceQueueLock ) + { + if( sequenceQueue != null ) + { + ListIterator i = sequenceQueue.listIterator(); + while( i.hasNext() ) + { + if( i.next().getFilename().equals( filename ) ) + { + i.remove(); + break; + } + } + } + } + } + +/** + * Fades out the volume of whatever sequence is currently playing, then + * begins playing the specified MIDI file at the previously assigned + * volume level. If the filenameURL parameter is null or empty, playback will + * simply fade out and stop. The miliseconds parameter must be non-negative or + * zero. This method will remove anything that is currently in the list of + * queued MIDI sequences that would have played next when current playback + * finished. + * @param filenameURL MIDI file to play next, or null for none. + * @param milis Number of miliseconds the fadeout should take. + */ + public void fadeOut( FilenameURL filenameURL, long milis ) + { + if( milis < 0 ) + { + errorMessage( "Miliseconds may not be negative in method " + + "'fadeOut'." ); + return; + } + + fadeOutMilis = milis; + fadeInMilis = 0; + fadeOutGain = 1.0f; + lastFadeCheck = System.currentTimeMillis(); + + synchronized( sequenceQueueLock ) + { + if( sequenceQueue != null ) + sequenceQueue.clear(); + + if( filenameURL != null ) + { + if( sequenceQueue == null ) + sequenceQueue = new LinkedList(); + sequenceQueue.add( filenameURL ); + } + } + if( fadeThread == null ) + { + fadeThread = new FadeThread(); + fadeThread.start(); + } + fadeThread.interrupt(); + } + +/** + * Fades out the volume of whatever sequence is currently playing, then + * fades the volume back in playing the specified MIDI file. Final volume + * after fade-in completes will be equal to the previously assigned volume + * level. The filenameURL parameter may not be null or empty. The miliseconds + * parameters must be non-negative or zero. This method will remove anything + * that is currently in the list of queued MIDI sequences that would have + * played next when current playback finished. + * @param filenameURL MIDI file to play next, or null for none. + * @param milisOut Number of miliseconds the fadeout should take. + * @param milisIn Number of miliseconds the fadein should take. + */ + public void fadeOutIn( FilenameURL filenameURL, long milisOut, + long milisIn ) + { + if( filenameURL == null ) + { + errorMessage( "Filename/URL not specified in method 'fadeOutIn'." ); + return; + } + if( milisOut < 0 || milisIn < 0 ) + { + errorMessage( "Miliseconds may not be negative in method " + + "'fadeOutIn'." ); + return; + } + + fadeOutMilis = milisOut; + fadeInMilis = milisIn; + fadeOutGain = 1.0f; + lastFadeCheck = System.currentTimeMillis(); + + synchronized( sequenceQueueLock ) + { + if( sequenceQueue == null ) + sequenceQueue = new LinkedList(); + sequenceQueue.clear(); + sequenceQueue.add( filenameURL ); + } + if( fadeThread == null ) + { + fadeThread = new FadeThread(); + fadeThread.start(); + } + fadeThread.interrupt(); + } + +/** + * Resets this source's volume if it is fading out or in. Returns true if this + * source is currently in the process of fading out. When fade-out completes, + * this method transitions the source to the next sound in the sound sequence + * queue if there is one. This method has no effect on non-streaming sources. + * @return True if this source is in the process of fading out. + */ + private synchronized boolean checkFadeOut() + { + if( fadeOutGain == -1.0f && fadeInGain == 1.0f ) + return false; + + long currentTime = System.currentTimeMillis(); + long milisPast = currentTime - lastFadeCheck; + lastFadeCheck = currentTime; + + if( fadeOutGain >= 0.0f ) + { + if( fadeOutMilis == 0 ) + { + fadeOutGain = 0.0f; + fadeInGain = 0.0f; + if( !incrementSequence() ) + stop(); + rewind(); + resetGain(); + return false; + } + else + { + float fadeOutReduction = ((float)milisPast) / ((float)fadeOutMilis); + + fadeOutGain -= fadeOutReduction; + if( fadeOutGain <= 0.0f ) + { + fadeOutGain = -1.0f; + fadeInGain = 0.0f; + if( !incrementSequence() ) + stop(); + rewind(); + resetGain(); + return false; + } + } + resetGain(); + return true; + } + + if( fadeInGain < 1.0f ) + { + fadeOutGain = -1.0f; + if( fadeInMilis == 0 ) + { + fadeOutGain = -1.0f; + fadeInGain = 1.0f; + } + else + { + float fadeInIncrease = ((float)milisPast) / ((float)fadeInMilis); + fadeInGain += fadeInIncrease; + if( fadeInGain >= 1.0f ) + { + fadeOutGain = -1.0f; + fadeInGain = 1.0f; + } + } + resetGain(); + } + + return false; + } + +/** + * Removes the next sequence from the queue and assigns it to the sequencer. + * @return True if there was something in the queue. + */ + private boolean incrementSequence() + { + synchronized( sequenceQueueLock ) + { + // Is there a queue, and if so, is there anything in it: + if( sequenceQueue != null && sequenceQueue.size() > 0 ) + { + // grab the next filename/URL from the queue: + filenameURL( SET, sequenceQueue.remove( 0 ) ); + + // Let everyone know we are busy loading: + loading( SET, true ); + + // Check if we have a sequencer: + if( sequencer == null ) + { + // nope, try and get one now: + getSequencer(); + } + else + { + // We have a sequencer. Stop it now: + sequencer.stop(); + // rewind to the beginning: + sequencer.setMicrosecondPosition( 0 ); + // Stop listening for a moment: + sequencer.removeMetaEventListener( this ); + // wait a bit for the sequencer to shut down and rewind: + try{ Thread.sleep( 100 ); }catch( InterruptedException e ){} + } + // We need to have a sequencer at this point: + if( sequencer == null ) + { + errorMessage( "Unable to set the sequence in method " + + "'incrementSequence', because there wasn't " + + "a sequencer to use." ); + + // Finished loading: + loading( SET, false ); + + // failure: + return false; + } + // set the new sequence to be played: + setSequence( filenameURL( GET, null ).getURL() ); + // start playing again: + sequencer.start(); + // make sure we play at the correct volume: + // (TODO: This doesn't always work??) + resetGain(); + // start listening for end of track event again: + sequencer.addMetaEventListener( this ); + + // Finished loading: + loading( SET, false ); + + // We successfully moved to the next sequence: + return true; + } + } + + // Nothing left to load + return false; + } + +/** + * Plays the MIDI file from the beginning, or from where it left off if it was + * paused. + */ + public void play() + { + if( !loading() ) + { + // Make sure there is a sequencer: + if( sequencer == null ) + return; + + try + { + // start playing: + sequencer.start(); + // event will be sent when end of track is reached: + sequencer.addMetaEventListener( this ); + } + catch( Exception e ) + { + errorMessage( "Exception in method 'play'" ); + printStackTrace( e ); + SoundSystemException sse = new SoundSystemException( + e.getMessage() ); + SoundSystem.setException( sse ); + } + } + } + +/** + * Stops playback and rewinds to the beginning. + */ + public void stop() + { + if( !loading() ) + { + // Make sure there is a sequencer: + if( sequencer == null ) + return; + + try + { + // stop playback: + sequencer.stop(); + // rewind to the beginning: + sequencer.setMicrosecondPosition( 0 ); + // No need to listen any more: + sequencer.removeMetaEventListener( this ); + } + catch( Exception e ) + { + errorMessage( "Exception in method 'stop'" ); + printStackTrace( e ); + SoundSystemException sse = new SoundSystemException( + e.getMessage() ); + SoundSystem.setException( sse ); + } + } + } + +/** + * Temporarily stops playback without rewinding. + */ + public void pause() + { + if( !loading() ) + { + // Make sure there is a sequencer: + if( sequencer == null ) + return; + + try + { + //stop playback. Will resume from this location next play. + sequencer.stop(); + } + catch( Exception e ) + { + errorMessage( "Exception in method 'pause'" ); + printStackTrace( e ); + SoundSystemException sse = new SoundSystemException( + e.getMessage() ); + SoundSystem.setException( sse ); + } + } + } + +/** + * Returns playback to the beginning. + */ + public void rewind() + { + if( !loading() ) + { + // Make sure there is a sequencer: + if( sequencer == null ) + return; + + try + { + // rewind to the beginning: + sequencer.setMicrosecondPosition( 0 ); + } + catch( Exception e ) + { + errorMessage( "Exception in method 'rewind'" ); + printStackTrace( e ); + SoundSystemException sse = new SoundSystemException( + e.getMessage() ); + SoundSystem.setException( sse ); + } + } + } + +/** + * Changes the volume of MIDI playback. + * @param value Float value (0.0f - 1.0f). + */ + public void setVolume( float value ) + { + gain = value; + resetGain(); + } + +/** + * Returns the current volume for the MIDI source. + * @return Float value (0.0f - 1.0f). + */ + public float getVolume() + { + return gain; + } + +/** + * Changes the basic information about the MIDI source. This method removes + * any queued filenames/URLs from the list of MIDI sequences that would have + * played after the current sequence ended. + * @param toLoop Should playback loop or play only once? + * @param sourcename Unique identifier for this source. + * @param filename Name of the MIDI file to play. + */ + public void switchSource( boolean toLoop, String sourcename, + String filename ) + { + // Let everyone know we are busy loading: + loading( SET, true ); + + // save information about the source: + filenameURL( SET, new FilenameURL( filename ) ); + sourcename( SET, sourcename ); + setLooping( toLoop ); + + reset(); + + // Finished loading: + loading( SET, false ); + } + +/** + * Changes the basic information about the MIDI source. This method removes + * any queued filenames/URLs from the list of MIDI sequences that would have + * played after the current sequence ended. The fourth parameter, + * 'identifier' should look like a filename, and it must have the correct + * extension (.mid or .midi). + * @param toLoop Should playback loop or play only once? + * @param sourcename Unique identifier for this source. + * @param midiFile URL to the MIDI file to play. + * @param identifier Filename/identifier for the MIDI file. + */ + public void switchSource( boolean toLoop, String sourcename, URL midiFile, + String identifier ) + { + // Let everyone know we are busy loading: + loading( SET, true ); + + // save information about the source: + filenameURL( SET, new FilenameURL( midiFile, identifier ) ); + sourcename( SET, sourcename ); + setLooping( toLoop ); + + reset(); + + // Finished loading: + loading( SET, false ); + } + +/** + * Changes the basic information about the MIDI source. This method removes + * any queued filenames/URLs from the list of MIDI sequences that would have + * played after the current sequence ended. + * @param toLoop Should playback loop or play only once? + * @param sourcename Unique identifier for this source. + * @param filenameURL Filename/URL of the MIDI file to play. + */ + public void switchSource( boolean toLoop, String sourcename, + FilenameURL filenameURL ) + { + // Let everyone know we are busy loading: + loading( SET, true ); + + // save information about the source: + filenameURL( SET, filenameURL ); + sourcename( SET, sourcename ); + setLooping( toLoop ); + + reset(); + + // Finished loading: + loading( SET, false ); + } + +/** + * Stops and rewinds the sequencer, and resets the sequence. + */ + private void reset() + { + synchronized( sequenceQueueLock ) + { + if( sequenceQueue != null ) + sequenceQueue.clear(); + } + + // Check if we have a sequencer: + if( sequencer == null ) + { + // nope, try and get one now: + getSequencer(); + } + else + { + // We have a sequencer. Stop it now: + sequencer.stop(); + // rewind to the beginning: + sequencer.setMicrosecondPosition( 0 ); + // Stop listening for a moment: + sequencer.removeMetaEventListener( this ); + // wait a bit for the sequencer to shut down and rewind: + try{ Thread.sleep( 100 ); }catch( InterruptedException e ){} + } + // We need to have a sequencer at this point: + if( sequencer == null ) + { + errorMessage( "Unable to set the sequence in method " + + "'reset', because there wasn't " + + "a sequencer to use." ); + return; + } + + // set the new sequence to be played: + setSequence( filenameURL( GET, null ).getURL() ); + // start playing again: + sequencer.start(); + // make sure we play at the correct volume: + // (TODO: This doesn't always work??) + resetGain(); + // start listening for end of track event again: + sequencer.addMetaEventListener( this ); + } + +/** + * Sets the value of boolean 'toLoop'. + * @param value True or False. + */ + public void setLooping( boolean value ) + { + toLoop( SET, value ); + } + +/** + * Returns the value of boolean 'toLoop'. + * @return True while looping. + */ + public boolean getLooping() + { + return toLoop( GET, XXX ); + } + +/** + * Sets or returns the value of boolean 'toLoop'. + * @param action GET or SET. + * @param value New value if action == SET, or XXX if action == GET. + * @return True while looping. + */ + private synchronized boolean toLoop( boolean action, boolean value ) + { + if( action == SET ) + toLoop = value; + return toLoop; + } + +/** + * Check if a MIDI file is in the process of loading. + */ + public boolean loading() + { + return( loading( GET, XXX ) ); + } + +/** + * Sets or returns the value of boolean 'loading'. + * @param action GET or SET. + * @param value New value if action == SET, or XXX if action == GET. + * @return True while a MIDI file is in the process of loading. + */ + private synchronized boolean loading( boolean action, boolean value ) + { + if( action == SET ) + loading = value; + return loading; + } + +/** + * Defines the unique identifier for this source + * @param value New source name. + */ + public void setSourcename( String value ) + { + sourcename( SET, value ); + } + +/** + * Returns the unique identifier for this source. + * @return The source's name. + */ + public String getSourcename() + { + return sourcename( GET, null ); + } + +/** + * Sets or returns the value of String 'sourcename'. + * @param action GET or SET. + * @param value New value if action == SET, or null if action == GET. + * @return The source's name. + */ + private synchronized String sourcename( boolean action, String value ) + { + if( action == SET ) + sourcename = value; + return sourcename; + } + +/** + * Defines which MIDI file to play. + * @param value Path to the MIDI file. + */ + public void setFilenameURL( FilenameURL value ) + { + filenameURL( SET, value ); + } + +/** + * Returns the filename/identifier of the MIDI file being played. + * @return Filename of identifier of the MIDI file. + */ + public String getFilename() + { + return filenameURL( GET, null ).getFilename(); + } + +/** + * Returns the MIDI file being played. + * @return Filename/URL of the MIDI file. + */ + public FilenameURL getFilenameURL() + { + return filenameURL( GET, null ); + } + +/** + * Sets or returns the value of filenameURL. + * @param action GET or SET. + * @param value New value if action == SET, or null if action == GET. + * @return Path to the MIDI file. + */ + private synchronized FilenameURL filenameURL( boolean action, + FilenameURL value ) + { + if( action == SET ) + filenameURL = value; + return filenameURL; + } + +/** + * Called when MIDI events occur. + * @param message Meta mssage describing the MIDI event. + */ + public void meta( MetaMessage message ) + { + if( message.getType() == END_OF_TRACK ) + { + // Generate an EOS event: + SoundSystemConfig.notifyEOS( sourcename, sequenceQueue.size() ); + + // check if we should loop or not: + if( toLoop ) + { + // looping + // Check if playback is in the process of fading out. + if( !checkFadeOut() ) + { + // Not fading out, progress to the next MIDI sequence if + // any are queued. + if( !incrementSequence() ) + { + try + { + // Rewind to the beginning. + sequencer.setMicrosecondPosition( 0 ); + sequencer.start(); + // Make sure playback volume is correct. + resetGain(); + } + catch( Exception e ){} + } + } + else if( sequencer != null ) + { + try + { + // Rewind to the beginning. + sequencer.setMicrosecondPosition( 0 ); + sequencer.start(); + // Make sure playback volume is correct. + resetGain(); + } + catch( Exception e ){} + } + } + else + { + //non-looping + if( !checkFadeOut() ) + { + if( !incrementSequence() ) + { + try + { + // stop playback: + sequencer.stop(); + // rewind to the beginning: + sequencer.setMicrosecondPosition( 0 ); + // stop looping: + sequencer.removeMetaEventListener( this ); + } + catch( Exception e ){} + } + } + else + { + try + { + // stop playback: + sequencer.stop(); + // rewind to the beginning: + sequencer.setMicrosecondPosition( 0 ); + // stop looping: + sequencer.removeMetaEventListener( this ); + } + catch( Exception e ){} + } + } + } + } + +/** + * Resets playback volume to the correct level. + */ + public void resetGain() + { + // make sure the value for gain is valid (between 0 and 1) + if( gain < 0.0f ) + gain = 0.0f; + if( gain > 1.0f ) + gain = 1.0f; + + int midiVolume = (int) ( gain * SoundSystemConfig.getMasterGain() + * (float) Math.abs( fadeOutGain ) * fadeInGain + * 127.0f ); + if( synthesizer != null ) + { + javax.sound.midi.MidiChannel[] channels = synthesizer.getChannels(); + for( int c = 0; channels != null && c < channels.length; c++ ) + { + channels[c].controlChange( CHANGE_VOLUME, midiVolume ); + } + } + else if( synthDevice != null ) + { + try + { + ShortMessage volumeMessage = new ShortMessage(); + for( int i = 0; i < 16; i++ ) + { + volumeMessage.setMessage( ShortMessage.CONTROL_CHANGE, i, + CHANGE_VOLUME, midiVolume ); + synthDevice.getReceiver().send( volumeMessage, -1 ); + } + } + catch( Exception e ) + { + errorMessage( "Error resetting gain on MIDI device" ); + printStackTrace( e ); + } + } + else if( sequencer != null && sequencer instanceof Synthesizer ) + { + synthesizer = (Synthesizer) sequencer; + javax.sound.midi.MidiChannel[] channels = synthesizer.getChannels(); + for( int c = 0; channels != null && c < channels.length; c++ ) + { + channels[c].controlChange( CHANGE_VOLUME, midiVolume ); + } + } + else + { + try + { + Receiver receiver = MidiSystem.getReceiver(); + ShortMessage volumeMessage= new ShortMessage(); + for( int c = 0; c < 16; c++ ) + { + volumeMessage.setMessage( ShortMessage.CONTROL_CHANGE, c, + CHANGE_VOLUME, midiVolume ); + receiver.send( volumeMessage, -1 ); + } + } + catch( Exception e ) + { + errorMessage( "Error resetting gain on default receiver" ); + printStackTrace( e ); + } + } + } + +/** + * Attempts to load the default sequencer. If it fails, then other common + * sequencers are tried. If none can be loaded, then variable 'sequencer' + * remains null. + */ + private void getSequencer() + { + try + { + sequencer = MidiSystem.getSequencer(); + if( sequencer != null ) + { + try + { + sequencer.getTransmitter(); + } + catch( MidiUnavailableException mue ) + { + message( "Unable to get a transmitter from the " + + "default MIDI sequencer" ); + } + sequencer.open(); + } + } + catch( MidiUnavailableException mue ) + { + message( "Unable to open the default MIDI sequencer" ); + sequencer = null; + } + catch( Exception e ) + { + if( e instanceof InterruptedException ) + { + message( "Caught InterruptedException while attempting to " + + "open the default MIDI sequencer. Trying again." ); + sequencer = null; + } + try + { + sequencer = MidiSystem.getSequencer(); + if( sequencer != null ) + { + try + { + sequencer.getTransmitter(); + } + catch( MidiUnavailableException mue ) + { + message( "Unable to get a transmitter from the " + + "default MIDI sequencer" ); + } + sequencer.open(); + } + } + catch( MidiUnavailableException mue ) + { + message( "Unable to open the default MIDI sequencer" ); + sequencer = null; + } + catch( Exception e2 ) + { + message( "Unknown error opening the default MIDI sequencer" ); + sequencer = null; + } + } + + if( sequencer == null ) + sequencer = openSequencer( "Real Time Sequencer" ); + if( sequencer == null ) + sequencer = openSequencer( "Java Sound Sequencer"); + if( sequencer == null ) + { + errorMessage( "Failed to find an available MIDI sequencer" ); + return; + } + } + +/** + * Loads the MIDI sequence form the specified URL, and sets the sequence. If + * variable 'sequencer' is null or an error occurs, then variable 'sequence' + * remains null. + * @param midiSource URL to a MIDI file. + */ + private void setSequence( URL midiSource ) + { + if( sequencer == null ) + { + errorMessage( "Unable to update the sequence in method " + + "'setSequence', because variable 'sequencer' " + + "is null" ); + return; + } + + if( midiSource == null ) + { + errorMessage( "Unable to load Midi file in method 'setSequence'." ); + return; + } + + try + { + sequence = MidiSystem.getSequence( midiSource ); + } + catch( IOException ioe ) + { + errorMessage( "Input failed while reading from MIDI file in " + + "method 'setSequence'." ); + printStackTrace( ioe ); + return; + } + catch( InvalidMidiDataException imde ) + { + errorMessage( "Invalid MIDI data encountered, or not a MIDI " + + "file in method 'setSequence' (1)." ); + printStackTrace( imde ); + return; + } + if( sequence == null ) + { + errorMessage( "MidiSystem 'getSequence' method returned null " + + "in method 'setSequence'." ); + } + else + { + try + { + sequencer.setSequence( sequence ); + } + catch( InvalidMidiDataException imde ) + { + errorMessage( "Invalid MIDI data encountered, or not a MIDI " + + "file in method 'setSequence' (2)." ); + printStackTrace( imde ); + return; + } + catch( Exception e ) + { + errorMessage( "Problem setting sequence from MIDI file in " + + "method 'setSequence'." ); + printStackTrace( e ); + return; + } + } + } + +/** + * First attempts to load the specified "override MIDI synthesizer" if one was + * defined. If none was defined or unable to use it, then attempts to load the + * default synthesizer. If that fails, then other common synthesizers are + * attempted. If none can be loaded, then MIDI is not possible on this system. + */ + private void getSynthesizer() + { + if( sequencer == null ) + { + errorMessage( "Unable to load a Synthesizer in method " + + "'getSynthesizer', because variable 'sequencer' " + + "is null" ); + return; + } + + // Check if an alternate MIDI synthesizer was specified to use + String overrideMIDISynthesizer = + SoundSystemConfig.getOverrideMIDISynthesizer(); + if( overrideMIDISynthesizer != null + && !overrideMIDISynthesizer.equals( "" ) ) + { + // Try and open the specified device: + synthDevice = openMidiDevice( overrideMIDISynthesizer ); + // See if we got it: + if( synthDevice != null ) + { + // Got it, try and link it to the sequencer: + try + { + sequencer.getTransmitter().setReceiver( + synthDevice.getReceiver() ); + // Success! + return; + } + catch( MidiUnavailableException mue ) + { + // Problem linking the two, let the user know + errorMessage( "Unable to link sequencer transmitter " + + "with receiver for MIDI device '" + + overrideMIDISynthesizer + "'" ); + } + } + } + + // No alternate MIDI synthesizer was specified, or unable to use it. + + // If the squencer were also a synthesizer, that would make things easy: + if( sequencer instanceof Synthesizer ) + { + synthesizer = (Synthesizer) sequencer; + } + else + { + // Try getting the default synthesizer first: + try + { + synthesizer = MidiSystem.getSynthesizer(); + synthesizer.open(); + } + catch( MidiUnavailableException mue ) + { + message( "Unable to open the default synthesizer" ); + synthesizer = null; + } + + // See if we were sucessful: + if( synthesizer == null ) + { + // Try for the common MIDI synthesizers: + synthDevice = openMidiDevice( "Java Sound Synthesizer" ); + if( synthDevice == null ) + synthDevice = openMidiDevice( "Microsoft GS Wavetable" ); + if( synthDevice == null ) + synthDevice = openMidiDevice( "Gervill" ); + if( synthDevice == null ) + { + // Still nothing, MIDI is not going to work + errorMessage( "Failed to find an available MIDI " + + "synthesizer" ); + return; + } + } + + // Are we using the default synthesizer or something else? + if( synthesizer == null ) + { + // Link the sequencer and synthesizer: + try + { + sequencer.getTransmitter().setReceiver( + synthDevice.getReceiver() ); + } + catch( MidiUnavailableException mue ) + { + errorMessage( "Unable to link sequencer transmitter " + + "with MIDI device receiver" ); + } + } + else + { + // Bug-fix for multiple-receivers playing simultaneously + if( synthesizer.getDefaultSoundbank() == null ) + { + // Link the sequencer to the default receiver: + try + { + sequencer.getTransmitter().setReceiver( + MidiSystem.getReceiver() ); + } + catch( MidiUnavailableException mue ) + { + errorMessage( "Unable to link sequencer transmitter " + + "with default receiver" ); + } + } + else + { + // Link the sequencer to the default synthesizer: + try + { + sequencer.getTransmitter().setReceiver( + synthesizer.getReceiver() ); + } + catch( MidiUnavailableException mue ) + { + errorMessage( "Unable to link sequencer transmitter " + + "with synthesizer receiver" ); + } + } + // End bug-fix + } + } + } + +/** + * Attempts to open the Sequencer with a name containing the specified string. + * @param containsString Part or all of a Sequencer's name. + * @return Handle to the Sequencer, or null if not found or error. + */ + private Sequencer openSequencer( String containsString ) + { + Sequencer s = null; + s = (Sequencer) openMidiDevice( containsString ); + if( s == null ) + return null; + try + { + s.getTransmitter(); + } + catch( MidiUnavailableException mue ) + { + message( " Unable to get a transmitter from this sequencer" ); + s = null; + return null; + } + + return s; + } + +/** + * Attempts to open the MIDI device with a name containing the specified + * string. + * @param containsString Part or all of a MIDI device's name. + * @return Handle to the MIDI device, or null if not found or error. + */ + private MidiDevice openMidiDevice( String containsString ) + { + message( "Searching for MIDI device with name containing '" + + containsString + "'" ); + MidiDevice device = null; + MidiDevice.Info[] midiDevices = MidiSystem.getMidiDeviceInfo(); + for( int i = 0; i < midiDevices.length; i++ ) + { + device = null; + try + { + device = MidiSystem.getMidiDevice( midiDevices[i] ); + } + catch( MidiUnavailableException e ) + { + message( " Problem in method 'getMidiDevice': " + + "MIDIUnavailableException was thrown" ); + device = null; + } + if( device != null && midiDevices[i].getName().contains( + containsString ) ) + { + message( " Found MIDI device named '" + + midiDevices[i].getName() + "'" ); + if( device instanceof Synthesizer ) + message( " *this is a Synthesizer instance" ); + if( device instanceof Sequencer ) + message( " *this is a Sequencer instance" ); + try + { + device.open(); + } + catch( MidiUnavailableException mue ) + { + message( " Unable to open this MIDI device" ); + device = null; + } + return device; + } + } + message( " MIDI device not found" ); + return null; + } + +/** + * Prints a message. + * @param message Message to print. + */ + protected void message( String message ) + { + logger.message( message, 0 ); + } + +/** + * Prints an important message. + * @param message Message to print. + */ + protected void importantMessage( String message ) + { + logger.importantMessage( message, 0 ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param message Message to print if error is true. + * @return True if error is true. + */ + protected boolean errorCheck( boolean error, String message ) + { + return logger.errorCheck( error, "MidiChannel", message, 0 ); + } + +/** + * Prints an error message. + * @param message Message to print. + */ + protected void errorMessage( String message ) + { + logger.errorMessage( "MidiChannel", message, 0 ); + } + +/** + * Prints an exception's error message followed by the stack trace. + * @param e Exception containing the information to print. + */ + protected void printStackTrace( Exception e ) + { + logger.printStackTrace( e, 1 ); + } + +/** + * The FadeThread class handles sequence changing, timing, and volume change + * messages in the background. + */ + private class FadeThread extends SimpleThread + { + @Override +/** + * Runs in the background, timing fade in and fade out, changing the sequence, + * and issuing the appropriate volume change messages. + */ + public void run() + { + while( !dying() ) + { + // if not currently fading in or out, put the thread to sleep + if( fadeOutGain == -1.0f && fadeInGain == 1.0f ) + snooze( 3600000 ); + checkFadeOut(); + // only update every 50 miliseconds (no need to peg the cpu) + snooze( 50 ); + } + // Important! + cleanup(); + } + } + +} + diff --git a/src/lwjgl/java/paulscode/sound/SimpleThread.java b/src/lwjgl/java/paulscode/sound/SimpleThread.java new file mode 100644 index 0000000..8bd65fa --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/SimpleThread.java @@ -0,0 +1,200 @@ +package paulscode.sound; + + +/** + * The SimpleThread class is the template used to create all thread classes + * used by in the SoundSystem library. It provides methods for common actions + * like sleeping, killing, and checking liveness. NOTE: super.cleanup() must + * be called at the bottom of overriden cleanup() methods, and cleanup() + * must be called at the bottom of the run() method for all extended classes. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class SimpleThread extends Thread +{ +/** + * Used to return a current value from one of the synchronized + * boolean-interface methods. + */ + private static final boolean GET = false; + +/** + * Used to set the value in one of the synchronized boolean-interface methods. + */ + private static final boolean SET = true; + +/** + * Used when a parameter for one of the synchronized boolean-interface methods + * is not aplicable. + */ + private static final boolean XXX = false; + +/** + * True when thread is running. + */ + private boolean alive = true; + +/** + * True when thread should end. + */ + private boolean kill = false; + +/** + * Removes all references to instantiated objects, and changes the thread's + * state to "not alive". Method alive() returns false when this method has + * completed. NOTE: super.cleanup() must be called at the bottom of overriden + * cleanup() methods, and cleanup() must be called at the bottom of the run() + * method for all extended classes. + */ + protected void cleanup() + { + kill( SET, true ); // tread needs to shut down + alive( SET, false ); // thread has ended + } + +/** + * Executes the thread's main loop. NOTES: Extended classes should check + * method dying() often to know when the user wants the thread to shut down. + * Method cleanup() must be called at the bottom of the run() method for all + * extended classes. + */ + @Override + public void run() + { + /* How the run() method should be set up: */ + + + // Do your stuff here. Remember to check dying() often to know when + // the user wants the thread to shut down. + + // MUST call cleanup() at the bottom of Overridden run() method!!!!! + cleanup(); // clears memory and sets status to dead. + } + +/** + * Calls the rerun() method on a seperate thread, which calls run() when the + * previous thread finishes. + */ + public void restart() + { + new Thread() + { + @Override + public void run() + { + rerun(); + } + }.start(); + } + +/** + * Kills the previous thread, waits for it to die, then calls run(). + */ + private void rerun() + { + kill( SET, true ); + while( alive( GET, XXX ) ) + { + snooze( 100 ); + } + alive( SET, true ); + kill( SET, false ); + run(); + } + +/** + * Returns false when the cleanup() method has finished. This method should be + * used to know when the thread has been safely shut down. + * @return True while the thread is alive. + */ + public boolean alive() + { + return alive( GET, XXX ); + } + +/** + * Causes method dying() to return true, letting the thread know it needs to + * shut down. + */ + public void kill() + { + kill( SET, true ); + } + +/** + * Returns true when the thread is supposed to shut down. + * @return True if the thread should die. + */ + protected boolean dying() + { + return kill( GET, XXX ); + } + +/** + * Sets or returns the value of boolean 'alive'. + * @param action GET or SET. + * @param value New value if action == SET, or XXX if action == GET. + * @return True while the thread is alive. + */ + private synchronized boolean alive( boolean action, boolean value ) + { + if( action == SET ) + alive = value; + return alive; + } + +/** + * Sets or returns the value of boolean 'kill'. + * @param action GET or SET. + * @param value New value if action == SET, or XXX if action == GET. + * @return True if the thread should die. + */ + private synchronized boolean kill( boolean action, boolean value ) + { + if( action == SET ) + kill = value; + return kill; + } + +/** + * Sleeps for the specified number of milliseconds. + */ + protected void snooze( long milliseconds ) + { + try + { + Thread.sleep( milliseconds ); + } + catch( InterruptedException e ){} + } +} diff --git a/src/lwjgl/java/paulscode/sound/SoundBuffer.java b/src/lwjgl/java/paulscode/sound/SoundBuffer.java new file mode 100644 index 0000000..b258502 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/SoundBuffer.java @@ -0,0 +1,91 @@ +package paulscode.sound; + +import javax.sound.sampled.AudioFormat; + +/** + * The SoundBuffer class is used to wrap audio data along with the format in + * which the data is stored. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class SoundBuffer +{ +/** + * The actual audio data. + */ + public byte[] audioData; +/** + * The audio format in which the data is stored. + */ + public AudioFormat audioFormat; + +/** + * Constructor: Wraps the specified data with the specified audio format. + * + * @param audioData The actual audio data. + * @param audioFormat The audio format in which the data is stored. + */ + public SoundBuffer( byte[] audioData, AudioFormat audioFormat ) + { + this.audioData = audioData; + this.audioFormat = audioFormat; + } + +/** + * Removes handles to all instantiated objects. + */ + public void cleanup() + { + audioData = null; + audioFormat = null; + } + +/** + * Trims down the size of the audio data if it is larger than the specified + * maximum length. + * + * @param maxLength Maximum size this buffer may be. + */ + public void trimData( int maxLength ) + { + if( audioData == null || maxLength == 0 ) + audioData = null; + else if( audioData.length > maxLength ) + { + byte[] trimmedArray = new byte[maxLength]; + System.arraycopy( audioData, 0, trimmedArray, 0, + maxLength ); + audioData = trimmedArray; + } + } +} diff --git a/src/lwjgl/java/paulscode/sound/SoundSystem.java b/src/lwjgl/java/paulscode/sound/SoundSystem.java new file mode 100644 index 0000000..0f25617 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/SoundSystem.java @@ -0,0 +1,2895 @@ +package paulscode.sound; + +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Random; +import java.util.Set; +import javax.sound.sampled.AudioFormat; + +/** + * The SoundSystem class is the core class for the SoundSystem library. It is + * capable of interfacing with external sound library and codec library + * pluggins. This core class is stripped down to give it a smaller memory + * footprint and to make it more customizable. This library was created to + * provide a simple, common interface to a variety of 3rd-party sound and codec + * libraries, and to simplify switching between them on the fly. If no + * external pluggins are loaded, this core class by itself is only capable of + * playing MIDI files. Specific implementations (such as SoundSystemJPCT) will + * extend this core class. They will automatically link with popular + * external pluggins and provide extra methods for ease of use. + * There should be only one instance of this class in any program! The + * SoundSystem can be constructed by defining which sound library to use, or by + * allowing SoundSystem to perform its own library compatibility checking. See + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for information + * about changing default settings and linking with external pluggins. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class SoundSystem +{ +/** + * Used to return a current value from one of the synchronized + * boolean-interface methods. + */ + private static final boolean GET = false; +/** + * Used to set the value in one of the synchronized boolean-interface methods. + */ + private static final boolean SET = true; +/** + * Used when a parameter for one of the synchronized boolean-interface methods + * is not aplicable. + */ + private static final boolean XXX = false; + +/** + * Processes status messages, warnings, and error messages. + */ + protected SoundSystemLogger logger; + +/** + * Handle to the active sound library. + */ + protected Library soundLibrary; + +/** + * List of queued commands to perform. + */ + protected List commandQueue; + +/** + * Used internally by SoundSystem to keep track of play/pause/stop/rewind + * commands. This prevents source management (culling and activating) from + * being adversely affected by the quickPlay, quickStream, and backgroundMusic + * methods. + */ + private List sourcePlayList; + +/** + * Processes queued commands in the background. + */ + protected CommandThread commandThread; + +/** + * Generates random numbers. + */ + public Random randomNumberGenerator; + +/** + * Name of this class. + */ + protected String className = "SoundSystem"; + +/** + * Indicates the currently loaded sound-library, or null if none. + */ + private static Class currentLibrary = null; + +/** + * Becomes true when the sound library has been initialized. + */ + private static boolean initialized = false; + +/** + * Indicates the last exception that was thrown. + */ + private static SoundSystemException lastException = null; + +/** + * Constructor: Create the sound system using the default library. If the + * default library is not compatible, another library type will be loaded + * instead, in the order of library preference. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for + * information about sound library types. + */ + public SoundSystem() + { + // create the message logger: + logger = SoundSystemConfig.getLogger(); + // if the user didn't create one, then do it now: + if( logger == null ) + { + logger = new SoundSystemLogger(); + SoundSystemConfig.setLogger( logger ); + } + + linkDefaultLibrariesAndCodecs(); + + LinkedList libraries = SoundSystemConfig.getLibraries(); + + if( libraries != null ) + { + ListIterator i = libraries.listIterator(); + Class c; + while( i.hasNext() ) + { + c = i.next(); + try + { + init( c ); + return; + } + catch( SoundSystemException sse ) + { + logger.printExceptionMessage( sse, 1 ); + } + } + } + try + { + init( Library.class ); + return; + } + catch( SoundSystemException sse ) + { + logger.printExceptionMessage( sse, 1 ); + } + } + +/** + * Constructor: Create the sound system using the specified library. + * @param libraryClass Library to use. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for + * information about chosing a sound library. + */ + public SoundSystem( Class libraryClass ) throws SoundSystemException + { + // create the message logger: + logger = SoundSystemConfig.getLogger(); + // if the user didn't create one, then do it now: + if( logger == null ) + { + logger = new SoundSystemLogger(); + SoundSystemConfig.setLogger( logger ); + } + linkDefaultLibrariesAndCodecs(); + + init( libraryClass ); + } + +/** + * Links with any default libraries or codecs should be made in this method. + * This method is empty in the core SoundSystem class, and should be overriden + * by classes which extend SoundSystem. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for + * information about linking with sound libraries and codecs. + */ + protected void linkDefaultLibrariesAndCodecs() + { + } + +/** + * Loads the message logger, initializes the specified sound library, and + * starts the command thread. Also instantiates the random number generator + * and the command queue. + * @param libraryClass Library to initialize. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for + * information about chosing a sound library. + */ + protected void init( Class libraryClass ) throws SoundSystemException + { + message( "", 0 ); + message( "Starting up " + className + " version "+ SoundSystem.class.getPackage().getImplementationVersion()+"...", 0 ); + + // create the random number generator: + randomNumberGenerator = new Random(); + // create the command queue: + commandQueue = new LinkedList(); + // create the working source playlist: + sourcePlayList = new LinkedList(); + + // Instantiate and start the Command Processer thread: + commandThread = new CommandThread( this ); // Gets a SoundSystem handle + commandThread.start(); + + snooze( 200 ); + + newLibrary( libraryClass ); + message( "", 0 ); + } + +/** + * Ends the command thread, shuts down the sound system, and removes references + * to all instantiated objects. + */ + public void cleanup() + { + boolean killException = false; + message( "", 0 ); + message( className + " shutting down...", 0 ); + + // End the command thread: + try + { + commandThread.kill(); // end the command processor loop. + commandThread.interrupt(); // wake the thread up so it can end. + } + catch( Exception e ) + { + killException = true; + } + + if( !killException ) + { + // wait up to 5 seconds for command thread to end: + for( int i = 0; i < 50; i++ ) + { + if( !commandThread.alive() ) + break; + snooze( 100 ); + } + } + + // Let user know if there was a problem ending the command thread + if( killException || commandThread.alive() ) + { + errorMessage( "Command thread did not die!", 0 ); + message( "Ignoring errors... continuing clean-up.", 0 ); + } + + initialized( SET, false ); + currentLibrary( SET, null ); + try + { + // Stop all sources and shut down the sound library: + if( soundLibrary != null ) + soundLibrary.cleanup(); + } + catch( Exception e ) + { + errorMessage( "Problem during Library.cleanup()!", 0 ); + message( "Ignoring errors... continuing clean-up.", 0 ); + } + + try + { + // remove any queued commands: + if( commandQueue != null ) + commandQueue.clear(); + } + catch( Exception e ) + { + errorMessage( "Unable to clear the command queue!", 0 ); + message( "Ignoring errors... continuing clean-up.", 0 ); + } + + try + { + // empty the source management list: + if( sourcePlayList != null ) + sourcePlayList.clear(); + } + catch( Exception e ) + { + errorMessage( "Unable to clear the source management list!", 0 ); + message( "Ignoring errors... continuing clean-up.", 0 ); + } + + // Remove references to all instantiated objects: + randomNumberGenerator = null; + soundLibrary = null; + commandQueue = null; + sourcePlayList = null; + commandThread = null; + + importantMessage( "Author: Paul Lamb, www.paulscode.com", 1 ); + message( "", 0 ); + } + +/** + * Wakes up the Command Thread to process commands. This method should be + * used if there is a need to call methods 'ManageSources' and 'CommandQueue' + * externally. In most cases, this method will not be needed, since + * SoundSystem automatically wakes the Command Thread every time commands are + * placed into either the ManageSources queue or CommandQueue to be processed. + */ + public void interruptCommandThread() + { + if( commandThread == null ) + { + errorMessage( "Command Thread null in method " + + "'interruptCommandThread'", 0 ); + return; + } + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Pre-loads a sound into memory. The file may either be located within the + * JAR or at an online location. If the file is online, filename must begin + * with "http://", since that is how SoundSystem recognizes URL's. If the file + * is located within the compiled JAR, the package in which sound files are + * located may be set by calling SoundSystemConfig.setSoundFilesPackage(). + * @param filename Filename of the sound file to load. + */ + public void loadSound( String filename ) + { + // Queue a command to load the sound file: + CommandQueue( new CommandObject( CommandObject.LOAD_SOUND, + new FilenameURL( filename ) ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Pre-loads a sound specified by the given URL into memory. The second + * parameter 'identifier' should look like a filename, and it must have the + * correct extension so SoundSystem knows what codec to use for the file + * referenced by the URL instance. + * @param url URL handle to the sound file to load. + * @param identifier Filename/identifier of the file referenced by the URL. + */ + public void loadSound( URL url, String identifier ) + { + // Queue a command to load the sound file from a URL: + CommandQueue( new CommandObject( CommandObject.LOAD_SOUND, + new FilenameURL( url, identifier ) ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Saves raw PCM audio data in the specified audio format, under the specified + * identifier. This identifier can be later used in place of 'filename' + * parameters to reference the sample data. + * @param data The sample data + * @param format Format the sample data is stored in + * @param identifier What to call the sample. + */ + public void loadSound( byte[] data, AudioFormat format, String identifier ) + { + // Queue a command to load the sound file from a URL: + CommandQueue( new CommandObject( CommandObject.LOAD_DATA, + identifier, + new SoundBuffer( data, format ) ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + + +/** + * Removes a pre-loaded sound from memory. This is a good method to use for + * freeing up memory after a large sound file is no longer needed. NOTE: the + * source will remain in memory after calling this method as long as the + * sound is attached to an existing source. When calling this method, calls + * should also be made to method removeSource( String ) for all sources which + * this sound is bound to. + * @param filename Filename/identifier of the sound file to unload. + */ + public void unloadSound( String filename ) + { + // Queue a command to unload the sound file: + CommandQueue( new CommandObject( CommandObject.UNLOAD_SOUND, filename ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * If the specified source is a streaming source or MIDI source, this method + * queues up the next sound to play when the previous playback ends. The file + * may either be located within the JAR or at an online location. If the file + * is online, filename must begin with "http://", since that is how SoundSystem + * recognizes URL paths. If the file is located within the compiled JAR, the + * package in which sound files are located may be set by calling + * SoundSystemConfig.setSoundFilesPackage(). This method has no effect on + * non-streaming sources. + * @param sourcename Source identifier. + * @param filename Name of the sound file to play next. + */ + public void queueSound( String sourcename, String filename ) + { + // Queue a command to queue the sound: + CommandQueue( new CommandObject( CommandObject.QUEUE_SOUND, sourcename, + new FilenameURL( filename ) ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * If the specified source is a streaming source or MIDI source, this method + * queues up the next sound to play when the previous playback ends. The third + * parameter 'identifier' should look like a filename, and it must have the + * correct extension so SoundSystem knows what codec to use for the file + * referenced by the URL instance. This method has no effect on non-streaming + * sources. + * @param sourcename Source identifier. + * @param url URL handle to the sound file to load. + * @param identifier Filename/identifier of the file referenced by the URL. + */ + public void queueSound( String sourcename, URL url, String identifier ) + { + // Queue a command to queue the sound: + CommandQueue( new CommandObject( CommandObject.QUEUE_SOUND, sourcename, + new FilenameURL( url, identifier ) ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Removes the first occurrence of the specified filename/identifier from the + * specified source's list of sounds to play when previous playback ends. This + * method has no effect on non-streaming sources. + * @param sourcename Source identifier. + * @param filename Filename/identifier of the sound file to play next. + */ + public void dequeueSound( String sourcename, String filename ) + { + // Queue a command to dequeue the sound: + CommandQueue( new CommandObject( CommandObject.DEQUEUE_SOUND, + sourcename, filename ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Fades out the volume of whatever the specified source is currently playing, + * then begins playing the specified file at the source's previously + * assigned volume level. The file may either be located within the JAR or at + * an online location. If the file is online, filename must begin with + * "http://", since that is how SoundSystem recognizes URL paths. If the file + * is located within the compiled JAR, the package in which sound files are + * located may be set by calling SoundSystemConfig.setSoundFilesPackage(). If + * the filename parameter is null or empty, the specified source will simply + * fade out and stop. The miliseconds parameter must be non-negative or zero. + * This method will remove anything that is currently in the specified source's + * list of queued sounds that would have played next when the current sound + * finished playing. This method may only be used for streaming and MIDI + * sources. + * @param sourcename Name of the source to fade out. + * @param filename Name of a sound file to play next, or null for none. + * @param milis Number of miliseconds the fadeout should take. + */ + public void fadeOut( String sourcename, String filename, long milis ) + { + FilenameURL fu = null; + if( filename != null ) + fu = new FilenameURL( filename ); + // Queue a command to fade out: + CommandQueue( new CommandObject( CommandObject.FADE_OUT, sourcename, fu, + milis ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Fades out the volume of whatever the specified source is currently playing, + * then begins playing the specified file at the source's previously + * assigned volume level. If the url parameter is null or empty, the + * specified source will simply fade out and stop. The third + * parameter 'identifier' should look like a filename, and it must have the + * correct extension so SoundSystem knows what codec to use for the file + * referenced by the URL instance. The miliseconds parameter must be + * non-negative or zero. This method will remove anything that is currently in + * the specified source's list of queued sounds that would have played next + * when the current sound finished playing. This method may only be used for + * streaming and MIDI sources. + * @param sourcename Name of the source to fade out. + * @param url URL handle to the sound file to play next, or null for none. + * @param identifier Filename/identifier of the file referenced by the URL. + * @param milis Number of miliseconds the fadeout should take. + */ + public void fadeOut( String sourcename, URL url, String identifier, + long milis ) + { + FilenameURL fu = null; + if( url != null && identifier != null ) + fu = new FilenameURL( url, identifier ); + // Queue a command to fade out: + CommandQueue( new CommandObject( CommandObject.FADE_OUT, sourcename, fu, + milis ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Fades out the volume of whatever the specified source is currently playing, + * then fades the volume back in playing the specified filename. Final volume + * after fade-in completes will be equal to the source's previously assigned + * volume level. The filename parameter may not be null or empty. The file + * may either be located within the JAR or at an online location. If the file + * is online, filename must begin with "http://", since that is how + * SoundSystem recognizes URL paths. If the file is located within the + * compiled JAR, the package in which sound files are located may be set by + * calling SoundSystemConfig.setSoundFilesPackage(). The miliseconds + * parameters must be non-negative or zero. This method will remove anything + * that is currently in the specified source's list of queued sounds that would + * have played next when the current sound finished playing. This method may + * only be used for streaming and MIDI sources. + * @param sourcename Name of the source to fade out/in. + * @param filename Name of a sound file to play next, or null for none. + * @param milisOut Number of miliseconds the fadeout should take. + * @param milisIn Number of miliseconds the fadein should take. + */ + public void fadeOutIn( String sourcename, String filename, long milisOut, + long milisIn ) + { + // Queue a command to load the sound file: + CommandQueue( new CommandObject( CommandObject.FADE_OUT_IN, + sourcename, + new FilenameURL( filename ), milisOut, + milisIn ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Fades out the volume of whatever the specified source is currently playing, + * then fades the volume back in playing the specified file. Final volume + * after fade-in completes will be equal to the source's previously assigned + * volume level. The url parameter may not be null or empty. The third + * parameter 'identifier' should look like a filename, and it must have the + * correct extension so SoundSystem knows what codec to use for the file + * referenced by the URL instance. The miliseconds parameters must be + * non-negative or zero. This method will remove anything that is currently + * in the specified source's list of queued sounds that would have played next + * when the current sound finished playing. This method may only be used for + * streaming and MIDI sources. + * @param sourcename Name of the source to fade out/in. + * @param url URL handle to the sound file to play next. + * @param identifier Filename/identifier of the file referenced by the URL. + * @param milisOut Number of miliseconds the fadeout should take. + * @param milisIn Number of miliseconds the fadein should take. + */ + public void fadeOutIn( String sourcename, URL url, String identifier, + long milisOut, long milisIn ) + { + // Queue a command to load the sound file: + CommandQueue( new CommandObject( CommandObject.FADE_OUT_IN, + sourcename, + new FilenameURL( url, identifier ), + milisOut, milisIn ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Makes sure the current volume levels of streaming sources and MIDI are + * correct. This method is designed to help reduce the "jerky" fading behavior + * that happens when using some library and codec pluggins (such as + * LibraryJavaSound and CodecJOrbis). This method has no effect on normal + * "non-streaming" sources. It would normally be called somewhere in the main + * "game loop". IMPORTANT: To optimize frame-rates, do not call this method + * for every frame. It is better to just call this method at some acceptable + * "granularity" (play around with different granularities to find what sounds + * acceptable for a particular situation). + */ + public void checkFadeVolumes() + { + // Queue a command to load check fading source volumes: + CommandQueue( new CommandObject( CommandObject.CHECK_FADE_VOLUMES ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Creates a new permanant, streaming, priority source with zero attenuation. + * The file may either be located within the JAR or at an online location. If + * the file is online, filename must begin with "http://", since that is how + * SoundSystem recognizes URL paths. If the file is located within the + * compiled JAR, the package in which sound files are located may be set by + * calling SoundSystemConfig.setSoundFilesPackage(). + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filename Filename of the sound file to stream at this source. + * @param toLoop Should this source loop, or play only once. + */ + public void backgroundMusic( String sourcename, String filename, + boolean toLoop ) + { + // Queue a command to quick stream a new source: + CommandQueue( new CommandObject( CommandObject.QUICK_PLAY, true, + true, toLoop, sourcename, + new FilenameURL( filename ), 0, 0, 0, + SoundSystemConfig.ATTENUATION_NONE, 0, false ) ); + CommandQueue( new CommandObject( CommandObject.PLAY, sourcename) ); + + commandThread.interrupt(); + } + +/** + * Creates a new permanant, streaming, priority source with zero attenuation. + * The third parameter 'identifier' should look like a filename, and it must + * have the correct extension so SoundSystem knows what codec to use for the + * file referenced by the URL instance. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param url URL handle to the sound file to stream at this source. + * @param identifier Filename/identifier of the file referenced by the URL. + * @param toLoop Should this source loop, or play only once. + */ + public void backgroundMusic( String sourcename, URL url, String identifier, + boolean toLoop ) + { + // Queue a command to quick stream a new source: + CommandQueue( new CommandObject( CommandObject.QUICK_PLAY, true, + true, toLoop, sourcename, + new FilenameURL( url, identifier ), + 0, 0, 0, + SoundSystemConfig.ATTENUATION_NONE, + 0, false ) ); + CommandQueue( new CommandObject( CommandObject.PLAY, sourcename) ); + + commandThread.interrupt(); + } + +/** + * Creates a new non-streaming source. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Attenuation, fade distance, and rolloff factor. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filename Filename/identifier of the sound file to play at this source. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void newSource( boolean priority, String sourcename, String filename, + boolean toLoop, float x, float y, float z, + int attmodel, float distOrRoll ) + { + CommandQueue( new CommandObject( CommandObject.NEW_SOURCE, priority, + false, toLoop, sourcename, + new FilenameURL( filename ), x, y, z, + attmodel, distOrRoll ) ); + commandThread.interrupt(); + } + +/** + * Creates a new non-streaming source. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Attenuation, fade distance, and rolloff factor. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param url URL handle to the sound file to stream at this source. + * @param identifier Filename/identifier of the file referenced by the URL. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void newSource( boolean priority, String sourcename, URL url, + String identifier, boolean toLoop, float x, float y, + float z, int attmodel, float distOrRoll ) + { + CommandQueue( new CommandObject( CommandObject.NEW_SOURCE, priority, + false, toLoop, sourcename, + new FilenameURL( url, identifier ), + x, y, z, + attmodel, distOrRoll ) ); + commandThread.interrupt(); + } + +/** + * Creates a new streaming source. The file may either be located within the + * JAR or at an online location. If the file is online, filename must begin + * with "http://", since that is how SoundSystem recognizes URL paths. If the + * file is located within the compiled JAR, the package in which sound files + * are located may be set by calling SoundSystemConfig.setSoundFilesPackage(). + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filename The filename of the sound file to play at this source. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void newStreamingSource( boolean priority, String sourcename, + String filename, boolean toLoop, float x, + float y, float z, int attmodel, + float distOrRoll ) + { + CommandQueue( new CommandObject( CommandObject.NEW_SOURCE, priority, + true, toLoop, sourcename, + new FilenameURL( filename ), x, y, z, + attmodel, distOrRoll ) ); + commandThread.interrupt(); + } + +/** + * Creates a new streaming source. The fourth parameter 'identifier' should + * look like a filename, and it must have the correct extension so SoundSystem + * knows what codec to use for the file referenced by the URL instance. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param url URL handle to the sound file to stream at this source. + * @param identifier Filename/identifier of the file referenced by the URL. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void newStreamingSource( boolean priority, String sourcename, + URL url, String identifier, boolean toLoop, + float x, float y, float z, int attmodel, + float distOrRoll ) + { + CommandQueue( new CommandObject( CommandObject.NEW_SOURCE, priority, + true, toLoop, sourcename, + new FilenameURL( url, identifier ), + x, y, z, attmodel, distOrRoll ) ); + commandThread.interrupt(); + } + +/** + * Opens a direct line for streaming audio data. This method creates a new + * streaming source to play the data at. The resulting streaming source can be + * manipulated the same as any other streaming source. Raw data can be sent to + * the new streaming source using the feedRawAudioData() method. + * @param audioFormat Format that the data will be in. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void rawDataStream( AudioFormat audioFormat, boolean priority, + String sourcename, float x, float y, float z, + int attModel, float distOrRoll ) + { + CommandQueue( new CommandObject( CommandObject.RAW_DATA_STREAM, + audioFormat, priority, sourcename, x, + y, z, attModel, distOrRoll ) ); + commandThread.interrupt(); + } + +/** + * Creates a temporary source and plays it. After the source finishes playing, + * it is removed. Returns a randomly generated name for the new source. NOTE: + * to make a source created by this method permanant, call the setActive() + * method using the return value for sourcename. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param filename Filename/identifier of the sound file to play at this source. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + * @return The new sorce's name. + */ + public String quickPlay( boolean priority, String filename, boolean toLoop, + float x, float y, float z, int attmodel, + float distOrRoll ) + { + //generate a random name for this source: + String sourcename = "Source_" + + randomNumberGenerator.nextInt() + + "_" + randomNumberGenerator.nextInt(); + + // Queue a command to quick play this new source: + CommandQueue( new CommandObject( CommandObject.QUICK_PLAY, priority, + false, toLoop, sourcename, + new FilenameURL( filename ), x, y, z, + attmodel, distOrRoll, true ) ); + CommandQueue( new CommandObject( CommandObject.PLAY, sourcename) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + + // return the new source name. + return sourcename; + } + +/** + * Creates a temporary source and plays it. After the source finishes playing, + * it is removed. Returns a randomly generated name for the new source. NOTE: + * to make a source created by this method permanant, call the setActive() + * method using the return value for sourcename. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param url URL handle to the sound file to stream at this source. + * @param identifier Filename/identifier of the file referenced by the URL. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + * @return The new sorce's name. + */ + public String quickPlay( boolean priority, URL url, String identifier, + boolean toLoop, float x, float y, float z, + int attmodel, float distOrRoll ) + { + //generate a random name for this source: + String sourcename = "Source_" + + randomNumberGenerator.nextInt() + + "_" + randomNumberGenerator.nextInt(); + + // Queue a command to quick play this new source: + CommandQueue( new CommandObject( CommandObject.QUICK_PLAY, priority, + false, toLoop, sourcename, + new FilenameURL( url, identifier ), + x, y, z, attmodel, distOrRoll, + true ) ); + CommandQueue( new CommandObject( CommandObject.PLAY, sourcename) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + + // return the new source name. + return sourcename; + } + +/** + * Creates a temporary source and streams it. After the source finishes + * playing, it is removed. The file may either be located within the + * JAR or at an online location. If the file is online, filename must begin + * with "http://", since that is how SoundSystem recognizes URL paths. If the + * file is located within the compiled JAR, the package in which sound files + * are located may be set by calling SoundSystemConfig.setSoundFilesPackage(). + * Returns a randomly generated name for the new source. NOTE: to make a + * source created by this method permanant, call the setActive() method using + * the return value for sourcename. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param filename Filename of the sound file to stream at this source. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + * @return The new sorce's name. + */ + public String quickStream( boolean priority, String filename, + boolean toLoop, float x, float y, float z, + int attmodel, float distOrRoll ) + { + //generate a random name for this source: + String sourcename = "Source_" + + randomNumberGenerator.nextInt() + + "_" + randomNumberGenerator.nextInt(); + + // Queue a command to quick stream this new source: + CommandQueue( new CommandObject( CommandObject.QUICK_PLAY, priority, + true, toLoop, sourcename, + new FilenameURL( filename ), x, y, z, + attmodel, distOrRoll, true ) ); + CommandQueue( new CommandObject( CommandObject.PLAY, sourcename) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + + // return the new source name. + return sourcename; + } +/** + * Creates a temporary source and streams it. After the source finishes + * playing, it is removed. The third parameter 'identifier' should + * look like a filename, and it must have the correct extension so SoundSystem + * knows what codec to use for the file referenced by the URL instance. + * Returns a randomly generated name for the new source. NOTE: to make a + * source created by this method permanant, call the setActive() method using + * the return value for sourcename. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param url URL handle to the sound file to stream at this source. + * @param identifier Filename/identifier of the file referenced by the URL. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + * @return The new sorce's name. + */ + public String quickStream( boolean priority, URL url, String identifier, + boolean toLoop, float x, float y, float z, + int attmodel, float distOrRoll ) + { + //generate a random name for this source: + String sourcename = "Source_" + + randomNumberGenerator.nextInt() + + "_" + randomNumberGenerator.nextInt(); + + // Queue a command to quick stream this new source: + CommandQueue( new CommandObject( CommandObject.QUICK_PLAY, priority, + true, toLoop, sourcename, + new FilenameURL( url, identifier ), + x, y, z, attmodel, distOrRoll, + true ) ); + CommandQueue( new CommandObject( CommandObject.PLAY, sourcename) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + + // return the new source name. + return sourcename; + } + +/** + * Move a source to the specified location. + * @param sourcename Identifier for the source. + * @param x destination X coordinate. + * @param y destination Y coordinate. + * @param z destination Z coordinate. + */ + public void setPosition( String sourcename, float x, float y, float z ) + { + CommandQueue( new CommandObject( CommandObject.SET_POSITION, + sourcename, x, y, z ) ); + commandThread.interrupt(); + } +/** + * Manually sets the specified source's volume. + * @param sourcename Source to move. + * @param value New volume, float value ( 0.0f - 1.0f ). + */ + public void setVolume( String sourcename, float value ) + { + CommandQueue( new CommandObject( CommandObject.SET_VOLUME, + sourcename, value ) ); + commandThread.interrupt(); + } + +/** + * Returns the current volume of the specified source, or zero if the specified + * source was not found. + * @param sourcename Source to read volume from. + * @return Float value representing the source volume (0.0f - 1.0f). + */ + public float getVolume( String sourcename ) + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( soundLibrary != null ) + return soundLibrary.getVolume( sourcename ); + else + return 0.0f; + } + } + +/** + * Manually sets the specified source's pitch. + * @param sourcename The source's name. + * @param value A float value ( 0.5f - 2.0f ). + */ + public void setPitch( String sourcename, float value ) + { + CommandQueue( new CommandObject( CommandObject.SET_PITCH, + sourcename, value ) ); + commandThread.interrupt(); + } + +/** + * Returns the pitch of the specified source. + * @param sourcename The source's name. + * @return Float value representing the source pitch (0.5f - 2.0f). + */ + public float getPitch( String sourcename ) + { + if( soundLibrary != null ) + return soundLibrary.getPitch( sourcename ); + else + return 1.0f; + } + +/** + * Set a source's priority factor. A priority source will not be overriden when + * too many sources are playing at once. + * @param sourcename Identifier for the source. + * @param pri Setting this to true makes this source a priority source. + */ + public void setPriority( String sourcename, boolean pri ) + { + CommandQueue( new CommandObject( CommandObject.SET_PRIORITY, + sourcename, pri ) ); + commandThread.interrupt(); + } +/** + * Changes a source to looping or non-looping. + * @param sourcename Identifier for the source. + * @param lp This source should loop. + */ + public void setLooping( String sourcename, boolean lp ) + { + CommandQueue( new CommandObject( CommandObject.SET_LOOPING, + sourcename, lp ) ); + commandThread.interrupt(); + } +/** + * Changes a source's attenuation model. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Attenuation. + * @param sourcename Identifier for the source. + * @param model Attenuation model to use. + */ + public void setAttenuation( String sourcename, int model ) + { + CommandQueue( new CommandObject( CommandObject.SET_ATTENUATION, + sourcename, model ) ); + commandThread.interrupt(); + } +/** + * Changes a source's fade distance or rolloff factor. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about fade distance and rolloff. + * @param sourcename Identifier for the source. + * @param dr Either the fading distance or rolloff factor, depending on the attenuation model used. + */ + public void setDistOrRoll( String sourcename, float dr) + { + CommandQueue( new CommandObject( CommandObject.SET_DIST_OR_ROLL, + sourcename, dr ) ); + commandThread.interrupt(); + } + +/** + * Changes the Doppler factor, for determining Doppler effect scale. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param dopplerFactor New value for Doppler factor. + */ + public void changeDopplerFactor( float dopplerFactor) + { + CommandQueue( new CommandObject( CommandObject.CHANGE_DOPPLER_FACTOR, + dopplerFactor ) ); + commandThread.interrupt(); + } + +/** + * Changes the Doppler velocity, for use in Doppler effect. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param dopplerVelocity New value for Doppler velocity. + */ + public void changeDopplerVelocity( float dopplerVelocity ) + { + CommandQueue( new CommandObject( CommandObject.CHANGE_DOPPLER_VELOCITY, + dopplerVelocity ) ); + commandThread.interrupt(); + } + +/** + * Sets the specified source's velocity, for use in Doppler effect. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param sourcename The source's name. + * @param x Velocity along world x-axis. + * @param y Velocity along world y-axis. + * @param z Velocity along world z-axis. + */ + public void setVelocity( String sourcename, float x, float y, float z ) + { + CommandQueue( new CommandObject( CommandObject.SET_VELOCITY, + sourcename, x, y, z ) ); + commandThread.interrupt(); + } + +/** + * Sets the listener's velocity, for use in Doppler effect. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param x Velocity along world x-axis. + * @param y Velocity along world y-axis. + * @param z Velocity along world z-axis. + */ + public void setListenerVelocity( float x, float y, float z ) + { + CommandQueue( new CommandObject( CommandObject.SET_LISTENER_VELOCITY, + x, y, z ) ); + commandThread.interrupt(); + } + +/** + * Returns the number of miliseconds since the specified source began playing. + * @return miliseconds, or -1 if not playing or unable to calculate + */ + public float millisecondsPlayed( String sourcename ) + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + return soundLibrary.millisecondsPlayed( sourcename ); + } + } + +/** + * Feeds raw data through the specified source. The source must be a + * streaming source and it can not be already associated with a file or URL to + * stream from. Only use this for streaming sources created with the + * rawDataStream() method. NOTE: Be carefull how much data you send to a + * source to stream. The data will be processed at playback speed, so if you + * queue up 1 hour worth of data, it will take 1 hour to play (not to mention + * hogging a ton of memory). To clear out all queued data from the source, use + * the flush() method. Also note: if there is a break in the data stream, + * you will hear clicks and studders, so ensure that the data flow is steady. + * @param sourcename Name of the streaming source to play from. + * @param buffer Byte buffer containing raw audio data to stream. + */ + public void feedRawAudioData( String sourcename, byte[] buffer ) + { + CommandQueue( new CommandObject( CommandObject.FEED_RAW_AUDIO_DATA, + sourcename, buffer ) ); + commandThread.interrupt(); + } +/** + * Plays the specified source. + * @param sourcename Identifier for the source. + */ + public void play( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.PLAY, sourcename) ); + commandThread.interrupt(); + } +/** + * Pauses the specified source. + * @param sourcename Identifier for the source. + */ + public void pause( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.PAUSE, sourcename) ); + commandThread.interrupt(); + } +/** + * Stops the specified source. + * @param sourcename Identifier for the source. + */ + public void stop( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.STOP, sourcename) ); + commandThread.interrupt(); + } +/** + * Rewinds the specified source. + * @param sourcename Identifier for the source. + */ + public void rewind( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.REWIND, sourcename) ); + commandThread.interrupt(); + } +/** + * Flushes all previously queued audio data from a streaming source. + * @param sourcename Identifier for the source. + */ + public void flush( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.FLUSH, sourcename) ); + commandThread.interrupt(); + } + +/** + * Culls the specified source. A culled source can not be played until it has + * been activated again. + * @param sourcename Identifier for the source. + */ + public void cull( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.CULL, sourcename) ); + commandThread.interrupt(); + } + +/** + * Activates the specified source after it was culled, so it can be played + * again. + * @param sourcename Identifier for the source. + */ + public void activate( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.ACTIVATE, sourcename) ); + commandThread.interrupt(); + } + +/** + * Sets a flag for a source indicating whether it should be used or if it + * should be removed after it finishes playing. One possible use for this + * method is to make temporary sources that were created with quickPlay() + * permanant. Another use could be to have a source automatically removed + * after it finishes playing. NOTE: Setting a source to temporary does not + * stop it, and setting a source to permanant does not play it. It is also + * important to note that a looping temporary source will not be removed as + * long as it keeps playing. + * @param sourcename Identifier for the source. + * @param temporary True = temporary, False = permanant. + */ + public void setTemporary( String sourcename, boolean temporary ) + { + CommandQueue( new CommandObject( CommandObject.SET_TEMPORARY, + sourcename, temporary ) ); + commandThread.interrupt(); + } + +/** + * Removes the specified source and clears up any memory it used. + * @param sourcename Identifier for the source. + */ + public void removeSource( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.REMOVE_SOURCE, + sourcename ) ); + commandThread.interrupt(); + } +/** + * Moves the listener relative to the current location. + * @param x X offset. + * @param y Y offset. + * @param z Z offset. + */ + public void moveListener( float x, float y, float z ) + { + CommandQueue( new CommandObject( CommandObject.MOVE_LISTENER, + x, y, z ) ); + commandThread.interrupt(); + } +/** + * Moves the listener to the specified location. + * @param x Destination X coordinate. + * @param y Destination Y coordinate. + * @param z Destination Z coordinate. + */ + public void setListenerPosition( float x, float y, float z ) + { + CommandQueue( new CommandObject( CommandObject.SET_LISTENER_POSITION, + x, y, z ) ); + commandThread.interrupt(); + } +/** + * Turns the listener counterclockwise by "angle" radians around the y-axis, + * relative to the current angle. + * @param angle radian offset. + */ + public void turnListener( float angle ) + { + CommandQueue( new CommandObject( CommandObject.TURN_LISTENER, + angle ) ); + commandThread.interrupt(); + } +/** + * Sets the listener's angle in radians around the y-axis. + * @param angle radians. + */ + public void setListenerAngle( float angle ) + { + CommandQueue( new CommandObject( CommandObject.SET_LISTENER_ANGLE, + angle ) ); + commandThread.interrupt(); + } +/** + * Sets the listener's orientation. + * @param lookX X coordinate of the (normalized) look-at vector. + * @param lookY Y coordinate of the (normalized) look-at vector. + * @param lookZ Z coordinate of the (normalized) look-at vector. + * @param upX X coordinate of the (normalized) up-direction vector. + * @param upY Y coordinate of the (normalized) up-direction vector. + * @param upZ Z coordinate of the (normalized) up-direction vector. + */ + public void setListenerOrientation( float lookX, float lookY, float lookZ, + float upX, float upY, float upZ ) + { + CommandQueue( new CommandObject( CommandObject.SET_LISTENER_ORIENTATION, + lookX, lookY, lookZ, upX, upY, upZ ) ); + commandThread.interrupt(); + } + +/** + * Sets the overall volume, affecting all sources. + * @param value New volume, float value ( 0.0f - 1.0f ). + */ + public void setMasterVolume( float value ) + { + CommandQueue( new CommandObject( CommandObject.SET_MASTER_VOLUME, + value ) ); + commandThread.interrupt(); + } + +/** + * Returns the overall volume, affecting all sources. + * @return Float value representing the master volume (0.0f - 1.0f). + */ + public float getMasterVolume() + { + return SoundSystemConfig.getMasterGain(); + } + +/** + * Method for obtaining information about the listener's position and + * orientation. + * @return a {@link paulscode.sound.ListenerData ListenerData} object. + */ + public ListenerData getListenerData() + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + return soundLibrary.getListenerData(); + } + } +/** + * Switches to the specified library, and preserves all sources. + * @param libraryClass Library to use. + * @return True if switch was successful. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for + * information about chosing a sound library. + */ + public boolean switchLibrary( Class libraryClass ) + throws SoundSystemException + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + initialized( SET, false ); + + HashMap sourceMap = null; + ListenerData listenerData = null; + + boolean wasMidiChannel = false; + MidiChannel midiChannel = null; + FilenameURL midiFilenameURL = null; + String midiSourcename = ""; + boolean midiToLoop = true; + + if( soundLibrary != null ) + { + currentLibrary( SET, null ); + sourceMap = copySources( soundLibrary.getSources() ); + listenerData = soundLibrary.getListenerData(); + midiChannel = soundLibrary.getMidiChannel(); + if( midiChannel != null ) + { + wasMidiChannel = true; + midiToLoop = midiChannel.getLooping(); + midiSourcename = midiChannel.getSourcename(); + midiFilenameURL = midiChannel.getFilenameURL(); + } + + soundLibrary.cleanup(); + soundLibrary = null; + } + message( "", 0 ); + message( "Switching to " + + SoundSystemConfig.getLibraryTitle( libraryClass ), 0 ); + message( "(" + SoundSystemConfig.getLibraryDescription( libraryClass ) + + ")", 1 ); + + try + { + soundLibrary = (Library) libraryClass.newInstance(); + } + catch( InstantiationException ie ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + catch( IllegalAccessException iae ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + catch( ExceptionInInitializerError eiie ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + catch( SecurityException se ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + + if( errorCheck( soundLibrary == null, "Library null after " + + "initialization in method 'switchLibrary'", 1 ) ) + { + SoundSystemException sse = new SoundSystemException( + className + " did not load properly. " + + "Library was null after initialization.", + SoundSystemException.LIBRARY_NULL ); + lastException( SET, sse ); + initialized( SET, true ); + throw sse; + } + + try + { + soundLibrary.init(); + } + catch( SoundSystemException sse ) + { + lastException( SET, sse ); + initialized( SET, true ); + throw sse; + } + + soundLibrary.setListenerData( listenerData ); + if( wasMidiChannel ) + { + if( midiChannel != null ) + midiChannel.cleanup(); + midiChannel = new MidiChannel( midiToLoop, midiSourcename, + midiFilenameURL ); + soundLibrary.setMidiChannel( midiChannel ); + } + soundLibrary.copySources( sourceMap ); + + message( "", 0 ); + + lastException( SET, null ); + initialized( SET, true ); + + return true; + } + } + +/** + * Switches to the specified library, loosing all sources. + * @param libraryClass Library to use. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for + * information about chosing a sound library. + */ + public boolean newLibrary( Class libraryClass ) + throws SoundSystemException + { + initialized( SET, false ); + + CommandQueue( new CommandObject( CommandObject.NEW_LIBRARY, + libraryClass ) ); + commandThread.interrupt(); + + for( int x = 0; (!initialized( GET, XXX )) && (x < 100); x++ ) + { + snooze( 400 ); + commandThread.interrupt(); + } + + if( !initialized( GET, XXX ) ) + { + SoundSystemException sse = new SoundSystemException( + className + + " did not load after 30 seconds.", + SoundSystemException.LIBRARY_NULL ); + lastException( SET, sse ); + throw sse; + } + else + { + SoundSystemException sse = lastException( GET, null ); + if( sse != null ) + throw sse; + } + return true; + } + +/** + * Switches to the specified library, loosing all sources. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the newLibrary() method instead. + * @param libraryClass Library to use. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for + * information about chosing a sound library. + */ + private void CommandNewLibrary( Class libraryClass ) + { + initialized( SET, false ); + + String headerMessage = "Initializing "; + if( soundLibrary != null ) + { + currentLibrary( SET, null ); + // we are switching libraries + headerMessage = "Switching to "; + soundLibrary.cleanup(); + soundLibrary = null; + } + message( headerMessage + + SoundSystemConfig.getLibraryTitle( libraryClass ), 0 ); + message( "(" + SoundSystemConfig.getLibraryDescription( libraryClass ) + + ")", 1 ); + + try + { + soundLibrary = (Library) libraryClass.newInstance(); + } + catch( InstantiationException ie ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + catch( IllegalAccessException iae ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + catch( ExceptionInInitializerError eiie ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + catch( SecurityException se ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + + if( errorCheck( soundLibrary == null, "Library null after " + + "initialization in method 'newLibrary'", 1 ) ) + { + lastException( SET, new SoundSystemException( + className + " did not load properly. " + + "Library was null after initialization.", + SoundSystemException.LIBRARY_NULL ) ); + importantMessage( "Switching to silent mode", 1 ); + + try + { + soundLibrary = new Library(); + } + catch( SoundSystemException sse ) + { + lastException( SET, new SoundSystemException( + "Silent mode did not load properly. " + + "Library was null after initialization.", + SoundSystemException.LIBRARY_NULL ) ); + initialized( SET, true ); + return; + } + } + + try + { + soundLibrary.init(); + } + catch( SoundSystemException sse ) + { + lastException( SET, sse ); + initialized( SET, true ); + return; + } + + lastException( SET, null ); + initialized( SET, true ); + + return; + } +/** + * Calls the library's initialize() method. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly. + */ + private void CommandInitialize() + { + try + { + if( errorCheck( soundLibrary == null, "Library null after " + + "initialization in method 'CommandInitialize'", + 1 ) ) + { + SoundSystemException sse = new SoundSystemException( + className + " did not load properly. " + + "Library was null after initialization.", + SoundSystemException.LIBRARY_NULL ); + lastException( SET, sse ); + throw sse; + } + soundLibrary.init(); + } + catch( SoundSystemException sse ) + { + lastException( SET, sse ); + initialized( SET, true ); + } + } +/** + * Loads sample data from a sound file or URL into memory. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the loadSound() method instead. + * @param filenameURL Filename/URL of the sound file to load. + */ + private void CommandLoadSound( FilenameURL filenameURL ) + { + if( soundLibrary != null ) + soundLibrary.loadSound( filenameURL ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandLoadSound'", 0 ); + } +/** + * Saves the specified sample data, under the specified identifier. This + * identifier can be later used in place of 'filename' parameters to reference + * the sample data. This method is used internally by SoundSystem for thread + * synchronization, and it can not be called directly - please use the + * loadSound() method instead. + * @param buffer the sample data and audio format to save. + * @param identifier What to call the sample. + */ + private void CommandLoadSound( SoundBuffer buffer, String identifier ) + { + if( soundLibrary != null ) + soundLibrary.loadSound( buffer, identifier ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandLoadSound'", 0 ); + } +/** + * Removes previously loaded sampled data from memory. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the unloadSound() method instead. + * @param filename Filename or string identifyer of sound to unload. + */ + private void CommandUnloadSound( String filename ) + { + if( soundLibrary != null ) + soundLibrary.unloadSound( filename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandLoadSound'", 0 ); + } +/** + * If the specified source is a streaming source or MIDI source, this method + * queues up the next sound to play when the previous playback ends. This + * method has no effect on non-streaming sources. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the queueSound() method instead. + * @param sourcename Source identifier. + * @param filenameURL Filename/URL of the sound file to play next. + */ + private void CommandQueueSound( String sourcename, + FilenameURL filenameURL ) + { + if( soundLibrary != null ) + soundLibrary.queueSound( sourcename, filenameURL ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandQueueSound'", 0 ); + } +/** + * Removes the first occurrence of the specified filename/identifier from the + * specified source's list of sounds to play when previous playback ends. This + * method has no effect on non-streaming sources. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the dequeueSound() method instead. + * @param sourcename Source identifier. + * @param filename Filename/identifier of the sound file to remove from the queue. + */ + private void CommandDequeueSound( String sourcename, String filename ) + { + if( soundLibrary != null ) + soundLibrary.dequeueSound( sourcename, filename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandDequeueSound'", 0 ); + } +/** + * Fades out the volume of whatever the specified source is currently playing, + * then begins playing the specified file at the source's previously + * assigned volume level. If the filenameURL parameter is null or empty, the + * specified source will simply fade out and stop. The miliseconds parameter + * must be non-negative or zero. This method will remove anything that is + * currently in the specified source's list of queued sounds that would have + * played next when the current sound finished playing. This method may only + * be used for streaming and MIDI sources. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the fadeOut() method instead. + * @param sourcename Name of the source to fade out. + * @param filenameURL Filename/URL of a sound file to play next, or null for none. + * @param milis Number of miliseconds the fadeout should take. + */ + private void CommandFadeOut( String sourcename, FilenameURL filenameURL, + long milis ) + { + if( soundLibrary != null ) + soundLibrary.fadeOut( sourcename, filenameURL, milis ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandFadeOut'", 0 ); + } +/** + * Fades out the volume of whatever the specified source is currently playing, + * then fades the volume back in playing the specified file. Final volume + * after fade-in completes will be equal to the source's previously assigned + * volume level. The filenameURL parameter may not be null or empty. The + * miliseconds parameters must be non-negative or zero. This method will + * remove anything that is currently in the specified source's list of queued + * sounds that would have played next when the current sound finished playing. + * This method may only be used for streaming and MIDI sources. This method is + * used internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the fadeOutIn() method instead. + * @param sourcename Name of the source to fade out/in. + * @param filenameURL Filename/URL of a sound file to play next, or null for none. + * @param milisOut Number of miliseconds the fadeout should take. + * @param milisIn Number of miliseconds the fadein should take. + */ + private void CommandFadeOutIn( String sourcename, FilenameURL filenameURL, + long milisOut, long milisIn ) + { + if( soundLibrary != null ) + soundLibrary.fadeOutIn( sourcename, filenameURL, milisOut, + milisIn ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandFadeOutIn'", 0 ); + } +/** + * Makes sure the current volume levels of streaming sources and MIDI are + * correct. This method is designed to help reduce the "jerky" fading behavior + * that happens when using some library and codec pluggins (such as + * LibraryJavaSound and CodecJOrbis). This method has no effect on normal + * "non-streaming" sources. It would normally be called somewhere in the main + * "game loop". IMPORTANT: To optimize frame-rates, do not call this method + * for every frame. It is better to just call this method at some acceptable + * "granularity" (play around with different granularities to find what sounds + * acceptable for a particular situation). This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the checkFadeVolumes() method instead. + */ + private void CommandCheckFadeVolumes() + { + if( soundLibrary != null ) + soundLibrary.checkFadeVolumes(); + else + errorMessage( "Variable 'soundLibrary' null in method " + + "'CommandCheckFadeVolumes'", 0 ); + } +/** + * Loads a sound file into memory. This method is used internally by + * SoundSystem for thread synchronization, and it can not be called directly - + * please use the newSource() method instead. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Whether or not to stream the source. + * @param toLoop Whether or not to loop the source. + * @param sourcename A unique identifier for the source. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distORroll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + private void CommandNewSource( boolean priority, boolean toStream, + boolean toLoop, String sourcename, + FilenameURL filenameURL, float x, + float y, float z, int attModel, + float distORroll ) + { + if( soundLibrary != null ) + { + if( filenameURL.getFilename().matches( + SoundSystemConfig.EXTENSION_MIDI ) + && !SoundSystemConfig.midiCodec() ) + { + soundLibrary.loadMidi( toLoop, sourcename, filenameURL ); + } + else + { + soundLibrary.newSource( priority, toStream, toLoop, sourcename, + filenameURL, x, y, z, attModel, + distORroll ); + } + } + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandNewSource'", 0 ); + } +/** + * Opens a direct line for streaming audio data. This method is used + * internally by SoundSystem, and it can not be called directly - please use + * the rawDataStream() method instead. + * @param audioFormat Format that the data will be in. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + private void CommandRawDataStream( AudioFormat audioFormat, + boolean priority, String sourcename, + float x, float y, float z, + int attModel, float distOrRoll ) + { + if( soundLibrary != null ) + soundLibrary.rawDataStream( audioFormat, priority, sourcename, + x, y, z, attModel, distOrRoll ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandRawDataStream'", 0 ); + } +/** + * Creates a temporary source and either plays or streams it. After the source + * finishes playing, it is removed. This method is used internally by + * SoundSystem for thread synchronization, and it can not be called directly - + * please use the quickPlay() method instead. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Whether or not to stream the source. + * @param toLoop Whether or not to loop the source. + * @param sourcename A unique identifier for the source. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distORroll Either the fading distance or rolloff factor, depending on the value of "attmodel". + * @param temporary Whether or not the source should be removed after it finishes playing. + */ + private void CommandQuickPlay( boolean priority, boolean toStream, + boolean toLoop, String sourcename, + FilenameURL filenameURL, float x, float y, + float z, int attModel, float distORroll, + boolean temporary ) + { + if( soundLibrary != null ) + { + if( filenameURL.getFilename().matches( SoundSystemConfig.EXTENSION_MIDI ) && + !SoundSystemConfig.midiCodec() ) + { + soundLibrary.loadMidi( toLoop, sourcename, filenameURL ); + } + else + { + soundLibrary.quickPlay( priority, toStream, toLoop, sourcename, + filenameURL, x, y, z, attModel, + distORroll, temporary ); + } + } + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandQuickPlay'", 0 ); + } +/** + * Moves a source to the specified coordinates. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setPosition() method instead. + * @param sourcename Source to move. + * @param x Destination X coordinate. + * @param y Destination Y coordinate. + * @param z Destination Z coordinate. + */ + private void CommandSetPosition( String sourcename, float x, float y, + float z) + { + if( soundLibrary != null ) + soundLibrary.setPosition( sourcename, x, y, z ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandMoveSource'", 0 ); + } +/** + * Manually sets the specified source's volume. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setVolume() method instead. + * @param sourcename Source to change the volume of. + * @param value New volume, float value ( 0.0f - 1.0f ). + */ + private void CommandSetVolume( String sourcename, float value ) + { + if( soundLibrary != null ) + soundLibrary.setVolume( sourcename, value ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetVolume'", 0 ); + } +/** + * Manually sets the specified source's pitch. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setPitch() method instead. + * @param sourcename Source to change the pitch of. + * @param value New pitch, float value ( 0.5f - 2.0f ). + */ + private void CommandSetPitch( String sourcename, float value ) + { + if( soundLibrary != null ) + soundLibrary.setPitch( sourcename, value ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetPitch'", 0 ); + } +/** + * Set a source's priority factor. A priority source will not be overriden when + * too many sources are playing at once. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setPriority() method instead. + * @param sourcename Identifier for the source. + * @param pri Setting this to true makes this source a priority source. + */ + private void CommandSetPriority( String sourcename, boolean pri ) + { + if( soundLibrary != null ) + soundLibrary.setPriority( sourcename, pri ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetPriority'", 0 ); + } +/** + * Changes a source to looping or non-looping. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setLooping() method instead. + * @param sourcename Identifier for the source. + * @param lp This source should loop. + */ + private void CommandSetLooping( String sourcename, boolean lp ) + { + if( soundLibrary != null ) + soundLibrary.setLooping( sourcename, lp ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetLooping'", 0 ); + } +/** + * Changes a source's attenuation model. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setAttenuation() method instead. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Attenuation. + * @param sourcename Identifier for the source. + * @param model Attenuation model to use. + */ + private void CommandSetAttenuation( String sourcename, int model ) + { + if( soundLibrary != null ) + soundLibrary.setAttenuation( sourcename, model ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetAttenuation'", + 0 ); + } +/** + * Changes a source's fade distance or rolloff factor. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about fade distance and rolloff. + * @param sourcename Identifier for the source. + * @param dr Either the fading distance or rolloff factor, depending on the attenuation model used. + */ + private void CommandSetDistOrRoll( String sourcename, float dr ) + { + if( soundLibrary != null ) + soundLibrary.setDistOrRoll( sourcename, dr ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetDistOrRoll'", + 0 ); + } +/** + * Changes the Doppler factor. This method is used internally by SoundSystem + * for thread synchronization, and it can not be called directly - please use + * the setDopplerFactor() method instead. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param dopplerFactor New Doppler factor, for determining Doppler effect scale. + */ + private void CommandChangeDopplerFactor( float dopplerFactor ) + { + if( soundLibrary != null ) + { + SoundSystemConfig.setDopplerFactor( dopplerFactor ); + soundLibrary.dopplerChanged(); + } + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetDopplerFactor'", + 0 ); + } +/** + * Changes the Doppler velocity. This method is used internally by SoundSystem + * for thread synchronization, and it can not be called directly - please use + * the setDopplerVelocity() method instead. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param dopplerVelocity New Doppler velocity, for use in Doppler effect. + */ + private void CommandChangeDopplerVelocity( float dopplerVelocity ) + { + if( soundLibrary != null ) + { + SoundSystemConfig.setDopplerVelocity( dopplerVelocity ); + soundLibrary.dopplerChanged(); + } + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetDopplerFactor'", + 0 ); + } +/** + * Changes a source's velocity, for use in Doppler effect. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setVelocity() method instead. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param sourcename Identifier for the source. + * @param x Source's velocity along the world x-axis. + * @param y Source's velocity along the world y-axis. + * @param z Source's velocity along the world z-axis. + */ + private void CommandSetVelocity( String sourcename, float x, float y, float z ) + { + if( soundLibrary != null ) + soundLibrary.setVelocity( sourcename, x, y, z ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandVelocity'", + 0 ); + } +/** + * Changes the listener's velocity, for use in Doppler effect. This method is + * used internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setListenerVelocity() method instead. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param x Velocity along the world x-axis. + * @param y Velocity along the world y-axis. + * @param z Velocity along the world z-axis. + */ + private void CommandSetListenerVelocity( float x, float y, float z ) + { + if( soundLibrary != null ) + soundLibrary.setListenerVelocity( x, y, z ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetListenerVelocity'", + 0 ); + } +/** + * Plays the specified source. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the play() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandPlay( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.play( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandPlay'", 0 ); + } +/** + * Feeds raw data through the specified source. The source must be a + * streaming source and it can not be already associated with a file or URL to + * stream from. This method is used internally by SoundSystem for thread + * synchronization, and it can not be called directly - please use the + * feedRawAudioData() method instead. + * @param sourcename Name of the streaming source to play from. + * @param buffer Byte buffer containing raw audio data to stream. + */ + private void CommandFeedRawAudioData( String sourcename, byte[] buffer ) + { + if( soundLibrary != null ) + soundLibrary.feedRawAudioData( sourcename, buffer ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandFeedRawAudioData'", 0 ); + } +/** + * Pauses the specified source. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the pause() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandPause( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.pause( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandPause'", 0 ); + } +/** + * Stops the specified source. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the stop() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandStop( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.stop( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandStop'", 0 ); + } +/** + * Rewinds the specified source. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the rewind() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandRewind( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.rewind( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandRewind'", 0 ); + } +/** + * Flushes all previously queued audio data from a streaming source. This + * method is used internally by SoundSystem for thread synchronization, and it + * can not be called directly - please use the flush() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandFlush( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.flush( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandFlush'", 0 ); + } +/** + * Sets a flag for a source indicating whether it should be used or if it + * should be removed after it finishes playing. One possible use for this + * method is to make temporary sources that were created with quickPlay() + * permanant. Another use could be to have a source automatically removed + * after it finishes playing. NOTE: Setting a source to inactive does not stop + * it, and setting a source to active does not play it. It is also important + * to note that a looping inactive source will not be removed as long as + * it keeps playing. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setTemporary() method instead. + * @param sourcename Identifier for the source. + * @param temporary True or False. + */ + private void CommandSetTemporary( String sourcename, boolean temporary ) + { + if( soundLibrary != null ) + soundLibrary.setTemporary( sourcename, temporary ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetActive'", 0 ); + } +/** + * Removes the specified source and clears up any memory it used. This method + * is used internally by SoundSystem for thread synchronization, and it can not + * be called directly - please use the removeSource() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandRemoveSource( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.removeSource( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandRemoveSource'", 0 ); + } +/** + * Moves the listener relative to the current location. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the moveListener() method instead. + * @param x X offset. + * @param y Y offset. + * @param z Z offset. + */ + private void CommandMoveListener( float x, float y, float z ) + { + if( soundLibrary != null ) + soundLibrary.moveListener( x, y, z ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandMoveListener'", 0 ); + } + /** + * Moves the listener to the specified location. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setListenerPosition() method instead. + * @param x Destination X coordinate. + * @param y Destination Y coordinate. + * @param z Destination Z coordinate. + */ + private void CommandSetListenerPosition( float x, float y, float z ) + { + if( soundLibrary != null ) + soundLibrary.setListenerPosition( x, y, z ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetListenerPosition'", + 0 ); + } +/** + * Turns the listener counterclockwise by "angle" radians around the y-axis, + * relative to the current angle. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the turnListener() method instead. + * @param angle radian offset. + */ + private void CommandTurnListener( float angle ) + { + if( soundLibrary != null ) + soundLibrary.turnListener( angle ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandTurnListener'", + 0 ); + } +/** + * Sets the listener's angle in radians around the y-axis. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setListenerAngle() method instead. + * @param angle radians. + */ + private void CommandSetListenerAngle( float angle ) + { + if( soundLibrary != null ) + soundLibrary.setListenerAngle( angle ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetListenerAngle'", + 0 ); + } +/** + * Sets the listener's orientation. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setListenerOrientation() method instead. + * @param lookX X coordinate of the (normalized) look-at vector. + * @param lookY Y coordinate of the (normalized) look-at vector. + * @param lookZ Z coordinate of the (normalized) look-at vector. + * @param upX X coordinate of the (normalized) look-at vector. + * @param upY Y coordinate of the (normalized) look-at vector. + * @param upZ Z coordinate of the (normalized) look-at vector. + */ + private void CommandSetListenerOrientation( float lookX, float lookY, + float lookZ, float upX, + float upY, float upZ ) + { + if( soundLibrary != null ) + soundLibrary.setListenerOrientation( lookX, lookY, lookZ, upX, upY, + upZ ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetListenerOrientation'", + 0 ); + } +/** + * Culls the specified source. A culled source can not be played until it has + * been activated again. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the cull() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandCull( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.cull( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandCull'", 0 ); + } +/** + * Activates a previously culled source, so it can be played again. This + * method is used internally by SoundSystem for thread synchronization, and it + * can not be called directly - please use the activate() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandActivate( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.activate( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandActivate'", + 0 ); + } +/** + * Sets the overall volume, affecting all sources. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setMasterVolume() method instead. + * @param value New volume, float value ( 0.0f - 1.0f ). + */ + private void CommandSetMasterVolume( float value ) + { + if( soundLibrary != null ) + soundLibrary.setMasterVolume( value ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetMasterVolume'", + 0 ); + } + +/** + * This method can be overridden by extended classes to be used for source + * management (culling and activating sources based on established rules). One + * possible use for this method is sorting sources by distance, culling the + * furthest, and activating the closest. + * This method is automatically called on the CommandThread before processing + * queued commands, so you do not need to call it anywhere else. Note: use + * methods cull() and activate() here, NOT CommandCull() and CommandActivate() + * (thread safety issue). + * IMPORTANT: Always use synchronized( SoundSystemConfig.THREAD_SYNC ) when + * manually manipulating sources from outside the Command Thread! + */ + protected void ManageSources() + { + // OVERRIDDEN METHODS MUST USE THIS: + + /******* + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + // TODO: Sort the sources, cull and activate, etc. + } + ********/ + } + +/** + * Queues a command. + * If newCommand is null, all commands are dequeued and executed. + * This is automatically used by the sound system, so it is not + * likely that a user would ever need to use this method. + * See {@link paulscode.sound.CommandObject CommandObject} for more information + * about commands. + * @param newCommand Command to queue, or null to execute commands. + * @return True if more commands exist, false if queue is empty. + */ + public boolean CommandQueue( CommandObject newCommand ) + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( newCommand == null ) + { + // New command is null - that means execute all queued commands. + boolean activations = false; + CommandObject commandObject; + + // Loop through the command queue: + while( commandQueue != null && commandQueue.size() > 0 ) + { + // Grab the oldest command in the queue: + commandObject = commandQueue.remove( 0 ); + // See what it is, and execute the proper Command method: + if( commandObject != null ) + { + switch( commandObject.Command ) + { + case CommandObject.INITIALIZE: + CommandInitialize(); + break; + case CommandObject.LOAD_SOUND: + CommandLoadSound( + (FilenameURL) commandObject.objectArgs[0] ); + break; + case CommandObject.LOAD_DATA: + CommandLoadSound( + (SoundBuffer) commandObject.objectArgs[0], + commandObject.stringArgs[0] ); + break; + case CommandObject.UNLOAD_SOUND: + CommandUnloadSound( commandObject.stringArgs[0] ); + break; + case CommandObject.QUEUE_SOUND: + CommandQueueSound( commandObject.stringArgs[0], + (FilenameURL) commandObject.objectArgs[0] ); + break; + case CommandObject.DEQUEUE_SOUND: + CommandDequeueSound( commandObject.stringArgs[0], + commandObject.stringArgs[1] ); + break; + case CommandObject.FADE_OUT: + CommandFadeOut( commandObject.stringArgs[0], + (FilenameURL) commandObject.objectArgs[0], + commandObject.longArgs[0] ); + break; + case CommandObject.FADE_OUT_IN: + CommandFadeOutIn( commandObject.stringArgs[0], + (FilenameURL) commandObject.objectArgs[0], + commandObject.longArgs[0], + commandObject.longArgs[1] ); + break; + case CommandObject.CHECK_FADE_VOLUMES: + CommandCheckFadeVolumes(); + break; + case CommandObject.NEW_SOURCE: + CommandNewSource( commandObject.boolArgs[0], + commandObject.boolArgs[1], + commandObject.boolArgs[2], + commandObject.stringArgs[0], + (FilenameURL) commandObject.objectArgs[0], + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2], + commandObject.intArgs[0], + commandObject.floatArgs[3] ); + break; + case CommandObject.RAW_DATA_STREAM: + CommandRawDataStream( + (AudioFormat) commandObject.objectArgs[0], + commandObject.boolArgs[0], + commandObject.stringArgs[0], + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2], + commandObject.intArgs[0], + commandObject.floatArgs[3] ); + break; + case CommandObject.QUICK_PLAY: + CommandQuickPlay( commandObject.boolArgs[0], + commandObject.boolArgs[1], + commandObject.boolArgs[2], + commandObject.stringArgs[0], + (FilenameURL) commandObject.objectArgs[0], + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2], + commandObject.intArgs[0], + commandObject.floatArgs[3], + commandObject.boolArgs[3] ); + break; + case CommandObject.SET_POSITION: + CommandSetPosition( commandObject.stringArgs[0], + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2] ); + break; + case CommandObject.SET_VOLUME: + CommandSetVolume( commandObject.stringArgs[0], + commandObject.floatArgs[0] ); + break; + case CommandObject.SET_PITCH: + CommandSetPitch( commandObject.stringArgs[0], + commandObject.floatArgs[0] ); + break; + case CommandObject.SET_PRIORITY: + CommandSetPriority( commandObject.stringArgs[0], + commandObject.boolArgs[0] ); + break; + case CommandObject.SET_LOOPING: + CommandSetLooping( commandObject.stringArgs[0], + commandObject.boolArgs[0] ); + break; + case CommandObject.SET_ATTENUATION: + CommandSetAttenuation( commandObject.stringArgs[0], + commandObject.intArgs[0] ); + break; + case CommandObject.SET_DIST_OR_ROLL: + CommandSetDistOrRoll( commandObject.stringArgs[0], + commandObject.floatArgs[0] ); + break; + case CommandObject.CHANGE_DOPPLER_FACTOR: + CommandChangeDopplerFactor( + commandObject.floatArgs[0] ); + break; + case CommandObject.CHANGE_DOPPLER_VELOCITY: + CommandChangeDopplerVelocity( + commandObject.floatArgs[0] ); + break; + case CommandObject.SET_VELOCITY: + CommandSetVelocity( commandObject.stringArgs[0], + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2] + ); + break; + case CommandObject.SET_LISTENER_VELOCITY: + CommandSetListenerVelocity( + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2] + ); + break; + // Methods related to playing sources must be processed + // after cull/activate commands in order for source + // management to work properly, so save them for + // later: + //------------------------------------------------------ + case CommandObject.PLAY: + sourcePlayList.add( commandObject ); + break; + case CommandObject.FEED_RAW_AUDIO_DATA: + sourcePlayList.add( commandObject ); + break; + //------------------------------------------------------ + case CommandObject.PAUSE: + CommandPause( commandObject.stringArgs[0] ); + break; + case CommandObject.STOP: + CommandStop( commandObject.stringArgs[0] ); + break; + case CommandObject.REWIND: + CommandRewind( commandObject.stringArgs[0] ); + break; + case CommandObject.FLUSH: + CommandFlush( commandObject.stringArgs[0] ); + break; + case CommandObject.CULL: + CommandCull( commandObject.stringArgs[0] ); + break; + case CommandObject.ACTIVATE: + activations = true; + CommandActivate( commandObject.stringArgs[0] ); + break; + case CommandObject.SET_TEMPORARY: + CommandSetTemporary( commandObject.stringArgs[0], + commandObject.boolArgs[0] ); + break; + case CommandObject.REMOVE_SOURCE: + CommandRemoveSource( commandObject.stringArgs[0] ); + break; + case CommandObject.MOVE_LISTENER: + CommandMoveListener( commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2]); + break; + case CommandObject.SET_LISTENER_POSITION: + CommandSetListenerPosition( + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2]); + break; + case CommandObject.TURN_LISTENER: + CommandTurnListener( commandObject.floatArgs[0] ); + break; + case CommandObject.SET_LISTENER_ANGLE: + CommandSetListenerAngle( + commandObject.floatArgs[0]); + break; + case CommandObject.SET_LISTENER_ORIENTATION: + CommandSetListenerOrientation( + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2], + commandObject.floatArgs[3], + commandObject.floatArgs[4], + commandObject.floatArgs[5]); + break; + case CommandObject.SET_MASTER_VOLUME: + CommandSetMasterVolume( + commandObject.floatArgs[0] ); + break; + case CommandObject.NEW_LIBRARY: + CommandNewLibrary( commandObject.classArgs[0] ); + break; + // If we don't recognize the command, just skip it: + default: + break; + } + } + } + + // If any sources were reactivated, check if they need to be + // replayed: + if( activations ) + soundLibrary.replaySources(); + + // Now that we have the correct sources culled and activated, we + // can start playing sources. Loop through the playlist and + // execute the commands: + while( sourcePlayList != null && sourcePlayList.size() > 0 ) + { + // Grab the oldest command in the queue: + commandObject = sourcePlayList.remove( 0 ); + if( commandObject != null ) + { + // See what it is, and execute the proper Command method: + switch( commandObject.Command ) + { + case CommandObject.PLAY: + CommandPlay( commandObject.stringArgs[0] ); + break; + case CommandObject.FEED_RAW_AUDIO_DATA: + CommandFeedRawAudioData( + commandObject.stringArgs[0], + commandObject.buffer ); + break; + } + } + } + + return( commandQueue != null && commandQueue.size() > 0 ); + } + else + { + // make sure the commandQueue exists: + if( commandQueue == null ) + return false; + // queue a new command + commandQueue.add( newCommand ); + // Of course there is something in the list now, since we just + // added it: + return true; + } + } + } + +/** + * Searches for and removes any temporary sources that have finished + * playing. This method is used internally by SoundSystem, and it is + * unlikely that the user will ever need to use it. + */ + public void removeTemporarySources() + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( soundLibrary != null ) + soundLibrary.removeTemporarySources(); + } + } + +/** + * Returns true if the specified source is playing. + * @param sourcename Unique identifier of the source to check. + * @return True or false. + */ + public boolean playing( String sourcename ) + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( soundLibrary == null ) + return false; + + Source src = soundLibrary.getSources().get( sourcename ); + + if( src == null ) + return false; + + return src.playing(); + } + } + +/** + * Returns true if anything is currently playing. + * @return True or false. + */ + public boolean playing() + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( soundLibrary == null ) + return false; + + HashMap sourceMap = soundLibrary.getSources(); + if( sourceMap == null ) + return false; + + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + if( source.playing() ) + return true; + } + + return false; + } + } + +/** + * Copies and returns the peripheral information from a map of sources. This + * method is used internally by SoundSystem, and it is unlikely that the user + * will ever need to use it. + * @param sourceMap Sources to copy. + * @return New map of sources. + */ + private HashMap copySources( HashMap sourceMap ) + { + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // New map of generic source data: + HashMap returnMap = new HashMap(); + + + // loop through and store information from all the sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + returnMap.put( sourcename, new Source( source, null ) ); + } + return returnMap; + } + +/** + * Checks if the specified library type is compatible. + * @param libraryClass Libary type to check. + * @return True or false. + */ + public static boolean libraryCompatible( Class libraryClass ) + { + // create the message logger: + SoundSystemLogger logger = SoundSystemConfig.getLogger(); + // if the user didn't create one, then do it now: + if( logger == null ) + { + logger = new SoundSystemLogger(); + SoundSystemConfig.setLogger( logger ); + } + logger.message( "", 0 ); + logger.message( "Checking if " + + SoundSystemConfig.getLibraryTitle( libraryClass ) + + " is compatible...", 0 ); + + boolean comp = SoundSystemConfig.libraryCompatible( libraryClass ); + + if( comp ) + logger.message( "...yes", 1 ); + else + logger.message( "...no", 1 ); + + return comp; + } + +/** + * Returns the currently loaded library, or -1 if none. + * @return Global library identifier + */ + public static Class currentLibrary() + { + return( currentLibrary( GET, null ) ); + } + +/** + * Returns false if a sound library is busy initializing. + * @return True or false. + */ + public static boolean initialized() + { + return( initialized( GET, XXX ) ); + } + +/** + * Returns the last SoundSystemException thrown, or null if none. + * @return The last exception. + */ + public static SoundSystemException getLastException() + { + return( lastException( GET, null ) ); + } + +/** + * Stores a SoundSystemException which can be retreived later with the + * 'getLastException' method. + * @param e Exception to store. + */ + public static void setException( SoundSystemException e ) + { + lastException( SET, e ); + } + +/** + * Sets or returns the value of boolean 'initialized'. + * @param action Action to perform (GET or SET). + * @param value New value if action is SET, otherwise XXX. + * @return value of boolean 'initialized'. + */ + private static boolean initialized( boolean action, boolean value ) + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( action == SET ) + initialized = value; + return initialized; + } + } + +/** + * Sets or returns the value of boolean 'initialized'. + * @param action Action to perform (GET or SET). + * @param value New value if action is SET, otherwise XXX. + * @return value of boolean 'initialized'. + */ + private static Class currentLibrary( boolean action, + Class value ) + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( action == SET ) + currentLibrary = value; + return currentLibrary; + } + } + +/** + * Sets or returns the error code for the last error that occurred. If no + * errors have occurred, returns SoundSystem.ERROR_NONE + * @param action Action to perform (GET or SET). + * @param e New exception if action is SET, otherwise XXX. + * @return Last SoundSystemException thrown. + */ + private static SoundSystemException lastException( boolean action, + SoundSystemException e ) + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( action == SET ) + lastException = e; + return lastException; + } + } + +/** + * Sleeps for the specified number of milliseconds. + */ + protected static void snooze( long milliseconds ) + { + try + { + Thread.sleep( milliseconds ); + } + catch( InterruptedException e ){} + } + +/** + * Prints a message. + * @param message Message to print. + * @param indent Number of tabs to indent the message. + */ + protected void message( String message, int indent ) + { + logger.message( message, indent ); + } + +/** + * Prints an important message. + * @param message Message to print. + * @param indent Number of tabs to indent the message. + */ + protected void importantMessage( String message, int indent ) + { + logger.importantMessage( message, indent ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param message Message to print if error is true. + * @param indent Number of tabs to indent the message. + * @return True if error is true. + */ + protected boolean errorCheck( boolean error, String message, int indent ) + { + return logger.errorCheck( error, className, message, indent ); + } + +/** + * Prints an error message. + * @param message Message to print. + * @param indent Number of tabs to indent the message. + */ + protected void errorMessage( String message, int indent ) + { + logger.errorMessage( className, message, indent ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/SoundSystemConfig.java b/src/lwjgl/java/paulscode/sound/SoundSystemConfig.java new file mode 100644 index 0000000..d5efbc0 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/SoundSystemConfig.java @@ -0,0 +1,1074 @@ +package paulscode.sound; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Locale; +import java.util.ListIterator; +import java.util.LinkedList; + +/** + * The SoundSystemConfig class is used to access global sound system settings, + * and to link with external pluggins. All members of this class are static. + * SoundSystemConfig is sort of a "catch all" configuration class, so if you + * are not sure where to find something in the SoundSystem library, this is + * probably a good place to start. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class SoundSystemConfig +{ +// GLOBAL THREAD SYNCHRONIZATION +/** + * Lock object used to synchronize the three threads used by SoundSystem. + * Synchronize on this anytime you manually manipulate a Source's properties. + */ + public static final Object THREAD_SYNC = new Object(); +// END GLOBAL THREAD SYNCHRONIZATION + +// GLOBAL IDENTIFIERS + +/** + * A normal (non-streaming) source. Also used to define a Channel type as + * normal. + */ + public static final int TYPE_NORMAL = 0; +/** + * A streaming source. Also used to define a Channel type as streaming. + */ + public static final int TYPE_STREAMING = 1; + +/** + * Global identifier for no attenuation. Attenuation is how a source's volume + * fades with distance. When there is no attenuation, a source's volume + * remains constaint regardles of distance. + */ + public static final int ATTENUATION_NONE = 0; // no attenuation +/** + * Global identifier for rolloff attenuation. Rolloff attenuation is a + * realistic attenuation model, which uses a rolloff factor to determine how + * quickly a source fades with distance. A smaller rolloff factor will fade at + * a further distance, and a rolloff factor of 0 will never fade. NOTE: In + * OpenAL, rolloff attenuation only works for monotone sounds. + */ + public static final int ATTENUATION_ROLLOFF = 1; // logrithmic attenuation +/** + * Global identifier for linear attenuation. Linear attenuation is less + * realistic than rolloff attenuation, but it allows the user to specify a + * maximum "fade distance" where a source's volume becomes zero. + */ + public static final int ATTENUATION_LINEAR = 2; // linear attenuation + +/** + * A Regular expression for determining if a file's extension is MIDI. + */ + public static String EXTENSION_MIDI = ".*[mM][iI][dD][iI]?$"; + +/** + * A Regular expression for determining if a path is an online URL. + */ + public static String PREFIX_URL = "^[hH][tT][tT][pP]://.*"; + +// END GLOBAL IDENTIFIERS + + +// PRIVATE STATIC VARIABLES + +/** + * Handle to the message logger. The default logger can be changed by + * overridding the {@link paulscode.sound.SoundSystemLogger SoundSystemLogger} + * class and calling the setLogger() method (must be done BEFORE instantiating + * the SoundSystem class!) + */ + private static SoundSystemLogger logger = null; + +/** + * List of library types in their order of priority. + */ + private static LinkedList libraries; + +/** + * List of codecs and the file formats they are associated with. + */ + private static LinkedList codecs = null; + +/** + * List of stream listeners. + */ + private static LinkedList streamListeners = null; +/** + * For synchronizing access to the streamListeners list. + */ + private static final Object streamListenersLock = new Object(); + +/** + * Maximum number of normal (non-streaming) channels that can be created. + * NOTE: JavaSound may require the total number of channels (non-streaming + + * streaming) to be 32. + */ + private static int numberNormalChannels = 28; +/** + * Maximum number of streaming channels that can be created. + * NOTE: JavaSound may require the total number of channels (non-streaming + + * streaming) to be 32. + */ + private static int numberStreamingChannels = 4; +/** + * Overall volume, affecting all sources. Float value (0.0f - 1.0f). + */ + private static float masterGain = 1.0f; +/** + * Attenuation model to use if not specified. Attenuation is how a source's + * volume fades with distance. + */ + private static int defaultAttenuationModel = ATTENUATION_ROLLOFF; +/** + * Default value to use for the rolloff factor if not specified. + */ + private static float defaultRolloffFactor = 0.03f; +/** + * Value to use for the doppler factor, for determining Doppler scale. + */ + private static float dopplerFactor = 0.0f; +/** + * Value to use for the doppler velocity. + */ + private static float dopplerVelocity = 1.0f; +/** + * Default value to use for fade distance if not specified. + */ + private static float defaultFadeDistance = 1000.0f; +/** + * Package where the sound files are located (must be followed by '/'). + */ + private static String soundFilesPackage = "Sounds/"; + +/** + * Number of bytes to load at a time when streaming. + */ + private static int streamingBufferSize = 131072; +/** + * Number of buffers used for each streaming sorce. Slow codecs may require + * this number to be greater than 2 to prevent audio skipping during playback. + */ + private static int numberStreamingBuffers = 3; +/** + * Enables a transition-speed optimization by assuming all sounds in each + * streaming source's queue will have exactly the same format once decoded + * (including channels, sample rate, and sample size). This is an advanced + * setting which should only be changed by experienced developers. + */ + private static boolean streamQueueFormatsMatch = false; +/** + * The maximum number of bytes to read in for (non-streaming) files. + * Increase this value if non-streaming sounds are getting cut off. + * Decrease this value if large sound files are causing lag during load time. + */ + private static int maxFileSize = 268435456; +/** + * Size of each chunk to read at a time for loading (non-streaming) files. + * Increase if loading sound files is causing significant lag. + */ + private static int fileChunkSize = 1048576; + +/** + * Indicates whether or not there is a codec for reading from MIDI files. If + * there is no codec for MIDI, then SoundSystem uses javax.sound.midi. + */ + private static boolean midiCodec = false; + +/** + * MIDI device to try using as the Synthesizer. May be the full name or part + * of the name. If this String is empty, the default Synthesizer will be used, + * or one of the common alternate synthesizers if the default Synthesizer is + * unavailable. + */ + private static String overrideMIDISynthesizer = ""; + +// END PRIVATE STATIC VARIABLES + +// THESE TWO METHODS PROVIDE INFORMATION ABOUT THE INDIVIDUAL SOUND LIBRARIES + +/** + * Adds an entry to the list of library types. This method has no effect if + * the specified library type is already in the list of libraries. + * NOTE: The parameterless constructor of the SoundSystem class will try to + * load libraries in the order that they were entered into the list. + * @param libraryClass Derivitive of class 'Library'. +*/ + public static void addLibrary( Class libraryClass ) + throws SoundSystemException + { + if( libraryClass == null ) + throw new SoundSystemException( + "Parameter null in method 'addLibrary'", + SoundSystemException.NULL_PARAMETER ); + if( !Library.class.isAssignableFrom( libraryClass ) ) + throw new SoundSystemException( "The specified class does not " + + "extend class 'Library' in method 'addLibrary'" ); + + if( libraries == null ) + libraries = new LinkedList(); + + if( !libraries.contains( libraryClass ) ) + libraries.add( libraryClass ); + } + +/** + * Removes the specified library from the list of library types. + * @param libraryClass Derivitive of class 'Library'. +*/ + public static void removeLibrary( Class libraryClass ) + throws SoundSystemException + { + if( libraries == null || libraryClass == null ) + return; + + libraries.remove( libraryClass ); + } + +/** + * Returns the list of library types. + * @return LinkedList of classes derived from 'Library', or null if none were specified. +*/ + public static LinkedList getLibraries() + { + return libraries; + } + +/** + * Checks if the specified library class is compatible on the user's machine. + * @param libraryClass Library type to check. + * @return True or false. +*/ + public static boolean libraryCompatible( Class libraryClass ) + { + if( libraryClass == null ) + { + errorMessage( "Parameter 'libraryClass' null in method" + + "'librayCompatible'" ); + return false; + } + if( !Library.class.isAssignableFrom( libraryClass ) ) + { + errorMessage( "The specified class does not extend class " + + "'Library' in method 'libraryCompatible'" ); + return false; + } + + Object o = runMethod( libraryClass, "libraryCompatible", + new Class[0], new Object[0] ); + + if( o == null ) + { + errorMessage( "Method 'Library.libraryCompatible' returned " + + "'null' in method 'libraryCompatible'" ); + return false; + } + + return( ( (Boolean) o ).booleanValue() ); + } + +/** + * Return the short title of the specified library, or null if error. + * @param libraryClass Derivitive of class 'Library'. + * @return String containing the library title. +*/ + public static String getLibraryTitle( Class libraryClass ) + { + if( libraryClass == null ) + { + errorMessage( "Parameter 'libraryClass' null in method" + + "'getLibrayTitle'" ); + return null; + } + if( !Library.class.isAssignableFrom( libraryClass ) ) + { + errorMessage( "The specified class does not extend class " + + "'Library' in method 'getLibraryTitle'" ); + return null; + } + + Object o = runMethod( libraryClass, "getTitle", new Class[0], + new Object[0] ); + if( o == null ) + { + errorMessage( "Method 'Library.getTitle' returned " + + "'null' in method 'getLibraryTitle'" ); + return null; + } + + return( (String) o ); + } + +/** + * Return the longer description of the specified library, or null if error. + * @param libraryClass Derivitive of class 'Library'. + * @return String containing the library title. +*/ + public static String getLibraryDescription( Class libraryClass ) + { + if( libraryClass == null ) + { + errorMessage( "Parameter 'libraryClass' null in method" + + "'getLibrayDescription'" ); + return null; + } + if( !Library.class.isAssignableFrom( libraryClass ) ) + { + errorMessage( "The specified class does not extend class " + + "'Library' in method 'getLibraryDescription'" ); + return null; + } + + Object o = runMethod( libraryClass, "getDescription", + new Class[0], new Object[0] ); + if( o == null ) + { + errorMessage( "Method 'Library.getDescription' returned " + + "'null' in method 'getLibraryDescription'" ); + return null; + } + + return( (String) o ); + } + +/** + * Return whether or not requires reversal of audio data byte-order. + * @param libraryClass Derivitive of class 'Library'. + * @return True if byte-order reversal is required. +*/ + public static boolean reverseByteOrder( Class libraryClass ) + { + if( libraryClass == null ) + { + errorMessage( "Parameter 'libraryClass' null in method" + + "'reverseByteOrder'" ); + return false; + } + if( !Library.class.isAssignableFrom( libraryClass ) ) + { + errorMessage( "The specified class does not extend class " + + "'Library' in method 'reverseByteOrder'" ); + return false; + } + + Object o = runMethod( libraryClass, "reversByteOrder", + new Class[0], new Object[0] ); + if( o == null ) + { + errorMessage( "Method 'Library.reverseByteOrder' returned " + + "'null' in method 'getLibraryDescription'" ); + return false; + } + + return( ((Boolean) o).booleanValue() ); + } + +// END LIBRARY INFORMATION + +// Use the following methods to interface the private variables above: + +// STATIC NONSYNCHRONIZED INTERFACE METHODS +/** + * Changes the message logger to use for handling status messages, warnings, + * and error messages. This method should only be called BEFORE instantiating + * the SoundSystem class! If this method is called after the SoundSystem has + * been created, there will be handles floating around to two different + * loggers, and the results will be undesirable. This method can be used to + * change how messages are handled. First, the + * {@link paulscode.sound.SoundSystemLogger SoundSystemLogger} class should be + * extended and methods overriden to change how messages are handled. Then, + * the overridden class should be instantiated, and a call made to + * SoundSystemConfig.setLogger() before creating the SoundSystem object. + * If an alternate logger is not set by the user before the SoundSystem is + * instantiated, then an instance of the base SoundSystemLogger class will be + * used by default. + * @param l Handle to a message logger. + */ + public static void setLogger( SoundSystemLogger l ) + { + logger = l; + } +/** + * Returns a handle to the message logger. + * @return The current message logger. + */ + public static SoundSystemLogger getLogger() + { + return logger; + } + +// STATIC SYNCHRONIZED INTERFACE METHODS + +/** + * Sets the maximum number of normal (non-streaming) channels that can be + * created. Streaming channels are created first, so the higher the maximum + * number of streaming channels is set, the fewer non-streaming channels will + * be available. If unable to create the number of channels specified, + * SoundSystem will create as many as possible. + * NOTE: Some sound library pluggins may require the total number of channels + * (non-streaming + streaming) to be 32. + * @param number How many normal audio channels. + */ + public static synchronized void setNumberNormalChannels( int number ) + { + numberNormalChannels = number; + } + +/** + * Returns the maximum number of normal (non-streaming) channels that can be + * created. + * @return Maximum non-streaming channels. + */ + public static synchronized int getNumberNormalChannels() + { + return numberNormalChannels; + } + +/** + * Sets the maximum number of streaming channels that can be created. + * Streaming channels are created first, so the higher the maximum number of + * streaming channels is set, the fewer non-streaming channels will + * be available. If unable to create the number of channels specified, + * SoundSystem will create as many as possible. + * NOTE: Some sound library pluggins may require the total number of channels + * (non-streaming + streaming) to be 32. + * @param number How many streaming audio channels. + */ + public static synchronized void setNumberStreamingChannels( int number ) + { + numberStreamingChannels = number; + } + +/** + * Returns the maximum number of streaming channels that can be created. + * @return Maximum streaming channels. + */ + public static synchronized int getNumberStreamingChannels() + { + return numberStreamingChannels; + } + +/** + * Sets the varriable used for overall volume, affecting all sources. + * @param value Float value (0.0f - 1.0f). + */ + public static synchronized void setMasterGain( float value ) + { + masterGain = value; + } + +/** + * Returns the value for the overall volume. + * @return A float value (0.0f - 1.0f). + */ + public static synchronized float getMasterGain() + { + return masterGain; + } + +/** + * Sets the default attenuation model to use when one is not specified. + * Attenuation is how a source's volume fades with distance. + * @param model A global attenuation model identifier. + */ + public static synchronized void setDefaultAttenuation( int model ) + { + defaultAttenuationModel = model; + } +/** + * Returns the default attenuation model used when one is not specified. + * @return A global attenuation model identifier + */ + public static synchronized int getDefaultAttenuation() + { + return defaultAttenuationModel; + } +/** + * Sets the default rolloff factor to use when one is not specified. + * @param rolloff Rolloff factor. + */ + public static synchronized void setDefaultRolloff( float rolloff ) + { + defaultRolloffFactor = rolloff; + } +/** + * Returns the doppler factor, for determining Doppler Effect scale. + * @return Doppler factor + */ + public static synchronized float getDopplerFactor() + { + return dopplerFactor; + } +/** + * Sets the doppler factor, for determining Doppler Effect scale. Use this + * method BEFORE instantiating the SoundSystem. To change the Doppler factor + * after the SoundSystem is instantiated, use the + * SoundSystem.changeDopplerFactor method instead. + * @param factor Doppler factor. + */ + public static synchronized void setDopplerFactor( float factor ) + { + dopplerFactor = factor; + } +/** + * Returns the Doppler Velocity, for use in Doppler Effect. + * @return Doppler velocity. + */ + public static synchronized float getDopplerVelocity() + { + return dopplerVelocity; + } +/** + * Sets the Doppler velocity, for use in Doppler Effect. Use this method + * BEFORE instantiating the SoundSystem. To change the Doppler velocity after + * the SoundSystem is instantiated, use the SoundSystem.changeDopplerVelocity + * method instead. + * @param velocity Doppler velocity. + */ + public static synchronized void setDopplerVelocity( float velocity ) + { + dopplerVelocity = velocity; + } +/** + * Returns the default rolloff factor used when one is not specified. + * @return Default rolloff factor + */ + public static synchronized float getDefaultRolloff() + { + return defaultRolloffFactor; + } +/** + * Sets the default fade distance to use when one is not specified. + * @param distance Fade Distance. + */ + public static synchronized void setDefaultFadeDistance( float distance ) + { + defaultFadeDistance = distance; + } +/** + * Returns the default fade distance used when one is not specified. + * @return Default fade distance + */ + public static synchronized float getDefaultFadeDistance() + { + return defaultFadeDistance; + } +/** + * Sets the package where sound files are located. + * @param location Path to the sound files location (must be followed by '/'). + */ + public static synchronized void setSoundFilesPackage( String location ) + { + soundFilesPackage = location; + } +/** + * Returns the package where sound files are located. + * @return Path to the sound files location + */ + public static synchronized String getSoundFilesPackage() + { + return soundFilesPackage; + } +/** + * Sets the number of bytes to load at a time when streaming. + * @param size Size in bytes. + */ + public static synchronized void setStreamingBufferSize( int size ) + { + streamingBufferSize = size; + } +/** + * Returns the number of bytes to load at a time when streaming. + * @return Size in bytes. + */ + public static synchronized int getStreamingBufferSize() + { + return streamingBufferSize; + } +/** + * Sets the number of buffers used for each streaming sorce. + * Slow codecs may require this number to be greater than 2 to prevent audio + * skipping during playback. + * @param num How many buffers. + */ + public static synchronized void setNumberStreamingBuffers( int num ) + { + numberStreamingBuffers = num; + } +/** + * Returns the number of buffers used for each streaming sorce. + * @return How many buffers. + */ + public static synchronized int getNumberStreamingBuffers() + { + return numberStreamingBuffers; + } + +/** + * Enables a transition-speed optimization by assuming all sounds in each + * streaming source's queue will have exactly the same format once decoded + * (including channels, sample rate, and sample size). This is an advanced + * setting which should only be changed by experienced developers. + * @param val False by default. + */ + public static synchronized void setStreamQueueFormatsMatch( boolean val ) + { + streamQueueFormatsMatch = val; + } + +/** + * Returns whether or not all sounds in each streaming source's queue will be + * handled as if they have exactly the same format once decoded (including + * channels, sample rate, and sample size). This is an advanced setting which + * should only be changed by experienced developers. + * @return Normally false. + */ + public static synchronized boolean getStreamQueueFormatsMatch() + { + return streamQueueFormatsMatch; + } + +/** + * Sets the maximum number of bytes to read in for (non-streaming) files. + * Increase this value if non-streaming sounds are getting cut off. + * Decrease this value if large sound files are causing lag during load time. + * @param size Size in bytes. + */ + public static synchronized void setMaxFileSize( int size ) + { + maxFileSize = size; + } +/** + * Returns the maximum number of bytes to read in for (non-streaming) files. + * @return Size in bytes. + */ + public static synchronized int getMaxFileSize() + { + return maxFileSize; + } +/** + * Sets the size of each chunk to read at a time for loading (non-streaming) + * files. Increase if loading sound files is causing significant lag. + * @param size Size in bytes. + */ + public static synchronized void setFileChunkSize( int size ) + { + fileChunkSize = size; + } +/** + * Returns the size of each chunk to read at a time for loading (non-streaming) + * files. + * @return Size in bytes. + */ + public static synchronized int getFileChunkSize() + { + return fileChunkSize; + } +/** + * Returns the name of the MIDI synthesizer to use instead of the default, or + * empty string if none was specified. + * @return All or part of a MIDI device name, or empty string for not specified. + */ + public static synchronized String getOverrideMIDISynthesizer() + { + return overrideMIDISynthesizer; + } +/** + * Sets the name of the MIDI synthesizer to use instead of the default. If + * 'name' is an empty string, the default Synthesizer will be used, or one of + * the common alternate synthesizers if the default Synthesizer is unavailable. + * @param name All or part of the MIDI device name. + */ + public static synchronized void setOverrideMIDISynthesizer( String name ) + { + overrideMIDISynthesizer = name; + } +/** + * Uses the specified file extension to associate a particular file format + * with the codec used to read audio data from it. + * @param extension File extension to be associated with the specified codec. + * @param iCodecClass Codec type to use for files with the specified extension. + */ + public static synchronized void setCodec( String extension, + Class iCodecClass ) + throws SoundSystemException + { + if( extension == null ) + throw new SoundSystemException( "Parameter 'extension' null in " + + "method 'setCodec'.", + SoundSystemException.NULL_PARAMETER ); + if( iCodecClass == null ) + throw new SoundSystemException( "Parameter 'iCodecClass' null in " + + "method 'setCodec'.", + SoundSystemException.NULL_PARAMETER ); + if( !ICodec.class.isAssignableFrom( iCodecClass ) ) + throw new SoundSystemException( "The specified class does " + + "not implement interface 'ICodec' in method 'setCodec'", + SoundSystemException.CLASS_TYPE_MISMATCH ); + + if( codecs == null ) + codecs = new LinkedList(); + + ListIterator i = codecs.listIterator(); + Codec codec; + + while( i.hasNext() ) + { + codec = i.next(); + if( extension.matches( codec.extensionRegX ) ) + i.remove(); + } + codecs.add( new Codec( extension, iCodecClass ) ); + + // Let SoundSystem know if this is a MIDI codec, so it won't use + // javax.sound.midi anymore: + if( extension.matches( EXTENSION_MIDI ) ) + midiCodec = true; + } +/** + * Returns the codec that can be used to read audio data from the specified + * file. + * @param filename File to get a codec for. + * @return Codec to use for reading audio data. + */ + public static synchronized ICodec getCodec( String filename ) + { + if( codecs == null ) + return null; + + ListIterator i = codecs.listIterator(); + Codec codec; + + while( i.hasNext() ) + { + codec = i.next(); + if( filename.matches( codec.extensionRegX ) ) + return codec.getInstance(); + } + + return null; + } + +/** + * Indicates whether or not there is a codec for reading from MIDI files. If + * there is no codec for MIDI, then SoundSystem uses javax.sound.midi. + * @return True if there the user defined a MIDI codec. + */ + public static boolean midiCodec() + { + return midiCodec; + } + +/** + * Adds an entry to the list of stream listeners. If the instance is already + * in the list, the command is ignored. + * @param streamListener Implementation of interface 'IStreamListener'. +*/ + public static void addStreamListener( IStreamListener streamListener ) + { + synchronized( streamListenersLock ) + { + if( streamListeners == null ) + streamListeners = new LinkedList(); + + if( !streamListeners.contains( streamListener ) ) + streamListeners.add( streamListener ); + } + } + +/** + * Removes an entry from the list of stream listeners. + * @param streamListener Implementation of interface 'IStreamListener'. +*/ + public static void removeStreamListener( IStreamListener streamListener ) + { + + synchronized( streamListenersLock ) + { + if( streamListeners == null ) + streamListeners = new LinkedList(); + + if( streamListeners.contains( streamListener ) ) + streamListeners.remove( streamListener ); + } + } + +/** + * Notifies all stream listeners that an End Of Stream was reached. If there + * are no listeners, the command is ignored. + * @param sourcename String identifier of the source which reached the EOS. + * @param queueSize Number of items left the the stream's play queue, or zero if none. +*/ + public static void notifyEOS( String sourcename, int queueSize ) + { + synchronized( streamListenersLock ) + { + if( streamListeners == null ) + return; + } + final String srcName = sourcename; + final int qSize = queueSize; + + new Thread() + { + @Override + public void run() + { + synchronized( streamListenersLock ) + { + if( streamListeners == null ) + return; + ListIterator i = streamListeners.listIterator(); + IStreamListener streamListener; + while( i.hasNext() ) + { + streamListener = i.next(); + if( streamListener == null ) + i.remove(); + else + streamListener.endOfStream( srcName, qSize ); + } + } + } + }.start(); + } + +// END STATIC SYNCHRONIZED INTERFACE METHODS + + +// PRIVATE INTERNAL METHODS + +/** + * Display the specified error message using the current logger. + * @param message Error message to display. +*/ + private static void errorMessage( String message ) + { + if( logger != null ) + logger.errorMessage( "SoundSystemConfig", message, 0 ); + } + + // We don't know what Class parameter 'c' is, so we will ignore the + // warning message "unchecked call to getMethod". + @SuppressWarnings("unchecked") +/** + * Returns the results of calling the specified method from the specified + * class using the specified parameters. + * @param c Class to call the method on. + * @param method Name of the method. + * @param paramTypes Data types of the parameters being passed to the method. + * @param params Actual parameters to pass to the method. + * @return Specified method's return value, or null if error or void. +*/ + private static Object runMethod( Class c, String method, Class[] paramTypes, + Object[] params ) + { + Method m = null; + try + { + m = c.getMethod( method, paramTypes ); // <--- generates a warning + } + catch( NoSuchMethodException nsme ) + { + errorMessage( "NoSuchMethodException thrown when attempting " + + "to call method '" + method + "' in " + + "method 'runMethod'" ); + return null; + } + catch( SecurityException se ) + { + errorMessage( "Access denied when attempting to call method '" + + method + "' in method 'runMethod'" ); + return null; + } + catch( NullPointerException npe ) + { + errorMessage( "NullPointerException thrown when attempting " + + "to call method '" + method + "' in " + + "method 'runMethod'" ); + return null; + } + if( m == null ) + { + errorMessage( "Method '" + method + "' not found for the class " + + "specified in method 'runMethod'" ); + return null; + } + + Object o = null; + try + { + o = m.invoke( null, params ); + } + catch( IllegalAccessException iae ) + { + errorMessage( "IllegalAccessException thrown when attempting " + + "to invoke method '" + method + "' in " + + "method 'runMethod'" ); + return null; + } + catch( IllegalArgumentException iae ) + { + errorMessage( "IllegalArgumentException thrown when attempting " + + "to invoke method '" + method + "' in " + + "method 'runMethod'" ); + return null; + } + catch( InvocationTargetException ite ) + { + errorMessage( "InvocationTargetException thrown while attempting " + + "to invoke method 'Library.getTitle' in " + + "method 'getLibraryTitle'" ); + return null; + } + catch( NullPointerException npe ) + { + errorMessage( "NullPointerException thrown when attempting " + + "to invoke method '" + method + "' in " + + "method 'runMethod'" ); + return null; + } + catch( ExceptionInInitializerError eiie ) + { + errorMessage( "ExceptionInInitializerError thrown when " + + "attempting to invoke method '" + method + "' in " + + "method 'runMethod'" ); + return null; + } + + return( o ); + } + +// END PRIVATE INTERNAL METHODS + + +// PRIVATE INTERNAL CLASSES + +/** + * The Codec class is used to associate individual file formats with the + * codecs used to load audio data from them. + * + * Author: Paul Lamb + */ + private static class Codec + { +/** + * A regular expression used to match a file's extension. This is used to + * determine the file format. + */ + public String extensionRegX; +/** + * Codec used to load audio data from this file format. + */ + public Class iCodecClass; +/** + * Constructor: Converts the specified extension string into a regular + * expression, and associates that with the specified codec. + * @param extension File extension to be associated with the specified codec. + * @param iCodec Codec to use for files with the specified extension. + */ + public Codec( String extension, Class iCodecClass ) + { + extensionRegX = ""; + // Make sure an extension was specified: + if( extension != null && extension.length() > 0 ) + { + // We are only interested in the file extension. The filename + // can begin with whatever: + extensionRegX = ".*"; + String c; + for( int x = 0; x < extension.length(); x++ ) + { + // Each character could be either upper or lower case: + c = extension.substring( x, x + 1 ); + extensionRegX += "[" + c.toLowerCase( Locale.ENGLISH ) + + c.toUpperCase( Locale.ENGLISH ) + "]"; + } + // The extension will be at the end of the filename: + extensionRegX += "$"; + } + // remember the codec to use for this format: + this.iCodecClass = iCodecClass; + } + + public ICodec getInstance() + { + if( iCodecClass == null ) + return null; + + Object o = null; + try + { + o = iCodecClass.newInstance(); + } + catch( InstantiationException ie ) + { + instantiationErrorMessage(); + return null; + } + catch( IllegalAccessException iae ) + { + instantiationErrorMessage(); + return null; + } + catch( ExceptionInInitializerError eiie ) + { + instantiationErrorMessage(); + return null; + } + catch( SecurityException se ) + { + instantiationErrorMessage(); + return null; + } + + + if( o == null ) + { + instantiationErrorMessage(); + return null; + } + + return (ICodec) o; + } + + private void instantiationErrorMessage() + { + errorMessage( "Unrecognized ICodec implementation in method " + + "'getInstance'. Ensure that the implementing " + + "class has one public, parameterless constructor." ); + } + } +// END PRIVATE INTERNAL CLASSES +} diff --git a/src/lwjgl/java/paulscode/sound/SoundSystemException.java b/src/lwjgl/java/paulscode/sound/SoundSystemException.java new file mode 100644 index 0000000..d0a0101 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/SoundSystemException.java @@ -0,0 +1,94 @@ +package paulscode.sound; + +/** + * The SoundSystemException class is used to provide information about serious + * errors. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class SoundSystemException extends Exception +{ +/** + * Global identifier for no problem. + */ + public static final int ERROR_NONE = 0; +/** + * Global identifier for a generic exception. + */ + public static final int UNKNOWN_ERROR = 1; +/** + * Global identifier for a null parameter. + */ + public static final int NULL_PARAMETER = 2; +/** + * Global identifier for a class type mismatch. + */ + public static final int CLASS_TYPE_MISMATCH = 3; +/** + * Global identifier for the sound library does not exist. + */ + public static final int LIBRARY_NULL = 4; +/** + * Global identifier for the sound library does not exist. + */ + public static final int LIBRARY_TYPE = 5; + +/** + * Holds a global identifier indicating the type of exception. + */ + private int myType = UNKNOWN_ERROR; + +/** + * Constructor: Generic exception. Specify the error message. + */ + public SoundSystemException( String message ) + { + super( message ); + } + +/** + * Constructor: Specify the error message and type of exception. + * @param message Description of the problem. + * @param type Global identifier for type of exception. + */ + public SoundSystemException( String message, int type ) + { + super( message ); + myType = type; + } + + public int getType() + { + return myType; + } +} diff --git a/src/lwjgl/java/paulscode/sound/SoundSystemLogger.java b/src/lwjgl/java/paulscode/sound/SoundSystemLogger.java new file mode 100644 index 0000000..7230a13 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/SoundSystemLogger.java @@ -0,0 +1,173 @@ +package paulscode.sound; + +/** + * The SoundSystemLogger class handles all status messages, warnings, and error + * messages for the SoundSystem library. This class can be extended and + * methods overriden to change how messages are handled. To do this, the + * overridden class should be instantiated, and a call should be made to method + * SoundSystemConfig.setLogger() BEFORE creating the SoundSystem object. If + * the setLogger() method is called after the SoundSystem has been created, + * there will be handles floating around to two different message loggers, and + * the results will be undesirable. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about changing default settings. If an alternate logger is not + * set by the user, then an instance of this base class will be automatically + * created by default when the SoundSystem class is instantiated. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class SoundSystemLogger +{ +/** + * Prints a message. + * @param message Message to print. + * @param indent Number of tabs to indent the message. + */ + public void message( String message, int indent ) + { + String messageText; + // Determine how many spaces to indent: + String spacer = ""; + for( int x = 0; x < indent; x++ ) + { + spacer += " "; + } + // indent the message: + messageText = spacer + message; + + // Print the message: + System.out.println( messageText ); + } + +/** + * Prints an important message. + * @param message Message to print. + * @param indent Number of tabs to indent the message. + */ + public void importantMessage( String message, int indent ) + { + String messageText; + // Determine how many spaces to indent: + String spacer = ""; + for( int x = 0; x < indent; x++ ) + { + spacer += " "; + } + // indent the message: + messageText = spacer + message; + + // Print the message: + System.out.println( messageText ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param classname Name of the class checking for an error. + * @param message Message to print if error is true. + * @param indent Number of tabs to indent the message. + * @return True if error is true. + */ + public boolean errorCheck( boolean error, String classname, String message, + int indent ) + { + if( error ) + errorMessage( classname, message, indent ); + return error; + } + +/** + * Prints the classname which generated the error, followed by the error + * message. + * @param classname Name of the class which generated the error. + * @param message The actual error message. + * @param indent Number of tabs to indent the message. +*/ + public void errorMessage( String classname, String message, int indent ) + { + String headerLine, messageText; + // Determine how many spaces to indent: + String spacer = ""; + for( int x = 0; x < indent; x++ ) + { + spacer += " "; + } + // indent the header: + headerLine = spacer + "Error in class '" + classname + "'"; + // indent the message one more than the header: + messageText = " " + spacer + message; + + // Print the error message: + System.out.println( headerLine ); + System.out.println( messageText ); + } + +/** + * Prints an exception's error message followed by the stack trace. + * @param e Exception containing the information to print. + * @param indent Number of tabs to indent the message and stack trace. + */ + public void printStackTrace( Exception e, int indent ) + { + printExceptionMessage( e, indent ); + importantMessage( "STACK TRACE:", indent ); + if( e == null ) + return; + + StackTraceElement[] stack = e.getStackTrace(); + if( stack == null ) + return; + + StackTraceElement line; + for( int x = 0; x < stack.length; x++ ) + { + line = stack[x]; + if( line != null ) + message( line.toString(), indent + 1 ); + } + } + +/** + * Prints an exception's error message. + * @param e Exception containing the message to print. + * @param indent Number of tabs to indent the message. + */ + public void printExceptionMessage( Exception e, int indent ) + { + importantMessage( "ERROR MESSAGE:", indent ); + if( e.getMessage() == null ) + message( "(none)", indent + 1 ); + else + message( e.getMessage(), indent + 1 ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/Source.java b/src/lwjgl/java/paulscode/sound/Source.java new file mode 100644 index 0000000..00c0a0a --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/Source.java @@ -0,0 +1,1344 @@ +package paulscode.sound; + +import java.net.URL; +import java.util.LinkedList; +import java.util.ListIterator; +import javax.sound.sampled.AudioFormat; + +/** + * The Source class is used to store information about a source. + * Source objects are stored in a map in the Library class. The + * information they contain is used to create library-specific sources. + * This is the template class which is extended for each specific library. + * This class is also used by the "No Sound" library to represent a mute + * source. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class Source +{ +/** + * The library class associated with this type of channel. + */ + protected Class libraryType = Library.class; + +/** + * Used to return a current value from one of the synchronized + * boolean-interface methods. + */ + private static final boolean GET = false; + +/** + * Used to set the value in one of the synchronized boolean-interface methods. + */ + private static final boolean SET = true; + +/** + * Used when a parameter for one of the synchronized boolean-interface methods + * is not aplicable. + */ + private static final boolean XXX = false; + +/** + * Processes status messages, warnings, and error messages. + */ + private SoundSystemLogger logger; + +/** + * True if this source is being directly fed with raw audio data. + */ + public boolean rawDataStream = false; + +/** + * Format the raw data will be in if this is a Raw Data Stream source. + */ + public AudioFormat rawDataFormat = null; + +/** + * Determines whether a source should be removed after it finishes playing. + */ + public boolean temporary = false; + +/** + * Determines whether or not this is a priority source. Priority sources will + * not be overwritten by other sources when there are no available channels. + */ + public boolean priority = false; + +/** + * Whether or not this source should be streamed. + */ + public boolean toStream = false; + +/** + * Whether this source should loop or only play once. + */ + public boolean toLoop = false; + +/** + * Whether this source needs to be played (for example if it was playing and + * looping when it got culled). + */ + public boolean toPlay = false; + +/** + * Unique name for this source. More than one source can not have the same + * sourcename. + */ + public String sourcename = ""; + +/** + * The audio file which this source should play. + */ + public FilenameURL filenameURL = null; + +/** + * This source's position in 3D space. + */ + public Vector3D position; + +/** + * Attenuation model to use for this source. + */ + public int attModel = 0; + +/** + * Either fade distance or rolloff factor, depending on the value of attModel. + */ + public float distOrRoll = 0.0f; + +/** + * Source's velocity in world-space, for use in Doppler effect. + */ + public Vector3D velocity; + +/** + * This source's volume (a float between 0.0 - 1.0). This value is used + * internally for attenuation, and should not be used to manually change a + * source's volume. + */ + public float gain = 1.0f; + +/** + * This value should be used to manually increase or decrease source volume. + */ + public float sourceVolume = 1.0f; + + /** + * Indicates to the streaming thread that this source is removed and needs cleanup. + * @see https://github.com/MinecraftForge/MinecraftForge/pull/4765 + */ + public boolean removed = false; + +/** + * This value represents the source's pitch (float value between 0.5f - 2.0f). + */ + protected float pitch = 1.0f; + +/** + * This source's distance from the listener. + */ + public float distanceFromListener = 0.0f; + +/** + * Channel to play this source on. + */ + public Channel channel = null; + +/** + * Holds the data used by normal sources. + */ + public SoundBuffer soundBuffer = null; + +/** + * False when this source gets culled. + */ + private boolean active = true; + +/** + * Whether or not this source has been stopped. + */ + private boolean stopped = true; + +/** + * Whether or not this source has been paused. + */ + private boolean paused = false; + +/** + * Codec used to read data for streaming sources. + */ + protected ICodec codec = null; + +/** + * Codec used to read in some initial data from the next sound in the queue. + */ + protected ICodec nextCodec = null; + +/** + * List of buffers to hold some initial data from the next sound in the queue. + */ + protected LinkedList nextBuffers = null; + + +/** + * The list of files to stream when the current stream finishes. + */ + protected LinkedList soundSequenceQueue = null; + +/** + * Ensures that only one thread accesses the soundSequenceQueue at a time. + */ + protected final Object soundSequenceLock = new Object(); + +/** + * Used by streaming sources to indicate whether or not the initial + * stream-buffers still need to be queued. + */ + public boolean preLoad = false; + +/** + * Specifies the gain factor used for the fade-out effect, or -1 when + * source is not currently fading out. + */ + protected float fadeOutGain = -1.0f; + +/** + * Specifies the gain factor used for the fade-in effect, or 1 when + * source is not currently fading in. + */ + protected float fadeInGain = 1.0f; + +/** + * Specifies the number of miliseconds it should take to fade out. + */ + protected long fadeOutMilis = 0; + +/** + * Specifies the number of miliseconds it should take to fade in. + */ + protected long fadeInMilis = 0; + +/** + * System time in miliseconds when the last fade in/out volume check occurred. + */ + protected long lastFadeCheck = 0; + +/** + * Constructor: Creates a new source using the specified parameters. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will create a streaming source. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL The filename/URL of the sound file to play at this source. + * @param soundBuffer Buffer containing audio data, or null if not loaded yet. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of 'att'. + * @param temporary Whether or not to remove this source after it finishes playing. + */ + public Source( boolean priority, boolean toStream, boolean toLoop, + String sourcename, FilenameURL filenameURL, + SoundBuffer soundBuffer, float x, float y, float z, + int attModel, float distOrRoll, boolean temporary ) + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + this.priority = priority; + this.toStream = toStream; + this.toLoop = toLoop; + this.sourcename = sourcename; + this.filenameURL = filenameURL; + this.soundBuffer = soundBuffer; + position = new Vector3D( x, y, z ); + this.attModel = attModel; + this.distOrRoll = distOrRoll; + this.velocity = new Vector3D( 0, 0, 0 ); + this.temporary = temporary; + + if( toStream && filenameURL != null ) + codec = SoundSystemConfig.getCodec( filenameURL.getFilename() ); + } + +/** + * Constructor: Creates a new source matching the specified one. + * @param old Source to copy information from. + * @param soundBuffer Buffer containing audio data, or null if not loaded yet. + */ + public Source( Source old, SoundBuffer soundBuffer ) + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + priority = old.priority; + toStream = old.toStream; + toLoop = old.toLoop; + sourcename = old.sourcename; + filenameURL = old.filenameURL; + position = old.position.clone(); + attModel = old.attModel; + distOrRoll = old.distOrRoll; + velocity = old.velocity.clone(); + temporary = old.temporary; + + sourceVolume = old.sourceVolume; + + rawDataStream = old.rawDataStream; + rawDataFormat = old.rawDataFormat; + + this.soundBuffer = soundBuffer; + + if( toStream && filenameURL != null ) + codec = SoundSystemConfig.getCodec( filenameURL.getFilename() ); + } + +/** + * Constructor: Creates a new streaming source that will be directly fed with + * raw audio data. + * @param audioFormat Format that the data will be in. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of 'att'. + */ + public Source( AudioFormat audioFormat, boolean priority, String sourcename, + float x, float y, float z, int attModel, float distOrRoll ) + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + this.priority = priority; + this.toStream = true; + this.toLoop = false; + this.sourcename = sourcename; + this.filenameURL = null; + this.soundBuffer = null; + position = new Vector3D( x, y, z ); + this.attModel = attModel; + this.distOrRoll = distOrRoll; + this.velocity = new Vector3D( 0, 0, 0 ); + this.temporary = false; + + rawDataStream = true; + rawDataFormat = audioFormat; + } +/* Override methods */ + +/** + * Shuts the source down and removes references to all instantiated objects. + */ + public void cleanup() + { + if( codec != null ) + codec.cleanup(); + + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue != null ) + soundSequenceQueue.clear(); + soundSequenceQueue = null; + } + + sourcename = null; + filenameURL = null; + position = null; + soundBuffer = null; + codec = null; + } + +/** + * If this is a streaming source, queues up the next sound to play when + * the previous stream ends. This method has no effect on non-streaming + * sources. + * @param filenameURL The filename/URL of the sound file to stream next. + */ + public void queueSound( FilenameURL filenameURL ) + { + if( !toStream ) + { + errorMessage( "Method 'queueSound' may only be used for " + + "streaming and MIDI sources." ); + return; + } + if( filenameURL == null ) + { + errorMessage( "File not specified in method 'queueSound'" ); + return; + } + + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue == null ) + soundSequenceQueue = new LinkedList(); + soundSequenceQueue.add( filenameURL ); + } + } + +/** + * Removes the first occurrence of the specified filename from the list of + * sounds to play when the previous stream ends. This method has no effect + * on non-streaming sources. + * @param filename Filename/identifier of a sound file to remove from the queue. + */ + public void dequeueSound( String filename ) + { + if( !toStream ) + { + errorMessage( "Method 'dequeueSound' may only be used for " + + "streaming and MIDI sources." ); + return; + } + if( filename == null || filename.equals( "" ) ) + { + errorMessage( "Filename not specified in method 'dequeueSound'" ); + return; + } + + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue != null ) + { + ListIterator i = soundSequenceQueue.listIterator(); + while( i.hasNext() ) + { + if( i.next().getFilename().equals( filename ) ) + { + i.remove(); + break; + } + } + } + } + } + +/** + * Fades out the volume of whatever this source is currently playing, then + * begins playing the specified filename at the source's previously assigned + * volume level. If the filename parameter is null or empty, the source will + * simply fade out and stop. The miliseconds parameter must be non-negative or + * zero. This method will remove anything that is currently in the list of + * queued sounds that would have played next when the current sound finished + * playing. This method has no effect on non-streaming sources. + * @param filenameURL Filename/URL of the sound file to play next, or null for none. + * @param milis Number of miliseconds the fadeout should take. + */ + public void fadeOut( FilenameURL filenameURL, long milis ) + { + if( !toStream ) + { + errorMessage( "Method 'fadeOut' may only be used for " + + "streaming and MIDI sources." ); + return; + } + if( milis < 0 ) + { + errorMessage( "Miliseconds may not be negative in method " + + "'fadeOut'." ); + return; + } + + fadeOutMilis = milis; + fadeInMilis = 0; + fadeOutGain = 1.0f; + lastFadeCheck = System.currentTimeMillis(); + + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue != null ) + soundSequenceQueue.clear(); + + if( filenameURL != null ) + { + if( soundSequenceQueue == null ) + soundSequenceQueue = new LinkedList(); + soundSequenceQueue.add( filenameURL ); + } + } + } + +/** + * Fades out the volume of whatever this source is currently playing, then + * fades the volume back in playing the specified file. Final volume after + * fade-in completes will be equal to the source's previously assigned volume + * level. The filenameURL parameter may not be null or empty. The miliseconds + * parameters must be non-negative or zero. This method will remove anything + * that is currently in the list of queued sounds that would have played next + * when the current sound finished playing. This method has no effect on + * non-streaming sources. + * @param filenameURL Filename/URL of the sound file to play next, or null for none. + * @param milisOut Number of miliseconds the fadeout should take. + * @param milisIn Number of miliseconds the fadein should take. + */ + public void fadeOutIn( FilenameURL filenameURL, long milisOut, long milisIn ) + { + if( !toStream ) + { + errorMessage( "Method 'fadeOutIn' may only be used for " + + "streaming and MIDI sources." ); + return; + } + if( filenameURL == null ) + { + errorMessage( "Filename/URL not specified in method 'fadeOutIn'." ); + return; + } + if( milisOut < 0 || milisIn < 0 ) + { + errorMessage( "Miliseconds may not be negative in method " + + "'fadeOutIn'." ); + return; + } + + fadeOutMilis = milisOut; + fadeInMilis = milisIn; + + fadeOutGain = 1.0f; + lastFadeCheck = System.currentTimeMillis(); + + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue == null ) + soundSequenceQueue = new LinkedList(); + soundSequenceQueue.clear(); + soundSequenceQueue.add( filenameURL ); + } + } + +/** + * Resets this source's volume if it is fading out or in. Returns true if this + * source is currently in the process of fading out. When fade-out completes, + * this method transitions the source to the next sound in the sound sequence + * queue if there is one. This method has no effect on non-streaming sources. + * @return True if this source is in the process of fading out. + */ + public boolean checkFadeOut() + { + if( !toStream ) + return false; + + if( fadeOutGain == -1.0f && fadeInGain == 1.0f ) + return false; + + long currentTime = System.currentTimeMillis(); + long milisPast = currentTime - lastFadeCheck; + lastFadeCheck = currentTime; + + if( fadeOutGain >= 0.0f ) + { + if( fadeOutMilis == 0 ) + { + fadeOutGain = -1.0f; + fadeInGain = 0.0f; + if( !incrementSoundSequence() ) + { + stop(); + } + positionChanged(); + preLoad = true; + return false; + } + else + { + float fadeOutReduction = ((float)milisPast) / ((float)fadeOutMilis); + fadeOutGain -= fadeOutReduction; + if( fadeOutGain <= 0.0f ) + { + fadeOutGain = -1.0f; + fadeInGain = 0.0f; + if( !incrementSoundSequence() ) + stop(); + positionChanged(); + preLoad = true; + return false; + } + } + positionChanged(); + return true; + } + + if( fadeInGain < 1.0f ) + { + fadeOutGain = -1.0f; + if( fadeInMilis == 0 ) + { + fadeOutGain = -1.0f; + fadeInGain = 1.0f; + } + else + { + float fadeInIncrease = ((float)milisPast) / ((float)fadeInMilis); + fadeInGain += fadeInIncrease; + if( fadeInGain >= 1.0f ) + { + fadeOutGain = -1.0f; + fadeInGain = 1.0f; + } + } + positionChanged(); + return true; + } + return false; + } + +/** + * Removes the next filename/URL from the sound sequence queue and assigns it to + * this source. This method has no effect on non-streaming sources. This + * method is used internally by SoundSystem, and it is unlikely that the user + * will ever need to use it. + * @return True if there was something in the queue. + */ + public boolean incrementSoundSequence() + { + if( !toStream ) + { + errorMessage( "Method 'incrementSoundSequence' may only be used " + + "for streaming and MIDI sources." ); + return false; + } + + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue != null && soundSequenceQueue.size() > 0 ) + { + filenameURL = soundSequenceQueue.remove( 0 ); + if( codec != null ) + codec.cleanup(); + codec = SoundSystemConfig.getCodec( filenameURL.getFilename() ); + return true; + } + } + return false; + } + +/** + * Reads in initial buffers of data from the next sound in the sound sequence + * queue, to reduce lag when the transition occurrs. This method has no effect + * on non-streaming sources. This method is used internally by SoundSystem, and + * it is unlikely that the user will ever need to use it. + * @return False if there is nothing in the queue to read from. + */ + public boolean readBuffersFromNextSoundInSequence() + { + if( !toStream ) + { + errorMessage( "Method 'readBuffersFromNextSoundInSequence' may " + + "only be used for streaming sources." ); + return false; + } + + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue != null && soundSequenceQueue.size() > 0 ) + { + if( nextCodec != null ) + nextCodec.cleanup(); + nextCodec = SoundSystemConfig.getCodec( + soundSequenceQueue.get( 0 ).getFilename() ); + nextCodec.initialize( soundSequenceQueue.get( 0 ).getURL() ); + + SoundBuffer buffer = null; + for( int i = 0; + i < SoundSystemConfig.getNumberStreamingBuffers() + && !nextCodec.endOfStream(); + i++ ) + { + buffer = nextCodec.read(); + if( buffer != null ) + { + if( nextBuffers == null ) + nextBuffers = new LinkedList(); + nextBuffers.add( buffer ); + } + } + return true; + } + } + return false; + } + + +/** + * Returns the size of the sound sequence queue (if this is a streaming source). + * @return Number of sounds left in the queue, or zero if none. + */ + public int getSoundSequenceQueueSize() + { + if( soundSequenceQueue == null ) + return 0; + return soundSequenceQueue.size(); + } + +/** + * Sets whether or not this source should be removed when it finishes playing. + * @param tmp True or false. + */ + public void setTemporary( boolean tmp ) + { + temporary = tmp; + } + +/** + * Called every time the listener's position or orientation changes. + */ + public void listenerMoved() + {} + +/** + * Moves the source to the specified position. + * @param x X coordinate to move to. + * @param y Y coordinate to move to. + * @param z Z coordinate to move to. + */ + public void setPosition( float x, float y, float z ) + { + position.x = x; + position.y = y; + position.z = z; + } + +/** + * Called every time the source changes position. + */ + public void positionChanged() + {} + +/** + * Sets whether or not this source is a priority source. A priority source + * will not be overritten by another source if there are no channels available + * to play on. + * @param pri True or false. + */ + public void setPriority( boolean pri ) + { + priority = pri; + } + +/** + * Sets whether this source should loop or only play once. + * @param lp True or false. + */ + public void setLooping( boolean lp ) + { + toLoop = lp; + } + +/** + * Sets this source's attenuation model. + * @param model Attenuation model to use. + */ + public void setAttenuation( int model ) + { + attModel = model; + } + +/** + * Sets this source's fade distance or rolloff factor, depending on the + * attenuation model. + * @param dr New value for fade distance or rolloff factor. + */ + public void setDistOrRoll( float dr) + { + distOrRoll = dr; + } + +/** + * Sets this source's velocity, for use in Doppler effect. + * @param x Velocity along world x-axis. + * @param y Velocity along world y-axis. + * @param z Velocity along world z-axis. + */ + public void setVelocity( float x, float y, float z ) + { + this.velocity.x = x; + this.velocity.y = y; + this.velocity.z = z; + } + +/** + * Returns the source's distance from the listener. + * @return How far away the source is. + */ + public float getDistanceFromListener() + { + return distanceFromListener; + } + +/** + * Manually sets the specified source's pitch. + * @param value A float value ( 0.5f - 2.0f ). + */ + public void setPitch( float value ) + { + float newPitch = value; + if( newPitch < 0.5f ) + newPitch = 0.5f; + else if( newPitch > 2.0f ) + newPitch = 2.0f; + pitch = newPitch; + } + +/** + * Returns the pitch of the specified source. + * @return Float value representing the source pitch (0.5f - 2.0f). + */ + public float getPitch() + { + return pitch; + } + +/** + * Indicates whether or not this source's associated library requires some + * codecs to reverse-order the audio data they generate. + * @return True if audio data should be reverse-ordered. + */ + public boolean reverseByteOrder() + { + return SoundSystemConfig.reverseByteOrder( libraryType ); + } + +/** + * Changes the sources peripheral information to match the supplied parameters. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will create a streaming source. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of 'att'. + * @param temporary Whether or not to remove this source after it finishes playing. + */ + public void changeSource( boolean priority, boolean toStream, + boolean toLoop, String sourcename, + FilenameURL filenameURL, SoundBuffer soundBuffer, + float x, float y, float z, int attModel, + float distOrRoll, boolean temporary ) + { + this.priority = priority; + this.toStream = toStream; + this.toLoop = toLoop; + this.sourcename = sourcename; + this.filenameURL = filenameURL; + this.soundBuffer = soundBuffer; + position.x = x; + position.y = y; + position.z = z; + this.attModel = attModel; + this.distOrRoll = distOrRoll; + this.temporary = temporary; + } + +/** + * Feeds raw data to the specified channel. + * @param buffer Byte buffer containing raw audio data to stream. + * @param c Channel to stream on. + * @return Number of prior buffers that have been processed, or -1 if unable to queue the buffer (if the source was culled, for example). + */ + public int feedRawAudioData( Channel c, byte[] buffer ) + { + if( !active( GET, XXX) ) + { + toPlay = true; + return -1; + } + if( channel != c ) + { + channel = c; + channel.close(); + channel.setAudioFormat( rawDataFormat ); + positionChanged(); + } + + // change the state of this source to not stopped and not paused: + stopped( SET, false ); + paused( SET, false ); + + return channel.feedRawAudioData( buffer ); + } + +/** + * Plays the source on the specified channel. + * @param c Channel to play on. + */ + public void play( Channel c ) + { + if( !active( GET, XXX) ) + { + if( toLoop ) + toPlay = true; + return; + } + if( channel != c ) + { + channel = c; + channel.close(); + } + // change the state of this source to not stopped and not paused: + stopped( SET, false ); + paused( SET, false ); + } +/* END Override methods */ + +/** + * Streams the source on its current channel + * @return False when stream has finished playing. + */ + public boolean stream() + { + if( channel == null ) + return false; + + if( preLoad ) + { + if( rawDataStream ) + preLoad = false; + else + return preLoad(); + } + + if( rawDataStream ) + { + if( stopped() || paused() ) + return true; + if( channel.buffersProcessed() > 0 ) + channel.processBuffer(); + return true; + } + else + { + if( codec == null ) + return false; + if( stopped() ) + return false; + if( paused() ) + return true; + + int processed = channel.buffersProcessed(); + + SoundBuffer buffer = null; + for( int i = 0; i < processed; i++ ) + { + buffer = codec.read(); + if( buffer != null ) + { + if( buffer.audioData != null ) + channel.queueBuffer( buffer.audioData ); + buffer.cleanup(); + buffer = null; + return true; + } + else if( codec.endOfStream() ) + { + synchronized( soundSequenceLock ) + { + if( SoundSystemConfig.getStreamQueueFormatsMatch() ) + { + if( soundSequenceQueue != null && + soundSequenceQueue.size() > 0 ) + { + if( codec != null ) + codec.cleanup(); + filenameURL = soundSequenceQueue.remove( 0 ); + codec = SoundSystemConfig.getCodec( + filenameURL.getFilename() ); + codec.initialize( filenameURL.getURL() ); + buffer = codec.read(); + if( buffer != null ) + { + if( buffer.audioData != null ) + channel.queueBuffer( buffer.audioData ); + buffer.cleanup(); + buffer = null; + return true; + } + } + else if( toLoop ) + { + codec.initialize( filenameURL.getURL() ); + buffer = codec.read(); + if( buffer != null ) + { + if( buffer.audioData != null ) + channel.queueBuffer( buffer.audioData ); + buffer.cleanup(); + buffer = null; + return true; + } + } + } + } + } +/* + if( codec.endOfStream() ) + { + synchronized( soundSequenceLock ) + { + if( SoundSystemConfig.getStreamQueueFormatsMatch() ) + { + if( soundSequenceQueue != null && + soundSequenceQueue.size() > 0 ) + { + if( codec != null ) + codec.cleanup(); + filenameURL = soundSequenceQueue.remove( 0 ); + codec = SoundSystemConfig.getCodec( + filenameURL.getFilename() ); + codec.initialize( filenameURL.getURL() ); + return true; + } + else if( toLoop ) + { + codec.initialize( filenameURL.getURL() ); + buffer = codec.read(); + if( buffer != null ) + { + if( buffer.audioData != null ) + channel.queueBuffer( buffer.audioData ); + buffer.cleanup(); + buffer = null; + } + } + } + } + return false; + } +*/ + } + } + return false; + } + +/** + * Queues up the initial stream-buffers for the stream. + * @return False if the end of the stream was reached. + */ + public boolean preLoad() + { + if( channel == null ) + return false; + + if( codec == null ) + return false; + + SoundBuffer buffer = null; + + boolean noNextBuffers = false; + synchronized( soundSequenceLock ) + { + if( nextBuffers == null || nextBuffers.isEmpty() ) + noNextBuffers = true; + } + + if( nextCodec != null && !noNextBuffers ) + { + codec = nextCodec; + nextCodec = null; + synchronized( soundSequenceLock ) + { + while( !nextBuffers.isEmpty() ) + { + buffer = nextBuffers.remove( 0 ); + if( buffer != null ) + { + if( buffer.audioData != null ) + channel.queueBuffer( buffer.audioData ); + buffer.cleanup(); + buffer = null; + } + } + } + } + else + { + nextCodec = null; + URL url = filenameURL.getURL(); + + codec.initialize( url ); + for( int i = 0; i < SoundSystemConfig.getNumberStreamingBuffers(); + i++ ) + { + buffer = codec.read(); + if( buffer != null ) + { + if( buffer.audioData != null ) + channel.queueBuffer( buffer.audioData ); + buffer.cleanup(); + buffer = null; + } + } + } + + return true; + } + +/** + * Pauses the source. + */ + public void pause() + { + toPlay = false; + paused( SET, true ); + if( channel != null ) + channel.pause(); + else + errorMessage( "Channel null in method 'pause'" ); + } + +/** + * Stops the source. + */ + public void stop() + { + toPlay = false; + stopped( SET, true ); + paused( SET, false ); + if( channel != null ) + channel.stop(); + else + errorMessage( "Channel null in method 'stop'" ); + } + +/** + * Rewinds the source. If the source was paused, then it is stopped. + */ + public void rewind() + { + if( paused( GET, XXX ) ) + { + stop(); + } + if( channel != null ) + { + boolean rePlay = playing(); + channel.rewind(); + if( toStream && rePlay ) + { + stop(); + play( channel ); + } + } + else + errorMessage( "Channel null in method 'rewind'" ); + } + +/** + * Dequeues any previously queued data. + */ + public void flush() + { + if( channel != null ) + channel.flush(); + else + errorMessage( "Channel null in method 'flush'" ); + } + +/** + * Stops and flushes the source, and prevents it from being played again until + * the activate() is called. + */ + public void cull() + { + if( !active( GET, XXX ) ) + return; + if( playing() && toLoop ) + toPlay = true; + if( rawDataStream ) + toPlay = true; + active( SET, false ); + if( channel != null ) + channel.close(); + channel = null; + } + +/** + * Allows a previously culled source to be played again. + */ + public void activate() + { + active( SET, true ); + } + +/** + * Returns false if the source has been culled. + * @return True or False + */ + public boolean active() + { + return active( GET, XXX ); + } + +/** + * Returns true if the source is playing. + * @return True or False + */ + public boolean playing() + { + if( channel == null || channel.attachedSource != this ) + return false; + else if( paused() || stopped() ) + return false; + else + return channel.playing(); + } + +/** + * Returns true if the source has been stopped. + * @return True or False + */ + public boolean stopped() + { + return stopped( GET, XXX ); + } + +/** + * Returns true if the source has been paused. + * @return True or False + */ + public boolean paused() + { + return paused( GET, XXX ); + } + +/** + * Returns the number of miliseconds since the source began playing. + * @return miliseconds, or -1 if not playing or unable to calculate + */ + public float millisecondsPlayed() + { + if( channel == null ) + return( -1 ); + else + return channel.millisecondsPlayed(); + } + +/** + * Sets or returns whether or not the source has been culled. + * @return True or False + */ + private synchronized boolean active( boolean action, boolean value ) + { + if( action == SET ) + active = value; + return active; + } + +/** + * Sets or returns whether or not the source has been stopped. + * @return True or False + */ + private synchronized boolean stopped( boolean action, boolean value ) + { + if( action == SET ) + stopped = value; + return stopped; + } + +/** + * Sets or returns whether or not the source has been paused. + * @return True or False + */ + private synchronized boolean paused( boolean action, boolean value ) + { + if( action == SET ) + paused = value; + return paused; + } + +/** + * Returns the name of the class. + * @return SoundLibraryXXXX. + */ + public String getClassName() + { + String libTitle = SoundSystemConfig.getLibraryTitle( libraryType ); + + if( libTitle.equals( "No Sound" ) ) + return "Source"; + else + return "Source" + libTitle; + } +/** + * Prints a message. + * @param message Message to print. + */ + protected void message( String message ) + { + logger.message( message, 0 ); + } + +/** + * Prints an important message. + * @param message Message to print. + */ + protected void importantMessage( String message ) + { + logger.importantMessage( message, 0 ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param message Message to print if error is true. + * @return True if error is true. + */ + protected boolean errorCheck( boolean error, String message ) + { + return logger.errorCheck( error, getClassName(), message, 0 ); + } + +/** + * Prints an error message. + * @param message Message to print. + */ + protected void errorMessage( String message ) + { + logger.errorMessage( getClassName(), message, 0 ); + } + +/** + * Prints an exception's error message followed by the stack trace. + * @param e Exception containing the information to print. + */ + protected void printStackTrace( Exception e ) + { + logger.printStackTrace( e, 1 ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/StreamThread.java b/src/lwjgl/java/paulscode/sound/StreamThread.java new file mode 100644 index 0000000..ab237be --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/StreamThread.java @@ -0,0 +1,303 @@ +package paulscode.sound; + +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; + +/** + * The StreamThread class is used to process all streaming sources. This + * thread starts out asleep, and it sleeps when all streaming sources are + * finished playing, so it is necessary to call interrupt() after adding new + * streaming sources to the list. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ * + */ +public class StreamThread extends SimpleThread +{ +/** + * Processes status messages, warnings, and error messages. + */ + private SoundSystemLogger logger; + +/** + * List of sources that are currently streaming. + */ + private List streamingSources; + +/** + * Used to synchronize access to the streaming sources list. + */ + private final Object listLock = new Object(); + +/** + * Constructor: Grabs a handle to the message logger and instantiates the + * streaming sources list. + */ + public StreamThread() + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + streamingSources = new LinkedList(); + } + +/** + * Removes all references to instantiated objects, and changes the thread's + * state to "not alive". Method alive() returns false when the cleanup() + * method has completed. + */ + @Override + protected void cleanup() + { + kill(); + super.cleanup(); // Important!! + } + +/** + * The main loop for processing commands. The thread sleeps when it finishes + * processing commands, and it must be interrupted to process more. + */ + @Override + public void run() + { + ListIterator iter; + Source src; + + // Start out asleep: + snooze( 3600000 ); + + while( !dying() ) + { + while( !dying() && !streamingSources.isEmpty() ) + { + // Make sure noone else is accessing the list of sources: + synchronized( listLock ) + { + iter = streamingSources.listIterator(); + while( !dying() && iter.hasNext() ) + { + src = iter.next(); + // If this is a removed source, we cleanup here and then let normal cleanup run - https://github.com/MinecraftForge/MinecraftForge/pull/4765 + if (src!=null && src.removed) + { + src.cleanup(); + src = null; + } + if( src == null ) + { + iter.remove(); + } + else if( src.stopped() ) + { + if( !src.rawDataStream ) + iter.remove(); + } + else if( !src.active() ) + { + if( src.toLoop || src.rawDataStream ) + src.toPlay = true; + iter.remove(); + } + else if( !src.paused() ) + { + src.checkFadeOut(); + if( (!src.stream()) && (!src.rawDataStream) ) + { + if( src.channel == null + || !src.channel.processBuffer() ) + { + if( src.nextCodec == null ) + { + src.readBuffersFromNextSoundInSequence(); + } +/* + if( src.getSoundSequenceQueueSize() > 0 ) + { + src.incrementSoundSequence(); + } + + // check if this is a looping source + else*/ if( src.toLoop ) + { + // wait for stream to finish playing + if( !src.playing() ) + { + // Generate an EOS event: + SoundSystemConfig.notifyEOS( + src.sourcename, + src.getSoundSequenceQueueSize() + ); + // Check if the source is currently + // in the process of fading out. + if( src.checkFadeOut() ) + { + // Source is fading out. + // Keep looping until it + // finishes. + src.preLoad = true; + } + else + { + // Source is not fading out. + // If there is another sound in + // the sequence, switch to it + // before replaying. + src.incrementSoundSequence(); + src.preLoad = true; // replay + } + } + } + else + { + // wait for stream to finish playing + if( !src.playing() ) + { + // Generate an EOS event: + SoundSystemConfig.notifyEOS( + src.sourcename, + src.getSoundSequenceQueueSize() + ); + // Check if the source is currently + // in the process of fading out + if( !src.checkFadeOut() ) + { + // Source is not fading out. + // Play anything else that is + // in the sound sequence queue. + if( + src.incrementSoundSequence() ) + src.preLoad = true; + else + iter.remove(); // finished + } + } + } + } + } + } + } + } + if( !dying() && !streamingSources.isEmpty() ) + snooze( 20 ); // sleep a bit so we don't peg the cpu + } + if( !dying() && streamingSources.isEmpty() ) + snooze( 3600000 ); // sleep until there is more to do. + } + + cleanup(); // Important!! + } + +/** + * Adds a new streaming source to the list. If another source in the list is + * already playing on the same channel, it is stopped and removed from the + * list. + * @param source New source to stream. + */ + public void watch( Source source ) + { + // make sure the source exists: + if( source == null ) + return; + + // make sure we aren't already watching this source: + if( streamingSources.contains( source ) ) + return; + + ListIterator iter; + Source src; + + // Make sure noone else is accessing the list of sources: + synchronized( listLock ) + { + // Any currently watched source which is null or playing on the + // same channel as the new source should be stopped and removed + // from the list. + iter = streamingSources.listIterator(); + while( iter.hasNext() ) + { + src = iter.next(); + if( src == null ) + { + iter.remove(); + } + else if( source.channel == src.channel ) + { + src.stop(); + iter.remove(); + } + } + + // Add the new source to the list: + streamingSources.add( source ); + } + } + +/** + * Prints a message. + * @param message Message to print. + */ + private void message( String message ) + { + logger.message( message, 0 ); + } + +/** + * Prints an important message. + * @param message Message to print. + */ + private void importantMessage( String message ) + { + logger.importantMessage( message, 0 ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param message Message to print if error is true. + * @return True if error is true. + */ + private boolean errorCheck( boolean error, String message ) + { + return logger.errorCheck( error, "StreamThread", message, 0 ); + } + +/** + * Prints an error message. + * @param message Message to print. + */ + private void errorMessage( String message ) + { + logger.errorMessage( "StreamThread", message, 0 ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/Vector3D.java b/src/lwjgl/java/paulscode/sound/Vector3D.java new file mode 100644 index 0000000..5c38676 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/Vector3D.java @@ -0,0 +1,210 @@ +package paulscode.sound; + +/** + * The Vector3D class contains methods to simplify common 3D vector functions, + * such as cross and dot product, normalize, etc. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class Vector3D +{ + +/** + * The vector's X coordinate. + */ + public float x; + +/** + * The vector's Y coordinate. + */ + public float y; + +/** + * The vector's Z coordinate. + */ + public float z; + +/** + * Constructor: Places the vector at the origin. + */ + public Vector3D() + { + x = 0.0f; + y = 0.0f; + z = 0.0f; + } + +/** + * Constructor: Places the vector at the specified 3D coordinates. + * @param nx X coordinate for the new vector. + * @param ny Y coordinate for the new vector. + * @param nz Z coordinate for the new vector. + */ + public Vector3D( float nx, float ny, float nz ) + { + x = nx; + y = ny; + z = nz; + } + +/** + * Returns a new instance containing the same information as this one. + * @return A new Vector3D. + */ + @Override + public Vector3D clone() + { + return new Vector3D( x, y, z ); + } + +/** + * Returns a vector containing the cross-product: A cross B. + * @param A First vector in the cross product. + * @param B Second vector in the cross product. + * @return A new Vector3D. + */ + public Vector3D cross( Vector3D A, Vector3D B ) + { + return new Vector3D( + A.y * B.z - B.y * A.z, + A.z * B.x - B.z * A.x, + A.x * B.y - B.x * A.y ); + } + +/** + * Returns a vector containing the cross-product: (this) cross B. + * @param B Second vector in the cross product. + * @return A new Vector3D. + */ + public Vector3D cross( Vector3D B ) + { + return new Vector3D( + y * B.z - B.y * z, + z * B.x - B.z * x, + x * B.y - B.x * y ); + + } + +/** + * Returns the dot-product result of: A dot B. + * @param A First vector in the dot product. + * @param B Second vector in the dot product. + * @return Dot product. + */ + public float dot( Vector3D A, Vector3D B ) + { + return( (A.x * B.x) + (A.y * B.y) + (A.z * B.z) ); + } + +/** + * Returns the dot-product result of: (this) dot B. + * @param B Second vector in the dot product. + * @return Dot product. + */ + public float dot( Vector3D B ) + { + return( (x * B.x) + (y * B.y) + (z * B.z) ); + } + +/** + * Returns the vector represented by: A + B. + * @param A First vector. + * @param B Vector to add to A. + * @return A new Vector3D. + */ + public Vector3D add( Vector3D A, Vector3D B ) + { + return new Vector3D( A.x + B.x, A.y + B.y, A.z + B.z ); + } + +/** + * Returns the vector represented by: (this) + B. + * @param B Vector to add to this one. + * @return A new Vector3D. + */ + public Vector3D add( Vector3D B ) + { + return new Vector3D( x + B.x, y + B.y, z + B.z ); + } + +/** + * Returns the vector represented by: A - B. + * @param A First vector. + * @param B Vector to subtract from A. + * @return A new Vector3D. + */ + public Vector3D subtract( Vector3D A, Vector3D B ) + { + return new Vector3D( A.x - B.x, A.y - B.y, A.z - B.z ); + } + +/** + * Returns the vector represented by: (this) - B. + * @param B Vector to subtract from this one. + * @return A new Vector3D. + */ + public Vector3D subtract( Vector3D B ) + { + return new Vector3D( x - B.x, y - B.y, z - B.z ); + } + +/** + * Returns the length of this vector. + * @return Length. + */ + public float length() + { + return (float) Math.sqrt( x * x + y * y + z * z ); + } + +/** + * Changes the length of this vector to 1.0. + */ + public void normalize() + { + double t = Math.sqrt( x*x + y*y + z*z ); + x = (float) (x / t); + y = (float) (y / t); + z = (float) (z / t); + } + +/** + * Returns a string depicting this vector. + * @return "Vector3D (x, y, z)". + */ + @Override + public String toString() + { + return "Vector3D (" + x + ", " + y + ", " + z + ")"; + } +} diff --git a/src/lwjgl/java/paulscode/sound/libraries/ChannelLWJGLOpenAL.java b/src/lwjgl/java/paulscode/sound/libraries/ChannelLWJGLOpenAL.java new file mode 100644 index 0000000..637d146 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/libraries/ChannelLWJGLOpenAL.java @@ -0,0 +1,696 @@ +package paulscode.sound.libraries; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.util.LinkedList; +import javax.sound.sampled.AudioFormat; + +// From the lwjgl library, http://www.lwjgl.org +import org.lwjgl.BufferUtils; +import org.lwjgl.openal.AL10; +import org.lwjgl.openal.AL11; + +import paulscode.sound.Channel; +import paulscode.sound.SoundSystemConfig; + +/** + * The ChannelLWJGLOpenAL class is used to reserve a sound-card voice using the + * lwjgl binding of OpenAL. Channels can be either normal or streaming + * channels. + *

+ * This software is based on or using the LWJGL Lightweight Java Gaming + * Library available from + * http://www.lwjgl.org/. + *


+ * LWJGL License: + *
+ * Copyright (c) 2002-2008 Lightweight Java Game Library Project + * All rights reserved. + *
+ * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + *
+ * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + *
+ * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + *
+ * * Neither the name of 'Light Weight Java Game Library' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *


+ * SoundSystem LibraryLWJGLOpenAL License:

+ * + * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You must abide by the conditions of the aforementioned LWJGL License. + *
+ * 2) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 3) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 4) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 5) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 6) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 7) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class ChannelLWJGLOpenAL extends Channel +{ +/** + * OpenAL's IntBuffer identifier for this channel. + */ + public IntBuffer ALSource; + +/** + * OpenAL data format to use when playing back the assigned source. + */ + public int ALformat; // OpenAL data format + +/** + * Sample rate (speed) to use for play-back. + */ + public int sampleRate; // sample rate + +/** + * Miliseconds of buffers previously played (streaming sources). + */ + public float millisPreviouslyPlayed = 0; + +/** + * Constructor: takes channelType identifier and a handle to the OpenAL + * IntBuffer identifier to use for this channel. Possible values for channel + * type can be found in the + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} class. + * @param type Type of channel (normal or streaming). + * @param src Handle to the OpenAL source identifier. + */ + public ChannelLWJGLOpenAL( int type, IntBuffer src ) + { + super( type ); + libraryType = LibraryLWJGLOpenAL.class; + ALSource = src; + } + +/** + * Empties the streamBuffers list, stops and deletes the ALSource, shuts the + * channel down, and removes references to all instantiated objects. + */ + @Override + public void cleanup() + { + if( ALSource != null ) + { + try + { + // Stop playing the source: + AL10.alSourceStop( ALSource ); + AL10.alGetError(); + } + catch( Exception e ) + {} + try + { + // Delete the source: + AL10.alDeleteSources( ALSource ); + AL10.alGetError(); + } + catch( Exception e ) + {} + ALSource.clear(); + } + ALSource = null; + + super.cleanup(); + } + +/** + * Attaches an OpenAL sound-buffer identifier for the sound data to be played + * back for a normal source. + * @param buf Intbuffer identifier for the sound data to play. + * @return False if an error occurred. + */ + public boolean attachBuffer( IntBuffer buf ) + { + // A sound buffer can only be attached to a normal source: + if( errorCheck( channelType != SoundSystemConfig.TYPE_NORMAL, + "Sound buffers may only be attached to normal " + + "sources." ) ) + return false; + + // send the sound buffer to the channel: + AL10.alSourcei( ALSource.get( 0 ), AL10.AL_BUFFER, + buf.get(0) ); + + + // save the format for later, for determining milliseconds played + if( attachedSource != null && attachedSource.soundBuffer != null && + attachedSource.soundBuffer.audioFormat != null ) + setAudioFormat( attachedSource.soundBuffer.audioFormat ); + + // Check for errors and return: + return checkALError(); + } +/** + * Sets the channel up to receive the specified audio format. + * @param audioFormat Format to use when playing the stream data. + */ + @Override + public void setAudioFormat( AudioFormat audioFormat ) + { + int soundFormat = 0; + if( audioFormat.getChannels() == 1 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_MONO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_MONO16; + } + else + { + errorMessage( "Illegal sample size in method " + + "'setAudioFormat'" ); + return; + } + } + else if( audioFormat.getChannels() == 2 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_STEREO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_STEREO16; + } + else + { + errorMessage( "Illegal sample size in method " + + "'setAudioFormat'" ); + return; + } + } + else + { + errorMessage( "Audio data neither mono nor stereo in " + + "method 'setAudioFormat'" ); + return; + } + ALformat = soundFormat; + sampleRate = (int) audioFormat.getSampleRate(); + } +/** + * Sets the channel up to receive the specified OpenAL audio format and sample + * rate. + * @param format Format to use. + * @param rate Sample rate (speed) to use. + */ + public void setFormat( int format, int rate ) + { + ALformat = format; + sampleRate = rate; + } + +/** + * Queues up the initial byte[] buffers of data to be streamed. + * @param bufferList List of the first buffers to be played for a streaming source. + * @return False if problem occurred or if end of stream was reached. + */ + @Override + public boolean preLoadBuffers( LinkedList bufferList ) + { + // Stream buffers can only be queued for streaming sources: + if( errorCheck( channelType != SoundSystemConfig.TYPE_STREAMING, + "Buffers may only be queued for streaming sources." ) ) + return false; + + if( errorCheck( bufferList == null, + "Buffer List null in method 'preLoadBuffers'" ) ) + return false; + + IntBuffer streamBuffers; + + // Remember if the channel was playing: + boolean playing = playing(); + // stop the channel if it is playing: + if( playing ) + { + AL10.alSourceStop( ALSource.get( 0 ) ); + checkALError(); + } + // Clear out any previously queued buffers: + int processed = AL10.alGetSourcei( ALSource.get( 0 ), + AL10.AL_BUFFERS_PROCESSED ); + if( processed > 0 ) + { + streamBuffers = BufferUtils.createIntBuffer( processed ); + AL10.alGenBuffers( streamBuffers ); + if( errorCheck( checkALError(), + "Error clearing stream buffers in method 'preLoadBuffers'" ) ) + return false; + AL10.alSourceUnqueueBuffers( ALSource.get( 0 ), streamBuffers ); + if( errorCheck( checkALError(), + "Error unqueuing stream buffers in method 'preLoadBuffers'" ) ) + return false; + } + + // restart the channel if it was previously playing: + if( playing ) + { + AL10.alSourcePlay( ALSource.get( 0 ) ); + checkALError(); + } + + streamBuffers = BufferUtils.createIntBuffer( bufferList.size() ); + AL10.alGenBuffers( streamBuffers ); + if( errorCheck( checkALError(), + "Error generating stream buffers in method 'preLoadBuffers'" ) ) + return false; + + ByteBuffer byteBuffer = null; + for( int i = 0; i < bufferList.size(); i++ ) + { + //byteBuffer = ByteBuffer.wrap( bufferList.get(i), 0, + // bufferList.get(i).length ); + byteBuffer = (ByteBuffer) BufferUtils.createByteBuffer( + bufferList.get(i).length ).put( bufferList.get( i ) ).flip(); + + try + { + AL10.alBufferData( streamBuffers.get(i), ALformat, byteBuffer, + sampleRate ); + } + catch( Exception e ) + { + errorMessage( "Error creating buffers in method " + + "'preLoadBuffers'" ); + printStackTrace( e ); + return false; + } + if( errorCheck( checkALError(), + "Error creating buffers in method 'preLoadBuffers'" ) ) + return false; + + } + + try + { + AL10.alSourceQueueBuffers( ALSource.get( 0 ), streamBuffers ); + } + catch( Exception e ) + { + errorMessage( "Error queuing buffers in method 'preLoadBuffers'" ); + printStackTrace( e ); + return false; + } + if( errorCheck( checkALError(), + "Error queuing buffers in method 'preLoadBuffers'" ) ) + return false; + + AL10.alSourcePlay( ALSource.get( 0 ) ); + if( errorCheck( checkALError(), + "Error playing source in method 'preLoadBuffers'" ) ) + return false; + + // Success: + return true; + } + +/** + * Queues up a byte[] buffer of data to be streamed. + * @param buffer The next buffer to be played for a streaming source. + * @return False if an error occurred or if the channel is shutting down. + */ + @Override + public boolean queueBuffer( byte[] buffer ) + { + // Stream buffers can only be queued for streaming sources: + if( errorCheck( channelType != SoundSystemConfig.TYPE_STREAMING, + "Buffers may only be queued for streaming sources." ) ) + return false; + + //ByteBuffer byteBuffer = ByteBuffer.wrap( buffer, 0, buffer.length ); + ByteBuffer byteBuffer = (ByteBuffer) BufferUtils.createByteBuffer( + buffer.length ).put( buffer ).flip(); + + IntBuffer intBuffer = BufferUtils.createIntBuffer( 1 ); + + AL10.alSourceUnqueueBuffers( ALSource.get( 0 ), intBuffer ); + if( checkALError() ) + return false; + + if( AL10.alIsBuffer( intBuffer.get( 0 ) ) ) + millisPreviouslyPlayed += millisInBuffer( intBuffer.get( 0 ) ); + checkALError(); + + AL10.alBufferData( intBuffer.get(0), ALformat, byteBuffer, sampleRate ); + if( checkALError() ) + return false; + + AL10.alSourceQueueBuffers( ALSource.get( 0 ), intBuffer ); + if( checkALError() ) + return false; + + return true; + } + +/** + * Feeds raw data to the stream. + * @param buffer Buffer containing raw audio data to stream. + * @return Number of prior buffers that have been processed., or -1 if error. + */ + @Override + public int feedRawAudioData( byte[] buffer ) + { + // Stream buffers can only be queued for streaming sources: + if( errorCheck( channelType != SoundSystemConfig.TYPE_STREAMING, + "Raw audio data can only be fed to streaming sources." ) ) + return -1; + + //ByteBuffer byteBuffer = ByteBuffer.wrap( buffer, 0, buffer.length ); + ByteBuffer byteBuffer = (ByteBuffer) BufferUtils.createByteBuffer( + buffer.length ).put( buffer ).flip(); + + IntBuffer intBuffer; + + // Clear out any previously queued buffers: + int processed = AL10.alGetSourcei( ALSource.get( 0 ), + AL10.AL_BUFFERS_PROCESSED ); + if( processed > 0 ) + { + intBuffer = BufferUtils.createIntBuffer( processed ); + AL10.alGenBuffers( intBuffer ); + if( errorCheck( checkALError(), + "Error clearing stream buffers in method 'feedRawAudioData'" ) ) + return -1; + AL10.alSourceUnqueueBuffers( ALSource.get( 0 ), intBuffer ); + if( errorCheck( checkALError(), + "Error unqueuing stream buffers in method 'feedRawAudioData'" ) ) + return -1; + int i; + intBuffer.rewind(); + while( intBuffer.hasRemaining() ) + { + i = intBuffer.get(); + if( AL10.alIsBuffer( i ) ) + { + millisPreviouslyPlayed += millisInBuffer( i ); + } + checkALError(); + } + AL10.alDeleteBuffers( intBuffer ); + checkALError(); + } + intBuffer = BufferUtils.createIntBuffer( 1 ); + AL10.alGenBuffers( intBuffer ); + if( errorCheck( checkALError(), + "Error generating stream buffers in method 'preLoadBuffers'" ) ) + return -1; + + AL10.alBufferData( intBuffer.get(0), ALformat, byteBuffer, sampleRate ); + if( checkALError() ) + return -1; + + AL10.alSourceQueueBuffers( ALSource.get( 0 ), intBuffer ); + if( checkALError() ) + return -1; + + if( attachedSource != null && attachedSource.channel == this && + attachedSource.active() ) + { + // restart the channel if it was previously playing: + if( !playing() ) + { + AL10.alSourcePlay( ALSource.get( 0 ) ); + checkALError(); + } + } + + return processed; + } + +/** + * Returns the number of milliseconds of audio contained in specified buffer. + * @return milliseconds, or 0 if unable to calculate. + */ + public float millisInBuffer( int alBufferi ) + { + return( ( (float) AL10.alGetBufferi( alBufferi, AL10.AL_SIZE ) / + (float) AL10.alGetBufferi( alBufferi, AL10.AL_CHANNELS ) / + ( (float) AL10.alGetBufferi( alBufferi, AL10.AL_BITS ) / 8.0f ) / + (float) sampleRate ) * 1000 ); + } + +/** + * Calculates the number of milliseconds since the channel began playing. + * @return Milliseconds, or -1 if unable to calculate. + */ + @Override + public float millisecondsPlayed() + { + // get number of samples played in current buffer + float offset = (float)AL10.alGetSourcei( ALSource.get( 0 ), + AL11.AL_BYTE_OFFSET ); + + float bytesPerFrame = 1f; + switch( ALformat ) + { + case AL10.AL_FORMAT_MONO8 : + bytesPerFrame = 1f; + break; + case AL10.AL_FORMAT_MONO16 : + bytesPerFrame = 2f; + break; + case AL10.AL_FORMAT_STEREO8 : + bytesPerFrame = 2f; + break; + case AL10.AL_FORMAT_STEREO16 : + bytesPerFrame = 4f; + break; + default : + break; + } + + offset = ( ( (float) offset / bytesPerFrame ) / (float) sampleRate ) + * 1000; + + // add the milliseconds from stream-buffers that played previously + if( channelType == SoundSystemConfig.TYPE_STREAMING ) + offset += millisPreviouslyPlayed; + + // Return millis played: + return( offset ); + } + +/** + * Returns the number of queued byte[] buffers that have finished playing. + * @return Number of buffers processed. + */ + @Override + public int buffersProcessed() + { + // Only streaming sources process buffers: + if( channelType != SoundSystemConfig.TYPE_STREAMING ) + return 0; + + // determine how many have been processed: + int processed = AL10.alGetSourcei( ALSource.get( 0 ), + AL10.AL_BUFFERS_PROCESSED ); + + // Check for errors: + if( checkALError() ) + return 0; + + // Return how many were processed: + return processed; + } + +/** + * Dequeues all previously queued data. + */ + @Override + public void flush() + { + // Only a streaming source can be flushed, because only streaming + // sources have queued buffers: + if( channelType != SoundSystemConfig.TYPE_STREAMING ) + return; + + // determine how many buffers have been queued: + int queued = AL10.alGetSourcei( ALSource.get( 0 ), + AL10.AL_BUFFERS_QUEUED ); + // Check for errors: + if( checkALError() ) + return; + + IntBuffer intBuffer = BufferUtils.createIntBuffer( 1 ); + while( queued > 0 ) + { + try + { + AL10.alSourceUnqueueBuffers( ALSource.get( 0 ), intBuffer ); + } + catch( Exception e ) + { + return; + } + if( checkALError() ) + return; + queued--; + } + millisPreviouslyPlayed = 0; + } + +/** + * Stops the channel, dequeues any queued data, and closes the channel. + */ + @Override + public void close() + { + try + { + AL10.alSourceStop( ALSource.get( 0 ) ); + AL10.alGetError(); + } + catch( Exception e ) + {} + + if( channelType == SoundSystemConfig.TYPE_STREAMING ) + flush(); + } + +/** + * Plays the currently attached normal source, opens this channel up for + * streaming, or resumes playback if this channel was paused. + */ + @Override + public void play() + { + AL10.alSourcePlay( ALSource.get( 0 ) ); + checkALError(); + } + +/** + * Temporarily stops playback for this channel. + */ + @Override + public void pause() + { + AL10.alSourcePause( ALSource.get( 0 ) ); + checkALError(); + } + +/** + * Stops playback for this channel and rewinds the attached source to the + * beginning. + */ + @Override + public void stop() + { + AL10.alSourceStop( ALSource.get( 0 ) ); + if( !checkALError() ) + millisPreviouslyPlayed = 0; + } + +/** + * Rewinds the attached source to the beginning. Stops the source if it was + * paused. + */ + @Override + public void rewind() + { + // rewinding for streaming sources is handled elsewhere + if( channelType == SoundSystemConfig.TYPE_STREAMING ) + return; + + AL10.alSourceRewind( ALSource.get( 0 ) ); + if( !checkALError() ) + millisPreviouslyPlayed = 0; + } + + +/** + * Used to determine if a channel is actively playing a source. This method + * will return false if the channel is paused or stopped and when no data is + * queued to be streamed. + * @return True if this channel is playing a source. + */ + @Override + public boolean playing() + { + int state = AL10.alGetSourcei( ALSource.get( 0 ), + AL10.AL_SOURCE_STATE ); + if( checkALError() ) + return false; + + return( state == AL10.AL_PLAYING ); + } + +/** + * Checks for OpenAL errors, and prints a message if there is an error. + * @return True if there was an error, False if not. + */ + private boolean checkALError() + { + switch( AL10.alGetError() ) + { + case AL10.AL_NO_ERROR: + return false; + case AL10.AL_INVALID_NAME: + errorMessage( "Invalid name parameter." ); + return true; + case AL10.AL_INVALID_ENUM: + errorMessage( "Invalid parameter." ); + return true; + case AL10.AL_INVALID_VALUE: + errorMessage( "Invalid enumerated parameter value." ); + return true; + case AL10.AL_INVALID_OPERATION: + errorMessage( "Illegal call." ); + return true; + case AL10.AL_OUT_OF_MEMORY: + errorMessage( "Unable to allocate memory." ); + return true; + default: + errorMessage( "An unrecognized error occurred." ); + return true; + } + } +} diff --git a/src/lwjgl/java/paulscode/sound/libraries/LibraryLWJGLOpenAL.java b/src/lwjgl/java/paulscode/sound/libraries/LibraryLWJGLOpenAL.java new file mode 100644 index 0000000..1b1b939 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/libraries/LibraryLWJGLOpenAL.java @@ -0,0 +1,1126 @@ +package paulscode.sound.libraries; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.nio.FloatBuffer; +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; +import javax.sound.sampled.AudioFormat; + +// From the lwjgl library, http://www.lwjgl.org +import org.lwjgl.BufferUtils; +import org.lwjgl.LWJGLException; +import org.lwjgl.openal.AL; +import org.lwjgl.openal.AL10; + +import paulscode.sound.Channel; +import paulscode.sound.FilenameURL; +import paulscode.sound.ICodec; +import paulscode.sound.Library; +import paulscode.sound.ListenerData; +import paulscode.sound.SoundBuffer; +import paulscode.sound.SoundSystemConfig; +import paulscode.sound.SoundSystemException; +import paulscode.sound.Source; + +/** + * The LibraryLWJGLOpenAL class interfaces the lwjgl binding of OpenAL. + *

+ * This software is based on or using the LWJGL Lightweight Java Gaming + * Library available from + * http://www.lwjgl.org/. + *


+ * LWJGL License: + *
+ * Copyright (c) 2002-2008 Lightweight Java Game Library Project + * All rights reserved. + *
+ * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + *
+ * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + *
+ * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + *
+ * * Neither the name of 'Light Weight Java Game Library' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *


+ * SoundSystem LibraryLWJGLOpenAL License:

+ * + * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You must abide by the conditions of the aforementioned LWJGL License. + *
+ * 2) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 3) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 4) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 5) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 6) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 7) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class LibraryLWJGLOpenAL extends Library +{ +/** + * Used to return a current value from one of the synchronized + * boolean-interface methods. + */ + private static final boolean GET = false; +/** + * Used to set the value in one of the synchronized boolean-interface methods. + */ + private static final boolean SET = true; +/** + * Used when a parameter for one of the synchronized boolean-interface methods + * is not aplicable. + */ + private static final boolean XXX = false; + +/** + * Position of the listener in 3D space. + */ + private FloatBuffer listenerPositionAL = null; +/** + * Information about the listener's orientation. + */ + private FloatBuffer listenerOrientation = null; +/** + * Velocity of the listener. + */ + private FloatBuffer listenerVelocity = null; +/** + * Map containing OpenAL identifiers for sound buffers. + */ + private HashMap ALBufferMap = null; + +/** + * Whether or not the AL_PITCH control is supported. + */ + private static boolean alPitchSupported = true; + +/** + * Constructor: Instantiates the source map, buffer map and listener + * information. Also sets the library type to + * SoundSystemConfig.LIBRARY_OPENAL + */ + public LibraryLWJGLOpenAL() throws SoundSystemException + { + super(); + ALBufferMap = new HashMap(); + reverseByteOrder = true; + } + +/** + * Initializes OpenAL, creates the listener, and grabs up audio channels. + */ + @Override + public void init() throws SoundSystemException + { + boolean errors = false; // set to 'true' if error(s) occur: + + try + { + // Try and create the sound system: + AL.create(); + errors = checkALError(); + } + catch( LWJGLException e ) + { + // There was an exception + errorMessage( "Unable to initialize OpenAL. Probable cause: " + + "OpenAL not supported." ); + printStackTrace( e ); + throw new LibraryLWJGLOpenAL.Exception( e.getMessage(), + LibraryLWJGLOpenAL.Exception.CREATE ); + } + + // Let user know if the library loaded properly + if( errors ) + importantMessage( "OpenAL did not initialize properly!" ); + else + message( "OpenAL initialized." ); + + // Listener is at the origin, facing along the z axis, no velocity: + listenerPositionAL = BufferUtils.createFloatBuffer( 3 ).put( + new float[] { listener.position.x, + listener.position.y, + listener.position.z } ); + listenerOrientation = BufferUtils.createFloatBuffer( 6 ).put ( + new float[] { listener.lookAt.x, listener.lookAt.y, + listener.lookAt.z, listener.up.x, listener.up.y, + listener.up.z } ); + listenerVelocity = BufferUtils.createFloatBuffer( 3 ).put ( + new float[] { 0.0f, 0.0f, 0.0f } ); + + // Flip the buffers, so they can be used: + listenerPositionAL.flip(); + listenerOrientation.flip(); + listenerVelocity.flip(); + + // Pass the buffers to the sound system, and check for potential errors: + AL10.alListener( AL10.AL_POSITION, listenerPositionAL ); + errors = checkALError() || errors; + AL10.alListener( AL10.AL_ORIENTATION, listenerOrientation ); + errors = checkALError() || errors; + AL10.alListener( AL10.AL_VELOCITY, listenerVelocity ); + errors = checkALError() || errors; + + AL10.alDopplerFactor( SoundSystemConfig.getDopplerFactor() ); + errors = checkALError() || errors; + + AL10.alDopplerVelocity( SoundSystemConfig.getDopplerVelocity() ); + errors = checkALError() || errors; + + // Let user know what caused the above error messages: + if( errors ) + { + importantMessage( "OpenAL did not initialize properly!" ); + throw new LibraryLWJGLOpenAL.Exception( "Problem encountered " + + "while loading OpenAL or " + + "creating the listener. " + + "Probable cause: OpenAL not " + + "supported", + LibraryLWJGLOpenAL.Exception.CREATE ); + } + + super.init(); + + // Check if we can use the AL_PITCH control: + ChannelLWJGLOpenAL channel = (ChannelLWJGLOpenAL) + normalChannels.get( 1 ); + try + { + AL10.alSourcef( channel.ALSource.get( 0 ), + AL10.AL_PITCH, 1.0f ); + if( checkALError() ) + { + alPitchSupported( SET, false ); + throw new LibraryLWJGLOpenAL.Exception( "OpenAL: AL_PITCH not " + + "supported.", LibraryLWJGLOpenAL.Exception.NO_AL_PITCH ); + } + else + { + alPitchSupported( SET, true ); + } + } + catch( java.lang.Exception e ) + { + alPitchSupported( SET, false ); + throw new LibraryLWJGLOpenAL.Exception( "OpenAL: AL_PITCH not " + + "supported.", LibraryLWJGLOpenAL.Exception.NO_AL_PITCH ); + } + } + +/** + * Checks if the OpenAL library type is compatible. + * @return True or false. + */ + public static boolean libraryCompatible() + { + if( AL.isCreated() ) + return true; + + try + { + AL.create(); + } + catch( java.lang.Exception e ) + { + return false; + } + + try + { + AL.destroy(); + } + catch( java.lang.Exception e ) + {} + + return true; + } + +/** + * Creates a new channel of the specified type (normal or streaming). Possible + * values for channel type can be found in the + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} class. + * @param type Type of channel. + */ + @Override + protected Channel createChannel( int type ) + { + ChannelLWJGLOpenAL channel; + IntBuffer ALSource; + + ALSource = BufferUtils.createIntBuffer( 1 ); + try + { + AL10.alGenSources( ALSource ); + } + catch( java.lang.Exception e ) + { + AL10.alGetError(); + return null; // no more voices left + } + + if( AL10.alGetError() != AL10.AL_NO_ERROR ) + return null; + + channel = new ChannelLWJGLOpenAL( type, ALSource ); + return channel; + } + + /** + * Stops all sources, shuts down OpenAL, and removes references to all + * instantiated objects. + */ + @Override + public void cleanup() + { + super.cleanup(); + + Set keys = bufferMap.keySet(); + Iterator iter = keys.iterator(); + String filename; + IntBuffer buffer; + + // loop through and clear all sound buffers: + while( iter.hasNext() ) + { + filename = iter.next(); + buffer = ALBufferMap.get( filename ); + if( buffer != null ) + { + AL10.alDeleteBuffers( buffer ); + checkALError(); + buffer.clear(); + } + } + + bufferMap.clear(); + AL.destroy(); + + bufferMap = null; + listenerPositionAL = null; + listenerOrientation = null; + listenerVelocity = null; + } + +/** + * Pre-loads a sound into memory. + * @param filenameURL Filename/URL of the sound file to load. + * @return True if the sound loaded properly. + */ + @Override + public boolean loadSound( FilenameURL filenameURL ) + { + // Make sure the buffer map exists: + if( bufferMap == null ) + { + bufferMap = new HashMap(); + importantMessage( "Buffer Map was null in method 'loadSound'" ); + } + // Make sure the OpenAL buffer map exists: + if( ALBufferMap == null ) + { + ALBufferMap = new HashMap(); + importantMessage( "Open AL Buffer Map was null in method" + + "'loadSound'" ); + } + + // make sure they gave us a filename: + if( errorCheck( filenameURL == null, + "Filename/URL not specified in method 'loadSound'" ) ) + return false; + + // check if it is already loaded: + if( bufferMap.get( filenameURL.getFilename() ) != null ) + return true; + + ICodec codec = SoundSystemConfig.getCodec( filenameURL.getFilename() ); + if( errorCheck( codec == null, "No codec found for file '" + + filenameURL.getFilename() + + "' in method 'loadSound'" ) ) + return false; + codec.reverseByteOrder( true ); + + URL url = filenameURL.getURL(); + if( errorCheck( url == null, "Unable to open file '" + + filenameURL.getFilename() + + "' in method 'loadSound'" ) ) + return false; + + codec.initialize( url ); + SoundBuffer buffer = codec.readAll(); + codec.cleanup(); + codec = null; + if( errorCheck( buffer == null, + "Sound buffer null in method 'loadSound'" ) ) + return false; + + bufferMap.put( filenameURL.getFilename(), buffer ); + + AudioFormat audioFormat = buffer.audioFormat; + int soundFormat = 0; + if( audioFormat.getChannels() == 1 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_MONO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_MONO16; + } + else + { + errorMessage( "Illegal sample size in method 'loadSound'" ); + return false; + } + } + else if( audioFormat.getChannels() == 2 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_STEREO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_STEREO16; + } + else + { + errorMessage( "Illegal sample size in method 'loadSound'" ); + return false; + } + } + else + { + errorMessage( "File neither mono nor stereo in method " + + "'loadSound'" ); + return false; + } + + IntBuffer intBuffer = BufferUtils.createIntBuffer( 1 ); + AL10.alGenBuffers( intBuffer ); + if( errorCheck( AL10.alGetError() != AL10.AL_NO_ERROR, + "alGenBuffers error when loading " + + filenameURL.getFilename() ) ) + return false; + +// AL10.alBufferData( intBuffer.get( 0 ), soundFormat, +// ByteBuffer.wrap( buffer.audioData ), +// (int) audioFormat.getSampleRate() ); + AL10.alBufferData( intBuffer.get( 0 ), soundFormat, + (ByteBuffer) BufferUtils.createByteBuffer( + buffer.audioData.length ).put( + buffer.audioData ).flip(), + (int) audioFormat.getSampleRate() ); + + if( errorCheck( AL10.alGetError() != AL10.AL_NO_ERROR, + "alBufferData error when loading " + + filenameURL.getFilename() ) ) + + + if( errorCheck( intBuffer == null, + "Sound buffer was not created for " + + filenameURL.getFilename() ) ) + return false; + + ALBufferMap.put( filenameURL.getFilename(), intBuffer ); + + return true; + } + +/** + * Saves the specified sample data, under the specified identifier. This + * identifier can be later used in place of 'filename' parameters to reference + * the sample data. + * @param buffer the sample data and audio format to save. + * @param identifier What to call the sample. + * @return True if there weren't any problems. + */ + @Override + public boolean loadSound( SoundBuffer buffer, String identifier ) + { + // Make sure the buffer map exists: + if( bufferMap == null ) + { + bufferMap = new HashMap(); + importantMessage( "Buffer Map was null in method 'loadSound'" ); + } + // Make sure the OpenAL buffer map exists: + if( ALBufferMap == null ) + { + ALBufferMap = new HashMap(); + importantMessage( "Open AL Buffer Map was null in method" + + "'loadSound'" ); + } + + // make sure they gave us an identifier: + if( errorCheck( identifier == null, + "Identifier not specified in method 'loadSound'" ) ) + return false; + + // check if it is already loaded: + if( bufferMap.get( identifier ) != null ) + return true; + + if( errorCheck( buffer == null, + "Sound buffer null in method 'loadSound'" ) ) + return false; + + bufferMap.put( identifier, buffer ); + + AudioFormat audioFormat = buffer.audioFormat; + int soundFormat = 0; + if( audioFormat.getChannels() == 1 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_MONO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_MONO16; + } + else + { + errorMessage( "Illegal sample size in method 'loadSound'" ); + return false; + } + } + else if( audioFormat.getChannels() == 2 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_STEREO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_STEREO16; + } + else + { + errorMessage( "Illegal sample size in method 'loadSound'" ); + return false; + } + } + else + { + errorMessage( "File neither mono nor stereo in method " + + "'loadSound'" ); + return false; + } + + IntBuffer intBuffer = BufferUtils.createIntBuffer( 1 ); + AL10.alGenBuffers( intBuffer ); + if( errorCheck( AL10.alGetError() != AL10.AL_NO_ERROR, + "alGenBuffers error when saving " + + identifier ) ) + return false; + +// AL10.alBufferData( intBuffer.get( 0 ), soundFormat, +// ByteBuffer.wrap( buffer.audioData ), +// (int) audioFormat.getSampleRate() ); + AL10.alBufferData( intBuffer.get( 0 ), soundFormat, + (ByteBuffer) BufferUtils.createByteBuffer( + buffer.audioData.length ).put( + buffer.audioData ).flip(), + (int) audioFormat.getSampleRate() ); + + if( errorCheck( AL10.alGetError() != AL10.AL_NO_ERROR, + "alBufferData error when saving " + + identifier ) ) + + + if( errorCheck( intBuffer == null, + "Sound buffer was not created for " + + identifier ) ) + return false; + + ALBufferMap.put( identifier, intBuffer ); + + return true; + } + +/** + * Removes a pre-loaded sound from memory. This is a good method to use for + * freeing up memory after a large sound file is no longer needed. NOTE: the + * source will remain in memory after this method has been called, for as long + * as the sound is attached to an existing source. + * @param filename Filename/identifier of the sound file to unload. + */ + @Override + public void unloadSound( String filename ) + { + ALBufferMap.remove( filename ); + super.unloadSound( filename ); + } + + /** + * Sets the overall volume to the specified value, affecting all sources. + * @param value New volume, float value ( 0.0f - 1.0f ). + */ + @Override + public void setMasterVolume( float value ) + { + super.setMasterVolume( value ); + + AL10.alListenerf( AL10.AL_GAIN, value ); + checkALError(); + } + +/** + * Creates a new source and places it into the source map. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will load the sound in pieces rather than all at once. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + @Override + public void newSource( boolean priority, boolean toStream, boolean toLoop, + String sourcename, FilenameURL filenameURL, float x, + float y, float z, int attModel, float distOrRoll ) + { + IntBuffer myBuffer = null; + if( !toStream ) + { + // Grab the sound buffer for this file: + myBuffer = ALBufferMap.get( filenameURL.getFilename() ); + + // if not found, try loading it: + if( myBuffer == null ) + { + if( !loadSound( filenameURL ) ) + { + errorMessage( "Source '" + sourcename + "' was not created " + + "because an error occurred while loading " + + filenameURL.getFilename() ); + return; + } + } + + // try and grab the sound buffer again: + myBuffer = ALBufferMap.get( filenameURL.getFilename() ); + // see if it was there this time: + if( myBuffer == null ) + { + errorMessage( "Source '" + sourcename + "' was not created " + + "because a sound buffer was not found for " + + filenameURL.getFilename() ); + return; + } + } + SoundBuffer buffer = null; + + if( !toStream ) + { + // Grab the audio data for this file: + buffer = bufferMap.get( filenameURL.getFilename() ); + // if not found, try loading it: + if( buffer == null ) + { + if( !loadSound( filenameURL ) ) + { + errorMessage( "Source '" + sourcename + "' was not created " + + "because an error occurred while loading " + + filenameURL.getFilename() ); + return; + } + } + // try and grab the sound buffer again: + buffer = bufferMap.get( filenameURL.getFilename() ); + // see if it was there this time: + if( buffer == null ) + { + errorMessage( "Source '" + sourcename + "' was not created " + + "because audio data was not found for " + + filenameURL.getFilename() ); + return; + } + } + + sourceMap.put( sourcename, + new SourceLWJGLOpenAL( listenerPositionAL, myBuffer, + priority, toStream, toLoop, + sourcename, filenameURL, buffer, x, + y, z, attModel, distOrRoll, + false ) ); + } + + /** + * Opens a direct line for streaming audio data. + * @param audioFormat Format that the data will be in. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + @Override + public void rawDataStream( AudioFormat audioFormat, boolean priority, + String sourcename, float x, float y, + float z, int attModel, float distOrRoll ) + { + sourceMap.put( sourcename, + new SourceLWJGLOpenAL( listenerPositionAL, audioFormat, + priority, sourcename, x, y, z, + attModel, distOrRoll ) ); + } + +/** + * Creates and immediately plays a new source. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will load the sound in pieces rather than all at once. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + * @param temporary Whether or not this source should be removed after it finishes playing. + */ + @Override + public void quickPlay( boolean priority, boolean toStream, boolean toLoop, + String sourcename, FilenameURL filenameURL, float x, + float y, float z, int attModel, float distOrRoll, + boolean temporary ) + { + IntBuffer myBuffer = null; + if( !toStream ) + { + // Grab the sound buffer for this file: + myBuffer = ALBufferMap.get( filenameURL.getFilename() ); + // if not found, try loading it: + if( myBuffer == null ) + loadSound( filenameURL ); + // try and grab the sound buffer again: + myBuffer = ALBufferMap.get( filenameURL.getFilename() ); + // see if it was there this time: + if( myBuffer == null ) + { + errorMessage( "Sound buffer was not created for " + + filenameURL.getFilename() ); + return; + } + } + + SoundBuffer buffer = null; + + if( !toStream ) + { + // Grab the sound buffer for this file: + buffer = bufferMap.get( filenameURL.getFilename() ); + // if not found, try loading it: + if( buffer == null ) + { + if( !loadSound( filenameURL ) ) + { + errorMessage( "Source '" + sourcename + "' was not created " + + "because an error occurred while loading " + + filenameURL.getFilename() ); + return; + } + } + // try and grab the sound buffer again: + buffer = bufferMap.get( filenameURL.getFilename() ); + // see if it was there this time: + if( buffer == null ) + { + errorMessage( "Source '" + sourcename + "' was not created " + + "because audio data was not found for " + + filenameURL.getFilename() ); + return; + } + } + SourceLWJGLOpenAL s = new SourceLWJGLOpenAL( listenerPositionAL, + myBuffer, priority, + toStream, toLoop, + sourcename, filenameURL, + buffer, x, y, z, + attModel, distOrRoll, + false ); + + sourceMap.put( sourcename, s ); + play( s ); + if( temporary ) + s.setTemporary( true ); +} + +/** + * Creates sources based on the source map provided. + * @param srcMap Sources to copy. + */ + @Override + public void copySources( HashMap srcMap ) + { + if( srcMap == null ) + return; + Set keys = srcMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // Make sure the buffer map exists: + if( bufferMap == null ) + { + bufferMap = new HashMap(); + importantMessage( "Buffer Map was null in method 'copySources'" ); + } + // Make sure the OpenAL buffer map exists: + if( ALBufferMap == null ) + { + ALBufferMap = new HashMap(); + importantMessage( "Open AL Buffer Map was null in method" + + "'copySources'" ); + } + + // remove any existing sources before starting: + sourceMap.clear(); + + SoundBuffer buffer; + // loop through and copy all the sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = srcMap.get( sourcename ); + if( source != null ) + { + buffer = null; + if( !source.toStream ) + { + loadSound( source.filenameURL ); + buffer = bufferMap.get( source.filenameURL.getFilename() ); + } + if( source.toStream || buffer != null ) + sourceMap.put( sourcename, new SourceLWJGLOpenAL( + listenerPositionAL, + ALBufferMap.get( + source.filenameURL.getFilename() ), + source, buffer ) ); + } + } + } + +/** + * Changes the listener's position. + * @param x Destination X coordinate. + * @param y Destination Y coordinate. + * @param z Destination Z coordinate. + */ + @Override + public void setListenerPosition( float x, float y, float z ) + { + super.setListenerPosition( x, y, z ); + + listenerPositionAL.put( 0, x ); + listenerPositionAL.put( 1, y ); + listenerPositionAL.put( 2, z ); + + // Update OpenAL listener position: + AL10.alListener( AL10.AL_POSITION, listenerPositionAL ); + // Check for errors: + checkALError(); + } + +/** + * Changes the listeners orientation to the specified 'angle' radians + * counterclockwise around the y-Axis. + * @param angle Radians. + */ + @Override + public void setListenerAngle( float angle ) + { + super.setListenerAngle( angle ); + + listenerOrientation.put( 0, listener.lookAt.x ); + listenerOrientation.put( 2, listener.lookAt.z ); + + // Update OpenAL listener orientation: + AL10.alListener( AL10.AL_ORIENTATION, listenerOrientation ); + // Check for errors: + checkALError(); + } + +/** + * Changes the listeners orientation using the specified coordinates. + * @param lookX X element of the look-at direction. + * @param lookY Y element of the look-at direction. + * @param lookZ Z element of the look-at direction. + * @param upX X element of the up direction. + * @param upY Y element of the up direction. + * @param upZ Z element of the up direction. + */ + @Override + public void setListenerOrientation( float lookX, float lookY, float lookZ, + float upX, float upY, float upZ ) + { + super.setListenerOrientation( lookX, lookY, lookZ, upX, upY, upZ ); + listenerOrientation.put( 0, lookX ); + listenerOrientation.put( 1, lookY ); + listenerOrientation.put( 2, lookZ ); + listenerOrientation.put( 3, upX ); + listenerOrientation.put( 4, upY ); + listenerOrientation.put( 5, upZ ); + AL10.alListener( AL10.AL_ORIENTATION, listenerOrientation ); + checkALError(); + } + +/** + * Changes the listeners position and orientation using the specified listener + * data. + * @param l Listener data to use. + */ + @Override + public void setListenerData( ListenerData l ) + { + super.setListenerData( l ); + + listenerPositionAL.put( 0, l.position.x ); + listenerPositionAL.put( 1, l.position.y ); + listenerPositionAL.put( 2, l.position.z ); + AL10.alListener( AL10.AL_POSITION, listenerPositionAL ); + checkALError(); + + listenerOrientation.put( 0, l.lookAt.x ); + listenerOrientation.put( 1, l.lookAt.y ); + listenerOrientation.put( 2, l.lookAt.z ); + listenerOrientation.put( 3, l.up.x ); + listenerOrientation.put( 4, l.up.y ); + listenerOrientation.put( 5, l.up.z ); + AL10.alListener( AL10.AL_ORIENTATION, listenerOrientation ); + checkALError(); + + listenerVelocity.put( 0, l.velocity.x ); + listenerVelocity.put( 1, l.velocity.y ); + listenerVelocity.put( 2, l.velocity.z ); + AL10.alListener( AL10.AL_VELOCITY, listenerVelocity ); + checkALError(); + } + +/** + * Sets the listener's velocity, for use in Doppler effect. + * @param x Velocity along world x-axis. + * @param y Velocity along world y-axis. + * @param z Velocity along world z-axis. + */ + @Override + public void setListenerVelocity( float x, float y, float z ) + { + super.setListenerVelocity( x, y, z ); + + listenerVelocity.put( 0, listener.velocity.x ); + listenerVelocity.put( 1, listener.velocity.y ); + listenerVelocity.put( 2, listener.velocity.z ); + AL10.alListener( AL10.AL_VELOCITY, listenerVelocity ); + } + +/** + * The Doppler parameters have changed. + */ + @Override + public void dopplerChanged() + { + super.dopplerChanged(); + + AL10.alDopplerFactor( SoundSystemConfig.getDopplerFactor() ); + checkALError(); + AL10.alDopplerVelocity( SoundSystemConfig.getDopplerVelocity() ); + checkALError(); + } + +/** + * Checks for OpenAL errors, and prints a message if there is an error. + * @return True if there was an error, False if not. + */ + private boolean checkALError() + { + switch( AL10.alGetError() ) + { + case AL10.AL_NO_ERROR: + return false; + case AL10.AL_INVALID_NAME: + errorMessage( "Invalid name parameter." ); + return true; + case AL10.AL_INVALID_ENUM: + errorMessage( "Invalid parameter." ); + return true; + case AL10.AL_INVALID_VALUE: + errorMessage( "Invalid enumerated parameter value." ); + return true; + case AL10.AL_INVALID_OPERATION: + errorMessage( "Illegal call." ); + return true; + case AL10.AL_OUT_OF_MEMORY: + errorMessage( "Unable to allocate memory." ); + return true; + default: + errorMessage( "An unrecognized error occurred." ); + return true; + } + } + +/** + * Whether or not the AL_PITCH control is supported. + * @return True if AL_PITCH is supported. + */ + public static boolean alPitchSupported() + { + return alPitchSupported( GET, XXX ); + } +/** + * Sets or returns the value of boolean 'alPitchSupported'. + * @param action Action to perform (GET or SET). + * @param value New value if action is SET, otherwise XXX. + * @return value of boolean 'alPitchSupported'. + */ + private static synchronized boolean alPitchSupported( boolean action, + boolean value ) + { + if( action == SET ) + alPitchSupported = value; + return alPitchSupported; + } + +/** + * Returns the short title of this library type. + * @return A short title. + */ + public static String getTitle() + { + return "LWJGL OpenAL"; + } + +/** + * Returns a longer description of this library type. + * @return A longer description. + */ + public static String getDescription() + { + return "The LWJGL binding of OpenAL. For more information, see " + + "http://www.lwjgl.org"; + } + +/** + * Returns the name of the class. + * @return "Library" + library title. + */ + @Override + public String getClassName() + { + return "LibraryLWJGLOpenAL"; + } + +/** + * The LibraryLWJGLOpenAL.Exception class provides library-specific error + * information. + */ + public static class Exception extends SoundSystemException + { + private static final long serialVersionUID = -7502452059037798035L; + /** + * Global identifier for an exception during AL.create(). Probably + * means that OpenAL is not supported. + */ + public static final int CREATE = 101; + /** + * Global identifier for an invalid name parameter in OpenAL. + */ + public static final int INVALID_NAME = 102; + /** + * Global identifier for an invalid parameter in OpenAL. + */ + public static final int INVALID_ENUM = 103; + /** + * Global identifier for an invalid enumerated parameter value in OpenAL. + */ + public static final int INVALID_VALUE = 104; + /** + * Global identifier for an illegal call in OpenAL. + */ + public static final int INVALID_OPERATION = 105; + /** + * Global identifier for OpenAL out of memory. + */ + public static final int OUT_OF_MEMORY = 106; + /** + * Global identifier for an exception while creating the OpenAL Listener. + */ + public static final int LISTENER = 107; + /** + * Global identifier for OpenAL AL_PITCH not supported. + */ + public static final int NO_AL_PITCH = 108; + + /** + * Constructor: Generates a standard "unknown error" exception with the + * specified message. + * @param message A brief description of the problem that occurred. + */ + public Exception( String message ) + { + super( message ); + } + + /** + * Constructor: Generates an exception of the specified type, with the + * specified message. + * @param message A brief description of the problem that occurred. + * @param type Identifier indicating they type of error. + */ + public Exception( String message, int type ) + { + super( message, type ); + } + } +} diff --git a/src/lwjgl/java/paulscode/sound/libraries/SourceLWJGLOpenAL.java b/src/lwjgl/java/paulscode/sound/libraries/SourceLWJGLOpenAL.java new file mode 100644 index 0000000..f22d74a --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/libraries/SourceLWJGLOpenAL.java @@ -0,0 +1,801 @@ +package paulscode.sound.libraries; + +import java.nio.IntBuffer; +import java.nio.FloatBuffer; +import java.util.LinkedList; +import javax.sound.sampled.AudioFormat; + +// From the lwjgl library, http://www.lwjgl.org +import org.lwjgl.BufferUtils; +import org.lwjgl.openal.AL10; + +import paulscode.sound.Channel; +import paulscode.sound.FilenameURL; +import paulscode.sound.Source; +import paulscode.sound.SoundBuffer; +import paulscode.sound.SoundSystemConfig; + +/** + * The SourceLWJGLOpenAL class provides an interface to the lwjgl binding of OpenAL. + *

+ * This software is based on or using the LWJGL Lightweight Java Gaming + * Library available from + * http://www.lwjgl.org/. + *


+ * LWJGL License: + *
+ * Copyright (c) 2002-2008 Lightweight Java Game Library Project + * All rights reserved. + *
+ * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + *
+ * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + *
+ * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + *
+ * * Neither the name of 'Light Weight Java Game Library' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *


+ * SoundSystem LibraryLWJGLOpenAL License:

+ * + * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You must abide by the conditions of the aforementioned LWJGL License. + *
+ * 2) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 3) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 4) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 5) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 6) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 7) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class SourceLWJGLOpenAL extends Source +{ +/** + * The source's basic Channel type-cast to a ChannelLWJGLOpenAL. + */ + private ChannelLWJGLOpenAL channelOpenAL = (ChannelLWJGLOpenAL) channel; + +/** + * OpenAL IntBuffer sound-buffer identifier for this source if it is a normal + * source. + */ + private IntBuffer myBuffer; + +/** + * FloatBuffer containing the listener's 3D coordinates. + */ + private FloatBuffer listenerPosition; + +/** + * FloatBuffer containing the source's 3D coordinates. + */ + private FloatBuffer sourcePosition; + +/** + * FloatBuffer containing the source's velocity vector. + */ + private FloatBuffer sourceVelocity; + +/** + * Constructor: Creates a new source using the specified parameters. + * @param listenerPosition FloatBuffer containing the listener's 3D coordinates. + * @param myBuffer OpenAL IntBuffer sound-buffer identifier to use for a new normal source. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will create a streaming source. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param soundBuffer Buffer containing audio data, or null if not loaded yet. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of 'att'. + * @param temporary Whether or not to remove this source after it finishes playing. + */ + public SourceLWJGLOpenAL( FloatBuffer listenerPosition, IntBuffer myBuffer, + boolean priority, boolean toStream, + boolean toLoop, String sourcename, + FilenameURL filenameURL, SoundBuffer soundBuffer, + float x, float y, float z, int attModel, + float distOrRoll, boolean temporary ) + { + super( priority, toStream, toLoop, sourcename, filenameURL, soundBuffer, + x, y, z, attModel, distOrRoll, temporary ); + if( codec != null ) + codec.reverseByteOrder( true ); + this.listenerPosition = listenerPosition; + this.myBuffer = myBuffer; + libraryType = LibraryLWJGLOpenAL.class; + pitch = 1.0f; + resetALInformation(); + } + +/** + * Constructor: Creates a new source matching the specified source. + * @param listenerPosition FloatBuffer containing the listener's 3D coordinates. + * @param myBuffer OpenAL IntBuffer sound-buffer identifier to use for a new normal source. + * @param old Source to copy information from. + * @param soundBuffer Buffer containing audio data, or null if not loaded yet. + */ + public SourceLWJGLOpenAL( FloatBuffer listenerPosition, IntBuffer myBuffer, + Source old, SoundBuffer soundBuffer ) + { + super( old, soundBuffer ); + if( codec != null ) + codec.reverseByteOrder( true ); + this.listenerPosition = listenerPosition; + this.myBuffer = myBuffer; + libraryType = LibraryLWJGLOpenAL.class; + pitch = 1.0f; + resetALInformation(); + } + + /** + * Constructor: Creates a new streaming source that will be directly fed with + * raw audio data. + * @param listenerPosition FloatBuffer containing the listener's 3D coordinates. + * @param audioFormat Format that the data will be in. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of 'att'. + */ + public SourceLWJGLOpenAL( FloatBuffer listenerPosition, + AudioFormat audioFormat, boolean priority, + String sourcename, float x, float y, float z, + int attModel, float distOrRoll ) + { + super( audioFormat, priority, sourcename, x, y, z, attModel, + distOrRoll ); + this.listenerPosition = listenerPosition; + libraryType = LibraryLWJGLOpenAL.class; + pitch = 1.0f; + resetALInformation(); + } + +/** + * Shuts the source down and removes references to all instantiated objects. + */ + @Override + public void cleanup() + { + + super.cleanup(); + } + +/** + * Changes the peripheral information about the source using the specified + * parameters. + * @param listenerPosition FloatBuffer containing the listener's 3D coordinates. + * @param myBuffer OpenAL IntBuffer sound-buffer identifier to use for a new normal source. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will create a streaming source. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param soundBuffer Buffer containing audio data, or null if not loaded yet. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of 'att'. + * @param temporary Whether or not to remove this source after it finishes playing. + */ + public void changeSource( FloatBuffer listenerPosition, IntBuffer myBuffer, + boolean priority, boolean toStream, + boolean toLoop, String sourcename, + FilenameURL filenameURL, SoundBuffer soundBuffer, + float x, float y, float z, int attModel, + float distOrRoll, boolean temporary ) + { + super.changeSource( priority, toStream, toLoop, sourcename, + filenameURL, soundBuffer, x, y, z, attModel, + distOrRoll, temporary ); + this.listenerPosition = listenerPosition; + this.myBuffer = myBuffer; + pitch = 1.0f; + resetALInformation(); + } + +/** + * Removes the next filename from the sound sequence queue and assigns it to + * this source. This method has no effect on non-streaming sources. This + * method is used internally by SoundSystem, and it is unlikely that the user + * will ever need to use it. + * @return True if there was something in the queue. + */ + @Override + public boolean incrementSoundSequence() + { + if( !toStream ) + { + errorMessage( "Method 'incrementSoundSequence' may only be used " + + "for streaming sources." ); + return false; + } + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue != null && soundSequenceQueue.size() > 0 ) + { + filenameURL = soundSequenceQueue.remove( 0 ); + if( codec != null ) + codec.cleanup(); + codec = SoundSystemConfig.getCodec( filenameURL.getFilename() ); + if( codec != null ) + { + codec.reverseByteOrder( true ); + if( codec.getAudioFormat() == null ) + codec.initialize( filenameURL.getURL() ); + + AudioFormat audioFormat = codec.getAudioFormat(); + + if( audioFormat == null ) + { + errorMessage( "Audio Format null in method " + + "'incrementSoundSequence'" ); + return false; + } + + int soundFormat = 0; + if( audioFormat.getChannels() == 1 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_MONO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_MONO16; + } + else + { + errorMessage( "Illegal sample size in method " + + "'incrementSoundSequence'" ); + return false; + } + } + else if( audioFormat.getChannels() == 2 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_STEREO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_STEREO16; + } + else + { + errorMessage( "Illegal sample size in method " + + "'incrementSoundSequence'" ); + return false; + } + } + else + { + errorMessage( "Audio data neither mono nor stereo in " + + "method 'incrementSoundSequence'" ); + return false; + } + + // Let the channel know what format and sample rate to use: + channelOpenAL.setFormat( soundFormat, + (int) audioFormat.getSampleRate() ); + preLoad = true; + } + return true; + } + } + return false; + } + +/** + * Called every time the listener's position or orientation changes. + */ + @Override + public void listenerMoved() + { + positionChanged(); + } + +/** + * Moves the source to the specified position. + * @param x X coordinate to move to. + * @param y Y coordinate to move to. + * @param z Z coordinate to move to. + */ + @Override + public void setPosition( float x, float y, float z ) + { + super.setPosition( x, y, z ); + + // Make sure OpenAL information has been created + if( sourcePosition == null ) + resetALInformation(); + else + positionChanged(); + + // put the new position information into the buffer: + sourcePosition.put( 0, x ); + sourcePosition.put( 1, y ); + sourcePosition.put( 2, z ); + + // make sure we are assigned to a channel: + if( channel != null && channel.attachedSource == this && + channelOpenAL != null && channelOpenAL.ALSource != null ) + { + // move the source: + AL10.alSource( channelOpenAL.ALSource.get( 0 ), AL10.AL_POSITION, + sourcePosition ); + checkALError(); + } + } + +/** + * Recalculates the distance from the listner and the gain. + */ + @Override + public void positionChanged() + { + calculateDistance(); + calculateGain(); + + if( channel != null && channel.attachedSource == this && + channelOpenAL != null && channelOpenAL.ALSource != null ) + { + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_GAIN, (gain * sourceVolume + * (float) Math.abs( fadeOutGain ) + * fadeInGain) ); + checkALError(); + } + checkPitch(); + } + +/** + * Checks the source's pitch. + */ + private void checkPitch() + { + if( channel != null && channel.attachedSource == this && + LibraryLWJGLOpenAL.alPitchSupported() && channelOpenAL != null && + channelOpenAL.ALSource != null ) + { + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_PITCH, pitch ); + checkALError(); + } + } + +/** + * Sets whether this source should loop or only play once. + * @param lp True or false. + */ + @Override + public void setLooping( boolean lp ) + { + super.setLooping( lp ); + + // make sure we are assigned to a channel: + if( channel != null && channel.attachedSource == this && + channelOpenAL != null && channelOpenAL.ALSource != null ) + { + if( lp ) + AL10.alSourcei( channelOpenAL.ALSource.get( 0 ), + AL10.AL_LOOPING, AL10.AL_TRUE ); + else + AL10.alSourcei( channelOpenAL.ALSource.get( 0 ), + AL10.AL_LOOPING, AL10.AL_FALSE ); + checkALError(); + } + } + +/** + * Sets this source's attenuation model. + * @param model Attenuation model to use. + */ + @Override + public void setAttenuation( int model ) + { + super.setAttenuation( model ); + // make sure we are assigned to a channel: + if( channel != null && channel.attachedSource == this && + channelOpenAL != null && channelOpenAL.ALSource != null ) + { + // attenuation changed, so update the rolloff factor accordingly + if( model == SoundSystemConfig.ATTENUATION_ROLLOFF ) + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_ROLLOFF_FACTOR, distOrRoll ); + else + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_ROLLOFF_FACTOR, 0.0f ); + checkALError(); + } + } + +/** + * Sets this source's fade distance or rolloff factor, depending on the + * attenuation model. + * @param dr New value for fade distance or rolloff factor. + */ + @Override + public void setDistOrRoll( float dr) + { + super.setDistOrRoll( dr ); + // make sure we are assigned to a channel: + if( channel != null && channel.attachedSource == this && + channelOpenAL != null && channelOpenAL.ALSource != null ) + { + // if we are using rolloff attenuation, then dr is a rolloff factor: + if( attModel == SoundSystemConfig.ATTENUATION_ROLLOFF ) + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_ROLLOFF_FACTOR, dr ); + else + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_ROLLOFF_FACTOR, 0.0f ); + checkALError(); + } + } + +/** + * Sets this source's velocity, for use in Doppler effect. + * @param x Velocity along world x-axis. + * @param y Velocity along world y-axis. + * @param z Velocity along world z-axis. + */ + @Override + public void setVelocity( float x, float y, float z ) + { + super.setVelocity( x, y, z ); + + sourceVelocity = BufferUtils.createFloatBuffer( 3 ).put( new float[] + { x, y, z } ); + sourceVelocity.flip(); + // make sure we are assigned to a channel: + if( channel != null && channel.attachedSource == this && + channelOpenAL != null && channelOpenAL.ALSource != null ) + { + AL10.alSource( channelOpenAL.ALSource.get( 0 ), + AL10.AL_VELOCITY, sourceVelocity ); + checkALError(); + } + } + +/** + * Manually sets this source's pitch. + * @param value A float value ( 0.5f - 2.0f ). + */ + @Override + public void setPitch( float value ) + { + super.setPitch( value ); + checkPitch(); + } + +/** + * Plays the source on the specified channel. + * @param c Channel to play on. + */ + @Override + public void play( Channel c ) + { + if( !active() ) + { + if( toLoop ) + toPlay = true; + return; + } + + if( c == null ) + { + errorMessage( "Unable to play source, because channel was null" ); + return; + } + + boolean newChannel = (channel != c); + if( channel != null && channel.attachedSource != this ) + newChannel = true; + + boolean wasPaused = paused(); + + super.play( c ); + + channelOpenAL = (ChannelLWJGLOpenAL) channel; + + // Make sure the channel exists: + // check if we are already on this channel: + if( newChannel ) + { + setPosition( position.x, position.y, position.z ); + checkPitch(); + + // Send the source's attributes to the channel: + if( channelOpenAL != null && channelOpenAL.ALSource != null ) + { + if( LibraryLWJGLOpenAL.alPitchSupported() ) + { + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_PITCH, pitch ); + checkALError(); + } + AL10.alSource( channelOpenAL.ALSource.get( 0 ), + AL10.AL_POSITION, sourcePosition ); + checkALError(); + + AL10.alSource( channelOpenAL.ALSource.get( 0 ), + AL10.AL_VELOCITY, sourceVelocity ); + + checkALError(); + + if( attModel == SoundSystemConfig.ATTENUATION_ROLLOFF ) + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_ROLLOFF_FACTOR, distOrRoll ); + else + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_ROLLOFF_FACTOR, 0.0f ); + checkALError(); + + if( toLoop && (!toStream) ) + AL10.alSourcei( channelOpenAL.ALSource.get( 0 ), + AL10.AL_LOOPING, AL10.AL_TRUE ); + else + AL10.alSourcei( channelOpenAL.ALSource.get( 0 ), + AL10.AL_LOOPING, AL10.AL_FALSE ); + checkALError(); + } + if( !toStream ) + { + // This is not a streaming source, so make sure there is + // a sound buffer loaded to play: + if( myBuffer == null ) + { + errorMessage( "No sound buffer to play" ); + return; + } + + channelOpenAL.attachBuffer( myBuffer ); + } + } + + // See if we are already playing: + if( !playing() ) + { + if( toStream && !wasPaused ) + { + if( codec == null ) + { + errorMessage( "Decoder null in method 'play'" ); + return; + } + if( codec.getAudioFormat() == null ) + codec.initialize( filenameURL.getURL() ); + + AudioFormat audioFormat = codec.getAudioFormat(); + + if( audioFormat == null ) + { + errorMessage( "Audio Format null in method 'play'" ); + return; + } + + int soundFormat = 0; + if( audioFormat.getChannels() == 1 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_MONO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_MONO16; + } + else + { + errorMessage( "Illegal sample size in method 'play'" ); + return; + } + } + else if( audioFormat.getChannels() == 2 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_STEREO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_STEREO16; + } + else + { + errorMessage( "Illegal sample size in method 'play'" ); + return; + } + } + else + { + errorMessage( "Audio data neither mono nor stereo in " + + "method 'play'" ); + return; + } + + // Let the channel know what format and sample rate to use: + channelOpenAL.setFormat( soundFormat, + (int) audioFormat.getSampleRate() ); + preLoad = true; + } + channel.play(); + if( pitch != 1.0f ) + checkPitch(); + } + } + +/** + * Queues up the initial stream-buffers for the stream. + * @return False if the end of the stream was reached. + */ + @Override + public boolean preLoad() + { + if( codec == null ) + return false; + + codec.initialize( filenameURL.getURL() ); + LinkedList preLoadBuffers = new LinkedList(); + for( int i = 0; i < SoundSystemConfig.getNumberStreamingBuffers(); i++ ) + { + soundBuffer = codec.read(); + + if( soundBuffer == null || soundBuffer.audioData == null ) + break; + + preLoadBuffers.add( soundBuffer.audioData ); + } + positionChanged(); + + channel.preLoadBuffers( preLoadBuffers ); + + preLoad = false; + return true; + } + +/** + * Resets all the information OpenAL uses to play this source. + */ + private void resetALInformation() + { + // Create buffers for the source's position and velocity + sourcePosition = BufferUtils.createFloatBuffer( 3 ).put( + new float[] { position.x, position.y, position.z } ); + sourceVelocity = BufferUtils.createFloatBuffer( 3 ).put( + new float[] { velocity.x, velocity.y, velocity.z } ); + + // flip the buffers, so they can be used: + sourcePosition.flip(); + sourceVelocity.flip(); + + positionChanged(); + } + +/** + * Calculates this source's distance from the listener. + */ + private void calculateDistance() + { + if( listenerPosition != null ) + { + // Calculate the source's distance from the listener: + double dX = position.x - listenerPosition.get( 0 ); + double dY = position.y - listenerPosition.get( 1 ); + double dZ = position.z - listenerPosition.get( 2 ); + distanceFromListener = (float) Math.sqrt( dX*dX + dY*dY + dZ*dZ ); + } + } + +/** + * If using linear attenuation, calculates the gain for this source based on + * its distance from the listener. + */ + private void calculateGain() + { + // If using linear attenuation, calculate the source's gain: + if( attModel == SoundSystemConfig.ATTENUATION_LINEAR ) + { + if( distanceFromListener <= 0 ) + { + gain = 1.0f; + } + else if( distanceFromListener >= distOrRoll ) + { + gain = 0.0f; + } + else + { + gain = 1.0f - (distanceFromListener / distOrRoll); + } + if( gain > 1.0f ) + gain = 1.0f; + if( gain < 0.0f ) + gain = 0.0f; + } + else + { + gain = 1.0f; + } + } + +/** + * Checks for OpenAL errors, and prints a message if there is an error. + * @return True if there was an error, False if not. + */ + private boolean checkALError() + { + switch( AL10.alGetError() ) + { + case AL10.AL_NO_ERROR: + return false; + case AL10.AL_INVALID_NAME: + errorMessage( "Invalid name parameter." ); + return true; + case AL10.AL_INVALID_ENUM: + errorMessage( "Invalid parameter." ); + return true; + case AL10.AL_INVALID_VALUE: + errorMessage( "Invalid enumerated parameter value." ); + return true; + case AL10.AL_INVALID_OPERATION: + errorMessage( "Illegal call." ); + return true; + case AL10.AL_OUT_OF_MEMORY: + errorMessage( "Unable to allocate memory." ); + return true; + default: + errorMessage( "An unrecognized error occurred." ); + return true; + } + } +} diff --git a/src/lwjgl/java/tritonus/TAsynchronousFilteredAudioInputStream.java b/src/lwjgl/java/tritonus/TAsynchronousFilteredAudioInputStream.java new file mode 100644 index 0000000..1719269 --- /dev/null +++ b/src/lwjgl/java/tritonus/TAsynchronousFilteredAudioInputStream.java @@ -0,0 +1,200 @@ +/* + * TAsynchronousFilteredAudioInputStream.java + * + * This file is part of Tritonus: http://www.tritonus.org/ + */ + +/* + * Copyright (c) 1999, 2000 by Matthias Pfisterer + * Copyright (c) 2012 by fireandfuel from Cuina Team (http://www.cuina.byethost12.com/) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +package tritonus; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import javax.sound.sampled.AudioFormat; + +/** + * Base class for asynchronous converters. This class serves as base class for + * converters that do not have a fixed ratio between the size of a block of + * input data and the size of a block of output data. These types of converters + * therefore need an internal buffer, which is realized in this class. + * + * @author Matthias Pfisterer + */ +public abstract class TAsynchronousFilteredAudioInputStream extends TAudioInputStream implements + TCircularBuffer.Trigger +{ + private static final int DEFAULT_BUFFER_SIZE = 327670; + private static final int DEFAULT_MIN_AVAILABLE = 4096; + private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; + + private TCircularBuffer m_circularBuffer; + private int m_nMinAvailable; + private byte[] m_abSingleByte; + + /** + * Constructor. This constructor uses the default buffer size and the + * default min available amount. + * + * @param lLength + * length of this stream in frames. May be + * AudioSystem.NOT_SPECIFIED. + */ + public TAsynchronousFilteredAudioInputStream(AudioFormat outputFormat, long lLength) + { + this(outputFormat, lLength, DEFAULT_BUFFER_SIZE, DEFAULT_MIN_AVAILABLE); + } + + /** + * Constructor. With this constructor, the buffer size and the minimum + * available amount can be specified as parameters. + * + * @param lLength + * length of this stream in frames. May be + * AudioSystem.NOT_SPECIFIED. + * @param nBufferSize + * size of the circular buffer in bytes. + */ + public TAsynchronousFilteredAudioInputStream(AudioFormat outputFormat, long lLength, + int nBufferSize, int nMinAvailable) + { + /* + * The usage of a ByteArrayInputStream is a hack. (the infamous + * "JavaOne hack", because I did it on June 6th 2000 in San Francisco, + * only hours before a JavaOne session where I wanted to show mp3 + * playback with Java Sound.) It is necessary because in the FCS version + * of the Sun jdk1.3, the constructor of AudioInputStream throws an + * exception if its first argument is null. So we have to pass a dummy + * non-null value. + */ + super(new ByteArrayInputStream(EMPTY_BYTE_ARRAY), outputFormat, lLength); + + m_circularBuffer = new TCircularBuffer(nBufferSize, false, // blocking + // read + true, // blocking write + this); // trigger + m_nMinAvailable = nMinAvailable; + + } + + /** + * Returns the circular buffer. + */ + protected TCircularBuffer getCircularBuffer() + { + return m_circularBuffer; + } + + /** + * Check if writing more data to the circular buffer is recommended. This + * checks the available write space in the circular buffer against the + * minimum available property. If the available write space is greater than + * the minimum available property, more writing is encouraged, so this method + * returns true. Note that this is only a hint to subclasses. However, it is + * an important hint. + * + * @return true if more writing to the circular buffer is recommended. + * Otherwise, false is returned. + */ + protected boolean writeMore() + { + return getCircularBuffer().availableWrite() > m_nMinAvailable; + } + + public int read() throws IOException + { + // if (TDebug.TraceAudioConverter) { + // TDebug.out("TAsynchronousFilteredAudioInputStream.read(): begin"); } + int nByte = -1; + if(m_abSingleByte == null) + { + m_abSingleByte = new byte[1]; + } + int nReturn = read(m_abSingleByte); + if(nReturn == -1) + { + nByte = -1; + } else + { + // $$fb 2001-04-14 nobody really knows that... + nByte = m_abSingleByte[0] & 0xFF; + } + // if (TDebug.TraceAudioConverter) { + // TDebug.out("TAsynchronousFilteredAudioInputStream.read(): end"); } + return nByte; + } + + public int read(byte[] abData) throws IOException + { + + int nRead = read(abData, 0, abData.length); + + return nRead; + } + + public int read(byte[] abData, int nOffset, int nLength) throws IOException + { + + int nRead = m_circularBuffer.read(abData, nOffset, nLength); + + return nRead; + } + + public long skip(long lSkip) throws IOException + { + // TODO: this is quite inefficient + for(long lSkipped = 0; lSkipped < lSkip; lSkipped++) + { + int nReturn = read(); + if(nReturn == -1) + { + return lSkipped; + } + } + return lSkip; + } + + public int available() throws IOException + { + return m_circularBuffer.availableRead(); + } + + public void close() throws IOException + { + m_circularBuffer.close(); + } + + public boolean markSupported() + { + return false; + } + + public void mark(int nReadLimit) + { + } + + public void reset() throws IOException + { + throw new IOException("mark not supported"); + } +} + +/*** TAsynchronousFilteredAudioInputStream.java ***/ diff --git a/src/lwjgl/java/tritonus/TAudioInputStream.java b/src/lwjgl/java/tritonus/TAudioInputStream.java new file mode 100644 index 0000000..50a3246 --- /dev/null +++ b/src/lwjgl/java/tritonus/TAudioInputStream.java @@ -0,0 +1,106 @@ +/* + * TAudioInputStream.java + * + * This file is part of Tritonus: http://www.tritonus.org/ + */ + +/* + * Copyright (c) 2003 by Matthias Pfisterer + * Copyright (c) 2012 by fireandfuel from Cuina Team (http://www.cuina.byethost12.com/) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +package tritonus; + +import java.io.InputStream; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; + +/** + * AudioInputStream base class. This class implements "dynamic" properties. + * "Dynamic" properties are properties that may change during the life time of + * the objects. This is typically used to pass information like the current + * frame number, volume of subbands and similar values. "Dynamic" properties are + * different from properties in AudioFormat and AudioFileFormat, which are + * considered "static", as they aren't allowed to change after creating of the + * object, thereby maintaining the immutable character of these classes. + */ + +public class TAudioInputStream extends AudioInputStream +{ + private Map m_properties; + private Map m_unmodifiableProperties; + + /** + * Constructor without properties. Creates an empty properties map. + */ + public TAudioInputStream(InputStream inputStream, AudioFormat audioFormat, long lLengthInFrames) + { + super(inputStream, audioFormat, lLengthInFrames); + initMaps(new HashMap()); + } + + /** + * Constructor with properties. The passed properties map is not copied. + * This allows subclasses to change values in the map after creation, and + * the changes are reflected in the map the application program can obtain. + */ + public TAudioInputStream(InputStream inputStream, AudioFormat audioFormat, + long lLengthInFrames, Map properties) + { + super(inputStream, audioFormat, lLengthInFrames); + initMaps(properties); + } + + private void initMaps(Map properties) + { + /* + * Here, we make a shallow copy of the map. It's unclear if this is + * sufficient (of if a deep copy should be made). + */ + m_properties = properties; + m_unmodifiableProperties = Collections.unmodifiableMap(m_properties); + } + + /** + * Obtain a Map containing the properties. This method returns a Map that + * cannot be modified by the application program, but reflects changes to + * the map made by the implementation. + * + * @return a map containing the properties. + */ + public Map properties() + { + return m_unmodifiableProperties; + } + + /** + * Set a property. Unlike in AudioFormat and AudioFileFormat, this method + * may be used anywhere by subclasses - it is not restricted to be used in + * the constructor. + */ + protected void setProperty(String key, Object value) + { + m_properties.put(key, value); + } +} + +/*** TAudioInputStream.java ***/ diff --git a/src/lwjgl/java/tritonus/TCircularBuffer.java b/src/lwjgl/java/tritonus/TCircularBuffer.java new file mode 100644 index 0000000..de04edf --- /dev/null +++ b/src/lwjgl/java/tritonus/TCircularBuffer.java @@ -0,0 +1,201 @@ +/* + * TCircularBuffer.java + * + * This file is part of Tritonus: http://www.tritonus.org/ + */ + +/* + * Copyright (c) 1999 by Matthias Pfisterer + * Copyright (c) 2012 by fireandfuel from Cuina Team (http://www.cuina.byethost12.com/) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +package tritonus; + +public class TCircularBuffer +{ + private boolean m_bBlockingRead; + private boolean m_bBlockingWrite; + private byte[] m_abData; + private int m_nSize; + private long m_lReadPos; + private long m_lWritePos; + private Trigger m_trigger; + private boolean m_bOpen; + + public TCircularBuffer(int nSize, boolean bBlockingRead, boolean bBlockingWrite, Trigger trigger) + { + m_bBlockingRead = bBlockingRead; + m_bBlockingWrite = bBlockingWrite; + m_nSize = nSize; + m_abData = new byte[m_nSize]; + m_lReadPos = 0; + m_lWritePos = 0; + m_trigger = trigger; + m_bOpen = true; + } + + public void close() + { + m_bOpen = false; + // TODO: call notify() ? + } + + private boolean isOpen() + { + return m_bOpen; + } + + public int availableRead() + { + return (int) (m_lWritePos - m_lReadPos); + } + + public int availableWrite() + { + return m_nSize - availableRead(); + } + + private int getReadPos() + { + return (int) (m_lReadPos % m_nSize); + } + + private int getWritePos() + { + return (int) (m_lWritePos % m_nSize); + } + + public int read(byte[] abData) + { + return read(abData, 0, abData.length); + } + + public int read(byte[] abData, int nOffset, int nLength) + { + + if(!isOpen()) + { + if(availableRead() > 0) + { + nLength = Math.min(nLength, availableRead()); + + } else + { + + return -1; + } + } + synchronized(this) + { + if(m_trigger != null && availableRead() < nLength) + { + + m_trigger.execute(); + } + if(!m_bBlockingRead) + { + nLength = Math.min(availableRead(), nLength); + } + int nRemainingBytes = nLength; + while(nRemainingBytes > 0) + { + while(availableRead() == 0) + { + try + { + wait(); + } catch (InterruptedException e) + { + + } + } + int nAvailable = Math.min(availableRead(), nRemainingBytes); + while(nAvailable > 0) + { + int nToRead = Math.min(nAvailable, m_nSize - getReadPos()); + System.arraycopy(m_abData, getReadPos(), abData, nOffset, nToRead); + m_lReadPos += nToRead; + nOffset += nToRead; + nAvailable -= nToRead; + nRemainingBytes -= nToRead; + } + notifyAll(); + } + + return nLength; + } + } + + public int write(byte[] abData) + { + return write(abData, 0, abData.length); + } + + public int write(byte[] abData, int nOffset, int nLength) + { + + synchronized(this) + { + + if(!m_bBlockingWrite) + { + nLength = Math.min(availableWrite(), nLength); + } + int nRemainingBytes = nLength; + while(nRemainingBytes > 0) + { + while(availableWrite() == 0) + { + try + { + wait(); + } catch (InterruptedException e) + { + + } + } + int nAvailable = Math.min(availableWrite(), nRemainingBytes); + while(nAvailable > 0) + { + int nToWrite = Math.min(nAvailable, m_nSize - getWritePos()); + // TDebug.out("src buf size= " + abData.length + + // ", offset = " + nOffset + ", dst buf size=" + + // m_abData.length + " write pos=" + getWritePos() + " len=" + // + nToWrite); + System.arraycopy(abData, nOffset, m_abData, getWritePos(), nToWrite); + m_lWritePos += nToWrite; + nOffset += nToWrite; + nAvailable -= nToWrite; + nRemainingBytes -= nToWrite; + } + notifyAll(); + } + + return nLength; + } + } + + public static interface Trigger + { + public void execute(); + } + +} + +/*** TCircularBuffer.java ***/ + diff --git a/src/main/java/com/baislsl/png/chunk/Chunk.java b/src/main/java/com/baislsl/png/chunk/Chunk.java new file mode 100644 index 0000000..eb4f975 --- /dev/null +++ b/src/main/java/com/baislsl/png/chunk/Chunk.java @@ -0,0 +1,63 @@ +package com.baislsl.png.chunk; + +import com.baislsl.png.util.ByteHandler; + +/** + * Created by baislsl on 17-7-9. + */ +public class Chunk { + protected long length; + protected ChunkType type; + protected byte[] data; + protected byte[] crc = new byte[4]; + + public byte[] dump() { + byte[] output = new byte[4 + 4 + data.length + 4]; + Byte[] lengthBytes = new Byte[4]; + for (int i = 0; i < 4; i++) { + output[3 - i] = (byte) (length & 0xff); + } + String typeName = type.name().toUpperCase(); + for (int i = 0; i < 4; i++) { + output[4 + i] = (byte) typeName.charAt(i); + } + System.arraycopy(data, 0, output, 8, data.length); + System.arraycopy(crc, 0, output, output.length - crc.length, crc.length); + return output; + } + + + protected Chunk(byte[] length, byte[] type, byte[] data, byte[] crc) { + this.length = ByteHandler.byteToLong(length); + this.data = data; + this.crc = crc; + + for (ChunkType chunkType : ChunkType.values()) { + if (chunkType.name().equals(ByteHandler.byteToString(type))) { + this.type = chunkType; + break; + } + } + + } + + public long dataLength() { + return data.length; + } + + public long getLength() { + return length; + } + + public ChunkType getType() { + return type; + } + + public byte[] getData() { + return data; + } + + public byte[] getCrc() { + return crc; + } +} diff --git a/src/main/java/com/baislsl/png/chunk/ChunkType.java b/src/main/java/com/baislsl/png/chunk/ChunkType.java new file mode 100644 index 0000000..330f66a --- /dev/null +++ b/src/main/java/com/baislsl/png/chunk/ChunkType.java @@ -0,0 +1,38 @@ +package com.baislsl.png.chunk; + +import com.baislsl.png.decode.DecodeException; +import com.baislsl.png.decode.PNG; + +/** + * Created by baislsl on 17-7-9. + */ +public enum ChunkType { + + IHDR { + @Override + public void apply(PNG png, byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException { + png.setIhdr(new IHDR(length, type, data, crc)); + } + }, + PLTE { + @Override + public void apply(PNG png, byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException { + png.setPlte(new PLTE(length, type, data, crc)); + } + }, + IDAT { + @Override + public void apply(PNG png, byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException { + png.add(new IDAT(length, type, data, crc)); + } + }, + IEND { + @Override + public void apply(PNG png, byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException { + png.setIend(new IEND(length, type, data, crc)); + } + }; + + public abstract void apply(PNG png, byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException; + +} diff --git a/src/main/java/com/baislsl/png/chunk/IDAT.java b/src/main/java/com/baislsl/png/chunk/IDAT.java new file mode 100644 index 0000000..91cd845 --- /dev/null +++ b/src/main/java/com/baislsl/png/chunk/IDAT.java @@ -0,0 +1,11 @@ +package com.baislsl.png.chunk; + +/** + * Created by baislsl on 17-7-10. + */ +public class IDAT extends Chunk { + + public IDAT(byte[] length, byte[] type, byte[] data, byte[] crc) { + super(length, type, data, crc); + } +} diff --git a/src/main/java/com/baislsl/png/chunk/IEND.java b/src/main/java/com/baislsl/png/chunk/IEND.java new file mode 100644 index 0000000..4f1861e --- /dev/null +++ b/src/main/java/com/baislsl/png/chunk/IEND.java @@ -0,0 +1,10 @@ +package com.baislsl.png.chunk; + +/** + * Created by baislsl on 17-7-9. + */ +public class IEND extends Chunk { + public IEND(byte[] length, byte[] type, byte[] data, byte[] crc) { + super(length, type, data, crc); + } +} diff --git a/src/main/java/com/baislsl/png/chunk/IHDR.java b/src/main/java/com/baislsl/png/chunk/IHDR.java new file mode 100644 index 0000000..6cb87d3 --- /dev/null +++ b/src/main/java/com/baislsl/png/chunk/IHDR.java @@ -0,0 +1,118 @@ +package com.baislsl.png.chunk; + +import com.baislsl.png.decode.DecodeException; +import com.baislsl.png.util.ByteHandler; + +/** + * Created by baislsl on 17-7-9. + */ +public class IHDR extends Chunk { + private long width, height; + private int bitDepth, colorType, compressionMethod, filterMethod, interlaceMethod; + + final private static int[] colorTypeValid = {0, 2, 3, 4, 6}; + final private static int[][] mapColorBitDepth = { + {1, 2, 4, 8, 16}, // color type = 0 + {}, + {8, 16}, // color type = 2 + {1, 2, 4, 8}, // color type = 3 + {8, 16}, // color type = 4 + {}, + {8, 16} // color type = 6 + }; + + // the number of bytes per complete pixel, rounding up to one + public int getBpp() { + if (colorType == 2) { // Each pixel is an R,G,B triple. + return 3; + } else if (colorType == 6) { // Each pixel is an R,G,B triple, followed by an alpha sample. + return 4; + } else if (colorType == 3) { // palette index, roll up to 1 + return 1; + } else { + //LOG.error("Error when find bpp"); + return 0; + } + } + + public IHDR(byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException { + super(length, type, data, crc); + build(); + checkLegal(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("width=");sb.append(width); + sb.append("height=");sb.append(height); + sb.append("bitDepth=");sb.append(bitDepth); + sb.append("colorType=");sb.append(colorType); + sb.append("compressionMethod=");sb.append(compressionMethod); + sb.append("filterMethod=");sb.append(filterMethod); + sb.append("interlaceMethod=");sb.append(interlaceMethod); + return sb.toString(); + } + + + private void build() { + this.width = ByteHandler.byteToLong(data); + this.height = ByteHandler.byteToLong(data, 4); + this.bitDepth = ((int)data[8]) & 0xFF; + this.colorType = ((int)data[9]) & 0xFF; + this.compressionMethod = ((int)data[10]) & 0xFF; + this.filterMethod = ((int)data[11]) & 0xFF; + this.interlaceMethod = ((int)data[12]) & 0xFF; + } + + + private void checkLegal() throws DecodeException { + boolean legal = false; + for (int c : colorTypeValid) { + if (c == colorType) { + legal = true; + break; + } + } + if (!legal) { + throw new DecodeException("Initialize IHDR : color type not legal to be " + colorType); + } + for (int b : mapColorBitDepth[colorType]) { + if (b == bitDepth) { + return; + } + } + throw new DecodeException("Initialzie IHDR : bit depth " + bitDepth + " not valid matching color type " + colorType); + } + + + public long getWidth() { + return this.width; + } + + public long getHeight() { + return this.height; + } + + public int getBitDepth() { + return bitDepth; + } + + public int getColorType() { + return colorType; + } + + public int getCompressionMethod() { + return compressionMethod; + } + + public int getFilterMethod() { + return filterMethod; + } + + public int getInterlaceMethod() { + return interlaceMethod; + } + + +} diff --git a/src/main/java/com/baislsl/png/chunk/PLTE.java b/src/main/java/com/baislsl/png/chunk/PLTE.java new file mode 100644 index 0000000..d8271ea --- /dev/null +++ b/src/main/java/com/baislsl/png/chunk/PLTE.java @@ -0,0 +1,38 @@ +package com.baislsl.png.chunk; + +import com.baislsl.png.decode.DecodeException; + + +/** + * Created by baislsl on 17-7-9. + */ +public class PLTE extends Chunk { + private int[] color; + + public PLTE(byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException{ + super(length, type, data, crc); + build(); + } + + + private void build() throws DecodeException{ + if(this.length % 3 != 0 ) + throw new DecodeException("PLTE length can not be divide by 3"); + + int size = (int)length / 3; + color = new int[size]; + for(int i=0;i { + + public byte[] getIDATData() { + int dataSize = 0; + for (IDAT idat : this) { + dataSize += idat.dataLength(); + } + byte[] data = new byte[dataSize]; + int curPos = 0; + for (IDAT idat : this) { + System.arraycopy(idat.getData(), 0, data, curPos, (int) idat.dataLength()); + curPos += idat.dataLength(); + } + return data; + } + +} diff --git a/src/main/java/com/baislsl/png/decode/PNG.java b/src/main/java/com/baislsl/png/decode/PNG.java new file mode 100644 index 0000000..b8ecabc --- /dev/null +++ b/src/main/java/com/baislsl/png/decode/PNG.java @@ -0,0 +1,122 @@ +package com.baislsl.png.decode; + +import com.baislsl.png.chunk.*; +import com.baislsl.png.util.ReverseFilter; + +import net.lax1dude.eaglercraft.EaglerInflater; + +import java.io.IOException; + +/** + * Created by baislsl on 17-7-9. + */ +public class PNG { + //private final static Logger LOG = LoggerFactory.getLogger(PNG.class); + public IHDR ihdr; + public IDATManager idats = new IDATManager(); + public PLTE plte; + public IEND iend; + + public PNG() { + } + + public PNG(IHDR ihdr, IDATManager idats, PLTE plte, IEND iend) { + this.ihdr = ihdr; + this.idats = idats; + this.plte = plte; + this.iend = iend; + } + + public int[] getColor() throws DecodeException { + byte[] rawData = idats.getIDATData(); + byte[] uncompressData = applyLZ77(rawData); + byte[][] transferData = applyReverseFilter(uncompressData); + int[] colors = applyColorTransfer(transferData); + return colors; + } + + private int[] applyColorTransfer(byte[][] data) throws DecodeException { + int bpp = ihdr.getBpp(); + int width = (int) ihdr.getWidth(); + int height = (int) ihdr.getHeight(); + int colorType = ihdr.getColorType(); + int bitDepth = ihdr.getBitDepth(); + int[] colors = new int[width * height]; + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + int idx = i * width + j; + switch (colorType) { + case 2: + if (bitDepth == 8) { // bpp = 3 + colors[idx] = ((int)data[i][bpp * j] & 0xff) << 16 | ((int)data[i][bpp * j + 1] & 0xff) << 8 | ((int)data[i][bpp * j + 2] & 0xff); + }else { + throw new DecodeException("not supported"); + } + break; + case 6: + if (bitDepth == 8) { // bpp = 4 + colors[idx] = ((int)data[i][bpp * j] & 0xff) << 16 | ((int)data[i][bpp * j + 1] & 0xff) << 8 | ((int)data[i][bpp * j + 2] & 0xff) | ((int)data[i][bpp * j + 3] & 0xff) << 24; + }else { + throw new DecodeException("not supported"); + } + break; + case 3: + int gap = 8 / bitDepth; + int a = (1 << bitDepth) - 1; + colors[idx] = plte.getColor(data[i][j / gap] & a); + break; + default: + throw new DecodeException("Do not support color type " + colorType); + } + } + } + + return colors; + } + + private byte[] applyLZ77(byte[] data) throws DecodeException { + byte[] result; + try { + result = EaglerInflater.uncompress(data); + } catch (IOException e) { + //LOG.error("LZ77 decode error", e); + throw new DecodeException(e); + } + //LOG.info("Size after decode={}", result.length); + return result; + } + + private byte[][] applyReverseFilter(byte[] data) { + int width = (int) ihdr.getWidth(), height = (int) ihdr.getHeight(); + return ReverseFilter.apply(data, width, height, ihdr.getBpp()); + } + + public void setIdats(IDATManager idats) { + this.idats = idats; + } + + public void setIhdr(IHDR ihdr) { + this.ihdr = ihdr; + } + + public void setPlte(PLTE plte) { + this.plte = plte; + } + + public void setIend(IEND iend) { + this.iend = iend; + } + + public void add(IDAT idat) throws DecodeException { + idats.add(idat); + } + + public long getWidth() { + return ihdr.getWidth(); + } + + public long getHeight() { + return ihdr.getHeight(); + } + +} diff --git a/src/main/java/com/baislsl/png/util/ByteHandler.java b/src/main/java/com/baislsl/png/util/ByteHandler.java new file mode 100644 index 0000000..ecc0172 --- /dev/null +++ b/src/main/java/com/baislsl/png/util/ByteHandler.java @@ -0,0 +1,33 @@ +package com.baislsl.png.util; + +/** + * Created by baislsl on 17-7-10. + */ +public class ByteHandler { + + public static long byteToLong(byte[] data, int offset, int size){ + long result = 0; + for(int i=0;i> 1); + } else { + c >>= 1; + } + } + crcTable[i] = c; + } + } + + + private static long updateCrc(long crc, byte[] buf, int size){ + long ans = crc; + for(int i=0;i> 8); + } + return ans; + } + + public static long crc(byte[] buf, int size){ + return updateCrc(0xffffffffL, buf, size) ^ 0xffffffffL; + } + +} diff --git a/src/main/java/com/baislsl/png/util/ReverseFilter.java b/src/main/java/com/baislsl/png/util/ReverseFilter.java new file mode 100644 index 0000000..74fa99d --- /dev/null +++ b/src/main/java/com/baislsl/png/util/ReverseFilter.java @@ -0,0 +1,63 @@ +package com.baislsl.png.util; + + + +public class ReverseFilter { + private ReverseFilter(){} + + private static int paethPredictor(int a, int b, int c) { + int p = a + b - c; + int pa = Math.abs(p - a), pb = Math.abs(p - b), pc = Math.abs(p - c); + if (pa <= pb && pa <= pc) return a; + if (pb <= pc) return b; + return c; + } + + // apply reverse Filter Algorithms to byte data + // bpp = 3 + public static byte[][] apply(byte[] data, int width, int height, int bpp) { + int[] filterType = new int[height]; + int[][] blocks = new int[height][width * bpp]; + int dataIndex = 0; + for (int i = 0; i < height; i++) { + filterType[i] = (int)(data[dataIndex++]) & 0xFF; + for (int j = 0; j < width * bpp; j++) { + blocks[i][j] = (int)(data[dataIndex++]) & 0xFF; + } + } + for (int i = 0; i < height; i++) { + for (int j = 0; j < width * bpp; j++) { + int prior = (i == 0) ? 0 : blocks[i - 1][j]; + int rawBpp = (j < bpp) ? 0 : blocks[i][j - bpp]; + int bppPrior = (i == 0 || j < bpp) ? 0 : blocks[i - 1][j - bpp]; + switch (filterType[i]) { + case 0: // none + break; + case 1: // sub + blocks[i][j] = blocks[i][j] + rawBpp; + break; + case 2: // up + blocks[i][j] = blocks[i][j] + prior; + break; + case 3: //average + blocks[i][j] = blocks[i][j] + (rawBpp + prior) / 2; + break; + case 4: // paeth + blocks[i][j] = blocks[i][j] + paethPredictor(rawBpp, prior, bppPrior); + break; + default: + } + blocks[i][j] &= 0xff; + } + } + + byte[][] result = new byte[height][width * bpp]; + for (int i = 0; i < height; i++) { + for (int j = 0; j < width * bpp; j++) { + result[i][j] = (byte) blocks[i][j]; + } + } + return result; + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/AssetRepository.java b/src/main/java/net/lax1dude/eaglercraft/AssetRepository.java new file mode 100644 index 0000000..b6a8809 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/AssetRepository.java @@ -0,0 +1,48 @@ +package net.lax1dude.eaglercraft; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.HashMap; + +import com.jcraft.jzlib.InflaterInputStream; + +public class AssetRepository { + + private static final HashMap filePool = new HashMap(); + + public static final void install(byte[] pkg) throws IOException { + ByteArrayInputStream in2 = new ByteArrayInputStream(pkg); + DataInputStream in = new DataInputStream(in2); + byte[] header = new byte[8]; + in.read(header); + if(!"EAGPKG!!".equals(new String(header, Charset.forName("UTF-8")))) throw new IOException("invalid epk file"); + in.readUTF(); + in = new DataInputStream(new InflaterInputStream(in2)); + String s = null; + SHA1Digest dg = new SHA1Digest(); + while("".equals(s = in.readUTF())) { + String path = in.readUTF(); + byte[] digest = new byte[20]; + byte[] digest2 = new byte[20]; + in.read(digest); + int len = in.readInt(); + byte[] file = new byte[len]; + in.read(file); + if(filePool.containsKey(path)) continue; + dg.update(file, 0, len); dg.doFinal(digest2, 0); + if(!Arrays.equals(digest, digest2)) throw new IOException("invalid file hash for "+path); + filePool.put(path, file); + if(!"".equals(in.readUTF())) throw new IOException("invalid epk file"); + } + if(in.available() > 0 || !" end".equals(s)) throw new IOException("invalid epk file"); + } + + public static final byte[] getResource(String path) { + if(path.startsWith("/")) path = path.substring(1); + return filePool.get(path); + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/Base64.java b/src/main/java/net/lax1dude/eaglercraft/Base64.java new file mode 100644 index 0000000..41a6f57 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/Base64.java @@ -0,0 +1,845 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 net.lax1dude.eaglercraft; + +import java.math.BigInteger; +import java.nio.charset.Charset; + +/** + * Provides Base64 encoding and decoding as defined by RFC 2045. + * + *

+ * This class implements section 6.8. Base64 Content-Transfer-Encoding from RFC 2045 Multipurpose + * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies by Freed and Borenstein. + *

+ *

+ * The class can be parameterized in the following manner with various constructors: + *

+ *
    + *
  • URL-safe mode: Default off.
  • + *
  • Line length: Default 76. Line length that aren't multiples of 4 will still essentially end up being multiples of + * 4 in the encoded data. + *
  • Line separator: Default is CRLF ("\r\n")
  • + *
+ *

+ * The URL-safe parameter is only applied to encode operations. Decoding seamlessly handles both modes. + *

+ *

+ * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only + * encode/decode character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, + * UTF-8, etc). + *

+ *

+ * This class is thread-safe. + *

+ * + * @see RFC 2045 + * @since 1.0 + */ +public class Base64 extends BaseNCodec { + + /** + * BASE32 characters are 6 bits in length. + * They are formed by taking a block of 3 octets to form a 24-bit string, + * which is converted into 4 BASE64 characters. + */ + private static final int BITS_PER_ENCODED_BYTE = 6; + private static final int BYTES_PER_UNENCODED_BLOCK = 3; + private static final int BYTES_PER_ENCODED_BLOCK = 4; + + /** + * This array is a lookup table that translates 6-bit positive integer index values into their "Base64 Alphabet" + * equivalents as specified in Table 1 of RFC 2045. + * + * Thanks to "commons" project in ws.apache.org for this code. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + */ + private static final byte[] STANDARD_ENCODE_TABLE = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' + }; + + /** + * This is a copy of the STANDARD_ENCODE_TABLE above, but with + and / + * changed to - and _ to make the encoded Base64 results more URL-SAFE. + * This table is only used when the Base64's mode is set to URL-SAFE. + */ + private static final byte[] URL_SAFE_ENCODE_TABLE = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' + }; + + /** + * This array is a lookup table that translates Unicode characters drawn from the "Base64 Alphabet" (as specified + * in Table 1 of RFC 2045) into their 6-bit positive integer equivalents. Characters that are not in the Base64 + * alphabet but fall within the bounds of the array are translated to -1. + * + * Note: '+' and '-' both decode to 62. '/' and '_' both decode to 63. This means decoder seamlessly handles both + * URL_SAFE and STANDARD base64. (The encoder, on the other hand, needs to know ahead of time what to emit). + * + * Thanks to "commons" project in ws.apache.org for this code. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + */ + private static final byte[] DECODE_TABLE = { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 00-0f + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10-1f + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, // 20-2f + - / + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 30-3f 0-9 + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 40-4f A-O + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, // 50-5f P-Z _ + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 60-6f a-o + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 // 70-7a p-z + }; + + /** + * Base64 uses 6-bit fields. + */ + /** Mask used to extract 6 bits, used when encoding */ + private static final int MASK_6BITS = 0x3f; + /** Mask used to extract 4 bits, used when decoding final trailing character. */ + private static final int MASK_4BITS = 0xf; + /** Mask used to extract 2 bits, used when decoding final trailing character. */ + private static final int MASK_2BITS = 0x3; + + // The static final fields above are used for the original static byte[] methods on Base64. + // The private member fields below are used with the new streaming approach, which requires + // some state be preserved between calls of encode() and decode(). + + /** + * Decodes Base64 data into octets. + *

+ * Note: this method seamlessly handles data encoded in URL-safe or normal mode. + *

+ * + * @param base64Data + * Byte array containing Base64 data + * @return Array containing decoded data. + */ + public static byte[] decodeBase64(final byte[] base64Data) { + return new Base64().decode(base64Data); + } + + /** + * Decodes a Base64 String into octets. + *

+ * Note: this method seamlessly handles data encoded in URL-safe or normal mode. + *

+ * + * @param base64String + * String containing Base64 data + * @return Array containing decoded data. + * @since 1.4 + */ + public static byte[] decodeBase64(final String base64String) { + return new Base64().decode(base64String); + } + + // Implementation of integer encoding used for crypto + /** + * Decodes a byte64-encoded integer according to crypto standards such as W3C's XML-Signature. + * + * @param pArray + * a byte array containing base64 character data + * @return A BigInteger + * @since 1.4 + */ + public static BigInteger decodeInteger(final byte[] pArray) { + return new BigInteger(1, decodeBase64(pArray)); + } + + /** + * Encodes binary data using the base64 algorithm but does not chunk the output. + * + * @param binaryData + * binary data to encode + * @return byte[] containing Base64 characters in their UTF-8 representation. + */ + public static byte[] encodeBase64(final byte[] binaryData) { + return encodeBase64(binaryData, false); + } + + /** + * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. + * + * @param binaryData + * Array containing binary data to encode. + * @param isChunked + * if {@code true} this encoder will chunk the base64 output into 76 character blocks + * @return Base64-encoded data. + * @throws IllegalArgumentException + * Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE} + */ + public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked) { + return encodeBase64(binaryData, isChunked, false); + } + + /** + * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. + * + * @param binaryData + * Array containing binary data to encode. + * @param isChunked + * if {@code true} this encoder will chunk the base64 output into 76 character blocks + * @param urlSafe + * if {@code true} this encoder will emit - and _ instead of the usual + and / characters. + * Note: no padding is added when encoding using the URL-safe alphabet. + * @return Base64-encoded data. + * @throws IllegalArgumentException + * Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE} + * @since 1.4 + */ + public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked, final boolean urlSafe) { + return encodeBase64(binaryData, isChunked, urlSafe, Integer.MAX_VALUE); + } + + /** + * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. + * + * @param binaryData + * Array containing binary data to encode. + * @param isChunked + * if {@code true} this encoder will chunk the base64 output into 76 character blocks + * @param urlSafe + * if {@code true} this encoder will emit - and _ instead of the usual + and / characters. + * Note: no padding is added when encoding using the URL-safe alphabet. + * @param maxResultSize + * The maximum result size to accept. + * @return Base64-encoded data. + * @throws IllegalArgumentException + * Thrown when the input array needs an output array bigger than maxResultSize + * @since 1.4 + */ + public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked, + final boolean urlSafe, final int maxResultSize) { + if (binaryData == null || binaryData.length == 0) { + return binaryData; + } + + // Create this so can use the super-class method + // Also ensures that the same roundings are performed by the ctor and the code + final Base64 b64 = isChunked ? new Base64(urlSafe) : new Base64(0, CHUNK_SEPARATOR, urlSafe); + final long len = b64.getEncodedLength(binaryData); + if (len > maxResultSize) { + throw new IllegalArgumentException("Input array too big, the output array would be bigger (" + + len + + ") than the specified maximum size of " + + maxResultSize); + } + + return b64.encode(binaryData); + } + + /** + * Encodes binary data using the base64 algorithm and chunks the encoded output into 76 character blocks + * + * @param binaryData + * binary data to encode + * @return Base64 characters chunked in 76 character blocks + */ + public static byte[] encodeBase64Chunked(final byte[] binaryData) { + return encodeBase64(binaryData, true); + } + + /** + * Encodes binary data using the base64 algorithm but does not chunk the output. + * + * NOTE: We changed the behavior of this method from multi-line chunking (commons-codec-1.4) to + * single-line non-chunking (commons-codec-1.5). + * + * @param binaryData + * binary data to encode + * @return String containing Base64 characters. + * @since 1.4 (NOTE: 1.4 chunked the output, whereas 1.5 does not). + */ + public static String encodeBase64String(final byte[] binaryData) { + return new String(encodeBase64(binaryData, false), Charset.forName("UTF-8")); + } + + /** + * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The + * url-safe variation emits - and _ instead of + and / characters. + * Note: no padding is added. + * @param binaryData + * binary data to encode + * @return byte[] containing Base64 characters in their UTF-8 representation. + * @since 1.4 + */ + public static byte[] encodeBase64URLSafe(final byte[] binaryData) { + return encodeBase64(binaryData, false, true); + } + + /** + * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The + * url-safe variation emits - and _ instead of + and / characters. + * Note: no padding is added. + * @param binaryData + * binary data to encode + * @return String containing Base64 characters + * @since 1.4 + */ + public static String encodeBase64URLSafeString(final byte[] binaryData) { + return new String(encodeBase64(binaryData, false, true), Charset.forName("UTF-8")); + } + + /** + * Encodes to a byte64-encoded integer according to crypto standards such as W3C's XML-Signature. + * + * @param bigInteger + * a BigInteger + * @return A byte array containing base64 character data + * @throws NullPointerException + * if null is passed in + * @since 1.4 + */ + public static byte[] encodeInteger(final BigInteger bigInteger) { + return encodeBase64(toIntegerBytes(bigInteger), false); + } + + /** + * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the + * method treats whitespace as valid. + * + * @param arrayOctet + * byte array to test + * @return {@code true} if all bytes are valid characters in the Base64 alphabet or if the byte array is empty; + * {@code false}, otherwise + * @deprecated 1.5 Use {@link #isBase64(byte[])}, will be removed in 2.0. + */ + @Deprecated + public static boolean isArrayByteBase64(final byte[] arrayOctet) { + return isBase64(arrayOctet); + } + + /** + * Returns whether or not the {@code octet} is in the base 64 alphabet. + * + * @param octet + * The value to test + * @return {@code true} if the value is defined in the the base 64 alphabet, {@code false} otherwise. + * @since 1.4 + */ + public static boolean isBase64(final byte octet) { + return octet == PAD_DEFAULT || (octet >= 0 && octet < DECODE_TABLE.length && DECODE_TABLE[octet] != -1); + } + + /** + * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the + * method treats whitespace as valid. + * + * @param arrayOctet + * byte array to test + * @return {@code true} if all bytes are valid characters in the Base64 alphabet or if the byte array is empty; + * {@code false}, otherwise + * @since 1.5 + */ + public static boolean isBase64(final byte[] arrayOctet) { + for (int i = 0; i < arrayOctet.length; i++) { + if (!isBase64(arrayOctet[i]) && !isWhiteSpace(arrayOctet[i])) { + return false; + } + } + return true; + } + + /** + * Tests a given String to see if it contains only valid characters within the Base64 alphabet. Currently the + * method treats whitespace as valid. + * + * @param base64 + * String to test + * @return {@code true} if all characters in the String are valid characters in the Base64 alphabet or if + * the String is empty; {@code false}, otherwise + * @since 1.5 + */ + public static boolean isBase64(final String base64) { + return isBase64(base64.getBytes(Charset.forName("UTF-8"))); + } + + /** + * Returns a byte-array representation of a {@code BigInteger} without sign bit. + * + * @param bigInt + * {@code BigInteger} to be converted + * @return a byte array representation of the BigInteger parameter + */ + static byte[] toIntegerBytes(final BigInteger bigInt) { + int bitlen = bigInt.bitLength(); + // round bitlen + bitlen = ((bitlen + 7) >> 3) << 3; + final byte[] bigBytes = bigInt.toByteArray(); + + if (((bigInt.bitLength() % 8) != 0) && (((bigInt.bitLength() / 8) + 1) == (bitlen / 8))) { + return bigBytes; + } + // set up params for copying everything but sign bit + int startSrc = 0; + int len = bigBytes.length; + + // if bigInt is exactly byte-aligned, just skip signbit in copy + if ((bigInt.bitLength() % 8) == 0) { + startSrc = 1; + len--; + } + final int startDst = bitlen / 8 - len; // to pad w/ nulls as per spec + final byte[] resizedBytes = new byte[bitlen / 8]; + System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, len); + return resizedBytes; + } + + /** + * Encode table to use: either STANDARD or URL_SAFE. Note: the DECODE_TABLE above remains static because it is able + * to decode both STANDARD and URL_SAFE streams, but the encodeTable must be a member variable so we can switch + * between the two modes. + */ + private final byte[] encodeTable; + + // Only one decode table currently; keep for consistency with Base32 code + private final byte[] decodeTable = DECODE_TABLE; + + /** + * Line separator for encoding. Not used when decoding. Only used if lineLength > 0. + */ + private final byte[] lineSeparator; + + /** + * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing. + * {@code decodeSize = 3 + lineSeparator.length;} + */ + private final int decodeSize; + + /** + * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing. + * {@code encodeSize = 4 + lineSeparator.length;} + */ + private final int encodeSize; + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length is 0 (no chunking), and the encoding table is STANDARD_ENCODE_TABLE. + *

+ * + *

+ * When decoding all variants are supported. + *

+ */ + public Base64() { + this(0); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in the given URL-safe mode. + *

+ * When encoding the line length is 76, the line separator is CRLF, and the encoding table is STANDARD_ENCODE_TABLE. + *

+ * + *

+ * When decoding all variants are supported. + *

+ * + * @param urlSafe + * if {@code true}, URL-safe encoding is used. In most cases this should be set to + * {@code false}. + * @since 1.4 + */ + public Base64(final boolean urlSafe) { + this(MIME_CHUNK_SIZE, CHUNK_SEPARATOR, urlSafe); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length is given in the constructor, the line separator is CRLF, and the encoding table is + * STANDARD_ENCODE_TABLE. + *

+ *

+ * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. + *

+ *

+ * When decoding all variants are supported. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of + * 4). If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when + * decoding. + * @since 1.4 + */ + public Base64(final int lineLength) { + this(lineLength, CHUNK_SEPARATOR); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length and line separator are given in the constructor, and the encoding table is + * STANDARD_ENCODE_TABLE. + *

+ *

+ * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. + *

+ *

+ * When decoding all variants are supported. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of + * 4). If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when + * decoding. + * @param lineSeparator + * Each line of encoded data will end with this sequence of bytes. + * @throws IllegalArgumentException + * Thrown when the provided lineSeparator included some base64 characters. + * @since 1.4 + */ + public Base64(final int lineLength, final byte[] lineSeparator) { + this(lineLength, lineSeparator, false); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length and line separator are given in the constructor, and the encoding table is + * STANDARD_ENCODE_TABLE. + *

+ *

+ * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. + *

+ *

+ * When decoding all variants are supported. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of + * 4). If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when + * decoding. + * @param lineSeparator + * Each line of encoded data will end with this sequence of bytes. + * @param urlSafe + * Instead of emitting '+' and '/' we emit '-' and '_' respectively. urlSafe is only applied to encode + * operations. Decoding seamlessly handles both modes. + * Note: no padding is added when using the URL-safe alphabet. + * @throws IllegalArgumentException + * Thrown when the {@code lineSeparator} contains Base64 characters. + * @since 1.4 + */ + public Base64(final int lineLength, final byte[] lineSeparator, final boolean urlSafe) { + this(lineLength, lineSeparator, urlSafe, CodecPolicy.LENIANT); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length and line separator are given in the constructor, and the encoding table is + * STANDARD_ENCODE_TABLE. + *

+ *

+ * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. + *

+ *

+ * When decoding all variants are supported. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of + * 4). If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when + * decoding. + * @param lineSeparator + * Each line of encoded data will end with this sequence of bytes. + * @param urlSafe + * Instead of emitting '+' and '/' we emit '-' and '_' respectively. urlSafe is only applied to encode + * operations. Decoding seamlessly handles both modes. + * Note: no padding is added when using the URL-safe alphabet. + * @param decodingPolicy The decoding policy. + * @throws IllegalArgumentException + * Thrown when the {@code lineSeparator} contains Base64 characters. + * @since 1.15 + */ + public Base64(final int lineLength, final byte[] lineSeparator, final boolean urlSafe, final CodecPolicy decodingPolicy) { + super(BYTES_PER_UNENCODED_BLOCK, BYTES_PER_ENCODED_BLOCK, + lineLength, + lineSeparator == null ? 0 : lineSeparator.length, + PAD_DEFAULT, + decodingPolicy); + // TODO could be simplified if there is no requirement to reject invalid line sep when length <=0 + // @see test case Base64Test.testConstructors() + if (lineSeparator != null) { + if (containsAlphabetOrPad(lineSeparator)) { + final String sep = new String(lineSeparator, Charset.forName("UTF-8")); + throw new IllegalArgumentException("lineSeparator must not contain base64 characters: [" + sep + "]"); + } + if (lineLength > 0){ // null line-sep forces no chunking rather than throwing IAE + this.encodeSize = BYTES_PER_ENCODED_BLOCK + lineSeparator.length; + this.lineSeparator = new byte[lineSeparator.length]; + System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length); + } else { + this.encodeSize = BYTES_PER_ENCODED_BLOCK; + this.lineSeparator = null; + } + } else { + this.encodeSize = BYTES_PER_ENCODED_BLOCK; + this.lineSeparator = null; + } + this.decodeSize = this.encodeSize - 1; + this.encodeTable = urlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE; + } + + // Implementation of the Encoder Interface + + /** + *

+ * Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once + * with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1" + * call is not necessary when decoding, but it doesn't hurt, either. + *

+ *

+ * Ignores all non-base64 characters. This is how chunked (e.g. 76 character) data is handled, since CR and LF are + * silently ignored, but has implications for other bytes, too. This method subscribes to the garbage-in, + * garbage-out philosophy: it will not check the provided data for validity. + *

+ *

+ * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + *

+ * + * @param in + * byte[] array of ascii data to base64 decode. + * @param inPos + * Position to start reading data from. + * @param inAvail + * Amount of bytes available from input for decoding. + * @param context + * the context to be used + */ + @Override + void decode(final byte[] in, int inPos, final int inAvail, final Context context) { + if (context.eof) { + return; + } + if (inAvail < 0) { + context.eof = true; + } + for (int i = 0; i < inAvail; i++) { + final byte[] buffer = ensureBufferSize(decodeSize, context); + final byte b = in[inPos++]; + if (b == pad) { + // We're done. + context.eof = true; + break; + } + if (b >= 0 && b < DECODE_TABLE.length) { + final int result = DECODE_TABLE[b]; + if (result >= 0) { + context.modulus = (context.modulus+1) % BYTES_PER_ENCODED_BLOCK; + context.ibitWorkArea = (context.ibitWorkArea << BITS_PER_ENCODED_BYTE) + result; + if (context.modulus == 0) { + buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 16) & MASK_8BITS); + buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 8) & MASK_8BITS); + buffer[context.pos++] = (byte) (context.ibitWorkArea & MASK_8BITS); + } + } + } + } + + // Two forms of EOF as far as base64 decoder is concerned: actual + // EOF (-1) and first time '=' character is encountered in stream. + // This approach makes the '=' padding characters completely optional. + if (context.eof && context.modulus != 0) { + final byte[] buffer = ensureBufferSize(decodeSize, context); + + // We have some spare bits remaining + // Output all whole multiples of 8 bits and ignore the rest + switch (context.modulus) { +// case 0 : // impossible, as excluded above + case 1 : // 6 bits - either ignore entirely, or raise an exception + validateTrailingCharacter(); + break; + case 2 : // 12 bits = 8 + 4 + validateCharacter(MASK_4BITS, context); + context.ibitWorkArea = context.ibitWorkArea >> 4; // dump the extra 4 bits + buffer[context.pos++] = (byte) ((context.ibitWorkArea) & MASK_8BITS); + break; + case 3 : // 18 bits = 8 + 8 + 2 + validateCharacter(MASK_2BITS, context); + context.ibitWorkArea = context.ibitWorkArea >> 2; // dump 2 bits + buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 8) & MASK_8BITS); + buffer[context.pos++] = (byte) ((context.ibitWorkArea) & MASK_8BITS); + break; + default: + throw new IllegalStateException("Impossible modulus " + context.modulus); + } + } + } + + /** + *

+ * Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least twice: once with + * the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been reached, to flush last + * remaining bytes (if not multiple of 3). + *

+ *

Note: no padding is added when encoding using the URL-safe alphabet.

+ *

+ * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + *

+ * + * @param in + * byte[] array of binary data to base64 encode. + * @param inPos + * Position to start reading data from. + * @param inAvail + * Amount of bytes available from input for encoding. + * @param context + * the context to be used + */ + @Override + void encode(final byte[] in, int inPos, final int inAvail, final Context context) { + if (context.eof) { + return; + } + // inAvail < 0 is how we're informed of EOF in the underlying data we're + // encoding. + if (inAvail < 0) { + context.eof = true; + if (0 == context.modulus && lineLength == 0) { + return; // no leftovers to process and not using chunking + } + final byte[] buffer = ensureBufferSize(encodeSize, context); + final int savedPos = context.pos; + switch (context.modulus) { // 0-2 + case 0 : // nothing to do here + break; + case 1 : // 8 bits = 6 + 2 + // top 6 bits: + buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 2) & MASK_6BITS]; + // remaining 2: + buffer[context.pos++] = encodeTable[(context.ibitWorkArea << 4) & MASK_6BITS]; + // URL-SAFE skips the padding to further reduce size. + if (encodeTable == STANDARD_ENCODE_TABLE) { + buffer[context.pos++] = pad; + buffer[context.pos++] = pad; + } + break; + + case 2 : // 16 bits = 6 + 6 + 4 + buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 10) & MASK_6BITS]; + buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 4) & MASK_6BITS]; + buffer[context.pos++] = encodeTable[(context.ibitWorkArea << 2) & MASK_6BITS]; + // URL-SAFE skips the padding to further reduce size. + if (encodeTable == STANDARD_ENCODE_TABLE) { + buffer[context.pos++] = pad; + } + break; + default: + throw new IllegalStateException("Impossible modulus " + context.modulus); + } + context.currentLinePos += context.pos - savedPos; // keep track of current line position + // if currentPos == 0 we are at the start of a line, so don't add CRLF + if (lineLength > 0 && context.currentLinePos > 0) { + System.arraycopy(lineSeparator, 0, buffer, context.pos, lineSeparator.length); + context.pos += lineSeparator.length; + } + } else { + for (int i = 0; i < inAvail; i++) { + final byte[] buffer = ensureBufferSize(encodeSize, context); + context.modulus = (context.modulus+1) % BYTES_PER_UNENCODED_BLOCK; + int b = in[inPos++]; + if (b < 0) { + b += 256; + } + context.ibitWorkArea = (context.ibitWorkArea << 8) + b; // BITS_PER_BYTE + if (0 == context.modulus) { // 3 bytes = 24 bits = 4 * 6 bits to extract + buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 18) & MASK_6BITS]; + buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 12) & MASK_6BITS]; + buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 6) & MASK_6BITS]; + buffer[context.pos++] = encodeTable[context.ibitWorkArea & MASK_6BITS]; + context.currentLinePos += BYTES_PER_ENCODED_BLOCK; + if (lineLength > 0 && lineLength <= context.currentLinePos) { + System.arraycopy(lineSeparator, 0, buffer, context.pos, lineSeparator.length); + context.pos += lineSeparator.length; + context.currentLinePos = 0; + } + } + } + } + } + + /** + * Returns whether or not the {@code octet} is in the Base64 alphabet. + * + * @param octet + * The value to test + * @return {@code true} if the value is defined in the the Base64 alphabet {@code false} otherwise. + */ + @Override + protected boolean isInAlphabet(final byte octet) { + return octet >= 0 && octet < decodeTable.length && decodeTable[octet] != -1; + } + + /** + * Returns our current encode mode. True if we're URL-SAFE, false otherwise. + * + * @return true if we're in URL-SAFE mode, false otherwise. + * @since 1.4 + */ + public boolean isUrlSafe() { + return this.encodeTable == URL_SAFE_ENCODE_TABLE; + } + + /** + * Validates whether decoding the final trailing character is possible in the context + * of the set of possible base 64 values. + * + *

The character is valid if the lower bits within the provided mask are zero. This + * is used to test the final trailing base-64 digit is zero in the bits that will be discarded. + * + * @param emptyBitsMask The mask of the lower bits that should be empty + * @param context the context to be used + * + * @throws IllegalArgumentException if the bits being checked contain any non-zero value + */ + private void validateCharacter(final int emptyBitsMask, final Context context) { + if (isStrictDecoding() && (context.ibitWorkArea & emptyBitsMask) != 0) { + throw new IllegalArgumentException( + "Strict decoding: Last encoded character (before the paddings if any) is a valid base 64 alphabet but not a possible encoding. " + + "Expected the discarded bits from the character to be zero."); + } + } + + /** + * Validates whether decoding allows an entire final trailing character that cannot be + * used for a complete byte. + * + * @throws IllegalArgumentException if strict decoding is enabled + */ + private void validateTrailingCharacter() { + if (isStrictDecoding()) { + throw new IllegalArgumentException( + "Strict decoding: Last encoded character (before the paddings if any) is a valid base 64 alphabet but not a possible encoding. " + + "Decoding requires at least two trailing 6-bit characters to create bytes."); + } + } + +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/BaseNCodec.java b/src/main/java/net/lax1dude/eaglercraft/BaseNCodec.java new file mode 100644 index 0000000..4478555 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/BaseNCodec.java @@ -0,0 +1,674 @@ +package net.lax1dude.eaglercraft; + +import java.nio.charset.Charset; +import java.util.Arrays; + +import net.lax1dude.eaglercraft.BaseNCodec.CodecPolicy; + +public abstract class BaseNCodec { + + static enum CodecPolicy { + STRICT,LENIANT; + } + + /** + * Holds thread context so classes can be thread-safe. + * + * This class is not itself thread-safe; each thread must allocate its own copy. + * + * @since 1.7 + */ + static class Context { + + /** + * Place holder for the bytes we're dealing with for our based logic. + * Bitwise operations store and extract the encoding or decoding from this variable. + */ + int ibitWorkArea; + + /** + * Place holder for the bytes we're dealing with for our based logic. + * Bitwise operations store and extract the encoding or decoding from this variable. + */ + long lbitWorkArea; + + /** + * Buffer for streaming. + */ + byte[] buffer; + + /** + * Position where next character should be written in the buffer. + */ + int pos; + + /** + * Position where next character should be read from the buffer. + */ + int readPos; + + /** + * Boolean flag to indicate the EOF has been reached. Once EOF has been reached, this object becomes useless, + * and must be thrown away. + */ + boolean eof; + + /** + * Variable tracks how many characters have been written to the current line. Only used when encoding. We use + * it to make sure each encoded line never goes beyond lineLength (if lineLength > 0). + */ + int currentLinePos; + + /** + * Writes to the buffer only occur after every 3/5 reads when encoding, and every 4/8 reads when decoding. This + * variable helps track that. + */ + int modulus; + + Context() { + } + + /** + * Returns a String useful for debugging (especially within a debugger.) + * + * @return a String useful for debugging. + */ + @SuppressWarnings("boxing") // OK to ignore boxing here + @Override + public String toString() { + return String.format("%s[buffer=%s, currentLinePos=%s, eof=%s, ibitWorkArea=%s, lbitWorkArea=%s, " + + "modulus=%s, pos=%s, readPos=%s]", this.getClass().getSimpleName(), Arrays.toString(buffer), + currentLinePos, eof, ibitWorkArea, lbitWorkArea, modulus, pos, readPos); + } + } + + /** + * EOF + * + * @since 1.7 + */ + static final int EOF = -1; + + /** + * MIME chunk size per RFC 2045 section 6.8. + * + *

+ * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any + * equal signs. + *

+ * + * @see RFC 2045 section 6.8 + */ + public static final int MIME_CHUNK_SIZE = 76; + + /** + * PEM chunk size per RFC 1421 section 4.3.2.4. + * + *

+ * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any + * equal signs. + *

+ * + * @see RFC 1421 section 4.3.2.4 + */ + public static final int PEM_CHUNK_SIZE = 64; + + private static final int DEFAULT_BUFFER_RESIZE_FACTOR = 2; + + /** + * Defines the default buffer size - currently {@value} + * - must be large enough for at least one encoded block+separator + */ + private static final int DEFAULT_BUFFER_SIZE = 8192; + + /** + * The maximum size buffer to allocate. + * + *

This is set to the same size used in the JDK {@code java.util.ArrayList}:

+ *
+ * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit. + *
+ */ + private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; + + /** Mask used to extract 8 bits, used in decoding bytes */ + protected static final int MASK_8BITS = 0xff; + + /** + * Byte used to pad output. + */ + protected static final byte PAD_DEFAULT = '='; // Allow static access to default + + /** + * Chunk separator per RFC 2045 section 2.1. + * + * @see RFC 2045 section 2.1 + */ + static final byte[] CHUNK_SEPARATOR = {'\r', '\n'}; + + /** + * Compares two {@code int} values numerically treating the values + * as unsigned. Taken from JDK 1.8. + * + *

TODO: Replace with JDK 1.8 Integer::compareUnsigned(int, int).

+ * + * @param x the first {@code int} to compare + * @param y the second {@code int} to compare + * @return the value {@code 0} if {@code x == y}; a value less + * than {@code 0} if {@code x < y} as unsigned values; and + * a value greater than {@code 0} if {@code x > y} as + * unsigned values + */ + private static int compareUnsigned(final int xx, final int yy) { + int x = xx + Integer.MIN_VALUE; + int y = yy + Integer.MIN_VALUE; + return (x < y) ? -1 : ((x == y) ? 0 : 1); + } + + /** + * Create a positive capacity at least as large the minimum required capacity. + * If the minimum capacity is negative then this throws an OutOfMemoryError as no array + * can be allocated. + * + * @param minCapacity the minimum capacity + * @return the capacity + * @throws OutOfMemoryError if the {@code minCapacity} is negative + */ + private static int createPositiveCapacity(final int minCapacity) { + if (minCapacity < 0) { + // overflow + throw new OutOfMemoryError("Unable to allocate array size: " + (minCapacity & 0xffffffffL)); + } + // This is called when we require buffer expansion to a very big array. + // Use the conservative maximum buffer size if possible, otherwise the biggest required. + // + // Note: In this situation JDK 1.8 java.util.ArrayList returns Integer.MAX_VALUE. + // This excludes some VMs that can exceed MAX_BUFFER_SIZE but not allocate a full + // Integer.MAX_VALUE length array. + // The result is that we may have to allocate an array of this size more than once if + // the capacity must be expanded again. + return (minCapacity > MAX_BUFFER_SIZE) ? + minCapacity : + MAX_BUFFER_SIZE; + } + + /** + * Gets a copy of the chunk separator per RFC 2045 section 2.1. + * + * @return the chunk separator + * @see RFC 2045 section 2.1 + * @since 1.15 + */ + public static byte[] getChunkSeparator() { + return CHUNK_SEPARATOR.clone(); + } + + /** + * Checks if a byte value is whitespace or not. + * Whitespace is taken to mean: space, tab, CR, LF + * @param byteToCheck + * the byte to check + * @return true if byte is whitespace, false otherwise + */ + protected static boolean isWhiteSpace(final byte byteToCheck) { + switch (byteToCheck) { + case ' ' : + case '\n' : + case '\r' : + case '\t' : + return true; + default : + return false; + } + } + + /** + * Increases our buffer by the {@link #DEFAULT_BUFFER_RESIZE_FACTOR}. + * @param context the context to be used + * @param minCapacity the minimum required capacity + * @return the resized byte[] buffer + * @throws OutOfMemoryError if the {@code minCapacity} is negative + */ + private static byte[] resizeBuffer(final Context context, final int minCapacity) { + // Overflow-conscious code treats the min and new capacity as unsigned. + final int oldCapacity = context.buffer.length; + int newCapacity = oldCapacity * DEFAULT_BUFFER_RESIZE_FACTOR; + if (compareUnsigned(newCapacity, minCapacity) < 0) { + newCapacity = minCapacity; + } + if (compareUnsigned(newCapacity, MAX_BUFFER_SIZE) > 0) { + newCapacity = createPositiveCapacity(minCapacity); + } + + final byte[] b = new byte[newCapacity]; + System.arraycopy(context.buffer, 0, b, 0, context.buffer.length); + context.buffer = b; + return b; + } + + /** + * @deprecated Use {@link #pad}. Will be removed in 2.0. + */ + @Deprecated + protected final byte PAD = PAD_DEFAULT; // instance variable just in case it needs to vary later + + protected final byte pad; // instance variable just in case it needs to vary later + + /** Number of bytes in each full block of unencoded data, e.g. 4 for Base64 and 5 for Base32 */ + private final int unencodedBlockSize; + + /** Number of bytes in each full block of encoded data, e.g. 3 for Base64 and 8 for Base32 */ + private final int encodedBlockSize; + + /** + * Chunksize for encoding. Not used when decoding. + * A value of zero or less implies no chunking of the encoded data. + * Rounded down to nearest multiple of encodedBlockSize. + */ + protected final int lineLength; + + /** + * Size of chunk separator. Not used unless {@link #lineLength} > 0. + */ + private final int chunkSeparatorLength; + + /** + * Defines the decoding behavior when the input bytes contain leftover trailing bits that + * cannot be created by a valid encoding. These can be bits that are unused from the final + * character or entire characters. The default mode is lenient decoding. Set this to + * {@code true} to enable strict decoding. + *
    + *
  • Lenient: Any trailing bits are composed into 8-bit bytes where possible. + * The remainder are discarded. + *
  • Strict: The decoding will raise an {@link IllegalArgumentException} if trailing bits + * are not part of a valid encoding. Any unused bits from the final character must + * be zero. Impossible counts of entire final characters are not allowed. + *
+ * + *

When strict decoding is enabled it is expected that the decoded bytes will be re-encoded + * to a byte array that matches the original, i.e. no changes occur on the final + * character. This requires that the input bytes use the same padding and alphabet + * as the encoder. + */ + private final CodecPolicy decodingPolicy; + + /** + * Note {@code lineLength} is rounded down to the nearest multiple of the encoded block size. + * If {@code chunkSeparatorLength} is zero, then chunking is disabled. + * @param unencodedBlockSize the size of an unencoded block (e.g. Base64 = 3) + * @param encodedBlockSize the size of an encoded block (e.g. Base64 = 4) + * @param lineLength if > 0, use chunking with a length {@code lineLength} + * @param chunkSeparatorLength the chunk separator length, if relevant + */ + protected BaseNCodec(final int unencodedBlockSize, final int encodedBlockSize, + final int lineLength, final int chunkSeparatorLength) { + this(unencodedBlockSize, encodedBlockSize, lineLength, chunkSeparatorLength, PAD_DEFAULT); + } + + /** + * Note {@code lineLength} is rounded down to the nearest multiple of the encoded block size. + * If {@code chunkSeparatorLength} is zero, then chunking is disabled. + * @param unencodedBlockSize the size of an unencoded block (e.g. Base64 = 3) + * @param encodedBlockSize the size of an encoded block (e.g. Base64 = 4) + * @param lineLength if > 0, use chunking with a length {@code lineLength} + * @param chunkSeparatorLength the chunk separator length, if relevant + * @param pad byte used as padding byte. + */ + protected BaseNCodec(final int unencodedBlockSize, final int encodedBlockSize, + final int lineLength, final int chunkSeparatorLength, final byte pad) { + this(unencodedBlockSize, encodedBlockSize, lineLength, chunkSeparatorLength, pad, CodecPolicy.LENIANT); + } + + /** + * Note {@code lineLength} is rounded down to the nearest multiple of the encoded block size. + * If {@code chunkSeparatorLength} is zero, then chunking is disabled. + * @param unencodedBlockSize the size of an unencoded block (e.g. Base64 = 3) + * @param encodedBlockSize the size of an encoded block (e.g. Base64 = 4) + * @param lineLength if > 0, use chunking with a length {@code lineLength} + * @param chunkSeparatorLength the chunk separator length, if relevant + * @param pad byte used as padding byte. + * @param decodingPolicy Decoding policy. + * @since 1.15 + */ + protected BaseNCodec(final int unencodedBlockSize, final int encodedBlockSize, + final int lineLength, final int chunkSeparatorLength, final byte pad, final CodecPolicy decodingPolicy) { + this.unencodedBlockSize = unencodedBlockSize; + this.encodedBlockSize = encodedBlockSize; + final boolean useChunking = lineLength > 0 && chunkSeparatorLength > 0; + this.lineLength = useChunking ? (lineLength / encodedBlockSize) * encodedBlockSize : 0; + this.chunkSeparatorLength = chunkSeparatorLength; + this.pad = pad; + this.decodingPolicy = decodingPolicy; + } + + /** + * Returns the amount of buffered data available for reading. + * + * @param context the context to be used + * @return The amount of buffered data available for reading. + */ + int available(final Context context) { // package protected for access from I/O streams + return context.buffer != null ? context.pos - context.readPos : 0; + } + + /** + * Tests a given byte array to see if it contains any characters within the alphabet or PAD. + * + * Intended for use in checking line-ending arrays + * + * @param arrayOctet + * byte array to test + * @return {@code true} if any byte is a valid character in the alphabet or PAD; {@code false} otherwise + */ + protected boolean containsAlphabetOrPad(final byte[] arrayOctet) { + if (arrayOctet == null) { + return false; + } + for (final byte element : arrayOctet) { + if (pad == element || isInAlphabet(element)) { + return true; + } + } + return false; + } + + /** + * Decodes a byte[] containing characters in the Base-N alphabet. + * + * @param pArray + * A byte array containing Base-N character data + * @return a byte array containing binary data + */ + public byte[] decode(final byte[] pArray) { + if (pArray == null || pArray.length == 0) { + return pArray; + } + final Context context = new Context(); + decode(pArray, 0, pArray.length, context); + decode(pArray, 0, EOF, context); // Notify decoder of EOF. + final byte[] result = new byte[context.pos]; + readResults(result, 0, result.length, context); + return result; + } + + // package protected for access from I/O streams + abstract void decode(byte[] pArray, int i, int length, Context context); + + /** + * Decodes an Object using the Base-N algorithm. This method is provided in order to satisfy the requirements of + * the Decoder interface, and will throw a DecoderException if the supplied object is not of type byte[] or String. + * + * @param obj + * Object to decode + * @return An object (of type byte[]) containing the binary data which corresponds to the byte[] or String + * supplied. + * @throws DecoderException + * if the parameter supplied is not of type byte[] + */ + public Object decode(final Object obj) { + if (obj instanceof byte[]) { + return decode((byte[]) obj); + } else if (obj instanceof String) { + return decode((String) obj); + } else { + return null; + } + } + + /** + * Decodes a String containing characters in the Base-N alphabet. + * + * @param pArray + * A String containing Base-N character data + * @return a byte array containing binary data + */ + public byte[] decode(final String pArray) { + return decode(pArray.getBytes(Charset.forName("UTF-8"))); + } + + /** + * Encodes a byte[] containing binary data, into a byte[] containing characters in the alphabet. + * + * @param pArray + * a byte array containing binary data + * @return A byte array containing only the base N alphabetic character data + */ + public byte[] encode(final byte[] pArray) { + if (pArray == null || pArray.length == 0) { + return pArray; + } + return encode(pArray, 0, pArray.length); + } + + /** + * Encodes a byte[] containing binary data, into a byte[] containing + * characters in the alphabet. + * + * @param pArray + * a byte array containing binary data + * @param offset + * initial offset of the subarray. + * @param length + * length of the subarray. + * @return A byte array containing only the base N alphabetic character data + * @since 1.11 + */ + public byte[] encode(final byte[] pArray, final int offset, final int length) { + if (pArray == null || pArray.length == 0) { + return pArray; + } + final Context context = new Context(); + encode(pArray, offset, length, context); + encode(pArray, offset, EOF, context); // Notify encoder of EOF. + final byte[] buf = new byte[context.pos - context.readPos]; + readResults(buf, 0, buf.length, context); + return buf; + } + + // package protected for access from I/O streams + abstract void encode(byte[] pArray, int i, int length, Context context); + + /** + * Encodes an Object using the Base-N algorithm. This method is provided in order to satisfy the requirements of + * the Encoder interface, and will throw an EncoderException if the supplied object is not of type byte[]. + * + * @param obj + * Object to encode + * @return An object (of type byte[]) containing the Base-N encoded data which corresponds to the byte[] supplied. + * @throws EncoderException + * if the parameter supplied is not of type byte[] + */ + public Object encode(final Object obj) { + return encode((byte[]) obj); + } + + /** + * Encodes a byte[] containing binary data, into a String containing characters in the appropriate alphabet. + * Uses UTF8 encoding. + * + * @param pArray a byte array containing binary data + * @return String containing only character data in the appropriate alphabet. + * @since 1.5 + * This is a duplicate of {@link #encodeToString(byte[])}; it was merged during refactoring. + */ + public String encodeAsString(final byte[] pArray){ + return new String(encode(pArray), Charset.forName("UTF-8")); + } + + /** + * Encodes a byte[] containing binary data, into a String containing characters in the Base-N alphabet. + * Uses UTF8 encoding. + * + * @param pArray + * a byte array containing binary data + * @return A String containing only Base-N character data + */ + public String encodeToString(final byte[] pArray) { + return new String(encode(pArray), Charset.forName("UTF-8")); + } + + /** + * Ensure that the buffer has room for {@code size} bytes + * + * @param size minimum spare space required + * @param context the context to be used + * @return the buffer + */ + protected byte[] ensureBufferSize(final int size, final Context context){ + if (context.buffer == null) { + context.buffer = new byte[Math.max(size, getDefaultBufferSize())]; + context.pos = 0; + context.readPos = 0; + + // Overflow-conscious: + // x + y > z == x + y - z > 0 + } else if (context.pos + size - context.buffer.length > 0) { + return resizeBuffer(context, context.pos + size); + } + return context.buffer; + } + + /** + * Returns the decoding behavior policy. + * + *

+ * The default is lenient. If the decoding policy is strict, then decoding will raise an + * {@link IllegalArgumentException} if trailing bits are not part of a valid encoding. Decoding will compose + * trailing bits into 8-bit bytes and discard the remainder. + *

+ * + * @return true if using strict decoding + * @since 1.15 + */ + public CodecPolicy getCodecPolicy() { + return decodingPolicy; + } + + /** + * Get the default buffer size. Can be overridden. + * + * @return the default buffer size. + */ + protected int getDefaultBufferSize() { + return DEFAULT_BUFFER_SIZE; + } + + /** + * Calculates the amount of space needed to encode the supplied array. + * + * @param pArray byte[] array which will later be encoded + * + * @return amount of space needed to encoded the supplied array. + * Returns a long since a max-len array will require > Integer.MAX_VALUE + */ + public long getEncodedLength(final byte[] pArray) { + // Calculate non-chunked size - rounded up to allow for padding + // cast to long is needed to avoid possibility of overflow + long len = ((pArray.length + unencodedBlockSize-1) / unencodedBlockSize) * (long) encodedBlockSize; + if (lineLength > 0) { // We're using chunking + // Round up to nearest multiple + len += ((len + lineLength-1) / lineLength) * chunkSeparatorLength; + } + return len; + } + + /** + * Returns true if this object has buffered data for reading. + * + * @param context the context to be used + * @return true if there is data still available for reading. + */ + boolean hasData(final Context context) { // package protected for access from I/O streams + return context.buffer != null; + } + + /** + * Returns whether or not the {@code octet} is in the current alphabet. + * Does not allow whitespace or pad. + * + * @param value The value to test + * + * @return {@code true} if the value is defined in the current alphabet, {@code false} otherwise. + */ + protected abstract boolean isInAlphabet(byte value); + + /** + * Tests a given byte array to see if it contains only valid characters within the alphabet. + * The method optionally treats whitespace and pad as valid. + * + * @param arrayOctet byte array to test + * @param allowWSPad if {@code true}, then whitespace and PAD are also allowed + * + * @return {@code true} if all bytes are valid characters in the alphabet or if the byte array is empty; + * {@code false}, otherwise + */ + public boolean isInAlphabet(final byte[] arrayOctet, final boolean allowWSPad) { + for (final byte octet : arrayOctet) { + if (!isInAlphabet(octet) && + (!allowWSPad || (octet != pad) && !isWhiteSpace(octet))) { + return false; + } + } + return true; + } + + /** + * Tests a given String to see if it contains only valid characters within the alphabet. + * The method treats whitespace and PAD as valid. + * + * @param basen String to test + * @return {@code true} if all characters in the String are valid characters in the alphabet or if + * the String is empty; {@code false}, otherwise + * @see #isInAlphabet(byte[], boolean) + */ + public boolean isInAlphabet(final String basen) { + return isInAlphabet(basen.getBytes(Charset.forName("UTF-8")), true); + } + + /** + * Returns true if decoding behavior is strict. Decoding will raise an {@link IllegalArgumentException} if trailing + * bits are not part of a valid encoding. + * + *

+ * The default is false for lenient decoding. Decoding will compose trailing bits into 8-bit bytes and discard the + * remainder. + *

+ * + * @return true if using strict decoding + * @since 1.15 + */ + public boolean isStrictDecoding() { + return decodingPolicy == CodecPolicy.STRICT; + } + + /** + * Extracts buffered data into the provided byte[] array, starting at position bPos, up to a maximum of bAvail + * bytes. Returns how many bytes were actually extracted. + *

+ * Package protected for access from I/O streams. + * + * @param b + * byte[] array to extract the buffered data into. + * @param bPos + * position in byte[] array to start extraction at. + * @param bAvail + * amount of bytes we're allowed to extract. We may extract fewer (if fewer are available). + * @param context + * the context to be used + * @return The number of bytes successfully extracted into the provided byte[] array. + */ + int readResults(final byte[] b, final int bPos, final int bAvail, final Context context) { + if (context.buffer != null) { + final int len = Math.min(available(context), bAvail); + System.arraycopy(context.buffer, context.readPos, b, bPos, len); + context.readPos += len; + if (context.readPos >= context.pos) { + context.buffer = null; // so hasData() will return false, and this method can return -1 + } + return len; + } + return context.eof ? EOF : 0; + } +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/ConfigConstants.java b/src/main/java/net/lax1dude/eaglercraft/ConfigConstants.java new file mode 100644 index 0000000..6dbb651 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/ConfigConstants.java @@ -0,0 +1,10 @@ +package net.lax1dude.eaglercraft; + +public class ConfigConstants { + + public static final String version = "alpha 20m06-29"; + public static final String mainMenuString = "eaglercraft " + version; + + public static final boolean html5build = false; + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/DefaultSkinRenderer.java b/src/main/java/net/lax1dude/eaglercraft/DefaultSkinRenderer.java new file mode 100644 index 0000000..458686a --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/DefaultSkinRenderer.java @@ -0,0 +1,333 @@ +package net.lax1dude.eaglercraft; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; + +import net.minecraft.client.Minecraft; +import net.minecraft.src.EntityClientPlayerMP; +import net.minecraft.src.EntityOtherPlayerMP; +import net.minecraft.src.EntityPlayer; +import net.minecraft.src.ModelBiped; +import net.minecraft.src.ModelBlaze; +import net.minecraft.src.ModelEnderman; +import net.minecraft.src.ModelSkeleton; +import net.minecraft.src.ModelVillager; +import net.minecraft.src.ModelZombie; +import net.minecraft.src.OpenGlHelper; +import net.minecraft.src.Packet250CustomPayload; +import net.minecraft.src.RenderEnderman; +import net.minecraft.src.RenderHelper; +import net.minecraft.src.RenderManager; + +public class DefaultSkinRenderer { + + public static final TextureLocation[] defaultVanillaSkins = new TextureLocation[] { + new TextureLocation("/skins/01.default_steve.png"), + new TextureLocation("/skins/02.default_alex.png"), + new TextureLocation("/skins/03.tennis_steve.png"), + new TextureLocation("/skins/04.tennis_alex.png"), + new TextureLocation("/skins/05.tuxedo_steve.png"), + new TextureLocation("/skins/06.tuxedo_alex.png"), + new TextureLocation("/skins/07.athlete_steve.png"), + new TextureLocation("/skins/08.athlete_alex.png"), + new TextureLocation("/skins/09.cyclist_steve.png"), + new TextureLocation("/skins/10.cyclist_alex.png"), + new TextureLocation("/skins/11.boxer_steve.png"), + new TextureLocation("/skins/12.boxer_alex.png"), + new TextureLocation("/skins/13.prisoner_steve.png"), + new TextureLocation("/skins/14.prisoner_alex.png"), + new TextureLocation("/skins/15.scottish_steve.png"), + new TextureLocation("/skins/16.scottish_alex.png"), + new TextureLocation("/skins/17.dev_steve.png"), + new TextureLocation("/skins/18.dev_alex.png"), + new TextureLocation("/skins/19.herobrine.png"), + new TextureLocation("/mob/enderman.png"), + new TextureLocation("/mob/skeleton.png"), + new TextureLocation("/mob/fire.png"), + new TextureLocation("/skins/20.barney.png"), + new TextureLocation("/skins/21.slime.png"), + new TextureLocation("/skins/22.noob.png"), + new TextureLocation("/skins/23.trump.png"), + new TextureLocation("/skins/24.notch.png"), + new TextureLocation("/skins/25.creeper.png"), + new TextureLocation("/skins/26.zombie.png"), + new TextureLocation("/skins/27.pig.png"), + new TextureLocation("/skins/28.squid.png"), + new TextureLocation("/skins/29.mooshroom.png"), + new TextureLocation("/mob/villager/villager.png"), + new TextureLocation("/skins/30.longarms.png"), + new TextureLocation("/skins/31.laxdude.png") + }; + + private static final HashMap skinCookies = new HashMap(); + private static final HashMap skinGLUnits = new HashMap(); + private static final HashMap skinGLTimeout = new HashMap(); + + private static long lastClean = 0l; + + public static void deleteOldSkins() { + if(System.currentTimeMillis() - lastClean > 60000l) { + lastClean = System.currentTimeMillis(); + Iterator> itr = skinGLTimeout.entrySet().iterator(); + while(itr.hasNext()) { + Entry ee = itr.next(); + if(System.currentTimeMillis() - ee.getValue() > 80000l) { + itr.remove(); + Minecraft.getMinecraft().renderEngine.deleteTexture(skinGLUnits.remove(ee.getKey())); + } + } + Iterator> itr2 = skinCookies.entrySet().iterator(); + while(itr2.hasNext()) { + Entry e = itr2.next(); + if(e.getValue().isDead) { + itr2.remove(); + } + } + } + } + + public static boolean bindSyncedSkin(EntityPlayer p) { + if(p instanceof EntityClientPlayerMP) { + return false; + }else if(p instanceof EntityOtherPlayerMP) { + EntityOtherPlayerMP pp = (EntityOtherPlayerMP) p; + if(pp.skinPacket != null) { + if(((int)pp.skinPacket[0] & 0xFF) < 4) { + if(!skinGLUnits.containsKey(pp)) { + byte[] skinToLoad = new byte[pp.skinPacket.length - 1]; + System.arraycopy(pp.skinPacket, 1, skinToLoad, 0, skinToLoad.length); + int w, h; + + switch((int)pp.skinPacket[0] & 0xFF) { + default: + case 0: + w = 64; + h = 32; + break; + case 1: + w = 64; + h = 64; + break; + case 2: + w = 128; + h = 64; + break; + case 3: + w = 128; + h = 128; + break; + } + + skinGLUnits.put(pp, Minecraft.getMinecraft().renderEngine.setupTextureRaw(skinToLoad, w, h)); + } + skinGLTimeout.put(pp, System.currentTimeMillis()); + Integer i = skinGLUnits.get(pp); + if(i != null && i.intValue() > 0) { + Minecraft.getMinecraft().renderEngine.bindTexture(i.intValue()); + }else { + defaultVanillaSkins[0].bindTexture(); + } + }else { + if(((int)pp.skinPacket[1] & 0xFF) < defaultVanillaSkins.length) { + defaultVanillaSkins[(int)pp.skinPacket[1] & 0xFF].bindTexture(); + } + } + return true; + }else { + if(!skinCookies.containsValue(pp)) { + int cookie = (int)(System.nanoTime() % 65536); + skinCookies.put(cookie, pp); + byte[] n = pp.username.getBytes(); + byte[] pkt = new byte[n.length + 2]; + System.arraycopy(n, 0, pkt, 2, n.length); + pkt[0] = (byte)(cookie & 0xFF); + pkt[1] = (byte)((cookie >> 8) & 0xFF); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new Packet250CustomPayload("EAG|FetchSkin", pkt)); + } + } + return false; + }else { + return false; + } + } + + public static void skinResponse(byte[] data) { + int cookie = ((int)data[0] & 0xFF) | (((int)data[1] & 0xFF) << 8); + if(skinCookies.containsKey(cookie) && (data.length > 3)) { + EntityOtherPlayerMP p = skinCookies.remove(cookie); + byte[] packet = new byte[data.length - 2]; + System.arraycopy(data, 2, packet, 0, packet.length); + p.skinPacket = packet; + } + } + + public static boolean isNewSkin(int id) { + return !(id == 0 || id == 2 || id == 4 || id == 6 || id == 8 || id == 10 || id == 12 || id == 14 || id == 18 || id == 28); + } + + public static boolean isStandardModel(int id) { + return !isZombieModel(id) && !(id == 19 || id == 20 || id == 21 || id == 32 || id == 33 || id == 34); + } + + public static boolean isZombieModel(int id) { + return id == 18 || id == 28; + } + + public static boolean isPlayerNewSkin(EntityPlayer p) { + if(p instanceof EntityClientPlayerMP) { + if(EaglerProfile.presetSkinId == -1) { + int type = EaglerProfile.getSkinSize(EaglerProfile.skinDatas.get(EaglerProfile.customSkinId).length); + return (type == 1 || type == 3); + }else { + return isNewSkin(EaglerProfile.presetSkinId); + } + }else if(p instanceof EntityOtherPlayerMP) { + EntityOtherPlayerMP pp = (EntityOtherPlayerMP) p; + if(pp.skinPacket != null) { + if(pp.skinPacket[0] < (byte)4) { + return (pp.skinPacket[0] == (byte)1) || (pp.skinPacket[0] == (byte)3); + }else { + return isNewSkin((int)pp.skinPacket[1] & 0xFF); + } + } + } + return false; + } + + public static boolean isPlayerStandard(EntityPlayer p) { + if(p instanceof EntityClientPlayerMP) { + if(EaglerProfile.presetSkinId == -1) { + return true; + }else { + return isStandardModel(EaglerProfile.presetSkinId); + } + }else if(p instanceof EntityOtherPlayerMP) { + EntityOtherPlayerMP pp = (EntityOtherPlayerMP) p; + if(pp.skinPacket != null) { + if(pp.skinPacket[0] < (byte)4) { + return true; + }else { + return isStandardModel((int)pp.skinPacket[1] & 0xFF); + } + } + } + return true; + } + + public static int getPlayerRenderer(EntityPlayer p) { + if(p instanceof EntityClientPlayerMP) { + if(EaglerProfile.presetSkinId == -1) { + return 0; + }else { + return EaglerProfile.presetSkinId; + } + }else if(p instanceof EntityOtherPlayerMP) { + EntityOtherPlayerMP pp = (EntityOtherPlayerMP) p; + if(pp.skinPacket != null) { + if(pp.skinPacket[0] < (byte)4) { + return 0; + }else { + return (int)pp.skinPacket[1] & 0xFF; + } + } + } + return 0; + } + + public static ModelBiped oldSkinRenderer = null; + public static ModelBipedNewSkins newSkinRenderer = null; + public static ModelZombie zombieRenderer = null; + public static ModelVillager villagerRenderer = null; + public static ModelEnderman endermanRenderer = null; + public static ModelBlaze blazeRenderer = null; + public static ModelSkeleton skeletonRenderer = null; + + public static void renderPlayerPreview(int x, int y, int mx, int my, int id2) { + int id = id2 - EaglerProfile.skinNames.size(); + + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + RenderHelper.enableStandardItemLighting(); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glDisable(EaglerAdapter.GL_CULL_FACE); + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef((float) x, (float) (y - 80), 100.0F); + EaglerAdapter.glScalef(50.0f, 50.0f, 50.0f); + EaglerAdapter.glRotatef(180.0f, 1.0f, 0.0f, 0.0f); + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + EaglerAdapter.glScalef(1.0F, -1.0F, 1.0F); + EaglerAdapter.glTranslatef(0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(((y - my) * -0.06f), 1.0f, 0.0f, 0.0f); + EaglerAdapter.glRotatef(((x - mx) * 0.06f), 0.0f, 1.0f, 0.0f); + EaglerAdapter.glTranslatef(0.0F, -1.0F, 0.0F); + + if(id < 0) { + Minecraft.getMinecraft().renderEngine.bindTexture(EaglerProfile.glTex.get(id2)); + }else { + defaultVanillaSkins[id].bindTexture(); + } + + if(isStandardModel(id) || id < 0) { + if(oldSkinRenderer == null) oldSkinRenderer = new ModelBiped(0.0F, 0.0F, 64, 32); + if(newSkinRenderer == null) newSkinRenderer = new ModelBipedNewSkins(0.0F, false); + newSkinRenderer.isChild = false; + oldSkinRenderer.isChild = false; + boolean isNew = isNewSkin(id); + if(id < 0) { + int type = EaglerProfile.getSkinSize(EaglerProfile.skinDatas.get(id2).length); + isNew = (type == 1 || type == 3); + } + if(isNew) { + newSkinRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + }else { + oldSkinRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + } + }else if(isZombieModel(id)) { + if(zombieRenderer == null) zombieRenderer = new ModelZombie(0.0F, true); + zombieRenderer.isChild = false; + zombieRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + }else if(id == 32) { + if(villagerRenderer == null) villagerRenderer = new ModelVillager(0.0F); + villagerRenderer.isChild = false; + villagerRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + }else if(id == 19) { + if(endermanRenderer == null) endermanRenderer = new ModelEnderman(); + endermanRenderer.isChild = false; + endermanRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + EaglerAdapter.glColor4f(1.4f, 1.4f, 1.4f, 1.0f); + //EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + //EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + //EaglerAdapter.glBlendFunc(EaglerAdapter.GL_ONE, EaglerAdapter.GL_ONE); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glDisable(EaglerAdapter.GL_DEPTH_TEST); + RenderEnderman.tex_eyes.bindTexture(); + endermanRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + }else if(id == 20) { + if(skeletonRenderer == null) skeletonRenderer = new ModelSkeleton(0.0F); + skeletonRenderer.isChild = false; + skeletonRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + }else if(id == 21) { + if(blazeRenderer == null) blazeRenderer = new ModelBlaze(); + blazeRenderer.isChild = false; + EaglerAdapter.glColor4f(1.5f, 1.5f, 1.5f, 1.0f); + blazeRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + } + + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/EaglerAdapter.java b/src/main/java/net/lax1dude/eaglercraft/EaglerAdapter.java new file mode 100644 index 0000000..bbec4b3 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/EaglerAdapter.java @@ -0,0 +1,7 @@ +package net.lax1dude.eaglercraft; + +import net.lax1dude.eaglercraft.glemu.EaglerAdapterGL30; + +public class EaglerAdapter extends EaglerAdapterGL30 { + +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/EaglerImage.java b/src/main/java/net/lax1dude/eaglercraft/EaglerImage.java new file mode 100644 index 0000000..1724e49 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/EaglerImage.java @@ -0,0 +1,55 @@ +package net.lax1dude.eaglercraft; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import com.baislsl.png.decode.DecodeException; +import com.baislsl.png.decode.Decoder; +import com.baislsl.png.decode.PNG; + +public class EaglerImage { + + public final int[] data; + public final int w; + public final int h; + public final boolean alpha; + + public EaglerImage(int pw, int ph, boolean palpha) { + this.w = pw; + this.h = ph; + this.alpha = palpha; + this.data = new int[pw * ph]; + } + + public EaglerImage(int[] pdata, int pw, int ph, boolean palpha) { + if(pdata.length != pw*ph) { + throw new IllegalArgumentException("array size does not equal image size"); + } + this.w = pw; + this.h = ph; + this.alpha = palpha; + this.data = pdata; + } + + public static final EaglerImage loadImage(byte[] file) { + try { + PNG p = (new Decoder(new ByteArrayInputStream(file))).readInPNG(); + return new EaglerImage(p.getColor(), (int)p.getWidth(), (int)p.getHeight(), p.ihdr.getBpp() == 4); + } catch (IOException e) { + e.printStackTrace(); + return null; + } catch (DecodeException e) { + e.printStackTrace(); + return null; + } + } + + public EaglerImage getSubImage(int x, int y, int pw, int ph) { + int[] img = new int[pw * ph]; + for(int i = 0; i < ph; ++i) { + System.arraycopy(data, (i + y) * this.w + x, img, i * pw, pw); + } + return new EaglerImage(img, pw, ph, alpha); + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/EaglerInflater.java b/src/main/java/net/lax1dude/eaglercraft/EaglerInflater.java new file mode 100644 index 0000000..4601d78 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/EaglerInflater.java @@ -0,0 +1,25 @@ +package net.lax1dude.eaglercraft; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import com.jcraft.jzlib.InflaterInputStream; + +public class EaglerInflater { + + public static byte[] uncompress(byte[] input) throws IOException { + return getBytesFromInputStream(new InflaterInputStream(new ByteArrayInputStream(input))); + } + + public static byte[] getBytesFromInputStream(InputStream is) throws IOException { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + byte[] buffer = new byte[0xFFFF]; + for (int len = is.read(buffer); len != -1; len = is.read(buffer)) { + os.write(buffer, 0, len); + } + return os.toByteArray(); + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/EaglerProfile.java b/src/main/java/net/lax1dude/eaglercraft/EaglerProfile.java new file mode 100644 index 0000000..aaff6c6 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/EaglerProfile.java @@ -0,0 +1,155 @@ +package net.lax1dude.eaglercraft; + +import java.util.ArrayList; +import java.util.Random; + +import net.minecraft.client.Minecraft; +import net.minecraft.src.NBTTagCompound; + +public class EaglerProfile { + + public static String username; + public static int presetSkinId; + public static int customSkinId; + + public static String myChannel; + + public static final int[] SKIN_DATA_SIZE = new int[] { 64*32*4, 64*64*4, 128*64*4, 128*128*4, 2 }; + public static ArrayList skinNames = new ArrayList(); + public static ArrayList skinDatas = new ArrayList(); + public static ArrayList glTex = new ArrayList(); + + public static final Random rand; + + public static int getSkinSize(int len) { + for(int i = 0; i < SKIN_DATA_SIZE.length; ++i) { + if(len == SKIN_DATA_SIZE[i]) { + return i; + } + } + return -1; + } + + public static byte[] getSkinPacket() { + if(presetSkinId == -1) { + byte[] d = skinDatas.get(customSkinId); + byte[] d2 = new byte[1 + d.length]; + d2[0] = (byte) getSkinSize(d.length); + System.arraycopy(d, 0, d2, 1, d.length); + return d2; + }else { + return new byte[] { (byte)4, (byte)presetSkinId }; + } + } + + public static String[] concatArrays(String[] a, String[] b) { + String[] r = new String[a.length + b.length]; + System.arraycopy(a, 0, r, 0, a.length); + System.arraycopy(b, 0, r, a.length, b.length); + return r; + } + + public static int addSkin(String name, byte[] data) { + int i = skinNames.indexOf(name); + + if(i != -1) { + skinDatas.set(i, data); + }else { + skinNames.add(name); + skinDatas.add(data); + } + + int t = getSkinSize(data.length); + int w, h; + + switch(t) { + default: + case 0: + w = 64; + h = 32; + break; + case 1: + w = 64; + h = 64; + break; + case 2: + w = 128; + h = 64; + break; + case 3: + w = 128; + h = 128; + break; + } + + int im = Minecraft.getMinecraft().renderEngine.setupTextureRaw(data, w, h); + if(i == -1) { + glTex.add(im); + }else { + glTex.set(i, im); + } + return i; + + } + + static { + String[] usernameDefaultWords = new String[] { + "Eagler", + "Eagler", + "Yeer", + "Groon", + "Eag", + "Deevis", + "Chode", + "Deev", + "Deev", + "Dumpster", + "Dumpster", + "Cum", + "Chad", + "Egg", + "Fudgler", + "Fudgli", + "Yee", + "Yee", + "Yee", + "Yeet", + "Flumpter", + "Darvy", + "Darver", + "Darver", + "Fuck", + "Fuck", + "Frick", + "Eagler", + "Vigg", + "Vigg", + "Darvig" + }; + + rand = new Random(); + + do { + username = usernameDefaultWords[rand.nextInt(usernameDefaultWords.length)] + usernameDefaultWords[rand.nextInt(usernameDefaultWords.length)] + (10 + rand.nextInt(90)); + }while(username.length() > 16); + + presetSkinId = rand.nextInt(GuiScreenEditProfile.defaultOptions.length); + myChannel = username + "_" + (100 + rand.nextInt(900)); + customSkinId = -1; + } + + public static void loadFromStorage() { + if(!LocalStorageManager.profileSettingsStorage.hasNoTags()) { + presetSkinId = LocalStorageManager.profileSettingsStorage.getInteger("ps"); + customSkinId = LocalStorageManager.profileSettingsStorage.getInteger("cs"); + username = LocalStorageManager.profileSettingsStorage.getString("name"); + myChannel = username + "_" + (100 + rand.nextInt(900)); + NBTTagCompound n = LocalStorageManager.profileSettingsStorage.getCompoundTag("skins"); + for(Object s : NBTTagCompound.getTagMap(n).keySet()) { + String s2 = (String)s; + addSkin(s2, n.getByteArray(s2)); + } + } + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/EarlyLoadScreen.java b/src/main/java/net/lax1dude/eaglercraft/EarlyLoadScreen.java new file mode 100644 index 0000000..60f7fb9 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/EarlyLoadScreen.java @@ -0,0 +1,171 @@ +package net.lax1dude.eaglercraft; + +import static net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2.*; + +import java.nio.IntBuffer; + +import net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2.BufferArrayGL; +import net.minecraft.src.GLAllocation; + +public class EarlyLoadScreen { + + public static final String loadScreen = "iVBORw0KGgoAAAANSUhEUgAAAMAAAADACAYAAABS3GwHAAAArXpUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjaXVBbDgMhCPznFD2CAr6OY7tu0hv0+B2F7sZOwgiDDkQan/dJj4lYmDSVmlvOAdCmjTuSGgx2xqCLF17eQr3pdDUYkuAUK/Pw+x16uh8Udf2561TciasbeeNnKHMyIzl8STcSNj16TY3DjnqHlGVxXf6vteAzjgRRmHhIlLCYbZJYdEQFR0EDrMiTNLDOZekLXFtIXuuhhAwAAAAJcEhZcwAACxMAAAsTAQCanBgAABiCSURBVHja7Z1ZUxtJ1obfWrVLpQVJgGwM2DR4umfC3W3HRExHzD+fmIu5mpnunq29sBiMACGBKEklqRZVqb6L/jKjqrQAbizb+DwRhGyVas8385yTJzMF3/d9EMQXikiPgCABEAQJgCBIAARBAiAIEgBBkAAIggRAECQAgiABEAQJgCBIAARBAiAIEgBBkAAIggRAECQAgiABEAQJgCBIAARBAiAIEgBBkAAIggRAECQAgiABEAQJgCBIAARBAiAIEgBBkAAIggRAECQAgiABEAQJgCBIAARBAiAIEgBBkAAIggRAECQAgiABEAQJgCBIAARBAiAIEgBBkAAIggRAECQAgiABEAQJgCBIAAQJgCBIAARBAiAIEgBBkAAIggRAECQAgiABEAQJgCBIAARBAiAIEgBB3ANkegTETRmPx3AcB6L4a72pKAoEQeDbfd/HaDTCaDSCKIoYj8cAAEmSIMsy/zeA0H4kAOKzwDAM6LqO8XiMVCqFYrHIC75lWeh2u1AUBb1eD8lkEqZpwnVdxGIxZDIZjMdjxGIxiKKIRCLBhcTEJYoiBEGA7/uhbSQA4pOo/U3TRLvdhmVZyOfzyOfzAABd19HtdlEsFtFut2EYBgqFAlzXha7rcF0Xoigim82i0+nA931ks1lkMhneUrBPQRAgCAL/jnwA4pPA9324rgsASCQSME0TADAajWCaJkqlElzXxeXlJSRJ4gW62+1CFEWkUin4vo9isQhZljEej2EYBi/07FMURfi+z89JAiA+GSRJQjqdRqfTQaVSwWg0giAIyOVyUFUVo9EIAFCr1eD7PnK5HDY3N1EulxGPx7ntr2layKdgBX08HnMh+L6/ED+BBEDcCFYYu90uNE2DKIq8to7FYtzWf/jwIbflme0fj8chCALi8TgXjSRJ/P+j0QiO43ARMB+AWgDikzKBVFVFLpdDp9PhtTXbJssyJEmCpmlQVRWqqgIAYrEYRqMRfN+H7/tQFAUAoKoqBEGAoiihgh70ARbRApATfM+4vLyE53mh78rl8p0UJtM00e/3kclk+Hej0QiKovAanJlCjuNAURSMRiOoqgrHcXihZ62GbdtwXReyLHP/QlVVbv4swgyiFuCe4bruxN9d+wCGYQAAHMeBLMuwbZubL6y2t22b/84wDNi2DcuyYNs2HMeBYRhwHIf7AbIscx+CmUHUAnyG9Pt9dLtd/vJzuRyWl5cXev5oob+LwsT27/f70DQNlmUhHo/D9310u10e0gw6tZZl8c9utwtVVVEul3mrwZ4Rc5CDtT/zAT60CEgAd1z7skKfy+UAgNu8i2J5eXnCebyLQuT7PjzPQzqdxunpKXzf544sM4Xi8ThisRgsy4Jpmsjlcuj1euh2uwDA+w0sy4Ku6/zYTBzZbBbJZJJ3mrFeYxLAZ0Kn08HBwcGE/b2+vr6wa9jd3eX2OOP777+/s8LU7XaxtraGw8NDAEChUOCFOpvNctPIcRwuPF3Xkc/n+ef5+Tl834emaXAcB57n4fDwEPl8HltbWzAMg7co1AJ8RuRyOTx9+jT03aJbgK2tLR6dYbX/XfaoJhIJvHv3Dvl8ntv+3W4XiUSC2/dXV1e848v3feTzed55ZlkW70kul8swDAONRgMAMBwO8e7dO1QqFWQyGfIBPjeGwyHOz88nRFGtVhd2Defn5xM+wJMnT+7EB5AkCb1eD9VqFWdnZ8jn87zws0hP9P+5XA6lUgm2baPVavHCfnp6iuFwiOXlZSwvL0PXddi2DV3XoWnaQvoA7nUUiNU+izyOLMtIpVKhPxYPX9Q1JJPJiWu4Sx+AmTvMpAF+DY+y0Gi/38fR0REsy4Isy1BVFalUCslkEgBg2zaurq64H9BoNJDL5fD8+XO+PZFILCxb9KO3AJ7nYTAYwLIsHhZjDlYsFkMikbjxS3QcB5ZlwXXdUGJVPB6/9UO1bRvD4ZDXpqIoIh6PI5lMzjyOKIoTBZ6lAb+vU93v93l4UJIkJJNJ7nhOQ1GUD+o8KooSCoUCv6Y+GIaBk5MT9Ho9WJYFz/OwtraG1dVV3oIsLS0hkUhgc3MT/X4fpVIJyWSSX+/6+jrOzs74M7z3USAWIZgWtWDCGAwG6HQ6KBaLSCQSod9dXl5iOBxy0bC/4P+DvZVMWGtraxPHAoBms4mLi4uF+w0PHjzg/9d1HWdnZzeq8bPZLGq1WsjGb7fbXDCMUqk0tSDV63UeoQmysrLCndt50S4AqFQqiMfjGI/HWF9fhyAI6Ha7qNVqPB2CkUqleCSIhULZ+/Z9H5VKBc1mE+12G8lkciH+k+AvytiKwArvdc0ue3G+76NQKIR6IT3Pm2oeBHsSp9UkoihOrZlZ9CTaNR899rzw4qzts76PXks0ghPdN7g/S08IHi+4P9svWAij98t+EzzmtN97nodGo4GzszOk02lIkoR2u40//OEPvOULHo+1RMFnb1kWr92DPb3s07Is/P3vf4cgCHj+/DlSqdT9NIF0XZ9a+GOxGGRZ5gMsotEMXdehqip/QZeXl7AsK1Try7LMO1FYqm5we1BMa2tr3IZ99epVqKD5vo9UKoVcLgdBEGAYBnq93p03yYVCAevr6+j3+3jz5s1U55MVhMFgMLVlWF1d5Y72mzdvJkT07NmzUCthWRZevXoVer7Mf9je3p57vel0mtv6mqbxRDf2/qKVTVBYTHTs/QULP4soraysIB6P34nv9Em2ALZto9lshr6TJAlLS0uhmx6Px9xZCtbyqqryl8260K8L83meN1VwqVQKoiii3+9PFIZZYTjDMEKFUJIkXkCZDxK1maeZW0HG4zH6/f7E99Ouwff9kP0dLLyyLE9cX/Q4rFKIoqrqXN+CtQC9Xi9038vLy3PzdlhPMXs2pVIJoiiGWhnbtnk+UavVgqZpyGQykCTp/vkAUZtTEASUy+UJe08URRSLRTSbTW7qsLwRlljFBl7cJITX6/VCfgIzH1RVxdXVVchXiMVivFMnimmaGAwGIQEwx9i2bbTb7Yka8zoBsJFW0f2mXYMgCDxoEC1oLFMzGgZNp9OhTqng9QdbkZsyGAyQz+e5YOYV/r29PV6JsVygjY2Nid9G/ZZZJuZnLQDXdSde3DxnhzX/zPSQJAnj8ZjbkjeNdrDheEETgoX1PM8L5bYzx3QWmUyGN9fsOLZtc1Mg6lvcRKC6rof2Yy3iLJaWlng8PVgoc7nc1GfCClKj0eDZl8FzsVr8Ju/PdV3kcjn+7FgCXCwWm7DrbdtGsViE7/sYDAZ8PLDrulBVFbZt85bAtm2ebp1MJu9nLtC0pve62jFqC7IHeFuCobVgiFIQBG7XBs2WebH+6O9ZoWMhwqhfc535k06nJ67ruv6GTCYz1bFOpVITvhMzYRKJxIR5FLThb0IqlYLnechms9xsicfj8DyPP4eg8x2Px2HbNm+F2EwSrBJhn+w5xeNx/l7uXQswLcLhuu7UJjka6Qk+jKi9Hv2967q8dmLmznA4hGma/LvxeIxKpYJ0Oo1GoxFykguFAlZWVqYev9Vq4fLyMvTdzs4Or4Xr9fqEk8s6gWaZhMfHxxMmS7SljHJ+fh56Dr7v4+uvv8bp6emEObG6uoqTk5MJ53Rzc/PaCigqlsFgAEmS0Gw2sba2xvP6g59RMbDBM8PhMFS5xGIxKIoC13X5vsEKg7XOH1IIC3WCz8/Pp4rgpmYMexCqqoZMBMdx0O/3YZpmKDQajAxF+xHYsDtRFPk+wW3T/IvxeDwx2CRo9kzbLoriXFONCfVOarPAwJLoNUZf8039p2BFdXV1heFwiHK5PNG6BqM74/GY5wWJosgrH9a56XkeFEWBqqp80EzwWLIso91uw3EcPsTyXrQAv+VFB+eNYUIYj8fQdT0UCg2+cDYzgeu6vMYMhkqXlpZ4r2ar1Qo5yLIso1qtcpOGJW1FBVwqlXi+f7fbxcnJSWh7Pp9HrVabeV/TWpT3ZWdnBwcHB1Mdyml+xG1ylARBgGma0DQNiqJAFEVuvrDCz6I5bEQYqxDYrBDsOTLfj+3Dan/f9+E4Du8ki/Zx3Jt+gN8iAiYAz/NweXnJazyW9ThNBKxQs4fJBmqzGovFs23bDjnJbF6bYKEJthKxWCxk8ycSiQnT6TofIJvN3lnMW5IkVCqViYoml8tN7fHt9Xozo12z+gDi8XioRev1eiGzJpgKHY/H4TgOH0PMavylpaXQe2GFv9VqwXVdrK6uckf4XvkA026oWq3eOl9GEARcXV2Fcs5Zwc1kMjwmHqw9dF3nodBer4dOp4NqtcpfHsv7CbYC7LizrMRo4fE8b8LRv64GmxaXz2azE72g10VEgr2pUTOsUChgNBpNmEemaSKVSt0omsYiaWwIJNvHsixcXFxgY2MDgiCExgKzfZjzLQhCaNSXbdt8H/YOmHm0KEd4oQKY9aBvq3SWJxSN6rDkqut8iKgpxfJnWGFPJpOhghlsQTKZDJ8WZNp1RZ3X62p3URQn9onH47eqmYOwgeZR+79areLk5GTiXEdHR6jVate2VCyCw3wN5uiWSiWe5x9M1AuOFmMpEdGAyHg8hqIoUBSF+xb5fJ6nUdy7KJCiKBO1nWmatzYBpjnSiqLMjbYEX2TQKbQsi3eEpdNppNNpPhrJdV2e38JSe+e9lHg8jkqlMuGYziORSEzs81uyOUul0szcoXK5HOrDuC2sEmBJbp7nQZZlbG5ucvs/ao5KkjQRZGDvK2g6sXAsq1juZTp0IpHgXekMwzB4ctVtXsRtWhHbtjEYDCb8AebYsdrGNE2MRiPeESbL8q3Ms8FggP39/Yl7/vrrr+dGbvb39yfMk0ePHs3tDJvFwcHBRAXx7bffQpIkqKqKXq/HhzNGnfXHjx9fW3kEBRr8nFaJRX/3KbLwXKCzs7OJl80co+sKG+u9dV0XrVZr4uUsLy9PHGMwGODq6mpqxmixWMRoNOITtrJIEpv49bYvjnX3Tyvk8zrXPM+bGR6+SZzeNE3+OxYRm3eMWeeL5uh8CSxcAKZpTs25FwSB25DBThRW4B3H4aOF8vn81Jx5SZJ4D+V4PMZgMJja+xx0DgVB4NcT7T9g18Xi10xcsixPHZjieR729vYmOqhYugFLSmNxcpYAp2ka9vf3p7Zs6XQapVKJTyfOUg/Y/oZhwPM87OzsQBAE7O7uToRBd3Z2Qi3kaDTC/v7+RLSIdY59SSL4KOMBdF2fmtF4E5LJJEql0o3GE0Rr4eB0fgBQLBaRTCZxfn7ObeNowhwLvbIQ4LQoUXDIn2maPNp0E+LxODRNw3g8xsXFxXsP46xUKhAEAa1Wa6Jgs23R1iqalRs0h74UEXyUMcH5fP69oxwMTdNubKLEYjFUKpWpfoIgCKhUKjyZizliwT8W7242m2i1WhPRoWCSHQvzTRPSrD9mfrCRVe/zFyzYs7ZF71tV1anHmtdq3jc+WkeYpmncKb7JA2dhOGZ2yLKMSqXCxwzMCrtms1meiDUrstDpdPisxawQsd5OZg55nsdDpcGQKds+GAywtrYGSZJQrVbR7XbRarUmYvLRfoVg5imbUKvT6Uzk+sxCVVVomsavvdfrTZhA1Wp16r0XCgWcnZ2h0+lMPA82/w+ZQAuAOWWj0Sg0PTbLo2FO5KwCzPwDFm5jUQlWqzNYR1dQIL1ebyIylclk+NjVaefSdZ0vFVQoFJDNZnnPZ/B8nufNDDuye5yVjcn6FKLDKqMijUZf2Ai4qNk479lPu0ZBEG6VKEcC+AxxXReNRiNUYIIjzuZxfHzMCxtrIR48eDB3LAFBPsAnRTD3J+iU3tSpZhmVLFL0Kce7iU/MB/gUmGZj32SwDUv4CqZU+L7/RZgM1ALcJ/VP6XgbDofodDoTzisTTL/f59MfBmv/20SlCPIBPgl838f5+fnM/PngoBFm50/LElUUBcvLywtb25YgAdwZo9EIFxcX7zXOmJk9xWKRan8SwOfdEhiGMXV1lakP7f9DhKx3mCAB3BtY3hGb9iOYE8SyQ1VVJXOHBEAQnz9UjREkAIIgARAECYAgSAAEQQIgCBIAQZAACIIEQBAkAIIgARAECYAgSAAEQQIgCBIAQZAACOLz46NPizJtkltZlmcuUxrE8zx0Op2Fzchw3fl+/vlnWJaF58+f33rZp9sSnGW7XC5/8KGZi37WX4wAms0mn2aEkUwmbySAvb09nJ6e4ocffljIS1n0+a57bm/fvuVDNh8+fPjF3Pu9EgDjz3/+8wevNT80z549W2jLWSwWYRgGLi8vP7gAyARaMN1uFz/++CNyuRy+/fZbCIKA169f4+zsjK/ty/jb3/4G4Ndp0H/44Qf85z//wXA4xDfffIP//e9/sCwLtVoNm5ubaDQaqNfrGAwGEAQBuVwOT5484cudNptNHB8fo9/vQ5ZlrK2twXEcvHv3bu75got+MDH7vo+//OUvePjwIRzHwcXFBVRVxdOnT6FpGobDIfb29vgaZYzHjx/PnZnZcRx0u11sbW1BVVU0Gg24rgtZlmFZFvb393F1dQXP85DJZLC9vc1Xn5+1zfM8HBwcoNlswvM8FAoFbG1t4eTkZO69zzsmCeAW1Ot13rSyRTA2NjZwcHCA09NTpFIpnJ6eYmNjA5qmwTAMNJtN9Ho9rK+v88WvgzbrL7/8gnw+j263i6OjI5TLZfT7fWQyGVQqFYxGI9Trdbx8+RIvXrxAo9HAy5cvkUgk8OjRI77KTLVahaqqM8+3vLwMTdPQaDT4qi9Bjo+PkU6n8fDhQ7x79w6vX7/GH//4R/zyyy8wTRNra2twXRcnJyfQNA2aps19VmztYrai4tnZGXRdx9LSEl6+fAld1/lU7WyVnHQ6PXfbq1evcHFxgVqtBlEUcXJygn//+9948uTJ3Hufd0wSwC14+/Yt/3e1WkWpVMLa2hp0Xcfe3h4URUEul8OjR48gCALy+TyGwyF6vR5WV1cnVjSxLAuVSgWPHz9Gv9/H1dUVJEnCkydPYBgGDMPgU5qzJVcPDw8hSRK+//77iWnH552PLWbH5haKkkwm8d1330GWZRiGgXa7DeDX9cs0TeMCaDQaUFX12hmm2+02ZFlGKpXiZmO73cbS0hL3CURRRLlcDq03PGubbdtoNpvQNI3fVyaTga7riMViKBQKM+993vlIAL/RBxAEARsbG/jnP/8J27b5Olg3hdnFbPlTVmM1Go3Q79hCGKZp3unK7Yx0Os3vLbhE68rKCur1Ov7617/ybcvLy3OP5fs+N6Xq9Tq//ouLC2xvb2N7exu7u7s4OjrC4eEhUqkUtre3oWnazG3smXY6nYnFMqbNkRpk3vlIAL+R8XiM3d1dpFIpvgDdtDDcrKmNooIaDodoNBooFov43e9+B0VR8OOPP6LX60EURSiKgsFgAMdx5orgLqZS8n0fl5eXWF1d5SvY5PP5a9c6NgwDruvCdV3s7e2F/ALDMJDJZPDs2TOMRiM0m028efMGu7u7ePHiBVKp1NRtbBnXBw8eYGtr69rrDjLrmC9evODX9dNPP0GWZTx79iz07t532733AVg/wP7+Pnq9Hr777jt4nod//etf2Nvbw/b2NnfEAOD169d8WdNarTbzHOz4/X4fJycnvMZj9mytVsPh4SH+8Y9/YGVlha/m+PTp07nnq9fr8H2fmz/sXubV5q7rwjRNdDodvjI6u5Z5MX1mPv3pT3/iv2u1Wvjvf/+Lq6sr7O/vI5VKQVVVPukvW6L1559/nrotmUxC0zTU63WMRiOkUik4jgPLsvD73/9+7r3POiaj0+lwE7PX64VW3nnfbffeB0gmk5AkCfV6HbVajTenlUoFp6enyOfzqFQqqNVq6Pf7aLfbaLfbiMVicwUQi8Xw1Vdf4e3btzg+PkapVMLKygrvh2AO3unpKY6OjqCqaqg/Ytb5okuOsnuZt9C1oih8tUvLskJLQ7Haelb4M5FIhETCns/l5SU0TUOz2YRlWVAUBdVqlS+Anc1mZ2775ptvcHBwgIuLCzSbTSSTSZTL5Wvvfd4x2bUxXyWTyYTu5X233SU0NeJHQtd1/PTTT/jqq6+4aOv1OnZ3d7Gzs3OjjkDinvsA9xm2UjuL4Y/HY5yfn/O+CWIxUAvwkfB9H0dHRzg/P4dpmpAkiYd5P5cICgmAID5zKB2aIAEQBAmAIEgABEECIAgSAEGQAAiCBEAQJACCIAEQBAmAIEgABEECIAgSAEGQAAiCBEAQJACCIAEQBAmAIEgABEECIAgSAEGQAAiCBEAQJACCIAEQBAmAIEgABEECIAgSAEGQAAiCBEAQJACCIAEQBAmAIEgABEECIAgSAEGQAAiCBEAQJACCIAEQBAmAIEgABEECIAgSAEGQAAiCBEAQJACCIAEQBAmAIAD8H6pQaRuRO1YIAAAAAElFTkSuQmCC"; + public static final String enableScreen = "iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAC4jAAAuIwF4pT92AAAEAklEQVR42u2dvXbjIBBG7T0+xw+gTp06v//LmE6dO/VR5a3wGZNh+BGSFeveJgkIBrDy8TGKds8/Pz/PExyW8/P55AY4MP9YgmNzmeeZVUABAA8AKADgAQAFADwAoACABwAUAPAAgAIAHgBQAMADAAoAeABAAY7LOI7fpQDX65VPtZCt18w5d7rdbigAbOgBxnE8DcPwJnnDMCTrNJlsUVcizTnj9HWxeVvINfN9y361OdTEk30551ZZt3PsvYDYxOSChoPQ6sJ21mRLBm61jY0lpy61gDKWNdfcNcv5wErWLbfPF88I9/s9WtayzopXS85YtPqcMeT23SqedV1pucal1V4iTUooV/IaWSfbWHU5JmkvpmzrsayaB9DqfJnVTpMff72sc869/WzVlcjjOI7mOOVYfBzfT05exLfT5pqae008a71Ly6tPASV79CfPylvFjpm+teLH+tXiF5nA2LOAUMpCibckWpPBUOJT20btFuDjyK8p+S45Z4fX+ti+LDb3pef62PosWbfkDbBW8mFPhB/gt8Vr7gG+kZK9+C/GM2+ArffnnKRHbT5gSdJoK0+ydrziGyCW115LolLxnHOr59q3lt89b6U8Czg4pgdI5bUtKY3VzfOclGBtTLVSmmqn1cdyC7Iud+5791KX1MLJDz3Mg2s59pK6sM/asdTmLrRx5pzjS+e+awWw9lstVeuv1/a10rqwT8sn5LQr8RzaMVfmKrR2qfnFjs57/puLS0nyoTZp0fL8XGq+ap8v4AES+3Msx74kN2/tmblewWoXPl9o+RykZH5/5hTQYv+y+vj084XcPHpJbHmt1s7yGbV1q+UBnHO/gnoZje2RmuzK/Vr2F3sWEF6TGkvutqH5CG08qTmk5u77tLyK5Qtq62rgxRA8AO8FHBkygQeHLQAFADwAoACABwAUAPAAgAIAHgBQAMADAAoAeABAAQAPACgA4AEABQA8AKAAgAcAFAC+3gNM03Tqum7VQSyN4dtvMdZDKcBWC9oqhr8JoIEHeDwep77vf5VJfL0vl9fLa/u+f+vPfx9eszSGNXZo5AH6vlcXW36gsqykrzViwAIPYL3r3nXd63v5m6i9J2+VaT8viWGNHZQbYE97+KdjHPIGKH0XPSyL7eXSjPk2YZlsN03Tq21OjLAs598ZggIT2MpMbW3IMICFN0Dsv4xpfUbfAvIAK9wAcOAtAMgDwJHzAIACAB4AUADAAwAKAHgAQAEADwAoAOABAAUAPACgAIAHABQA8ACAAgAeAFAAwAMACgB4AEABAA8AKADgAQAFADwAoACABwAUAPAAgAIAHgBQAMADAAoAeABAAQAPACgA4AEABQA8AKAAgAcAFADwANCe/0of1jQ8XY5YAAAAAElFTkSuQmCC"; + + private static BufferGL vbo = null; + private static ProgramGL program = null; + + public static void paintScreen() { + + TextureGL tex = _wglGenTextures(); + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, tex); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + EaglerImage img = EaglerImage.loadImage(Base64.decodeBase64(loadScreen)); + IntBuffer upload = GLAllocation.createDirectIntBuffer(192*192); + upload.put(img.data); + upload.flip(); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGBA, 192, 192, 0, _wGL_RGBA, _wGL_UNSIGNED_BYTE, upload); + + upload.clear(); + upload.put(Float.floatToIntBits(0.0f)); upload.put(Float.floatToIntBits(0.0f)); + upload.put(Float.floatToIntBits(0.0f)); upload.put(Float.floatToIntBits(1.0f)); + upload.put(Float.floatToIntBits(1.0f)); upload.put(Float.floatToIntBits(0.0f)); + upload.put(Float.floatToIntBits(1.0f)); upload.put(Float.floatToIntBits(0.0f)); + upload.put(Float.floatToIntBits(0.0f)); upload.put(Float.floatToIntBits(1.0f)); + upload.put(Float.floatToIntBits(1.0f)); upload.put(Float.floatToIntBits(1.0f)); + upload.flip(); + + vbo = _wglCreateBuffer(); + _wglBindBuffer(_wGL_ARRAY_BUFFER, vbo); + _wglBufferData0(_wGL_ARRAY_BUFFER, upload, _wGL_STATIC_DRAW); + + ShaderGL vert = _wglCreateShader(_wGL_VERTEX_SHADER); + _wglShaderSource(vert, _wgetShaderHeader()+"\nprecision lowp float; in vec2 a_pos; out vec2 v_pos; void main() { gl_Position = vec4(((v_pos = a_pos) - 0.5) * vec2(2.0, -2.0), 0.0, 1.0); }"); + _wglCompileShader(vert); + + ShaderGL frag = _wglCreateShader(_wGL_FRAGMENT_SHADER); + _wglShaderSource(frag, _wgetShaderHeader()+"\nprecision lowp float; in vec2 v_pos; out vec4 fragColor; uniform sampler2D tex; uniform vec2 aspect; void main() { fragColor = vec4(texture(tex, clamp(v_pos * aspect - ((aspect - 1.0) * 0.5), 0.02, 0.98)).rgb, 1.0); }"); + _wglCompileShader(frag); + + program = _wglCreateProgram(); + + _wglAttachShader(program, vert); + _wglAttachShader(program, frag); + _wglLinkProgram(program); + _wglDetachShader(program, vert); + _wglDetachShader(program, frag); + _wglDeleteShader(vert); + _wglDeleteShader(frag); + + try { + Thread.sleep(50l); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + _wglUseProgram(program); + _wglBindAttributeLocation(program, 0, "a_pos"); + _wglUniform1i(_wglGetUniformLocation(program, "tex"), 0); + + int width = getCanvasWidth(); + int height = getCanvasHeight(); + float x, y; + if(width > height) { + x = (float)width / (float)height; + y = 1.0f; + }else { + x = 1.0f; + y = (float)height / (float)width; + } + + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, tex); + + _wglViewport(0, 0, width, height); + _wglClearColor(1.0f, 1.0f, 1.0f, 1.0f); + _wglClear(_wGL_COLOR_BUFFER_BIT | _wGL_DEPTH_BUFFER_BIT); + + _wglUniform2f(_wglGetUniformLocation(program, "aspect"), x, y); + + BufferArrayGL vao = _wglCreateVertexArray(); + _wglBindVertexArray(vao); + _wglEnableVertexAttribArray(0); + _wglVertexAttribPointer(0, 2, _wGL_FLOAT, false, 8, 0); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + _wglDisableVertexAttribArray(0); + _wglFlush(); + updateDisplay(); + + _wglUseProgram(null); + _wglBindBuffer(_wGL_ARRAY_BUFFER, null); + _wglBindTexture(_wGL_TEXTURE_2D, null); + _wglDeleteTextures(tex); + _wglDeleteVertexArray(vao); + } + + public static void paintEnable() { + + TextureGL tex = _wglGenTextures(); + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, tex); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + EaglerImage img = EaglerImage.loadImage(Base64.decodeBase64(enableScreen)); + IntBuffer upload = GLAllocation.createDirectIntBuffer(128*128); + upload.put(img.data); + upload.flip(); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGBA, 128, 128, 0, _wGL_RGBA, _wGL_UNSIGNED_BYTE, upload); + + try { + Thread.sleep(50l); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + _wglUseProgram(program); + + int width = getCanvasWidth(); + int height = getCanvasHeight(); + float x, y; + if(width > height) { + x = (float)width / (float)height; + y = 1.0f; + }else { + x = 1.0f; + y = (float)height / (float)width; + } + + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, tex); + + _wglViewport(0, 0, width, height); + _wglClearColor(1.0f, 1.0f, 1.0f, 1.0f); + _wglClear(_wGL_COLOR_BUFFER_BIT | _wGL_DEPTH_BUFFER_BIT); + + _wglUniform2f(_wglGetUniformLocation(program, "aspect"), x, y); + + BufferArrayGL vao = _wglCreateVertexArray(); + _wglBindVertexArray(vao); + _wglBindBuffer(_wGL_ARRAY_BUFFER, vbo); + _wglEnableVertexAttribArray(0); + _wglVertexAttribPointer(0, 2, _wGL_FLOAT, false, 8, 0); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + _wglDisableVertexAttribArray(0); + _wglFlush(); + updateDisplay(); + + _wglUseProgram(null); + _wglBindBuffer(_wGL_ARRAY_BUFFER, null); + _wglBindTexture(_wGL_TEXTURE_2D, null); + _wglDeleteTextures(tex); + _wglDeleteVertexArray(vao); + + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/GeneralDigest.java b/src/main/java/net/lax1dude/eaglercraft/GeneralDigest.java new file mode 100644 index 0000000..0ebbb07 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/GeneralDigest.java @@ -0,0 +1,124 @@ +package net.lax1dude.eaglercraft; + +/** + * base implementation of MD4 family style digest as outlined in + * "Handbook of Applied Cryptography", pages 344 - 347. + */ +public abstract class GeneralDigest { + private byte[] xBuf; + private int xBufOff; + + private long byteCount; + + /** + * Standard constructor + */ + protected GeneralDigest() + { + xBuf = new byte[4]; + xBufOff = 0; + } + + /** + * Copy constructor. We are using copy constructors in place + * of the Object.clone() interface as this interface is not + * supported by J2ME. + */ + protected GeneralDigest(GeneralDigest t) + { + xBuf = new byte[t.xBuf.length]; + System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length); + + xBufOff = t.xBufOff; + byteCount = t.byteCount; + } + + public void update( + byte in) + { + xBuf[xBufOff++] = in; + + if (xBufOff == xBuf.length) + { + processWord(xBuf, 0); + xBufOff = 0; + } + + byteCount++; + } + + public void update( + byte[] in, + int inOff, + int len) + { + // + // fill the current word + // + while ((xBufOff != 0) && (len > 0)) + { + update(in[inOff]); + + inOff++; + len--; + } + + // + // process whole words. + // + while (len > xBuf.length) + { + processWord(in, inOff); + + inOff += xBuf.length; + len -= xBuf.length; + byteCount += xBuf.length; + } + + // + // load in the remainder. + // + while (len > 0) + { + update(in[inOff]); + + inOff++; + len--; + } + } + + public void finish() + { + long bitLength = (byteCount << 3); + + // + // add the pad bytes. + // + update((byte)128); + + while (xBufOff != 0) + { + update((byte)0); + } + + processLength(bitLength); + + processBlock(); + } + + public void reset() + { + byteCount = 0; + + xBufOff = 0; + for ( int i = 0; i < xBuf.length; i++ ) { + xBuf[i] = 0; + } + } + + protected abstract void processWord(byte[] in, int inOff); + + protected abstract void processLength(long bitLength); + + protected abstract void processBlock(); +} diff --git a/src/main/java/net/lax1dude/eaglercraft/GuiScreenEditProfile.java b/src/main/java/net/lax1dude/eaglercraft/GuiScreenEditProfile.java new file mode 100644 index 0000000..dedcead --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/GuiScreenEditProfile.java @@ -0,0 +1,332 @@ +package net.lax1dude.eaglercraft; + +import net.minecraft.src.GuiButton; +import net.minecraft.src.GuiScreen; +import net.minecraft.src.GuiTextField; +import net.minecraft.src.NBTTagCompound; +import net.minecraft.src.StringTranslate; + +public class GuiScreenEditProfile extends GuiScreen { + + private GuiScreen parent; + private GuiTextField username; + + private boolean dropDownOpen = false; + private String[] dropDownOptions; + private int slotsVisible = 0; + private int selectedSlot = 0; + private int scrollPos = -1; + private int skinsHeight = 0; + private boolean dragging = false; + private int mousex = 0; + private int mousey = 0; + + private static final TextureLocation gui = new TextureLocation("/gui/gui.png"); + + public static final String[] defaultOptions = new String[] { + "Default Steve", + "Default Alex", + "Tennis Steve", + "Tennis Alex", + "Tuxedo Steve", + "Tuxedo Alex", + "Athlete Steve", + "Athlete Alex", + "Cyclist Steve", + "Cyclist Alex", + "Boxer Steve", + "Boxer Alex", + "Prisoner Steve", + "Prisoner Alex", + "Scottish Steve", + "Scottish Alex", + "Developer Steve", + "Developer Alex", + "Herobrine", + "Enderman", + "Skeleton", + "Blaze", + "Barney", + "Slime", + "Noob", + "Trump", + "Notch", + "Creeper", + "Zombie", + "Pig", + "Squid", + "Mooshroom", + "Villager", + "Long Arms", + "Laxative Dude" + }; + + protected String screenTitle = "Edit Profile"; + + public GuiScreenEditProfile(GuiScreen parent) { + this.parent = parent; + this.dropDownOptions = EaglerProfile.concatArrays(EaglerProfile.skinNames.toArray(new String[0]), defaultOptions); + } + + private GuiButton button0, button1, button2; + + public void initGui() { + super.initGui(); + EaglerAdapter.enableRepeatEvents(true); + StringTranslate var1 = StringTranslate.getInstance(); + this.screenTitle = var1.translateKey("profile.title"); + this.username = new GuiTextField(this.fontRenderer, this.width / 2 - 20 + 1, this.height / 6 + 24 + 1, 138, 20); + this.username.setFocused(true); + this.username.setText(EaglerProfile.username); + selectedSlot = EaglerProfile.presetSkinId == -1 ? EaglerProfile.customSkinId : (EaglerProfile.presetSkinId + EaglerProfile.skinNames.size()); + //this.buttonList.add(new GuiButton(0, this.width / 2 - 100, 140, "eeeee")); + this.buttonList.add(button0 = new GuiButton(200, this.width / 2 - 100, this.height / 6 + 168, var1.translateKey("gui.done"))); + this.buttonList.add(button1 = new GuiButton(2, this.width / 2 - 21, this.height / 6 + 110, 71, 20, var1.translateKey("profile.addSkin"))); + this.buttonList.add(button2 = new GuiButton(3, this.width / 2 - 21 + 71, this.height / 6 + 110, 72, 20, var1.translateKey("profile.clearSkin"))); + //this.buttonList.add(new GuiButton(200, this.width / 2, this.height / 6 + 72, 150, 20, var1.translateKey("gui.done"))); + } + + public void drawScreen(int mx, int my, float par3) { + StringTranslate var1 = StringTranslate.getInstance(); + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, 15, 16777215); + this.drawString(this.fontRenderer, var1.translateKey("profile.screenname"), this.width / 2 - 20, this.height / 6 + 8, 10526880); + this.drawString(this.fontRenderer, var1.translateKey("profile.playerSkin"), this.width / 2 - 20, this.height / 6 + 66, 10526880); + + mousex = mx; + mousey = my; + + int skinX = this.width / 2 - 120; + int skinY = this.height / 6 + 8; + int skinWidth = 80; + int skinHeight = 130; + + drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, -6250336); + drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, 0xff000015); + + this.username.drawTextBox(); + if(dropDownOpen) { + super.drawScreen(0, 0, par3); + }else { + super.drawScreen(mx, my, par3); + } + + skinX = this.width / 2 - 20; + skinY = this.height / 6 + 82; + skinWidth = 140; + skinHeight = 22; + + drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, -6250336); + drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 21, skinY + skinHeight - 1, -16777216); + drawRect(skinX + skinWidth - 20, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, -16777216); + + EaglerAdapter.glColor4f(1f, 1f, 1f, 1f); + gui.bindTexture(); + drawTexturedModalRect(skinX + skinWidth - 18, skinY + 3, 0, 240, 16, 16); + + this.fontRenderer.drawStringWithShadow(dropDownOptions[selectedSlot], skinX + 5, skinY + 7, 14737632); + + skinX = this.width / 2 - 20; + skinY = this.height / 6 + 103; + skinWidth = 140; + skinHeight = (this.height - skinY - 10); + slotsVisible = (skinHeight / 10); + if(slotsVisible > dropDownOptions.length) slotsVisible = dropDownOptions.length; + skinHeight = slotsVisible * 10 + 7; + skinsHeight = skinHeight; + if(scrollPos == -1) { + scrollPos = selectedSlot - 2; + } + if(scrollPos > (dropDownOptions.length - slotsVisible)) { + scrollPos = (dropDownOptions.length - slotsVisible); + } + if(scrollPos < 0) { + scrollPos = 0; + } + if(dropDownOpen) { + drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, -6250336); + drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, -16777216); + for(int i = 0; i < slotsVisible; i++) { + if(i + scrollPos < dropDownOptions.length) { + if(selectedSlot == i + scrollPos) { + drawRect(skinX + 1, skinY + i*10 + 4, skinX + skinWidth - 1, skinY + i*10 + 14, 0x77ffffff); + }else if(mx >= skinX && mx < (skinX + skinWidth - 10) && my >= (skinY + i*10 + 5) && my < (skinY + i*10 + 15)) { + drawRect(skinX + 1, skinY + i*10 + 4, skinX + skinWidth - 1, skinY + i*10 + 14, 0x55ffffff); + } + this.fontRenderer.drawStringWithShadow(dropDownOptions[i + scrollPos], skinX + 5, skinY + 5 + i*10, 14737632); + } + } + int scrollerSize = skinHeight * slotsVisible / dropDownOptions.length; + int scrollerPos = skinHeight * scrollPos / dropDownOptions.length; + drawRect(skinX + skinWidth - 4, skinY + scrollerPos + 1, skinX + skinWidth - 1, skinY + scrollerPos + scrollerSize, 0xff888888); + } + + int xx = this.width / 2 - 80; + int yy = this.height / 6 + 130; + DefaultSkinRenderer.renderPlayerPreview(xx, yy, mx, my, selectedSlot); + + } + + public void handleMouseInput() { + super.handleMouseInput(); + if(dropDownOpen) { + int var1 = EaglerAdapter.mouseGetEventDWheel(); + if(var1 < 0) { + scrollPos += 3; + } + if(var1 > 0) { + scrollPos -= 3; + } + } + } + + protected void actionPerformed(GuiButton par1GuiButton) { + if(!dropDownOpen) { + if(par1GuiButton.id == 200) { + EaglerProfile.username = this.username.getText(); + EaglerProfile.presetSkinId = selectedSlot - EaglerProfile.skinNames.size(); + if(EaglerProfile.presetSkinId < 0) { + EaglerProfile.presetSkinId = -1; + EaglerProfile.customSkinId = selectedSlot; + }else { + EaglerProfile.customSkinId = -1; + } + + LocalStorageManager.profileSettingsStorage.setInteger("ps", EaglerProfile.presetSkinId); + LocalStorageManager.profileSettingsStorage.setInteger("cs", EaglerProfile.customSkinId); + LocalStorageManager.profileSettingsStorage.setString("name", EaglerProfile.username); + + NBTTagCompound skins = new NBTTagCompound(); + for(int i = 0; i < EaglerProfile.skinNames.size(); i++) { + skins.setByteArray(EaglerProfile.skinNames.get(i), EaglerProfile.skinDatas.get(i)); + } + LocalStorageManager.profileSettingsStorage.setCompoundTag("skins", skins); + + LocalStorageManager.saveStorageP(); + + this.mc.displayGuiScreen((GuiScreen) parent); + }else if(par1GuiButton.id == 2) { + EaglerAdapter.openFileChooser("png", "image/png"); + }else if(par1GuiButton.id == 3) { + EaglerProfile.skinDatas.clear(); + EaglerProfile.skinNames.clear(); + for(Integer i : EaglerProfile.glTex) { + this.mc.renderEngine.deleteTexture(i.intValue()); + } + EaglerProfile.glTex.clear(); + this.dropDownOptions = defaultOptions; + this.selectedSlot = 0; + } + } + } + + public void updateScreen() { + this.username.updateCursorCounter(); + + if(dropDownOpen) { + if(EaglerAdapter.mouseIsButtonDown(0)) { + int skinX = this.width / 2 - 20; + int skinY = this.height / 6 + 103; + int skinWidth = 140; + if(mousex >= (skinX + skinWidth - 10) && mousex < (skinX + skinWidth) && mousey >= skinY && mousey < (skinY + skinsHeight)) { + dragging = true; + } + if(dragging) { + int scrollerSize = skinsHeight * slotsVisible / dropDownOptions.length; + scrollPos = (mousey - skinY - (scrollerSize / 2)) * dropDownOptions.length / skinsHeight; + } + }else { + dragging = false; + } + }else { + dragging = false; + } + + byte[] b; + if((b = EaglerAdapter.getFileChooserResult()) != null && b.length > 0) { + EaglerImage img = EaglerImage.loadImage(b); + if(!((img.w == 64 && img.h == 32) || (img.w == 64 && img.h == 64) || (img.w == 128 && img.h == 64) || (img.w == 128 && img.h == 128))) return; + byte[] rawSkin = new byte[img.data.length * 4]; + for(int i = 0; i < img.data.length; i++) { + int i2 = i * 4; int i3 = img.data[i]; + rawSkin[i2] = (byte)(i3); + rawSkin[i2 + 1] = (byte)(i3 >> 8); + rawSkin[i2 + 2] = (byte)(i3 >> 16); + rawSkin[i2 + 3] = (byte)(i3 >> 24); + } + String name = EaglerAdapter.getFileChooserResultName(); + if(name.length() > 32) { + name = name.substring(0, 32); + } + EaglerProfile.addSkin(name, rawSkin); + selectedSlot = EaglerProfile.skinNames.size() - 1; + this.dropDownOptions = EaglerProfile.concatArrays(EaglerProfile.skinNames.toArray(new String[0]), defaultOptions); + } + } + + public void onGuiClosed() { + EaglerAdapter.enableRepeatEvents(false); + } + + protected void keyTyped(char par1, int par2) { + this.username.textboxKeyTyped(par1, par2); + + String text = username.getText(); + if(text.length() > 16) text = text.substring(0, 16); + text = text.replaceAll("[^A-Za-z0-9\\-_]", "_"); + this.username.setText(text); + + if(par2 == 200 && selectedSlot > 0) { + --selectedSlot; + scrollPos = selectedSlot - 2; + } + if(par2 == 208 && selectedSlot < (dropDownOptions.length - 1)) { + ++selectedSlot; + scrollPos = selectedSlot - 2; + } + } + + protected void mouseClicked(int par1, int par2, int par3) { + super.mouseClicked(par1, par2, par3); + this.username.mouseClicked(par1, par2, par3); + + if (par3 == 0) { + int skinX = this.width / 2 + 140 - 40; + int skinY = this.height / 6 + 82; + + if(par1 >= skinX && par1 < (skinX + 20) && par2 >= skinY && par2 < (skinY + 22)) { + dropDownOpen = !dropDownOpen; + } + + skinX = this.width / 2 - 20; + skinY = this.height / 6 + 82; + int skinWidth = 140; + int skinHeight = skinsHeight; + + if(!(par1 >= skinX && par1 < (skinX + skinWidth) && par2 >= skinY && par2 < (skinY + skinHeight + 22))) { + dropDownOpen = false; + dragging = false; + } + + skinY += 21; + + if(dropDownOpen && !dragging) { + for(int i = 0; i < slotsVisible; i++) { + if(i + scrollPos < dropDownOptions.length) { + if(selectedSlot != i + scrollPos) { + if(par1 >= skinX && par1 < (skinX + skinWidth - 10) && par2 >= (skinY + i*10 + 5) && par2 < (skinY + i*10 + 15) && selectedSlot != i + scrollPos) { + selectedSlot = i + scrollPos; + dropDownOpen = false; + dragging = false; + } + } + } + } + } + + } + } + + + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/GuiScreenVoiceChannel.java b/src/main/java/net/lax1dude/eaglercraft/GuiScreenVoiceChannel.java new file mode 100644 index 0000000..0a5dd4d --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/GuiScreenVoiceChannel.java @@ -0,0 +1,243 @@ +package net.lax1dude.eaglercraft; + +import java.util.Arrays; + +import net.minecraft.client.Minecraft; +import net.minecraft.src.GuiButton; +import net.minecraft.src.GuiIngameMenu; +import net.minecraft.src.GuiMainMenu; +import net.minecraft.src.GuiScreen; +import net.minecraft.src.GuiSlider2; +import net.minecraft.src.GuiTextField; +import net.minecraft.src.ScaledResolution; +import net.minecraft.src.StringTranslate; + +public class GuiScreenVoiceChannel extends GuiScreen { + + public GuiScreenVoiceChannel(GuiScreen parent) { + this.parent = parent; + } + + protected String screenTitle = "Voice Channel"; + private GuiScreen parent; + private GuiTextField channel; + + private GuiButton done; + private GuiButton connect; + private GuiButton disconnect; + private GuiSlider2 slider; + + public void initGui() { + StringTranslate var1 = StringTranslate.getInstance(); + this.screenTitle = var1.translateKey("voice.title"); + this.channel = new GuiTextField(this.fontRenderer, this.width / 2 - 98, this.height / 6 + 24, 195, 20); + this.channel.setText(EaglerProfile.myChannel); + EaglerAdapter.enableRepeatEvents(true); + this.buttonList.add(done = new GuiButton(200, this.width / 2 - 100, this.height / 6 + 148, var1.translateKey("gui.done"))); + this.buttonList.add(connect = new GuiButton(1, this.width / 2 - 100, this.height / 6 + 52, 99, 20, var1.translateKey("voice.connect"))); + this.buttonList.add(disconnect = new GuiButton(2, this.width / 2 + 1, this.height / 6 + 52, 99, 20, var1.translateKey("voice.disconnect"))); + this.buttonList.add(slider = new GuiSlider2(3, this.width / 2 - 100, this.height / 6 + 103, 200, 20, 0.5f, 2.0f)); + } + + public void onGuiClosed() { + EaglerAdapter.enableRepeatEvents(false); + } + + public void drawScreen(int mx, int my, float par3) { + this.drawDefaultBackground(); + StringTranslate var1 = StringTranslate.getInstance(); + this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, 15, 16777215); + this.drawString(this.fontRenderer, var1.translateKey("voice.addr"), this.width / 2 - 98, this.height / 6 + 8, 10526880); + if(voiceRelayed) { + this.drawCenteredString(this.fontRenderer, var1.translateKey("voice.warning1"), this.width / 2, this.height / 6 + 125, 0xffcccc); + this.drawCenteredString(this.fontRenderer, var1.translateKey("voice.warning2"), this.width / 2, this.height / 6 + 136, 0xffcccc); + this.drawCenteredString(this.fontRenderer, var1.translateKey("voice.warning3"), this.width / 2, this.height / 6 + 147, 0xffcccc); + this.drawString(this.fontRenderer, var1.translateKey("voice.volume"), this.width / 2 - 98, this.height / 6 + 81, 10526880); + slider.yPosition = this.height / 6 + 95; + done.yPosition = this.height / 6 + 168; + }else { + this.drawString(this.fontRenderer, var1.translateKey("voice.volume"), this.width / 2 - 98, this.height / 6 + 89, 10526880); + slider.yPosition = this.height / 6 + 103; + done.yPosition = this.height / 6 + 148; + } + super.drawScreen(mx, my, par3); + this.channel.drawTextBox(); + } + + protected void actionPerformed(GuiButton par1GuiButton) { + if(par1GuiButton.id == 200) { + this.mc.displayGuiScreen(parent); + }else if(par1GuiButton.id == 1) { + EaglerAdapter.voiceConnect(channel.getText()); + }else if(par1GuiButton.id == 2) { + EaglerAdapter.voiceEnd(); + } + } + + public void updateScreen() { + this.channel.updateCursorCounter(); + this.connect.enabled = !voiceActive; + this.disconnect.enabled = voiceActive; + this.channel.setEnabled(!voiceActive); + this.slider.enabled = voiceActive; + } + + protected void keyTyped(char par1, int par2) { + this.channel.textboxKeyTyped(par1, par2); + } + + protected void mouseClicked(int par1, int par2, int par3) { + super.mouseClicked(par1, par2, par3); + this.channel.mouseClicked(par1, par2, par3); + } + + public boolean doesGuiPauseGame() { + return false; + } + + private static final TextureLocation tex_gui = new TextureLocation("/gui/gui.png"); + + private static String[] connectedUsers = new String[0]; + private static String[] talkingUsers = new String[0]; + private static boolean voiceActive = false; + private static boolean voiceRelayed = false; + + public static void tickVoiceConnection() { + voiceActive = EaglerAdapter.voiceActive(); + if(voiceActive) { + voiceRelayed = EaglerAdapter.voiceRelayed(); + connectedUsers = EaglerAdapter.voiceUsers(); + talkingUsers = EaglerAdapter.voiceUsersTalking(); + Arrays.sort(talkingUsers); + Arrays.sort(connectedUsers); + }else { + voiceRelayed = false; + } + } + + public static long fadeInTimer = 0l; + + public static void drawOverlay() { + Minecraft mc = Minecraft.getMinecraft(); + if(System.currentTimeMillis() - fadeInTimer < 1500l) { + ScaledResolution res = new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glDisable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glDepthMask(false); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + float i = (float)(System.currentTimeMillis() - fadeInTimer) / 600f; + i = 1.0f / (i + 1.0f); + i = i * i * 1.08f - 0.08f; + if(i < 0.0f) i = 0.0f; + drawRect(0, 0, res.getScaledWidth(), res.getScaledHeight(), ((int)(i * 255f) << 24) | 0xffffff); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + if(System.currentTimeMillis() - fadeInTimer < 130l) { + mc.showWarningText(); + } + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glDepthMask(true); + } + boolean titleScreen = (mc.currentScreen != null && (mc.currentScreen instanceof GuiMainMenu)); + if(voiceActive && !(titleScreen && ((GuiMainMenu)mc.currentScreen).showAck) && !mc.gameSettings.showDebugInfo) { + ScaledResolution res = new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight); + int width = res.getScaledWidth(); int height = res.getScaledHeight(); + if(titleScreen) { + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(0f, 12f, 0f); + } + + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + String line1 = "voice connected"; + String line2 = "" + connectedUsers.length + " users listening"; + int ll1 = mc.fontRenderer.getStringWidth(line1); + int ll2 = mc.fontRenderer.getStringWidth(line2); + drawRect(width - 17 - ll1 - 6, 0, width, 20, 0x33000000); + + if(mc.gameSettings.keyBindPlayerList.pressed || (mc.currentScreen != null && ((mc.currentScreen instanceof GuiIngameMenu) || (mc.currentScreen instanceof GuiScreenVoiceChannel)))) { + if(connectedUsers.length > 0) { + int wid = 0; + for(int i = 0; i < connectedUsers.length; ++i) { + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + int sw = mc.fontRenderer.getStringWidth(connectedUsers[i]); + mc.fontRenderer.drawStringWithShadow(connectedUsers[i], width - 12 - sw, 26 + i*11, 0xffeeeeee); + if(wid < sw) { + wid = sw; + } + + boolean isTalking = false; + for(int j = 0; j < talkingUsers.length; ++j) { + if(talkingUsers[j].equals(connectedUsers[i])) { + isTalking = true; + break; + } + } + + tex_gui.bindTexture(); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 0.65f); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(width - 9, 27 + i*11, 0f); + EaglerAdapter.glScalef(0.5f, 0.5f, 0.5f); + static_drawTexturedModalRect(0, 0, isTalking ? 208 : 224, 0, 15, 15); + EaglerAdapter.glPopMatrix(); + } + + drawRect(width - wid - 15, 24, width, 26 + connectedUsers.length*11, 0x33000000); + } + }else { + if(talkingUsers.length > 0) { + int wid = 0; + for(int i = 0; i < talkingUsers.length; ++i) { + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + int sw = mc.fontRenderer.getStringWidth(talkingUsers[i]); + mc.fontRenderer.drawStringWithShadow(talkingUsers[i], width - 12 - sw, 26 + i*11, 0xffeeeeee); + if(wid < sw) { + wid = sw; + } + + tex_gui.bindTexture(); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 0.65f); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(width - 9, 27 + i*11, 0f); + EaglerAdapter.glScalef(0.5f, 0.5f, 0.5f); + static_drawTexturedModalRect(0, 0, 208, 0, 15, 15); + EaglerAdapter.glPopMatrix(); + } + + drawRect(width - wid - 15, 24, width, 26 + talkingUsers.length*11, 0x33000000); + } + } + + mc.fontRenderer.drawStringWithShadow(line1, width - 16 - ll1 - 4, 2, 0xffffffff); + + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(width - 20, 11f, 0f); + EaglerAdapter.glScalef(0.75f, 0.75f, 0.75f); + mc.fontRenderer.drawStringWithShadow(line2, -ll2, 0, 0xffffffff); + EaglerAdapter.glPopMatrix(); + + boolean b = ((System.currentTimeMillis() / 800l) % 2l) == 1l; + + tex_gui.bindTexture(); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 0.65f); + static_drawTexturedModalRect(width - 17, 2, b ? 192 : 224, 0, 15, 15); + + if(titleScreen) { + EaglerAdapter.glPopMatrix(); + } + } + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/LocalStorageManager.java b/src/main/java/net/lax1dude/eaglercraft/LocalStorageManager.java new file mode 100644 index 0000000..043ba4a --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/LocalStorageManager.java @@ -0,0 +1,96 @@ +package net.lax1dude.eaglercraft; + +import java.io.IOException; + +import net.minecraft.src.Achievement; +import net.minecraft.src.CompressedStreamTools; +import net.minecraft.src.NBTTagCompound; + +public class LocalStorageManager { + + public static NBTTagCompound achievementStorage = null; + public static NBTTagCompound gameSettingsStorage = null; + public static NBTTagCompound profileSettingsStorage = null; + + public static void loadStorage() { + byte[] a = EaglerAdapter.loadLocalStorage("a"); + byte[] g = EaglerAdapter.loadLocalStorage("g"); + byte[] p = EaglerAdapter.loadLocalStorage("p"); + + if(a != null) { + try { + achievementStorage = CompressedStreamTools.readUncompressed(a); + }catch(IOException e) { + ; + } + } + + if(g != null) { + try { + gameSettingsStorage = CompressedStreamTools.readUncompressed(g); + }catch(IOException e) { + ; + } + } + + if(p != null) { + try { + profileSettingsStorage = CompressedStreamTools.readUncompressed(p); + }catch(IOException e) { + ; + } + } + + if(achievementStorage == null) achievementStorage = new NBTTagCompound(); + if(gameSettingsStorage == null) gameSettingsStorage = new NBTTagCompound(); + if(profileSettingsStorage == null) profileSettingsStorage = new NBTTagCompound(); + + } + + public static void saveStorageA() { + try { + EaglerAdapter.saveLocalStorage("a", CompressedStreamTools.writeUncompressed(achievementStorage)); + } catch (IOException e) { + ; + } + } + + public static void saveStorageG() { + try { + EaglerAdapter.saveLocalStorage("g", CompressedStreamTools.writeUncompressed(gameSettingsStorage)); + } catch (IOException e) { + ; + } + } + + public static void saveStorageP() { + try { + EaglerAdapter.saveLocalStorage("p", CompressedStreamTools.writeUncompressed(profileSettingsStorage)); + } catch (IOException e) { + ; + } + } + + public static String dumpConfiguration() { + try { + return Base64.encodeBase64String(CompressedStreamTools.writeUncompressed(gameSettingsStorage)); + } catch(Throwable e) { + return ""; + } + } + + public static boolean hasMadeAchievement(Achievement stat) { + if(stat.parentAchievement != null && (!achievementStorage.getBoolean(stat.parentAchievement.statGuid))) { + return false; + }else { + if(!achievementStorage.getBoolean(stat.statGuid)) { + achievementStorage.setBoolean(stat.statGuid, true); + saveStorageA(); + return true; + }else { + return false; + } + } + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/ModelBipedNewSkins.java b/src/main/java/net/lax1dude/eaglercraft/ModelBipedNewSkins.java new file mode 100644 index 0000000..36ccb69 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/ModelBipedNewSkins.java @@ -0,0 +1,146 @@ +package net.lax1dude.eaglercraft; + +import net.minecraft.src.Entity; +import net.minecraft.src.ModelBiped; +import net.minecraft.src.ModelRenderer; + +public class ModelBipedNewSkins extends ModelBiped { + public ModelRenderer field_178734_a; + public ModelRenderer field_178732_b; + public ModelRenderer field_178733_c; + public ModelRenderer field_178731_d; + public ModelRenderer field_178730_v; + private ModelRenderer field_178729_w; + private ModelRenderer field_178736_x; + private boolean field_178735_y; + private static final String __OBFID = "CL_00002626"; + + public ModelBipedNewSkins(float p_i46304_1_, boolean p_i46304_2_) + { + super(p_i46304_1_, 0.0F, 64, 64); + this.field_178735_y = p_i46304_2_; + this.field_178736_x = new ModelRenderer(this, 24, 0); + this.field_178736_x.addBox(-3.0F, -6.0F, -1.0F, 6, 6, 1, p_i46304_1_); + this.field_178729_w = new ModelRenderer(this, 0, 0); + this.field_178729_w.setTextureSize(64, 32); + this.field_178729_w.addBox(-5.0F, 0.0F, -1.0F, 10, 16, 1, p_i46304_1_); + + if (p_i46304_2_) + { + this.bipedLeftArm = new ModelRenderer(this, 32, 48); + this.bipedLeftArm.addBox(-1.0F, -2.0F, -2.0F, 3, 12, 4, p_i46304_1_); + this.bipedLeftArm.setRotationPoint(5.0F, 2.5F, 0.0F); + this.bipedRightArm = new ModelRenderer(this, 40, 16); + this.bipedRightArm.addBox(-2.0F, -2.0F, -2.0F, 3, 12, 4, p_i46304_1_); + this.bipedRightArm.setRotationPoint(-5.0F, 2.5F, 0.0F); + this.field_178734_a = new ModelRenderer(this, 48, 48); + this.field_178734_a.addBox(-1.0F, -2.0F, -2.0F, 3, 12, 4, p_i46304_1_ + 0.25F); + this.field_178734_a.setRotationPoint(5.0F, 2.5F, 0.0F); + this.field_178732_b = new ModelRenderer(this, 40, 32); + this.field_178732_b.addBox(-2.0F, -2.0F, -2.0F, 3, 12, 4, p_i46304_1_ + 0.25F); + this.field_178732_b.setRotationPoint(-5.0F, 2.5F, 10.0F); + } + else + { + this.bipedLeftArm = new ModelRenderer(this, 32, 48); + this.bipedLeftArm.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, p_i46304_1_); + this.bipedLeftArm.setRotationPoint(5.0F, 2.0F, 0.0F); + this.field_178734_a = new ModelRenderer(this, 48, 48); + this.field_178734_a.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, p_i46304_1_ + 0.25F); + this.field_178734_a.setRotationPoint(5.0F, 2.0F, 0.0F); + this.field_178732_b = new ModelRenderer(this, 40, 32); + this.field_178732_b.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4, p_i46304_1_ + 0.25F); + this.field_178732_b.setRotationPoint(-5.0F, 2.0F, 10.0F); + } + + this.bipedLeftLeg = new ModelRenderer(this, 16, 48); + this.bipedLeftLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, p_i46304_1_); + this.bipedLeftLeg.setRotationPoint(1.9F, 12.0F, 0.0F); + this.field_178733_c = new ModelRenderer(this, 0, 48); + this.field_178733_c.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, p_i46304_1_ + 0.25F); + this.field_178733_c.setRotationPoint(1.9F, 12.0F, 0.0F); + this.field_178731_d = new ModelRenderer(this, 0, 32); + this.field_178731_d.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, p_i46304_1_ + 0.25F); + this.field_178731_d.setRotationPoint(-1.9F, 12.0F, 0.0F); + this.field_178730_v = new ModelRenderer(this, 16, 32); + this.field_178730_v.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, p_i46304_1_ + 0.25F); + this.field_178730_v.setRotationPoint(0.0F, 0.0F, 0.0F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity p_78088_1_, float p_78088_2_, float p_78088_3_, float p_78088_4_, float p_78088_5_, float p_78088_6_, float p_78088_7_) { + super.render(p_78088_1_, p_78088_2_, p_78088_3_, p_78088_4_, p_78088_5_, p_78088_6_, p_78088_7_); + EaglerAdapter.glPushMatrix(); + + if (p_78088_1_ != null && p_78088_1_.isSneaking()) { + EaglerAdapter.glTranslatef(0.0F, 0.2F, 0.0F); + } + + this.field_178733_c.render(p_78088_7_); + this.field_178731_d.render(p_78088_7_); + this.field_178734_a.render(p_78088_7_); + this.field_178732_b.render(p_78088_7_); + this.field_178730_v.render(p_78088_7_); + + EaglerAdapter.glPopMatrix(); + } + + public void func_178727_b(float p_178727_1_) { + func_178685_a(this.bipedHead, this.field_178736_x); + this.field_178736_x.rotationPointX = 0.0F; + this.field_178736_x.rotationPointY = 0.0F; + this.field_178736_x.render(p_178727_1_); + } + + public void func_178728_c(float p_178728_1_) { + this.field_178729_w.render(p_178728_1_); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float p_78087_1_, float p_78087_2_, float p_78087_3_, float p_78087_4_, float p_78087_5_, float p_78087_6_, Entity p_78087_7_) { + super.setRotationAngles(p_78087_1_, p_78087_2_, p_78087_3_, p_78087_4_, p_78087_5_, p_78087_6_, p_78087_7_); + func_178685_a(this.bipedLeftLeg, this.field_178733_c); + func_178685_a(this.bipedRightLeg, this.field_178731_d); + func_178685_a(this.bipedLeftArm, this.field_178734_a); + func_178685_a(this.bipedRightArm, this.field_178732_b); + func_178685_a(this.bipedBody, this.field_178730_v); + } + + public void func_178725_a() { + this.bipedRightArm.render(0.0625F); + this.field_178732_b.render(0.0625F); + } + + public void func_178726_b() { + this.bipedLeftArm.render(0.0625F); + this.field_178734_a.render(0.0625F); + } + + public void postRenderHiddenArm(float p_178718_1_) { + if (this.field_178735_y) { + ++this.bipedRightArm.rotationPointX; + this.bipedRightArm.postRender(p_178718_1_); + --this.bipedRightArm.rotationPointX; + } else { + this.bipedRightArm.postRender(p_178718_1_); + } + } + + public static void func_178685_a(ModelRenderer p_178685_0_, ModelRenderer p_178685_1_) + { + p_178685_1_.rotateAngleX = p_178685_0_.rotateAngleX; + p_178685_1_.rotateAngleY = p_178685_0_.rotateAngleY; + p_178685_1_.rotateAngleZ = p_178685_0_.rotateAngleZ; + p_178685_1_.rotationPointX = p_178685_0_.rotationPointX; + p_178685_1_.rotationPointY = p_178685_0_.rotationPointY; + p_178685_1_.rotationPointZ = p_178685_0_.rotationPointZ; + } + +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/SHA1Digest.java b/src/main/java/net/lax1dude/eaglercraft/SHA1Digest.java new file mode 100644 index 0000000..2163594 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/SHA1Digest.java @@ -0,0 +1,258 @@ +package net.lax1dude.eaglercraft; + + +/** + * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349. + * + * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5 + * is the "endienness" of the word processing! + */ +public class SHA1Digest + extends GeneralDigest +{ + private static final int DIGEST_LENGTH = 20; + + private int H1, H2, H3, H4, H5; + + private int[] X = new int[80]; + private int xOff; + + /** + * Standard constructor + */ + public SHA1Digest() + { + reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public SHA1Digest(SHA1Digest t) + { + super(t); + + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + + System.arraycopy(t.X, 0, X, 0, t.X.length); + xOff = t.xOff; + } + + public String getAlgorithmName() + { + return "SHA-1"; + } + + public int getDigestSize() + { + return DIGEST_LENGTH; + } + + protected void processWord( + byte[] in, + int inOff) + { + X[xOff++] = ((in[inOff] & 0xff) << 24) | ((in[inOff + 1] & 0xff) << 16) + | ((in[inOff + 2] & 0xff) << 8) | ((in[inOff + 3] & 0xff)); + + if (xOff == 16) + { + processBlock(); + } + } + + private void unpackWord( + int word, + byte[] out, + int outOff) + { + out[outOff] = (byte)(word >>> 24); + out[outOff + 1] = (byte)(word >>> 16); + out[outOff + 2] = (byte)(word >>> 8); + out[outOff + 3] = (byte)word; + } + + protected void processLength( + long bitLength) + { + if (xOff > 14) + { + processBlock(); + } + + X[14] = (int)(bitLength >>> 32); + X[15] = (int)(bitLength & 0xffffffff); + } + + public int doFinal( + byte[] out, + int outOff) + { + finish(); + + unpackWord(H1, out, outOff); + unpackWord(H2, out, outOff + 4); + unpackWord(H3, out, outOff + 8); + unpackWord(H4, out, outOff + 12); + unpackWord(H5, out, outOff + 16); + + reset(); + + return DIGEST_LENGTH; + } + + /** + * reset the chaining variables + */ + public void reset() + { + super.reset(); + + H1 = 0x67452301; + H2 = 0xefcdab89; + H3 = 0x98badcfe; + H4 = 0x10325476; + H5 = 0xc3d2e1f0; + + xOff = 0; + for (int i = 0; i != X.length; i++) + { + X[i] = 0; + } + } + + // + // Additive constants + // + private static final int Y1 = 0x5a827999; + private static final int Y2 = 0x6ed9eba1; + private static final int Y3 = 0x8f1bbcdc; + private static final int Y4 = 0xca62c1d6; + + private int f( + int u, + int v, + int w) + { + return ((u & v) | ((~u) & w)); + } + + private int h( + int u, + int v, + int w) + { + return (u ^ v ^ w); + } + + private int g( + int u, + int v, + int w) + { + return ((u & v) | (u & w) | (v & w)); + } + + private int rotateLeft( + int x, + int n) + { + return (x << n) | (x >>> (32 - n)); + } + + protected void processBlock() + { + // + // expand 16 word block into 80 word block. + // + for (int i = 16; i <= 79; i++) + { + X[i] = rotateLeft((X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]), 1); + } + + // + // set up working variables. + // + int A = H1; + int B = H2; + int C = H3; + int D = H4; + int E = H5; + + // + // round 1 + // + for (int j = 0; j <= 19; j++) + { + int t = rotateLeft(A, 5) + f(B, C, D) + E + X[j] + Y1; + + E = D; + D = C; + C = rotateLeft(B, 30); + B = A; + A = t; + } + + // + // round 2 + // + for (int j = 20; j <= 39; j++) + { + int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y2; + + E = D; + D = C; + C = rotateLeft(B, 30); + B = A; + A = t; + } + + // + // round 3 + // + for (int j = 40; j <= 59; j++) + { + int t = rotateLeft(A, 5) + g(B, C, D) + E + X[j] + Y3; + + E = D; + D = C; + C = rotateLeft(B, 30); + B = A; + A = t; + } + + // + // round 4 + // + for (int j = 60; j <= 79; j++) + { + int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y4; + + E = D; + D = C; + C = rotateLeft(B, 30); + B = A; + A = t; + } + + H1 += A; + H2 += B; + H3 += C; + H4 += D; + H5 += E; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.length; i++) + { + X[i] = 0; + } + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/TextureLocation.java b/src/main/java/net/lax1dude/eaglercraft/TextureLocation.java new file mode 100644 index 0000000..7c87d82 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/TextureLocation.java @@ -0,0 +1,38 @@ +package net.lax1dude.eaglercraft; + +import java.util.ArrayList; + +import net.minecraft.client.Minecraft; +import net.minecraft.src.RenderEngine; + +public class TextureLocation { + + private String path; + private int glObject; + + public TextureLocation(String path) { + this.path = path; + this.glObject = -1; + locations.add(this); + } + + public static void freeTextures() { + for(TextureLocation l : locations) { + l.glObject = -1; + } + } + + public void bindTexture() { + RenderEngine r = Minecraft.getMinecraft().renderEngine; + if(glObject == -1) { + glObject = r.getTexture(path); + if(glObject == -1) { + System.err.println("could not load: "+path); + } + } + r.bindTexture(glObject); + } + + private static final ArrayList locations = new ArrayList(); + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/TextureTerrainMap.java b/src/main/java/net/lax1dude/eaglercraft/TextureTerrainMap.java new file mode 100644 index 0000000..961c63b --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/TextureTerrainMap.java @@ -0,0 +1,465 @@ +package net.lax1dude.eaglercraft; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.IntBuffer; +import java.util.ArrayList; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.EaglerImage; +import net.minecraft.client.Minecraft; +import net.minecraft.src.Block; +import net.minecraft.src.GLAllocation; +import net.minecraft.src.Icon; +import net.minecraft.src.IconRegister; +import net.minecraft.src.RenderManager; + +//supports only 16x16 textures, mipmap is four levels deep +public class TextureTerrainMap implements IconRegister { + + private static class TerrainIcon implements Icon { + + public final TextureTerrainMap map; + public final String name; + public final int id; + private EaglerImage[][] frames = null; + private int[] framesIdx = null; + + protected int originX; + protected int originY; + private float minU; + private float maxU; + private float minV; + private float maxV; + + protected int originX_center; + protected int originY_center; + private float minU_center; + private float maxU_center; + private float minV_center; + private float maxV_center; + + protected int frameCounter = 0; + protected int frameCurrent = 0; + + private TerrainIcon(int id, TextureTerrainMap map, String name) { + this.id = id; + this.map = map; + this.name = name; + this.originX = (id % (map.width / 48)) * 48; + this.originY = (id / (map.width / 48)) * 48; + this.minU = (float)originX / (float)map.width; + this.minV = (float)originY / (float)map.height; + this.maxU = (float)(originX + 48) / (float)map.width; + this.maxV = (float)(originY + 48) / (float)map.height; + this.originX_center = originX + 16; + this.originY_center = originY + 16; + this.minU_center = (float)originX_center / (float)map.width; + this.minV_center = (float)originY_center / (float)map.height; + this.maxU_center = (float)(originX_center + 16) / (float)map.width; + this.maxV_center = (float)(originY_center + 16) / (float)map.height; + } + + @Override + public int getOriginX() { + return originX_center; + } + + @Override + public int getOriginY() { + return originY_center; + } + + @Override + public float getMinU() { + return minU_center; + } + + @Override + public float getMaxU() { + return maxU_center; + } + + @Override + public float getInterpolatedU(double var1) { + float var3 = this.maxU_center - this.minU_center; + return this.minU_center + var3 * ((float) var1 / 16.0F); + } + + @Override + public float getMinV() { + return minV_center; + } + + @Override + public float getMaxV() { + return maxV_center; + } + + @Override + public float getInterpolatedV(double var1) { + float var3 = this.maxV_center - this.minV_center; + return this.minV_center + var3 * ((float) var1 / 16.0F); + } + + @Override + public String getIconName() { + return name == null ? "missingno" : name; + } + + @Override + public int getSheetWidth() { + return map.width; + } + + @Override + public int getSheetHeight() { + return map.height; + } + + private void updateAnimation() { + if(frames != null) { + int var4 = this.frameCounter; + this.frameCounter = (this.frameCounter + 1) % this.framesIdx.length; + int i = framesIdx[this.frameCounter]; + if (this.frameCurrent != i) { + this.frameCurrent = i; + map.replaceTexture(this, frames[i]); + } + } + } + + private void loadData() { + byte[] data = EaglerAdapter.loadResourceBytes("/" + map.basePath + name + ".png"); + if(data == null) { + map.replaceTexture(this, map.missingData); + }else { + EaglerImage img = EaglerImage.loadImage(data); + if(img == null) { + map.replaceTexture(this, map.missingData); + }else { + int divs = img.h / 16; + if(divs == 1) { + this.frames = null; + this.framesIdx = null; + map.replaceTexture(this, generateMip(img)); + }else { + frames = new EaglerImage[divs][]; + for(int i = 0; i < divs; ++i) { + frames[i] = generateMip(img.getSubImage(0, i * 16, 16, 16)); + } + String dat = EaglerAdapter.fileContents("/" + map.basePath + name + ".txt"); + if(dat != null) System.out.println("Found animation info for: " + map.basePath + name + ".png"); + if(dat == null || (dat = dat.trim()).isEmpty()) { + framesIdx = new int[frames.length]; + for(int i = 0; i < frames.length; ++i) { + framesIdx[i] = i; + } + }else { + String[] fd = dat.split(","); + int len = 0; + for(int i = 0; i < fd.length; ++i) { + int j = fd[i].indexOf('*'); + len += (j == -1 ? 1 : Integer.parseInt(fd[i].substring(j + 1))); + } + framesIdx = new int[len]; + len = 0; + for(int i = 0; i < fd.length; ++i) { + int j = fd[i].indexOf('*'); + if(j == -1) { + framesIdx[len++] = Integer.parseInt(fd[i]); + }else { + int c = Integer.parseInt(fd[i].substring(0, j)); + int l = Integer.parseInt(fd[i].substring(j + 1)); + for(int k = 0; k < l; ++k) { + framesIdx[len++] = c; + } + } + } + } + map.replaceTexture(this, this.frames[framesIdx[0]]); + } + } + } + } + + } + + private final String basePath; + private final int width; + private final int height; + private TerrainIcon missingImage; + private ArrayList iconList; + public final int texture; + private final EaglerImage[] missingData; + + private static final IntBuffer uploadBuffer = EaglerAdapter.isWebGL ? IntBuffer.wrap(new int[4096]) : ByteBuffer.allocateDirect(4096 << 2).order(ByteOrder.nativeOrder()).asIntBuffer(); + + private int nextSlot = 0; + + public TextureTerrainMap(int size, String par2, String par3Str, EaglerImage par4BufferedImage) { + this.width = size / 48 * 48; + this.height = size / 48 * 48; + this.basePath = par3Str; + this.missingImage = new TerrainIcon(nextSlot++, this, null); + this.iconList = new ArrayList(); + this.texture = EaglerAdapter.glGenTextures(); + EaglerAdapter.glBindTexture(EaglerAdapter.GL_TEXTURE_2D, texture); + int levelW = width; + int levelH = height; + IntBuffer blank = GLAllocation.createDirectIntBuffer(levelW * levelH); + for(int i = 0; i < blank.limit(); ++i) { + blank.put(i, ((i / width + (i % width)) % 2 == 0) ? 0xffff00ff : 0xff000000); + } + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MIN_FILTER, EaglerAdapter.GL_NEAREST_MIPMAP_LINEAR); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MAG_FILTER, EaglerAdapter.GL_NEAREST); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_WRAP_S, EaglerAdapter.GL_CLAMP); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_WRAP_T, EaglerAdapter.GL_CLAMP); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MAX_LEVEL, 4); + EaglerAdapter.glTexParameterf(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MAX_ANISOTROPY, 1.0f); + for(int i = 0; i < 5; ++i) { + blank.clear().limit(levelW * levelH); + EaglerAdapter.glTexImage2D(EaglerAdapter.GL_TEXTURE_2D, i, EaglerAdapter.GL_RGBA, levelW, levelH, 0, EaglerAdapter.GL_RGBA, EaglerAdapter.GL_UNSIGNED_BYTE, blank); + levelW /= 2; + levelH /= 2; + } + replaceTexture(missingImage, missingData = generateMip(par4BufferedImage)); + } + + public static EaglerImage[] generateMip(EaglerImage src16x16) { + EaglerImage[] ret = new EaglerImage[5]; + ret[0] = populateAlpha(src16x16); + ret[1] = generateLevel(ret[0]); ret[0] = create3x3(ret[0]); + ret[2] = generateLevel(ret[1]); ret[1] = create3x3(ret[1]); + ret[3] = generateLevel(ret[2]); ret[2] = create3x3(ret[2]); + ret[4] = create3x3_2(generateLevel(ret[3])); ret[3] = create3x3(ret[3]); + return ret; + } + + public static EaglerImage generateLevel(EaglerImage src) { + EaglerImage e = new EaglerImage(src.w / 2, src.h / 2, true); + for(int y = 0; y < e.h; ++y) { + for(int x = 0; x < e.w; ++x) { + int x2 = x * 2; + int y2 = y * 2; + int a = src.data[y2 * src.w + x2]; + int b = src.data[y2 * src.w + x2 + 1]; + int c = src.data[(y2 + 1) * src.w + x2]; + int d = src.data[(y2 + 1) * src.w + x2 + 1]; + int ca = (((a >> 24) & 255) + ((b >> 24) & 255) + ((c >> 24) & 255) + ((d >> 24) & 255)) >> 2; + int cr = (((a >> 16) & 255) + ((b >> 16) & 255) + ((c >> 16) & 255) + ((d >> 16) & 255)) >> 2; + int cg = (((a >> 8) & 255) + ((b >> 8) & 255) + ((c >> 8) & 255) + ((d >> 8) & 255)) >> 2; + int cb = ((a & 255) + (b & 255) + (c & 255) + (d & 255)) >> 2; + e.data[y * e.w + x] = (ca << 24) | (cr << 16) | (cg << 8) | cb; + } + } + return e; + } + + public static EaglerImage premultiplyAlpha(EaglerImage src) { + EaglerImage e = new EaglerImage(src.w, src.h, true); + for(int i = 0; i < src.data.length; ++i) { + int x = src.data[i]; + int a = (x >> 24) & 255; + int r = (x >> 16) & 255; + int g = (x >> 8) & 255; + int b = x & 255; + r = (r * a) / 255; + g = (g * a) / 255; + b = (b * a) / 255; + e.data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + return e; + } + + public static EaglerImage populateAlpha(EaglerImage src) { + EaglerImage ret = new EaglerImage(src.w, src.h, true); + int reducedR = 0; + int reducedG = 0; + int reducedB = 0; + int divisor = 0; + int[] array = src.data; + for(int i = 0; i < array.length; ++i) { + int x = array[i]; + int a = (x >> 24) & 255; + if(a > 2) { + reducedR += (x >> 16) & 255; + reducedG += (x >> 8) & 255; + reducedB += x & 255; + ++divisor; + } + } + if(divisor == 0) { + reducedR = 0; + reducedG = 0; + reducedB = 0; + }else { + reducedR /= divisor; + reducedG /= divisor; + reducedB /= divisor; + } + int reducedR2, reducedG2, reducedB2, blend1, blend2, blend3, blend4, j; + int alpha = (reducedR << 16) | (reducedG << 8) | reducedB; + for(int i = 0; i < array.length; ++i) { + int x = array[i]; + int a = (x >> 24) & 255; + if(a < 2) { + reducedR2 = 0; + reducedG2 = 0; + reducedB2 = 0; + divisor = 0; + blend1 = i + 1; + blend2 = i - 1; + blend3 = i + src.w; + blend4 = i - src.w; + if(blend1 >= 0 && blend1 < array.length) { + j = array[blend1]; + if(((x >> 24) & 255) > 2){ + reducedR2 += (x >> 16) & 255; + reducedG2 += (x >> 8) & 255; + reducedB2 += x & 255; + ++divisor; + } + } + if(blend2 >= 0 && blend2 < array.length) { + j = array[blend2]; + if(((x >> 24) & 255) > 2){ + reducedR2 += (x >> 16) & 255; + reducedG2 += (x >> 8) & 255; + reducedB2 += x & 255; + ++divisor; + } + } + if(blend3 >= 0 && blend3 < array.length) { + j = array[blend3]; + if(((x >> 24) & 255) > 2){ + reducedR2 += (x >> 16) & 255; + reducedG2 += (x >> 8) & 255; + reducedB2 += x & 255; + ++divisor; + } + } + if(blend4 >= 0 && blend4 < array.length) { + j = array[blend4]; + if(((x >> 24) & 255) > 2){ + reducedR2 += (x >> 16) & 255; + reducedG2 += (x >> 8) & 255; + reducedB2 += x & 255; + ++divisor; + } + } + if(divisor == 0) { + ret.data[i] = alpha; + }else { + ret.data[i] = ((reducedR2 / divisor) << 16) | ((reducedG2 / divisor) << 8) | (reducedB2 / divisor); + } + }else { + ret.data[i] = src.data[i]; + } + } + return ret; + } + + public static EaglerImage create3x3(EaglerImage src) { + EaglerImage ret = new EaglerImage(src.w * 3, src.h * 3, true); + for(int y = 0; y < src.h; ++y) { + for(int x = 0; x < src.w; ++x) { + int pixel = src.data[y * src.w + x]; + + if(y != src.h - 1) { + ret.data[(src.h - 1 - y) * ret.w + (x)] = pixel; + ret.data[(src.h - 1 - y) * ret.w + (x + src.w)] = pixel; + ret.data[(src.h - 1 - y) * ret.w + (x + src.w*2)] = pixel; + } + + ret.data[(y + src.h) * ret.w + (x)] = pixel; + ret.data[(y + src.h) * ret.w + (x + src.w)] = pixel; + ret.data[(y + src.h) * ret.w + (x + src.w*2)] = pixel; + + if(y != 0) { + ret.data[(src.h*3 - 1 - y) * ret.w + (x)] = pixel; + ret.data[(src.h*3 - 1 - y) * ret.w + (x + src.w)] = pixel; + ret.data[(src.h*3 - 1 - y) * ret.w + (x + src.w*2)] = pixel; + } + } + } + return ret; + } + + public static EaglerImage create3x3_2(EaglerImage src) { + EaglerImage ret = new EaglerImage(3, 3, true); + ret.data[0] = src.data[0]; + ret.data[1] = src.data[0]; + ret.data[2] = src.data[0]; + ret.data[3] = src.data[0]; + ret.data[4] = src.data[0]; + ret.data[5] = src.data[0]; + ret.data[6] = src.data[0]; + ret.data[7] = src.data[0]; + ret.data[8] = src.data[0]; + return ret; + } + + public void refreshTextures() { + iconList.clear(); + nextSlot = 1; + Block[] var1 = Block.blocksList; + int var2 = var1.length; + + for (int var3 = 0; var3 < var2; ++var3) { + Block var4 = var1[var3]; + + if (var4 != null) { + var4.registerIcons(this); + } + } + + Minecraft.getMinecraft().renderGlobal.registerDestroyBlockIcons(this); + RenderManager.instance.updateIcons(this); + + for(TerrainIcon t : iconList) { + t.loadData(); + } + } + + private void replaceTexture(TerrainIcon icon, EaglerImage[] textures) { + int levelW = width; + int levelH = height; + int divisor = 1; + EaglerAdapter.glBindTexture(EaglerAdapter.GL_TEXTURE_2D, texture); + for(int i = 0; i < 5; i++) { + uploadBuffer.clear(); + uploadBuffer.put(textures[i].data); + uploadBuffer.flip(); + EaglerAdapter.glTexSubImage2D(EaglerAdapter.GL_TEXTURE_2D, i, icon.originX / divisor, icon.originY / divisor, 48 / divisor, 48 / divisor, EaglerAdapter.GL_RGBA, EaglerAdapter.GL_UNSIGNED_BYTE, uploadBuffer); + levelW /= 2; + levelH /= 2; + divisor *= 2; + } + } + + public void updateAnimations() { + for(TerrainIcon t : iconList) { + t.updateAnimation(); + } + } + + public Icon registerIcon(String par1Str) { + if(par1Str != null) { + for(TerrainIcon t : iconList) { + if(par1Str.equals(t.name)) { + return t; + } + } + TerrainIcon ret = new TerrainIcon(nextSlot++, this, par1Str); + iconList.add(ret); + return ret; + }else{ + return missingImage; + } + } + + public Icon getMissingIcon() { + return missingImage; + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/WebsocketNetworkManager.java b/src/main/java/net/lax1dude/eaglercraft/WebsocketNetworkManager.java new file mode 100644 index 0000000..c7c9705 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/WebsocketNetworkManager.java @@ -0,0 +1,140 @@ +package net.lax1dude.eaglercraft; + +import java.io.InputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.EOFException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.LinkedList; + +import net.minecraft.src.INetworkManager; +import net.minecraft.src.NetHandler; +import net.minecraft.src.Packet; + +public class WebsocketNetworkManager implements INetworkManager { + + private NetHandler netHandler; + + public WebsocketNetworkManager(String uri, String eagler, NetHandler netHandler) throws IOException { + this.netHandler = netHandler; + if(!EaglerAdapter.startConnection(uri)) { + throw new IOException("websocket to "+uri+" failed"); + } + EaglerAdapter.setDebugVar("minecraftServer", uri); + } + + public void setNetHandler(NetHandler netHandler) { + this.netHandler = netHandler; + } + + private ByteArrayOutputStream sendBuffer = new ByteArrayOutputStream(); + + public void addToSendQueue(Packet var1) { + try { + sendBuffer.reset(); + DataOutputStream yee = new DataOutputStream(sendBuffer); + Packet.writePacket(var1, yee); + EaglerAdapter.writePacket(sendBuffer.toByteArray()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void wakeThreads() { + } + + private static class ByteBufferDirectInputStream extends InputStream { + private ByteBuffer buf; + private ByteBufferDirectInputStream(ByteBuffer b) { + this.buf = b; + } + + @Override + public int read() throws IOException { + return buf.remaining() > 0 ? ((int)buf.get() & 0xFF) : -1; + } + + @Override + public int available() { + return buf.remaining(); + } + } + + private ByteBuffer oldChunkBuffer = null; + private LinkedList readChunks = new LinkedList(); + + public void processReadPackets() { + readChunks.clear(); + + if(oldChunkBuffer != null) { + readChunks.add(oldChunkBuffer); + } + + byte[] packet; + while((packet = EaglerAdapter.readPacket()) != null) { + readChunks.add(ByteBuffer.wrap(packet)); + } + if(!readChunks.isEmpty()) { + + int cap = 0; + for(ByteBuffer b : readChunks) { + cap += b.limit(); + } + + ByteBuffer stream = ByteBuffer.allocate(cap); + for(ByteBuffer b : readChunks) { + stream.put(b); + } + stream.flip(); + + DataInputStream packetStream = new DataInputStream(new ByteBufferDirectInputStream(stream)); + while(stream.hasRemaining()) { + stream.mark(); + try { + Packet pkt = Packet.readPacket(packetStream, false); + //System.out.println(pkt.toString()); + pkt.processPacket(this.netHandler); + } catch (EOFException e) { + stream.reset(); + break; + } catch (IOException e) { + continue; + } catch (Throwable e2) { + e2.printStackTrace(); + } + } + + if(stream.hasRemaining()) { + oldChunkBuffer = stream.slice(); + }else { + oldChunkBuffer = null; + } + + } + } + + public void serverShutdown() { + if(EaglerAdapter.connectionOpen()) { + EaglerAdapter.endConnection(); + EaglerAdapter.setDebugVar("minecraftServer", "null"); + } + } + + public int packetSize() { + return 0; + } + + public void networkShutdown(String var1, Object... var2) { + serverShutdown(); + } + + public void closeConnections() { + if(EaglerAdapter.connectionOpen()) { + EaglerAdapter.endConnection(); + EaglerAdapter.setDebugVar("minecraftServer", "null"); + } + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/EaglerAdapterGL30.java b/src/main/java/net/lax1dude/eaglercraft/glemu/EaglerAdapterGL30.java new file mode 100644 index 0000000..186e051 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/EaglerAdapterGL30.java @@ -0,0 +1,1338 @@ +package net.lax1dude.eaglercraft.glemu; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.util.HashMap; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +import net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2; +import net.lax1dude.eaglercraft.glemu.vector.Matrix3f; +import net.lax1dude.eaglercraft.glemu.vector.Matrix4f; +import net.lax1dude.eaglercraft.glemu.vector.Vector3f; +import net.lax1dude.eaglercraft.glemu.vector.Vector4f; + +public class EaglerAdapterGL30 extends EaglerAdapterImpl2 { + + public static final int GL_ZERO = 0; + public static final int GL_ONE = 1; + public static final int GL_TEXTURE_2D = 2; + public static final int GL_SMOOTH = 3; + public static final int GL_DEPTH_TEST = 4; + public static final int GL_LEQUAL = 5; + public static final int GL_ALPHA_TEST = 6; + public static final int GL_GREATER = 7; + public static final int GL_BACK = 8; + public static final int GL_PROJECTION = 9; + public static final int GL_MODELVIEW = 10; + public static final int GL_COLOR_BUFFER_BIT = 1; + public static final int GL_DEPTH_BUFFER_BIT = 2; + public static final int GL_LIGHTING = 13; + public static final int GL_FOG = 14; + public static final int GL_COLOR_MATERIAL = 15; + public static final int GL_BLEND = 16; + public static final int GL_RGBA = 18; + public static final int GL_UNSIGNED_BYTE = 19; + public static final int GL_TEXTURE_WIDTH = 20; + public static final int GL_LIGHT0 = 21; + public static final int GL_LIGHT1 = 22; + public static final int GL_POSITION = 30; + public static final int GL_DIFFUSE = 31; + public static final int GL_SPECULAR = 32; + public static final int GL_AMBIENT = 33; + public static final int GL_FLAT = 34; + public static final int GL_LIGHT_MODEL_AMBIENT = 35; + public static final int GL_FRONT_AND_BACK = 36; + public static final int GL_AMBIENT_AND_DIFFUSE = 37; + public static final int GL_MODELVIEW_MATRIX = 38; + public static final int GL_PROJECTION_MATRIX = 39; + public static final int GL_VIEWPORT = 40; + public static final int GL_RESCALE_NORMAL = 41; + public static final int GL_SRC_ALPHA = 42; + public static final int GL_ONE_MINUS_SRC_ALPHA = 43; + public static final int GL_ONE_MINUS_DST_COLOR = 44; + public static final int GL_ONE_MINUS_SRC_COLOR = 45; + public static final int GL_CULL_FACE = 46; + public static final int GL_TEXTURE_MIN_FILTER = 47; + public static final int GL_TEXTURE_MAG_FILTER = 48; + public static final int GL_LINEAR = 49; + public static final int GL_COLOR_LOGIC_OP = 50; + public static final int GL_OR_REVERSE = 51; + public static final int GL_EQUAL = 52; + public static final int GL_SRC_COLOR = 53; + public static final int GL_TEXTURE = 54; + public static final int GL_FRONT = 55; + public static final int GL_COMPILE = 56; + public static final int GL_S = 57; + public static final int GL_T = 58; + public static final int GL_R = 59; + public static final int GL_Q = 60; + public static final int GL_TEXTURE_GEN_S = 61; + public static final int GL_TEXTURE_GEN_T = 62; + public static final int GL_TEXTURE_GEN_R = 63; + public static final int GL_TEXTURE_GEN_Q = 64; + public static final int GL_TEXTURE_GEN_MODE = 65; + public static final int GL_OBJECT_PLANE = 66; + public static final int GL_EYE_PLANE = 67; + public static final int GL_OBJECT_LINEAR = 68; + public static final int GL_EYE_LINEAR = 69; + public static final int GL_NEAREST = 70; + public static final int GL_CLAMP = 71; + public static final int GL_TEXTURE_WRAP_S = 72; + public static final int GL_TEXTURE_WRAP_T = 73; + public static final int GL_REPEAT = 74; + public static final int GL_BGRA = 75; + public static final int GL_UNSIGNED_INT_8_8_8_8_REV = 76; + public static final int GL_DST_COLOR = 77; + public static final int GL_POLYGON_OFFSET_FILL = 78; + public static final int GL_NORMALIZE = 79; + public static final int GL_DST_ALPHA = 80; + public static final int GL_FLOAT = 81; + public static final int GL_TEXTURE_COORD_ARRAY = 82; + public static final int GL_SHORT = 83; + public static final int GL_COLOR_ARRAY = 84; + public static final int GL_VERTEX_ARRAY = 85; + public static final int GL_TRIANGLES = 86; + public static final int GL_NORMAL_ARRAY = 87; + public static final int GL_TEXTURE_3D = 88; + public static final int GL_FOG_MODE = 89; + public static final int GL_EXP = 90; + public static final int GL_FOG_DENSITY = 91; + public static final int GL_FOG_START = 92; + public static final int GL_FOG_END = 93; + public static final int GL_FOG_COLOR = 94; + public static final int GL_TRIANGLE_STRIP = 95; + public static final int GL_PACK_ALIGNMENT = 96; + public static final int GL_UNPACK_ALIGNMENT = 97; + public static final int GL_QUADS = 98; + public static final int GL_TEXTURE0 = 99; + public static final int GL_TEXTURE1 = 100; + public static final int GL_TEXTURE2 = 101; + public static final int GL_TEXTURE3 = 102; + public static final int GL_INVALID_ENUM = 140; + public static final int GL_INVALID_VALUE= 141; + public static final int GL_INVALID_OPERATION = 142; + public static final int GL_OUT_OF_MEMORY = 143; + public static final int GL_CONTEXT_LOST_WEBGL = 144; + public static final int GL_TRIANGLE_FAN = 145; + public static final int GL_LINE_STRIP = 146; + public static final int GL_LIGHTING2 = 147; + public static final int GL_LINES = 148; + public static final int GL_NEAREST_MIPMAP_LINEAR = 149; + public static final int GL_TEXTURE_MAX_ANISOTROPY = 150; + public static final int GL_TEXTURE_MAX_LEVEL = 151; + public static final int GL_LINEAR_MIPMAP_LINEAR = 152; + public static final int GL_LINEAR_MIPMAP_NEAREST = 153; + public static final int GL_NEAREST_MIPMAP_NEAREST = 154; + + public static final boolean isWebGL = _wisWebGL(); + + private static final GLObjectMap texObjects = new GLObjectMap(256); + + private static boolean enableTexture2D = false; + private static boolean enableTexture2D_1 = false; + private static boolean enableLighting = false; + private static boolean enableAlphaTest = false; + private static float alphaThresh = 0.1f; + + private static boolean isCompilingDisplayList = false; + private static DisplayList compilingDisplayList = null; + + private static boolean enableColorArray = false; + private static boolean enableNormalArray = false; + private static boolean enableTex0Array = false; + private static boolean enableTex1Array = false; + + private static float colorR = 1.0f; + private static float colorG = 1.0f; + private static float colorB = 1.0f; + private static float colorA = 1.0f; + + private static float normalX = 1.0f; + private static float normalY = 0.0f; + private static float normalZ = 0.0f; + + private static int selectedTex = 0; + private static int selectedClientTex = 0; + private static float tex0X = 0; + private static float tex0Y = 0; + private static float tex1X = 0; + private static float tex1Y = 0; + + private static boolean enableTexGen = false; + private static boolean enableColorMaterial = false; + + private static int texS_plane = 0; + private static float texS_X = 0.0f; + private static float texS_Y = 0.0f; + private static float texS_Z = 0.0f; + private static float texS_W = 0.0f; + + private static int texT_plane = 0; + private static float texT_X = 0.0f; + private static float texT_Y = 0.0f; + private static float texT_Z = 0.0f; + private static float texT_W = 0.0f; + + private static int texR_plane = 0; + private static float texR_X = 0.0f; + private static float texR_Y = 0.0f; + private static float texR_Z = 0.0f; + private static float texR_W = 0.0f; + + private static int texQ_plane = 0; + private static float texQ_X = 0.0f; + private static float texQ_Y = 0.0f; + private static float texQ_Z = 0.0f; + private static float texQ_W = 0.0f; + + private static float fogColorR = 1.0f; + private static float fogColorG = 1.0f; + private static float fogColorB = 1.0f; + private static float fogColorA = 1.0f; + private static int fogMode = 1; + private static boolean fogEnabled = false; + private static boolean fogPremultiply = false; + private static float fogStart = 1.0f; + private static float fogEnd = 1.0f; + private static float fogDensity = 1.0f; + + private static int bytesUploaded = 0; + private static int vertexDrawn = 0; + private static int triangleDrawn = 0; + + private static int matrixMode = GL_MODELVIEW; + + static Matrix4f[] matModelV = new Matrix4f[32]; + static Matrix4f matNormV = new Matrix4f(); + static Matrix3f matNormV3 = new Matrix3f(); + static int matModelPointer = 0; + + static Matrix4f[] matProjV = new Matrix4f[6]; + static int matProjPointer = 0; + + static Matrix4f[] matTexV = new Matrix4f[16]; + static int matTexPointer = 0; + + static { + for(int i = 0; i < matModelV.length; ++i) { + matModelV[i] = new Matrix4f(); + } + for(int i = 0; i < matProjV.length; ++i) { + matProjV[i] = new Matrix4f(); + } + for(int i = 0; i < matTexV.length; ++i) { + matTexV[i] = new Matrix4f(); + } + } + + public static void glClearStack() { + matModelV[0].load(matModelV[matModelPointer]); matModelPointer = 0; + matProjV[0].load(matProjV[matProjPointer]); matProjPointer = 0; + matTexV[0].load(matTexV[matTexPointer]); matTexPointer = 0; + } + + private static BufferGL quadsToTrianglesBuffer = null; + private static BufferArrayGL currentArray = null; + + private static class DisplayList { + private final int id; + private BufferArrayGL glarray; + private BufferGL glbuffer; + private int shaderMode; + private int listLength; + private DisplayList(int id) { + this.id = id; + this.glarray = null; + this.glbuffer = null; + this.shaderMode = -1; + this.listLength = 0; + } + } + + private static final HashMap displayLists = new HashMap(); + private static final HashMap displayListsInitialized = new HashMap(); + + public static final int getDisplayListCount() { + return displayListsInitialized.size(); + } + + public static final void glEnable(int p1) { + switch(p1) { + case GL_DEPTH_TEST: + _wglEnable(_wGL_DEPTH_TEST); + break; + case GL_CULL_FACE: + _wglEnable(_wGL_CULL_FACE); + break; + case GL_BLEND: + _wglEnable(_wGL_BLEND); + break; + case GL_RESCALE_NORMAL: + //enableRescaleNormal = true; + //matNormalScalePointer = matModelPointer; + //matNormScaleV[0].setIdentity(); + break; + case GL_TEXTURE_2D: + if(selectedTex == 0) { + enableTexture2D = true; + } + if(selectedTex == 1) { + enableTexture2D_1 = true; + } + break; + case GL_LIGHTING: + enableLighting = true; + break; + case GL_LIGHTING2: + break; + case GL_ALPHA_TEST: + enableAlphaTest = true; + break; + case GL_FOG: + fogEnabled = true; + break; + case GL_COLOR_MATERIAL: + enableColorMaterial = true; + break; + case GL_TEXTURE_GEN_S: + case GL_TEXTURE_GEN_T: + case GL_TEXTURE_GEN_R: + case GL_TEXTURE_GEN_Q: + enableTexGen = true; + break; + default: + break; + } + } + public static final void glShadeModel(int p1) { + + } + public static final void glClearDepth(float p1) { + _wglClearDepth(-p1); + } + public static final void glDepthFunc(int p1) { + int f = _wGL_GEQUAL; + switch(p1) { + case GL_GREATER: f = _wGL_LESS; break; + case GL_LEQUAL: f = _wGL_GEQUAL; break; + case GL_EQUAL: f = _wGL_EQUAL; + default: break; + } + _wglDepthFunc(f); + } + public static final void glAlphaFunc(int p1, float p2) { + alphaThresh = p2; + } + public static final void glCullFace(int p1) { + int f = _wGL_BACK; + switch(p1) { + case GL_BACK: f = _wGL_BACK; break; + case GL_FRONT: f = _wGL_FRONT; break; + case GL_FRONT_AND_BACK: f = _wGL_FRONT_AND_BACK; break; + default: break; + } + _wglCullFace(f); + } + public static final void glMatrixMode(int p1) { + matrixMode = p1; + } + private static final Matrix4f getMatrix() { + switch(matrixMode) { + case GL_MODELVIEW: + default: + return matModelV[matModelPointer]; + case GL_PROJECTION: + return matProjV[matProjPointer]; + case GL_TEXTURE: + return matTexV[matTexPointer]; + } + } + public static final void glLoadIdentity() { + getMatrix().setIdentity(); + } + public static final void glViewport(int p1, int p2, int p3, int p4) { + _wglViewport(p1, p2, p3, p4); + } + public static final void glClear(int p1) { + int f = 0; + if((p1 & GL_COLOR_BUFFER_BIT) == GL_COLOR_BUFFER_BIT) { + f = f | _wGL_COLOR_BUFFER_BIT; + } + if((p1 & GL_DEPTH_BUFFER_BIT) == GL_DEPTH_BUFFER_BIT) { + f = f | _wGL_DEPTH_BUFFER_BIT; + } + _wglClear(f); + } + public static final void glOrtho(float left, float right, float bottom, float top, float zNear, float zFar) { + Matrix4f res = getMatrix(); + res.m00 = 2.0f / (right - left); + res.m01 = 0.0f; + res.m02 = 0.0f; + res.m03 = 0.0f; + res.m10 = 0.0f; + res.m11 = 2.0f / (top - bottom); + res.m12 = 0.0f; + res.m13 = 0.0f; + res.m20 = 0.0f; + res.m21 = 0.0f; + res.m22 = 2.0f / (zFar - zNear); + res.m23 = 0.0f; + res.m30 = -(right + left) / (right - left); + res.m31 = -(top + bottom) / (top - bottom); + res.m32 = (zFar + zNear) / (zFar - zNear); + res.m33 = 1.0f; + } + private static final Vector3f deevis = new Vector3f(); + public static final void glTranslatef(float p1, float p2, float p3) { + deevis.set(p1, p2, p3); + getMatrix().translate(deevis); + if(isCompilingDisplayList) { + System.err.println("matrix is not supported while recording display list use tessellator class instead"); + } + } + public static final void glClearColor(float p1, float p2, float p3, float p4) { + _wglClearColor(p1, p2, p3, p4); + } + public static final void glDisable(int p1) { + switch(p1) { + case GL_DEPTH_TEST: + _wglDisable(_wGL_DEPTH_TEST); + break; + case GL_CULL_FACE: + _wglDisable(_wGL_CULL_FACE); + break; + case GL_BLEND: + _wglDisable(_wGL_BLEND); + break; + case GL_RESCALE_NORMAL: + break; + case GL_TEXTURE_2D: + if(selectedTex == 0) { + enableTexture2D = false; + } + if(selectedTex == 1) { + enableTexture2D_1 = false; + } + break; + case GL_LIGHTING: + enableLighting = false; + break; + case GL_LIGHTING2: + break; + case GL_ALPHA_TEST: + enableAlphaTest = false; + break; + case GL_FOG: + fogEnabled = false; + break; + case GL_COLOR_MATERIAL: + enableColorMaterial = false; + break; + case GL_TEXTURE_GEN_S: + case GL_TEXTURE_GEN_T: + case GL_TEXTURE_GEN_R: + case GL_TEXTURE_GEN_Q: + enableTexGen = false; + break; + default: + break; + } + } + public static final void glColor4f(float p1, float p2, float p3, float p4) { + colorR = p1; + colorG = p2; + colorB = p3; + colorA = p4; + } + public static final int glGetError() { + int err = _wglGetError(); + if(err == _wGL_INVALID_ENUM) return GL_INVALID_ENUM; + if(err == _wGL_INVALID_OPERATION) return GL_INVALID_OPERATION; + if(err == _wGL_INVALID_VALUE) return GL_INVALID_VALUE; + if(err == _wGL_OUT_OF_MEMORY) return GL_OUT_OF_MEMORY; + if(err == _wGL_CONTEXT_LOST_WEBGL) return GL_CONTEXT_LOST_WEBGL; + return err; + } + public static final void glFlush() { + EaglerAdapter._wglFlush(); + } + public static final void glLineWidth(float p1) { + + } + public static final void glTexImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, ByteBuffer p9) { + _wglTexImage2D(_wGL_TEXTURE_2D, p2, _wGL_RGBA8, p4, p5, p6, _wGL_RGBA, _wGL_UNSIGNED_BYTE, p9); + } + public static final void glLight(int p1, int p2, FloatBuffer p3) { + + } + public static final void glLightModel(int p1, FloatBuffer p2) { + + } + private static Vector4f lightPos0vec = new Vector4f(); + private static Vector4f lightPos1vec = new Vector4f(); + public static final void copyModelToLightMatrix() { + lightPos0vec.set(0.2f, 1.0f, -0.7f, 0.0f); lightPos0vec.normalise(); + lightPos1vec.set(-0.2f, 1.0f, 0.7f, 0.0f); lightPos1vec.normalise(); + Matrix4f.transform(matModelV[matModelPointer], lightPos0vec, lightPos0vec).normalise(); + Matrix4f.transform(matModelV[matModelPointer], lightPos1vec, lightPos1vec).normalise(); + + } + public static final void glPushMatrix() { + switch(matrixMode) { + case GL_MODELVIEW: + default: + if(matModelPointer < matModelV.length - 1) { + ++matModelPointer; + matModelV[matModelPointer].load(matModelV[matModelPointer - 1]); + }else { + System.err.println("modelview matrix stack overflow"); + } + break; + case GL_PROJECTION: + if(matProjPointer < matProjV.length - 1) { + ++matProjPointer; + matProjV[matProjPointer].load(matProjV[matProjPointer - 1]); + }else { + System.err.println("projection matrix stack overflow"); + } + break; + case GL_TEXTURE: + if(matTexPointer < matTexV.length - 1) { + ++matTexPointer; + matTexV[matTexPointer].load(matTexV[matTexPointer - 1]); + }else { + System.err.println("texture matrix stack overflow"); + } + break; + } + } + private static final float toRad = 0.0174532925f; + public static final void glRotatef(float p1, float p2, float p3, float p4) { + deevis.set(p2, p3, p4); + getMatrix().rotate(p1 * toRad, deevis); + if(isCompilingDisplayList) { + System.err.println("matrix is not supported while recording display list use tessellator class instead"); + } + } + public static final void glPopMatrix() { + switch(matrixMode) { + case GL_MODELVIEW: + default: + if(matModelPointer > 0) { + --matModelPointer; + }else { + System.err.println("modelview matrix stack underflow"); + } + break; + case GL_PROJECTION: + if(matProjPointer > 0) { + --matProjPointer; + }else { + System.err.println("projection matrix stack underflow"); + } + break; + case GL_TEXTURE: + if(matTexPointer > 0) { + --matTexPointer; + }else { + System.err.println("texture matrix stack underflow"); + } + break; + } + } + public static final void glColorMaterial(int p1, int p2) { + + } + public static final void glGetFloat(int p1, FloatBuffer p2) { + switch(p1) { + case GL_MODELVIEW_MATRIX: + default: + matModelV[matModelPointer].store(p2); + break; + case GL_PROJECTION_MATRIX: + matProjV[matProjPointer].store(p2); + break; + } + } + public static final void glGetInteger(int p1, int[] p2) { + if(p1 == GL_VIEWPORT) { + _wglGetParameter(_wGL_VIEWPORT, 4, p2); + } + } + public static final void glScalef(float p1, float p2, float p3) { + deevis.set(p1, p2, p3); + getMatrix().scale(deevis); + if(isCompilingDisplayList) { + System.err.println("matrix is not supported while recording display list use tessellator class instead"); + } + } + public static final void glBlendFunc(int p1, int p2) { + int pp1 = 0; + int pp2 = 0; + switch(p1) { + default: + case GL_SRC_ALPHA: pp1 = _wGL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: pp1 = _wGL_ONE_MINUS_SRC_ALPHA; break; + case GL_DST_ALPHA: pp1 = _wGL_DST_ALPHA; break; + case GL_DST_COLOR: pp1 = _wGL_DST_COLOR; break; + case GL_SRC_COLOR: pp1 = _wGL_SRC_COLOR; break; + case GL_ONE_MINUS_SRC_COLOR: pp1 = _wGL_ONE_MINUS_SRC_COLOR; break; + case GL_ONE: pp1 = _wGL_ONE; break; + case GL_ZERO: pp1 = _wGL_ZERO; break; + } + switch(p2) { + default: + case GL_SRC_ALPHA: pp2 = _wGL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: pp2 = _wGL_ONE_MINUS_SRC_ALPHA; break; + case GL_DST_ALPHA: pp2 = _wGL_DST_ALPHA; break; + case GL_DST_COLOR: pp2 = _wGL_DST_COLOR; break; + case GL_SRC_COLOR: pp2 = _wGL_SRC_COLOR; break; + case GL_ONE_MINUS_SRC_COLOR: pp2 = _wGL_ONE_MINUS_SRC_COLOR; break; + case GL_ONE: pp2 = _wGL_ONE; break; + case GL_ZERO: pp2 = _wGL_ZERO; break; + } + fogPremultiply = (p1 == GL_ONE && p2 == GL_ONE_MINUS_SRC_ALPHA); + _wglBlendFunc(pp1, pp2); + } + public static final void glDepthMask(boolean p1) { + _wglDepthMask(p1); + } + public static final void glColorMask(boolean p1, boolean p2, boolean p3, boolean p4) { + _wglColorMask(p1, p2, p3, p4); + } + public static final void glBindTexture(int p1, int p2) { + _wglBindTexture(_wGL_TEXTURE_2D, texObjects.get(p2)); + } + public static final void glCopyTexSubImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) { + _wglCopyTexSubImage2D(_wGL_TEXTURE_2D, p2, p3, p4, p5, p6, p7, p8); + } + public static final void glTexParameteri(int p1, int p2, int p3) { + int pp1 = 0; + switch(p1) { + default: + case GL_TEXTURE_2D: pp1 = _wGL_TEXTURE_2D; break; + //case GL_TEXTURE_3D: pp1 = _wGL_TEXTURE_3D; break; + } + int pp2 = 0; + switch(p2) { + default: + case GL_TEXTURE_MAG_FILTER: pp2 = _wGL_TEXTURE_MAG_FILTER; break; + case GL_TEXTURE_MIN_FILTER: pp2 = _wGL_TEXTURE_MIN_FILTER; break; + case GL_TEXTURE_WRAP_S: pp2 = _wGL_TEXTURE_WRAP_S; break; + case GL_TEXTURE_WRAP_T: pp2 = _wGL_TEXTURE_WRAP_T; break; + case GL_TEXTURE_MAX_LEVEL: pp2 = _wGL_TEXTURE_MAX_LEVEL; break; + } + int pp3 = 0; + switch(p3) { + default: + pp3 = p3; break; + case GL_LINEAR: pp3 = _wGL_LINEAR; break; + case GL_NEAREST_MIPMAP_LINEAR: pp3 = _wGL_NEAREST_MIPMAP_LINEAR; break; + case GL_LINEAR_MIPMAP_LINEAR: pp3 = _wGL_LINEAR_MIPMAP_LINEAR; break; + case GL_LINEAR_MIPMAP_NEAREST: pp3 = _wGL_LINEAR_MIPMAP_NEAREST; break; + case GL_NEAREST_MIPMAP_NEAREST: pp3 = _wGL_NEAREST_MIPMAP_NEAREST; break; + case GL_NEAREST: pp3 = _wGL_NEAREST; break; + case GL_REPEAT: pp3 = _wGL_REPEAT; break; + case GL_CLAMP: pp3 = _wGL_CLAMP; break; + } + _wglTexParameteri(pp1, pp2, pp3); + } + public static final void glTexParameterf(int p1, int p2, float p3) { + int pp1 = 0; + switch(p1) { + default: + case GL_TEXTURE_2D: pp1 = _wGL_TEXTURE_2D; break; + //case GL_TEXTURE_3D: pp1 = _wGL_TEXTURE_3D; break; + } + int pp2 = 0; + switch(p2) { + default: + case GL_TEXTURE_MAX_ANISOTROPY: pp2 = _wGL_TEXTURE_MAX_ANISOTROPY; break; + } + _wglTexParameterf(pp1, pp2, p3); + } + public static final void glLogicOp(int p1) { + + } + public static final void glNormal3f(float p1, float p2, float p3) { + float len = (float) Math.sqrt(p1 * p1 + p2 * p2 + p3 * p3); + normalX = p1 / len; + normalY = p2 / len; + normalZ = p3 / len; + } + public static final int glGenLists(int p1) { + int base = displayListId + 1; + for(int i = 0; i < p1; i++) { + int id = ++displayListId; + displayLists.put(id, new DisplayList(id)); + } + return base; + } + public static final void _wglBindVertexArray0(BufferArrayGL p1) { + currentArray = p1; + _wglBindVertexArray(p1); + } + private static int displayListId = 0; + public static final void glCallList(int p1) { + if(!isCompilingDisplayList) { + DisplayList d = displayListsInitialized.get(p1); + if(d != null && d.listLength > 0) { + bindTheShader(d.shaderMode | getShaderModeFlag1()); + _wglBindVertexArray0(d.glarray); + _wglDrawQuadArrays(0, d.listLength); + shader.unuseProgram(); + vertexDrawn += d.listLength * 6 / 4; + triangleDrawn += d.listLength / 2; + } + } + } + public static final void glNewList(int p1, int p2) { + if(!isCompilingDisplayList) { + compilingDisplayList = displayLists.get(p1); + if(compilingDisplayList != null) { + compilingDisplayList.listLength = 0; + isCompilingDisplayList = true; + } + } + } + public static final void glEndList() { + if(isCompilingDisplayList) { + isCompilingDisplayList = false; + Object upload = _wGetLowLevelBuffersAppended(); + int l = _wArrayByteLength(upload); + if(l > 0) { + if(compilingDisplayList.glbuffer == null) { + displayListsInitialized.put(compilingDisplayList.id, compilingDisplayList); + compilingDisplayList.glarray = _wglCreateVertexArray(); + compilingDisplayList.glbuffer = _wglCreateBuffer(); + FixedFunctionShader f = FixedFunctionShader.instance(compilingDisplayList.shaderMode); + _wglBindVertexArray0(compilingDisplayList.glarray); + _wglBindBuffer(_wGL_ARRAY_BUFFER, compilingDisplayList.glbuffer); + f.setupArrayForProgram(); + } + _wglBindBuffer(_wGL_ARRAY_BUFFER, compilingDisplayList.glbuffer); + _wglBufferData(_wGL_ARRAY_BUFFER, upload, _wGL_STATIC_DRAW); + bytesUploaded += l; + } + } + } + public static final void glColor3f(float p1, float p2, float p3) { + colorR = p1; + colorG = p2; + colorB = p3; + colorA = 1.0f; + } + public static final void glTexGeni(int p1, int p2, int p3) { + + } + public static final void glTexGen(int p1, int p2, FloatBuffer p3) { + switch(p1) { + case GL_S: + texS_plane = (p2 == GL_EYE_PLANE ? 1 : 0); + texS_X = p3.get(); + texS_Y = p3.get(); + texS_Z = p3.get(); + texS_W = p3.get(); + break; + case GL_T: + texT_plane = (p2 == GL_EYE_PLANE ? 1 : 0); + texT_X = p3.get(); + texT_Y = p3.get(); + texT_Z = p3.get(); + texT_W = p3.get(); + break; + case GL_R: + texR_plane = (p2 == GL_EYE_PLANE ? 1 : 0); + texR_X = p3.get(); + texR_Y = p3.get(); + texR_Z = p3.get(); + texR_W = p3.get(); + break; + case GL_Q: + texQ_plane = (p2 == GL_EYE_PLANE ? 1 : 0); + texQ_X = p3.get(); + texQ_Y = p3.get(); + texQ_Z = p3.get(); + texQ_W = p3.get(); + break; + } + } + public static final void glTexImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, IntBuffer p9) { + /* + int pp2 = 0; + switch(p3) { + default: + case GL_RGBA: pp2 = _wGL_RGBA; break; + case GL_BGRA: pp2 = _wGL_BGRA; break; + } + int pp3 = 0; + switch(p7) { + default: + case GL_RGBA: pp3 = _wGL_RGBA; break; + case GL_BGRA: pp3 = _wGL_BGRA; break; + } + */ + bytesUploaded += p9.remaining()*4; + _wglTexImage2D(_wGL_TEXTURE_2D, p2, _wGL_RGBA8, p4, p5, p6, _wGL_RGBA, _wGL_UNSIGNED_BYTE, p9); + } + public static final void glTexImage2D_2(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, IntBuffer p9) { + bytesUploaded += p9.remaining()*4; + _wglTexImage2D(_wGL_TEXTURE_2D, p2, _wGL_RGB8, p4, p5, p6, _wGL_RGB, _wGL_UNSIGNED_BYTE, p9); + } + public static final void glTexSubImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, IntBuffer p9) { + int pp1 = 0; + switch(p1) { + default: + case GL_TEXTURE_2D: pp1 = _wGL_TEXTURE_2D; break; + //case GL_TEXTURE_3D: pp1 = _wGL_TEXTURE_3D; break; + } + /* + int pp3 = 0; + switch(p7) { + default: + case GL_RGBA: pp3 = _wGL_RGBA; break; + case GL_BGRA: pp3 = _wGL_BGRA; break; + } + */ + bytesUploaded += p9.remaining()*4; + _wglTexSubImage2D(pp1, p2, p3, p4, p5, p6, _wGL_RGBA, _wGL_UNSIGNED_BYTE, p9); + } + public static final void glDeleteTextures(int p1) { + _wglDeleteTextures(texObjects.free(p1)); + } + public static final void glPolygonOffset(float p1, float p2) { + _wglPolygonOffset(p1, p2); + } + public static final void glCallLists(IntBuffer p1) { + while(p1.hasRemaining()) { + glCallList(p1.get()); + } + } + public static final void glEnableVertexAttrib(int p1) { + switch(p1) { + case GL_COLOR_ARRAY: + enableColorArray = true; + break; + case GL_NORMAL_ARRAY: + enableNormalArray = true; + break; + case GL_TEXTURE_COORD_ARRAY: + switch(selectedClientTex) { + case 0: + enableTex0Array = true; + break; + case 1: + enableTex1Array = true; + break; + default: + break; + } + break; + default: + break; + } + } + public static final void glDisableVertexAttrib(int p1) { + switch(p1) { + case GL_COLOR_ARRAY: + enableColorArray = false; + break; + case GL_NORMAL_ARRAY: + enableNormalArray = false; + break; + case GL_TEXTURE_COORD_ARRAY: + switch(selectedClientTex) { + case 0: + enableTex0Array = false; + break; + case 1: + enableTex1Array = false; + break; + default: + break; + } + break; + default: + break; + } + } + private static final int getShaderModeFlag0() { + int mode = 0; + mode = (mode | (enableColorArray ? FixedFunctionShader.COLOR : 0)); + mode = (mode | (enableNormalArray ? FixedFunctionShader.NORMAL : 0)); + mode = (mode | (enableTex0Array ? FixedFunctionShader.TEXTURE0 : 0)); + mode = (mode | (enableTex1Array ? FixedFunctionShader.TEXTURE1 : 0)); + return mode; + } + private static final int getShaderModeFlag1() { + int mode = 0; + mode = (mode | (enableTexGen ? FixedFunctionShader.TEXGEN : 0)); + mode = (mode | ((enableColorMaterial && enableLighting) ? FixedFunctionShader.LIGHTING : 0)); + mode = (mode | (fogEnabled ? FixedFunctionShader.FOG : 0)); + mode = (mode | (enableAlphaTest ? FixedFunctionShader.ALPHATEST : 0)); + mode = (mode | (enableTexture2D ? FixedFunctionShader.UNIT0 : 0)); + mode = (mode | (enableTexture2D_1 ? FixedFunctionShader.UNIT1 : 0)); + return mode; + } + private static final int getShaderModeFlag() { + int mode = 0; + mode = (mode | (enableColorArray ? FixedFunctionShader.COLOR : 0)); + mode = (mode | (enableNormalArray ? FixedFunctionShader.NORMAL : 0)); + mode = (mode | (enableTex0Array ? FixedFunctionShader.TEXTURE0 : 0)); + mode = (mode | (enableTex1Array ? FixedFunctionShader.TEXTURE1 : 0)); + mode = (mode | (enableTexGen ? FixedFunctionShader.TEXGEN : 0)); + mode = (mode | ((enableColorMaterial && enableLighting) ? FixedFunctionShader.LIGHTING : 0)); + mode = (mode | (fogEnabled ? FixedFunctionShader.FOG : 0)); + mode = (mode | (enableAlphaTest ? FixedFunctionShader.ALPHATEST : 0)); + mode = (mode | (enableTexture2D ? FixedFunctionShader.UNIT0 : 0)); + mode = (mode | (enableTexture2D_1 ? FixedFunctionShader.UNIT1 : 0)); + return mode; + } + private static FixedFunctionShader shader = null; + private static final void bindTheShader() { + bindTheShader(getShaderModeFlag()); + } + private static final void bindTheShader(int mode) { + FixedFunctionShader s = shader = FixedFunctionShader.instance(mode); + s.useProgram(); + if(enableAlphaTest) { + s.setAlphaTest(alphaThresh); + } + s.setColor(colorR, colorG, colorB, colorA); + if(fogEnabled) { + s.setFogMode((fogPremultiply ? 2 : 0) + fogMode); + s.setFogColor(fogColorR, fogColorG, fogColorB, fogColorA); + s.setFogDensity(fogDensity); + s.setFogStartEnd(fogStart, fogEnd); + } + s.setModelMatrix(matModelV[matModelPointer]); + s.setProjectionMatrix(matProjV[matProjPointer]); + s.setTextureMatrix(matTexV[matTexPointer]); + if(enableColorMaterial && enableLighting) { + s.setNormal(normalX, normalY, normalZ); + Matrix4f matNormV_l = matNormV; + Matrix3f matNormV3_l = matNormV3; + matNormV_l.load(matModelV[matModelPointer]).invert().transpose(); + matNormV3_l.m00 = matNormV_l.m00; matNormV3_l.m01 = matNormV_l.m01; matNormV3_l.m02 = matNormV_l.m02; + matNormV3_l.m10 = matNormV_l.m10; matNormV3_l.m11 = matNormV_l.m11; matNormV3_l.m12 = matNormV_l.m12; + matNormV3_l.m20 = matNormV_l.m20; matNormV3_l.m21 = matNormV_l.m21; matNormV3_l.m22 = matNormV_l.m22; + s.setModelNormalMatrix(matNormV3_l); + s.setLightPositions(lightPos0vec, lightPos1vec); + } + s.setTex0Coords(tex0X, tex0Y); + s.setTex1Coords(tex1X, tex1Y); + if(enableTexGen) { + s.setTexGenS(texS_plane, texS_X, texS_Y, texS_Z, texS_W); + s.setTexGenT(texT_plane, texT_X, texT_Y, texT_Z, texT_W); + s.setTexGenR(texR_plane, texR_X, texR_Y, texR_Z, texR_W); + s.setTexGenQ(texQ_plane, texQ_X, texQ_Y, texQ_Z, texQ_W); + } + } + private static Object blankUploadArray = _wCreateLowLevelIntBuffer(525000); + public static final void glDrawArrays(int p1, int p2, int p3, Object buffer) { + if(isCompilingDisplayList) { + if(p1 == GL_QUADS) { + if(compilingDisplayList.shaderMode == -1) { + compilingDisplayList.shaderMode = getShaderModeFlag0(); + }else { + if(compilingDisplayList.shaderMode != getShaderModeFlag0()) { + System.err.println("vertex format inconsistent in display list"); + } + } + compilingDisplayList.listLength += p3; + _wAppendLowLevelBuffer(buffer); + }else { + System.err.println("only GL_QUADS supported in a display list"); + } + }else { + bytesUploaded += _wArrayByteLength(buffer); + vertexDrawn += p3; + + bindTheShader(); + + _wglBindVertexArray0(shader.genericArray); + _wglBindBuffer(_wGL_ARRAY_BUFFER, shader.genericBuffer); + if(!shader.bufferIsInitialized) { + shader.bufferIsInitialized = true; + _wglBufferData(_wGL_ARRAY_BUFFER, blankUploadArray, _wGL_DYNAMIC_DRAW); + } + _wglBufferSubData(_wGL_ARRAY_BUFFER, 0, buffer); + + if(p1 == GL_QUADS) { + _wglDrawQuadArrays(p2, p3); + triangleDrawn += p3 / 2; + }else { + int drawMode = 0; + switch(p1) { + default: + case GL_TRIANGLES: + drawMode = _wGL_TRIANGLES; + triangleDrawn += p3 / 3; + break; + case GL_TRIANGLE_STRIP: + drawMode = _wGL_TRIANGLE_STRIP; + triangleDrawn += p3 - 2; + break; + case GL_TRIANGLE_FAN: + drawMode = _wGL_TRIANGLE_FAN; + triangleDrawn += p3 - 2; + break; + case GL_LINE_STRIP: + drawMode = _wGL_LINE_STRIP; + triangleDrawn += p3 - 1; + break; + case GL_LINES: + drawMode = _wGL_LINES; + triangleDrawn += p3 / 2; + break; + } + _wglDrawArrays(drawMode, p2, p3); + } + + shader.unuseProgram(); + + } + } + + private static final void _wglDrawQuadArrays(int p2, int p3) { + if(quadsToTrianglesBuffer == null) { + IntBuffer upload = isWebGL ? IntBuffer.wrap(new int[98400 / 2]) : ByteBuffer.allocateDirect(98400 * 2).order(ByteOrder.nativeOrder()).asIntBuffer(); + for(int i = 0; i < 16384; ++i) { + int v1 = i * 4; + int v2 = i * 4 + 1; + int v3 = i * 4 + 2; + int v4 = i * 4 + 3; + upload.put(v1 | (v2 << 16)); + upload.put(v4 | (v2 << 16)); + upload.put(v3 | (v4 << 16)); + } + upload.flip(); + quadsToTrianglesBuffer = _wglCreateBuffer(); + _wglBindBuffer(_wGL_ELEMENT_ARRAY_BUFFER, quadsToTrianglesBuffer); + _wglBufferData0(_wGL_ELEMENT_ARRAY_BUFFER, upload, _wGL_STATIC_DRAW); + } + if(!currentArray.isQuadBufferBound) { + currentArray.isQuadBufferBound = true; + _wglBindBuffer(_wGL_ELEMENT_ARRAY_BUFFER, quadsToTrianglesBuffer); + } + _wglDrawElements(_wGL_TRIANGLES, p3 * 6 / 4, _wGL_UNSIGNED_SHORT, p2 * 6 / 4); + } + + + private static BufferArrayGL occlusion_vao = null; + private static BufferGL occlusion_vbo = null; + private static ProgramGL occlusion_program = null; + private static UniformGL occlusion_matrix_m = null; + private static UniformGL occlusion_matrix_p = null; + + private static final void initializeOcclusionObjects() { + occlusion_vao = _wglCreateVertexArray(); + occlusion_vbo = _wglCreateBuffer(); + + IntBuffer upload = (isWebGL ? IntBuffer.wrap(new int[108]) : ByteBuffer.allocateDirect(108 << 2).order(ByteOrder.nativeOrder()).asIntBuffer()); + float[] verts = new float[] { + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f + }; + for(int i = 0; i < verts.length; i++) { + upload.put(Float.floatToRawIntBits(verts[i])); + } + upload.flip(); + + _wglBindVertexArray(occlusion_vao); + _wglBindBuffer(_wGL_ARRAY_BUFFER, occlusion_vbo); + _wglBufferData0(_wGL_ARRAY_BUFFER, upload, _wGL_STATIC_DRAW); + _wglEnableVertexAttribArray(0); + _wglVertexAttribPointer(0, 3, _wGL_FLOAT, false, 12, 0); + + ShaderGL vert = _wglCreateShader(_wGL_VERTEX_SHADER); + ShaderGL frag = _wglCreateShader(_wGL_FRAGMENT_SHADER); + + String src = fileContents("/glsl/occl.glsl"); + _wglShaderSource(vert, _wgetShaderHeader() + "\n#define CC_VERT\n" + src); + _wglShaderSource(frag, _wgetShaderHeader() + "\n#define CC_FRAG\n" + src); + + _wglCompileShader(vert); + if (!_wglGetShaderCompiled(vert)) System.err.println(("\n" + _wglGetShaderInfoLog(vert)).replace("\n", "\n[/glsl/occl.glsl][VERT] ") + "\n"); + + _wglCompileShader(frag); + if (!_wglGetShaderCompiled(frag)) System.err.println(("\n" + _wglGetShaderInfoLog(frag)).replace("\n", "\n[/glsl/occl.glsl][FRAG] ") + "\n"); + + occlusion_program = _wglCreateProgram(); + + _wglAttachShader(occlusion_program, vert); + _wglAttachShader(occlusion_program, frag); + _wglLinkProgram(occlusion_program); + _wglDetachShader(occlusion_program, vert); + _wglDetachShader(occlusion_program, frag); + _wglDeleteShader(vert); + _wglDeleteShader(frag); + + if(!_wglGetProgramLinked(occlusion_program)) System.err.println(("\n\n"+_wglGetProgramInfoLog(occlusion_program)).replace("\n", "\n[/glsl/occl.glsl][LINKER] ")); + + _wglUseProgram(occlusion_program); + occlusion_matrix_m = _wglGetUniformLocation(occlusion_program, "matrix_m"); + occlusion_matrix_p = _wglGetUniformLocation(occlusion_program, "matrix_p"); + + } + + private static final GLObjectMap queryObjs = new GLObjectMap(256); + + public static final int glCreateQuery() { + return queryObjs.register(_wglCreateQuery()); + } + + public static final void glBeginQuery(int obj) { + _wglBeginQuery(_wGL_ANY_SAMPLES_PASSED, queryObjs.get(obj)); + } + + public static final void glDeleteQuery(int obj) { + _wglDeleteQuery(queryObjs.free(obj)); + } + + private static final Matrix4f cachedOcclusionP = (Matrix4f) (new Matrix4f()).setZero(); + private static float[] occlusionModel = new float[16]; + private static float[] occlusionProj = new float[16]; + + public static final void glBindOcclusionBB() { + if(occlusion_vao == null) initializeOcclusionObjects(); + _wglUseProgram(occlusion_program); + _wglBindVertexArray(occlusion_vao); + if(!cachedOcclusionP.equals(matProjV[matProjPointer])) { + cachedOcclusionP.load(matProjV[matProjPointer]); + cachedOcclusionP.store(occlusionProj); + _wglUniformMat4fv(occlusion_matrix_p, occlusionProj); + } + } + + public static final void glEndOcclusionBB() { + + } + + public static final void glDrawOcclusionBB(float posX, float posY, float posZ, float sizeX, float sizeY, float sizeZ) { + glPushMatrix(); + glTranslatef(posX - sizeX * 0.0001f, posY - sizeY * 0.0001f, posZ - sizeZ * 0.0001f); + glScalef(sizeX * 1.0002f, sizeY * 1.0002f, sizeZ * 1.0002f); + matModelV[matModelPointer].store(occlusionModel); + _wglUniformMat4fv(occlusion_matrix_m, occlusionModel); + _wglDrawArrays(_wGL_TRIANGLES, 0, 36); + glPopMatrix(); + //glPushMatrix(); + //glTranslatef(posX + sizeX * 0.0001f, posY + sizeY * 0.0001f, posZ + sizeZ * 0.0001f); + //glScalef(sizeX * 0.9998f, sizeY * 0.9998f, sizeZ * 0.9998f); + //matModelV[matModelPointer].store(occlusionModel); + //_wglUniformMat4fv(occlusion_matrix_m, occlusionModel); + //_wglDrawArrays(_wGL_TRIANGLES, 0, 36); + //glPopMatrix(); + + } + + public static final void glEndQuery() { + _wglEndQuery(_wGL_ANY_SAMPLES_PASSED); + } + + public static final boolean glGetQueryResult(int obj) { + QueryGL q = queryObjs.get(obj); + return _wglGetQueryObjecti(q, _wGL_QUERY_RESULT_AVAILABLE) == 0 || _wglGetQueryObjecti(q, _wGL_QUERY_RESULT) > 0; + } + + public static final int glGenTextures() { + return texObjects.register(_wglGenTextures()); + } + public static final void glTexSubImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, ByteBuffer p9) { + int pp1 = 0; + switch(p1) { + default: + case GL_TEXTURE_2D: pp1 = _wGL_TEXTURE_2D; break; + //case GL_TEXTURE_3D: pp1 = _wGL_TEXTURE_3D; break; + } + /* + int pp3 = 0; + switch(p7) { + default: + case GL_RGBA: pp3 = _wGL_RGBA; break; + case GL_BGRA: pp3 = _wGL_BGRA; break; + } + */ + bytesUploaded += p9.remaining(); + _wglTexSubImage2D(pp1, p2, p3, p4, p5, p6, _wGL_RGBA, _wGL_UNSIGNED_BYTE, p9); + } + public static final void glFogi(int p1, int p2) { + if(p1 == GL_FOG_MODE) { + switch(p2) { + default: + case GL_LINEAR: + fogMode = 1; + break; + case GL_EXP: + fogMode = 2; + break; + } + } + } + public static final void glFogf(int p1, float p2) { + switch(p1) { + case GL_FOG_START: + fogStart = p2; + break; + case GL_FOG_END: + fogEnd = p2; + break; + case GL_FOG_DENSITY: + fogDensity = p2; + break; + default: + break; + } + } + public static final void glFog(int p1, FloatBuffer p2) { + if(p1 == GL_FOG_COLOR) { + fogColorR = p2.get(); + fogColorG = p2.get(); + fogColorB = p2.get(); + fogColorA = p2.get(); + } + } + public static final void glDeleteLists(int p1, int p2) { + for(int i = 0; i < p2; i++) { + DisplayList d = displayListsInitialized.remove(p1 + i); + if(d != null) { + _wglDeleteVertexArray(d.glarray); + _wglDeleteBuffer(d.glbuffer); + } + displayLists.remove(p1 + i); + } + } + public static final void glActiveTexture(int p1) { + switch(p1) { + case GL_TEXTURE0: + selectedTex = 0; + _wglActiveTexture(_wGL_TEXTURE0); + break; + case GL_TEXTURE1: + selectedTex = 1; + _wglActiveTexture(_wGL_TEXTURE1); + break; + default: + System.err.println("only two texture units implemented"); + break; + } + } + public static final void glClientActiveTexture(int p1) { + switch(p1) { + case GL_TEXTURE0: + selectedClientTex = 0; + break; + case GL_TEXTURE1: + selectedClientTex = 1; + break; + default: + System.err.println("only two texture units implemented"); + break; + } + } + public static final void glMultiTexCoord2f(int p1, float p2, float p3) { + switch(p1) { + case GL_TEXTURE0: + tex0X = p2; + tex0Y = p3; + break; + case GL_TEXTURE1: + tex1X = p2; + tex1Y = p3; + break; + default: + System.err.println("only two texture units implemented"); + break; + } + } + private static Matrix4f unprojA = new Matrix4f(); + private static Matrix4f unprojB = new Matrix4f(); + private static Vector4f unprojC = new Vector4f(); + public static final void gluUnProject(float p1, float p2, float p3, FloatBuffer p4, FloatBuffer p5, int[] p6, FloatBuffer p7) { + unprojA.load(p4); + unprojB.load(p5); + Matrix4f.mul(unprojA, unprojB, unprojB); + unprojB.invert(); + unprojC.set(((p1 - (float)p6[0]) / (float)p6[2]) * 2f - 1f, ((p2 - (float)p6[1]) / (float)p6[3]) * 2f - 1f, p3, 1.0f); + Matrix4f.transform(unprojB, unprojC, unprojC); + p7.put(unprojC.x / unprojC.w); + p7.put(unprojC.y / unprojC.w); + p7.put(unprojC.z / unprojC.w); + } + public static final void gluPerspective(float fovy, float aspect, float zNear, float zFar) { + Matrix4f res = getMatrix(); + float cotangent = (float) Math.cos(fovy * toRad * 0.5f) / (float) Math.sin(fovy * toRad * 0.5f); + res.m00 = cotangent / aspect; + res.m01 = 0.0f; + res.m02 = 0.0f; + res.m03 = 0.0f; + res.m10 = 0.0f; + res.m11 = cotangent; + res.m12 = 0.0f; + res.m13 = 0.0f; + res.m20 = 0.0f; + res.m21 = 0.0f; + res.m22 = (zFar + zNear) / (zFar - zNear); + res.m23 = -1.0f; + res.m30 = 0.0f; + res.m31 = 0.0f; + res.m32 = 2.0f * zFar * zNear / (zFar - zNear); + res.m33 = 0.0f; + } + public static final void gluPerspectiveFlat(float fovy, float aspect, float zNear, float zFar) { + Matrix4f res = getMatrix(); + float cotangent = (float) Math.cos(fovy * toRad * 0.5f) / (float) Math.sin(fovy * toRad * 0.5f); + res.m00 = cotangent / aspect; + res.m01 = 0.0f; + res.m02 = 0.0f; + res.m03 = 0.0f; + res.m10 = 0.0f; + res.m11 = cotangent; + res.m12 = 0.0f; + res.m13 = 0.0f; + res.m20 = 0.0f; + res.m21 = 0.0f; + res.m22 = ((zFar + zNear) / (zFar - zNear)) * 0.001f; + res.m23 = -1.0f; + res.m30 = 0.0f; + res.m31 = 0.0f; + res.m32 = 2.0f * zFar * zNear / (zFar - zNear); + res.m33 = 0.0f; + } + public static final String gluErrorString(int p1) { + switch(p1) { + case GL_INVALID_ENUM: return "GL_INVALID_ENUM"; + case GL_INVALID_VALUE: return "GL_INVALID_VALUE"; + case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION"; + case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY"; + case GL_CONTEXT_LOST_WEBGL: return "CONTEXT_LOST_WEBGL"; + default: return "Unknown Error"; + } + } + private static long lastBandwidthReset = 0l; + private static int lastBandwidth = 0; + public static final int getBitsPerSecond() { + if(System.currentTimeMillis() - lastBandwidthReset > 1000) { + lastBandwidthReset = System.currentTimeMillis(); + lastBandwidth = bytesUploaded * 8; + bytesUploaded = 0; + } + return lastBandwidth; + } + public static final int getVertexesPerSecond() { + int ret = vertexDrawn; + vertexDrawn = 0; + return ret; + } + public static final int getTrianglesPerSecond() { + int ret = triangleDrawn; + triangleDrawn = 0; + return ret; + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/EffectPipeline.java b/src/main/java/net/lax1dude/eaglercraft/glemu/EffectPipeline.java new file mode 100644 index 0000000..a289f07 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/EffectPipeline.java @@ -0,0 +1,482 @@ +package net.lax1dude.eaglercraft.glemu; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.IntBuffer; +import java.util.HashMap; +import java.util.Random; + +import net.lax1dude.eaglercraft.glemu.vector.Matrix4f; + +import static net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2._wGL_CULL_FACE; +import static net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2._wglDisable; +import static net.lax1dude.eaglercraft.glemu.EaglerAdapterGL30.*; + +public class EffectPipeline { + + private static String[] pipeline_tmp = null; + public static String[] pipeline = new String[0]; + private static HashMap programs = new HashMap(); + private static HashMap uniforms = new HashMap(); + + private static FramebufferGL framebuffer; + private static FramebufferGL framebuffer1; + private static FramebufferGL framebuffer2; + private static TextureGL framebuffer_color; + private static TextureGL framebuffer_color1; + private static TextureGL framebuffer_color2; + private static TextureGL framebuffer_depth; + + private static FramebufferGL framebuffer_bloom_a = null; + private static TextureGL framebuffer_bloom_a_color = null; + private static FramebufferGL framebuffer_bloom_b = null; + private static TextureGL framebuffer_bloom_b_color = null; + + private static BufferArrayGL renderQuadArray; + private static BufferGL renderQuadBuffer; + + private static ShaderGL pvert_shader; + + private static int width = -1; + private static int height = -1; + + private static int[] originalViewport = null; + + public static void init() { + framebuffer = _wglCreateFramebuffer(); + //framebuffer1 = _wglCreateFramebuffer(); + //framebuffer2 = _wglCreateFramebuffer(); + framebuffer_color = _wglGenTextures(); + //framebuffer_color1 = _wglGenTextures(); + //framebuffer_color2 = _wglGenTextures(); + framebuffer_depth = _wglGenTextures(); + pvert_shader = _wglCreateShader(_wGL_VERTEX_SHADER); + + _wglShaderSource(pvert_shader, _wgetShaderHeader() + "\n" + fileContents("/glsl/pvert.glsl")); + _wglCompileShader(pvert_shader); + + if (!_wglGetShaderCompiled(pvert_shader)) System.err.println(("\n" + _wglGetShaderInfoLog(pvert_shader)).replace("\n", "\n[/glsl/pvert.glsl] ") + "\n"); + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + + //_wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color1); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + + //_wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color2); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_depth); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer); + _wglFramebufferTexture2D(_wGL_COLOR_ATTACHMENT0, framebuffer_color); + _wglFramebufferTexture2D(_wGL_DEPTH_STENCIL_ATTACHMENT, framebuffer_depth); + + //_wglBindFramebuffer(framebuffer1); + //_wglFramebufferTexture2D(_wGL_COLOR_ATTACHMENT0, framebuffer_color1); + + //_wglBindFramebuffer(framebuffer2); + //_wglFramebufferTexture2D(_wGL_COLOR_ATTACHMENT0, framebuffer_color2); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, null); + + renderQuadArray = _wglCreateVertexArray(); + renderQuadBuffer = _wglCreateBuffer(); + IntBuffer upload = (isWebGL ? IntBuffer.wrap(new int[12]) : ByteBuffer.allocateDirect(12 << 2).order(ByteOrder.nativeOrder()).asIntBuffer()); + upload.put(Float.floatToRawIntBits(0.0f)); upload.put(Float.floatToRawIntBits(0.0f)); + upload.put(Float.floatToRawIntBits(0.0f)); upload.put(Float.floatToRawIntBits(1.0f)); + upload.put(Float.floatToRawIntBits(1.0f)); upload.put(Float.floatToRawIntBits(0.0f)); + upload.put(Float.floatToRawIntBits(1.0f)); upload.put(Float.floatToRawIntBits(0.0f)); + upload.put(Float.floatToRawIntBits(1.0f)); upload.put(Float.floatToRawIntBits(1.0f)); + upload.put(Float.floatToRawIntBits(0.0f)); upload.put(Float.floatToRawIntBits(1.0f)); + upload.flip(); + _wglBindBuffer(_wGL_ARRAY_BUFFER, renderQuadBuffer); + _wglBufferData0(_wGL_ARRAY_BUFFER, upload, _wGL_STATIC_DRAW); + _wglBindVertexArray(renderQuadArray); + _wglEnableVertexAttribArray(0); + _wglVertexAttribPointer(0, 2, _wGL_FLOAT, false, 8, 0); + } + + public static void beginPipelineRender() { + if (pipeline_tmp != null) { + pipeline = pipeline_tmp; + pipeline_tmp = null; + } + + if (pipeline.length > 0) { + int[] viewport = new int[4]; + _wglGetParameter(_wGL_VIEWPORT, 4, viewport); + if (width != viewport[2] || height != viewport[3]) { + System.out.println("setting up framebuffer textures"); + width = viewport[2]; + height = viewport[3]; + originalViewport = viewport; + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB, width, height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer) null); + + //_wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color1); + //_wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB, width, height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer) null); + + //_wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color2); + //_wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB, width, height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer) null); + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_depth); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_DEPTH24_STENCIL8, width, height, 0, _wGL_DEPTH_STENCIL, _wGL_UNSIGNED_INT_24_8, (ByteBuffer) null); + } + + _wglActiveTexture(_wGL_TEXTURE1); + _wglBindTexture(_wGL_TEXTURE_2D, null); + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, null); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer); + _wglViewport(0, 0, width, height); + } + + } + + private static boolean framebufferFlip = false; + + private static int bloom_width = -1; + private static int bloom_height = -1; + + public static void reloadPipeline() { + System.out.println("reloading "+pipeline.length+" pipeline shader programs"); + String[] tmp1 = pipeline; + String[] tmp = programs.keySet().toArray(new String[0]); + for(ProgramGL i : programs.values()) { + _wglDeleteProgram(i); + } + programs.clear(); + uniforms.clear(); + setupPipeline(tmp1, tmp); + } + + public static void endPipelineRender() { + if (pipeline.length > 0) { + _wglBindFramebuffer(_wGL_FRAMEBUFFER, null); + + _wglDisable(_wGL_DEPTH_TEST); + _wglDisable(_wGL_CULL_FACE); + _wglDepthMask(true); + + _wglActiveTexture(_wGL_TEXTURE1); + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_depth); + _wglActiveTexture(_wGL_TEXTURE0); + + _wglBindVertexArray(renderQuadArray); + + for(int i = 0; i < pipeline.length; ++i) { + framebufferFlip = !framebufferFlip; + if(i == 0) { + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color); + }else { + _wglBindTexture(_wGL_TEXTURE_2D, framebufferFlip ? framebuffer_color2 : framebuffer_color1); + } + + if(i == pipeline.length - 1) { + _wglBindFramebuffer(_wGL_FRAMEBUFFER, null); + _wglViewport(originalViewport[0], originalViewport[1], originalViewport[2], originalViewport[3]); + }else { + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebufferFlip ? framebuffer1 : framebuffer2); + _wglViewport(0, 0, width, height); + } + + _wglActiveTexture(_wGL_TEXTURE0); + + ProgramGL prog = programs.get(pipeline[i]); + _wglUseProgram(prog); + setUniforms(uniforms.get(pipeline[i])); + + _wglActiveTexture(_wGL_TEXTURE0); + if(i == 0) { + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color); + }else { + _wglBindTexture(_wGL_TEXTURE_2D, framebufferFlip ? framebuffer_color2 : framebuffer_color1); + } + + if(i == pipeline.length - 1) { + _wglBindFramebuffer(_wGL_FRAMEBUFFER, null); + _wglViewport(originalViewport[0], originalViewport[1], originalViewport[2], originalViewport[3]); + }else { + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebufferFlip ? framebuffer1 : framebuffer2); + _wglViewport(0, 0, width, height); + } + + _wglUseProgram(prog); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, null); + _wglActiveTexture(_wGL_TEXTURE1); + _wglBindTexture(_wGL_TEXTURE_2D, null); + _wglActiveTexture(_wGL_TEXTURE2); + _wglBindTexture(_wGL_TEXTURE_2D, null); + _wglActiveTexture(_wGL_TEXTURE0); + } + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, null); + } + } + + private static final Random deevis = new Random(); + + private static float[] projBuffer = new float[16]; + private static float[] projBufferInv = new float[16]; + private static Matrix4f projectionMatrix = (Matrix4f) new Matrix4f().setZero(); + private static Matrix4f projectionMatrixInv = (Matrix4f) new Matrix4f().setZero(); + + private static long randomInterTimer = 0l; + private static float randomInterA = 0.0f; + private static float randomInterB = 0.0f; + + private static void setUniforms(UniformGL[] is) { + if(is[0] != null) { + _wglUniform2f(is[0], width, height); + } + if(is[1] != null) { + _wglUniform1f(is[1], deevis.nextFloat()); + } + if(is[2] != null) { + /* + _wglUniform1i(is[2], 2); + makeSSAOTexture(); + _wglActiveTexture(_wGL_TEXTURE2); + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_ssao_color); + _wglActiveTexture(_wGL_TEXTURE0); + */ + } + if((is[3] != null || is[4] != null) && !projectionMatrix.equals(matProjV[matProjPointer])) { + projectionMatrix.load(matProjV[matProjPointer]); + if(is[3] != null) { + projectionMatrix.store(projBuffer); + _wglUniformMat4fv(is[3], projBuffer); + } + if(is[4] != null) { + Matrix4f.invert(projectionMatrix, projectionMatrixInv); + projectionMatrixInv.store(projBufferInv); + _wglUniformMat4fv(is[4], projBufferInv); + } + } + if(is[5] != null) { + _wglUniform1i(is[5], 2); + makeBloomTexture(); + _wglActiveTexture(_wGL_TEXTURE2); + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_bloom_a_color); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_LINEAR); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_LINEAR); + _wglActiveTexture(_wGL_TEXTURE0); + } + if(is[7] != null) { + long time = System.currentTimeMillis(); + if(time - randomInterTimer > 140l) { + randomInterTimer = time; + randomInterB = randomInterA; + randomInterA = deevis.nextFloat(); + } + _wglUniform2f(is[7], randomInterA, randomInterB); + float r = ((float)(time - randomInterTimer) / 140.0f); + _wglUniform1f(is[8], 0 - 2 * r * r * r + 3 * r * r); + } + } + + private static void makeBloomTexture() { + if(framebuffer_bloom_a == null) { + framebuffer_bloom_a = _wglCreateFramebuffer(); + framebuffer_bloom_a_color = _wglGenTextures(); + framebuffer_bloom_b = _wglCreateFramebuffer(); + framebuffer_bloom_b_color = _wglGenTextures(); + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_bloom_a_color); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_bloom_b_color); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer_bloom_a); + _wglFramebufferTexture2D(_wGL_COLOR_ATTACHMENT0, framebuffer_bloom_a_color); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer_bloom_b); + _wglFramebufferTexture2D(_wGL_COLOR_ATTACHMENT0, framebuffer_bloom_b_color); + } + + int w = width / 4; + int h = height / 4; + if(bloom_width != w || bloom_height != h) { + bloom_width = w; + bloom_height = h; + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_bloom_a_color); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB, bloom_width, bloom_height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer) null); + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_bloom_b_color); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB, bloom_width, bloom_height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer) null); + } + + int[] viewport = new int[4]; + _wglGetParameter(_wGL_VIEWPORT, 4, viewport); + + _wglActiveTexture(_wGL_TEXTURE0); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer_bloom_a); + _wglViewport(0, 0, bloom_width, bloom_height); + UniformGL i; + _wglUseProgram(programs.get("/glsl/bloom_a.glsl")); + i = uniforms.get("/glsl/bloom_a.glsl")[0]; + _wglUniform2i(i, bloom_width, bloom_height); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer_bloom_b); + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_bloom_a_color); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglUseProgram(programs.get("/glsl/bloom_b.glsl")); + i = uniforms.get("/glsl/bloom_b.glsl")[0]; + UniformGL j = uniforms.get("/glsl/bloom_b.glsl")[6]; + _wglUniform2i(i, bloom_width, bloom_height); + _wglUniform2i(j, 0, 1); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + _wglBindTexture(_wGL_TEXTURE_2D, null); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer_bloom_a); + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_bloom_b_color); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglUniform2i(j, 1, 0); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + _wglBindTexture(_wGL_TEXTURE_2D, null); + + _wglViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, null); + + } + + /* + private static void makeSSAOTexture() { + if(framebuffer_ssao == -1) { + framebuffer_ssao = _wglCreateFramebuffer(); + framebuffer_ssao_color = _wglGenTextures(); + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_ssao_color); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_LINEAR); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_LINEAR); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + + _wglBindFramebuffer(framebuffer_ssao); + _wglFramebufferTexture2D(_wGL_COLOR_ATTACHMENT0, framebuffer_ssao_color); + } + + int sssao_width = width; + int sssao_height = height; + if(sssao_width != ssao_width || sssao_height != ssao_height) { + ssao_width = sssao_width; + ssao_height = sssao_height; + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_ssao_color); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB, ssao_width, ssao_height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer) null); + } + + int[] viewport = _wglGetParameter(_wGL_VIEWPORT, 4); + _wglBindFramebuffer(framebuffer_ssao); + _wglViewport(0, 0, ssao_width, ssao_height); + _wglUseProgram(programs.get("/glsl/ssao_a.glsl")); + setUniforms(uniforms.get("/glsl/ssao_a.glsl")); + _wglColorMask(true, false, false, false); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + _wglColorMask(true, true, true, true); + _wglViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + } + */ + + public static void setupPipeline(String[] shaders, String[] load) { + pipeline_tmp = shaders; + for(int i = 0; i < load.length; i++) { + if(!programs.containsKey(load[i])) { + ProgramGL prog = _wglCreateProgram(); + ShaderGL f = _wglCreateShader(_wGL_FRAGMENT_SHADER); + + _wglShaderSource(f, _wgetShaderHeader() + "\n" + fileContents(load[i])); + _wglCompileShader(f); + + if (!_wglGetShaderCompiled(f)) System.err.println(("\n" + _wglGetShaderInfoLog(f)).replace("\n", "\n["+load[i]+"][CC_FRAG] ") + "\n"); + + _wglAttachShader(prog, pvert_shader); + _wglAttachShader(prog, f); + _wglLinkProgram(prog); + _wglDetachShader(prog, pvert_shader); + _wglDetachShader(prog, f); + _wglDeleteShader(f); + + if(!_wglGetProgramLinked(prog)) { + System.err.println(("\n"+_wglGetProgramInfoLog(prog)).replace("\n", "\n["+load[i]+"][LINKER] ") + "\n"); + pipeline_tmp = new String[0]; + return; + } + + _wglUseProgram(prog); + + UniformGL c = _wglGetUniformLocation(prog, "f_color"); + if(c != null) _wglUniform1i(c, 0); + UniformGL d = _wglGetUniformLocation(prog, "f_depth"); + if(d != null) _wglUniform1i(d, 1); + + _wglBindAttributeLocation(prog, 0, "a_pos"); + + if(_wglGetUniformLocation(prog, "ssao_kernel[0]") != null) { + Random r = new Random("eeeaglerrENOPHILEr".hashCode()); + for(int j = 0; j < 24; j++) { + float x = r.nextFloat() * 2.0f - 1.0f; + float y = r.nextFloat() * 2.0f - 1.0f; + float z = r.nextFloat() * 2.0f - 1.0f; + + float s = 0.3f + 0.7f * r.nextFloat(); + float hypot = (1.0f / (float) Math.sqrt(x*x + y*y + z*z)) * s; + x *= hypot; + y *= hypot; + z *= hypot; + + _wglUniform3f(_wglGetUniformLocation(prog, "ssao_kernel["+j+"]"), x, y, z); + } + } + + programs.put(load[i], prog); + uniforms.put(load[i], new UniformGL[] { + _wglGetUniformLocation(prog, "screenSize"), + _wglGetUniformLocation(prog, "randomFloat"), + _wglGetUniformLocation(prog, "f_ssao"), + _wglGetUniformLocation(prog, "matrix_p"), + _wglGetUniformLocation(prog, "matrix_p_inv"), + _wglGetUniformLocation(prog, "f_bloom"), + _wglGetUniformLocation(prog, "direction"), + _wglGetUniformLocation(prog, "randomInter"), + _wglGetUniformLocation(prog, "randomInterF") + }); + } + } + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/EffectPipelineFXAA.java b/src/main/java/net/lax1dude/eaglercraft/glemu/EffectPipelineFXAA.java new file mode 100644 index 0000000..a136b39 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/EffectPipelineFXAA.java @@ -0,0 +1,223 @@ +package net.lax1dude.eaglercraft.glemu; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.IntBuffer; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.minecraft.client.Minecraft; + +import static net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2._wGL_DEPTH_TEST; +import static net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2._wglDisable; +import static net.lax1dude.eaglercraft.glemu.EaglerAdapterGL30.*; + +public class EffectPipelineFXAA { + + private static boolean isUsingFXAA = false; + + private static FramebufferGL framebuffer = null; + private static RenderbufferGL framebuffer_color = null; + private static RenderbufferGL framebuffer_depth = null; + + private static ProgramGL fxaaProgram = null; + private static TextureGL fxaaSourceTexture = null; + private static UniformGL fxaaScreenSize = null; + + private static BufferArrayGL renderQuadArray = null; + private static BufferGL renderQuadBuffer; + + private static int width = -1; + private static int height = -1; + + private static int[] originalViewport = new int[4]; + + private static int state = 1; + private static int newState = -1; + private static boolean msaaInit = false; + + private static void initFXAA() { + if(fxaaProgram == null) { + renderQuadArray = _wglCreateVertexArray(); + renderQuadBuffer = _wglCreateBuffer(); + + IntBuffer upload = (isWebGL ? IntBuffer.wrap(new int[12]) : ByteBuffer.allocateDirect(12 << 2).order(ByteOrder.nativeOrder()).asIntBuffer()); + upload.put(Float.floatToRawIntBits(0.0f)); upload.put(Float.floatToRawIntBits(0.0f)); + upload.put(Float.floatToRawIntBits(0.0f)); upload.put(Float.floatToRawIntBits(1.0f)); + upload.put(Float.floatToRawIntBits(1.0f)); upload.put(Float.floatToRawIntBits(0.0f)); + upload.put(Float.floatToRawIntBits(0.0f)); upload.put(Float.floatToRawIntBits(1.0f)); + upload.put(Float.floatToRawIntBits(1.0f)); upload.put(Float.floatToRawIntBits(1.0f)); + upload.put(Float.floatToRawIntBits(1.0f)); upload.put(Float.floatToRawIntBits(0.0f)); + upload.flip(); + + _wglBindVertexArray(renderQuadArray); + _wglBindBuffer(_wGL_ARRAY_BUFFER, renderQuadBuffer); + _wglBufferData0(_wGL_ARRAY_BUFFER, upload, _wGL_STATIC_DRAW); + _wglEnableVertexAttribArray(0); + _wglVertexAttribPointer(0, 2, _wGL_FLOAT, false, 8, 0); + + ShaderGL pvert_shader = _wglCreateShader(_wGL_VERTEX_SHADER); + + _wglShaderSource(pvert_shader, _wgetShaderHeader() + "\n" + fileContents("/glsl/pvert.glsl")); + _wglCompileShader(pvert_shader); + + if (!_wglGetShaderCompiled(pvert_shader)) System.err.println(("\n" + _wglGetShaderInfoLog(pvert_shader)).replace("\n", "\n[/glsl/pvert.glsl] ") + "\n"); + + ShaderGL fxaa_shader = _wglCreateShader(_wGL_FRAGMENT_SHADER); + _wglShaderSource(fxaa_shader, _wgetShaderHeader() + "\n" + fileContents("/glsl/fxaa.glsl")); + _wglCompileShader(fxaa_shader); + + if (!_wglGetShaderCompiled(fxaa_shader)) System.err.println(("\n" + _wglGetShaderInfoLog(fxaa_shader)).replace("\n", "\n[/glsl/fxaa.glsl] ") + "\n"); + + fxaaProgram = _wglCreateProgram(); + _wglAttachShader(fxaaProgram, pvert_shader); + _wglAttachShader(fxaaProgram, fxaa_shader); + _wglLinkProgram(fxaaProgram); + _wglDetachShader(fxaaProgram, pvert_shader); + _wglDetachShader(fxaaProgram, fxaa_shader); + _wglDeleteShader(pvert_shader); + _wglDeleteShader(fxaa_shader); + + if(!_wglGetProgramLinked(fxaaProgram)) { + System.err.println(("\n"+_wglGetProgramInfoLog(fxaaProgram)).replace("\n", "\n[/glsl/fxaa.glsl][LINKER] ") + "\n"); + fxaaProgram = null; + throw new RuntimeException("Invalid shader code"); + } + + _wglUseProgram(fxaaProgram); + + UniformGL c = _wglGetUniformLocation(fxaaProgram, "f_color"); + if(c != null) _wglUniform1i(c, 0); + + fxaaScreenSize = _wglGetUniformLocation(fxaaProgram, "screenSize"); + } + isUsingFXAA = true; + + destroy(); + framebuffer = _wglCreateFramebuffer(); + fxaaSourceTexture = _wglGenTextures(); + + _wglBindTexture(_wGL_TEXTURE_2D, fxaaSourceTexture); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB8, width, height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer)null); + + + framebuffer_depth = _wglCreateRenderBuffer(); + _wglBindRenderbuffer(framebuffer_depth); + _wglRenderbufferStorage(_wGL_DEPTH_COMPONENT32F, width, height); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer); + _wglFramebufferTexture2D(_wGL_COLOR_ATTACHMENT0, fxaaSourceTexture); + _wglFramebufferRenderbuffer(_wGL_DEPTH_ATTACHMENT, framebuffer_depth); + } + + private static void initMSAA() { + msaaInit = true; + isUsingFXAA = false; + destroy(); + framebuffer = _wglCreateFramebuffer(); + framebuffer_color = _wglCreateRenderBuffer(); + framebuffer_depth = _wglCreateRenderBuffer(); + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer); + _wglBindRenderbuffer(framebuffer_color); + _wglRenderbufferStorageMultisample(state == 2 ? 4 : 8, _wGL_RGB8, width, height); + _wglBindRenderbuffer(framebuffer_depth); + _wglRenderbufferStorageMultisample(state == 2 ? 4 : 8, _wGL_DEPTH_COMPONENT32F, width, height); + _wglFramebufferRenderbuffer(_wGL_COLOR_ATTACHMENT0, framebuffer_color); + _wglFramebufferRenderbuffer(_wGL_DEPTH_ATTACHMENT, framebuffer_depth); + _wglBindFramebuffer(_wGL_FRAMEBUFFER, null); + } + + public static void destroy() { + if(framebuffer != null) _wglDeleteFramebuffer(framebuffer); + if(framebuffer_color != null) _wglDeleteRenderbuffer(framebuffer_color); + if(framebuffer_depth != null) _wglDeleteRenderbuffer(framebuffer_depth); + if(fxaaSourceTexture != null) _wglDeleteTextures(fxaaSourceTexture); + framebuffer = null; + framebuffer_color = null; + framebuffer_depth = null; + fxaaSourceTexture = null; + } + + public static void beginPipelineRender() { + int mode = Minecraft.getMinecraft().gameSettings.antialiasMode; + if(mode == 0) newState = 0; + if(mode == 1) newState = Minecraft.getMinecraft().gameSettings.fancyGraphics ? 1 : 0; + if(mode == 2) newState = 1; + if(mode == 3) newState = 2; + if(mode == 4) newState = 3; + if(state != newState) { + state = newState; + if(state == 0) { + destroy(); + } + width = -1; + height = -1; + } + if(state == 0) return; + _wglGetParameter(_wGL_VIEWPORT, 4, originalViewport); + if (width != originalViewport[2] || height != originalViewport[3]) { + width = originalViewport[2]; + height = originalViewport[3]; + if(state == 1) { + if(isUsingFXAA == false || fxaaProgram == null) { + initFXAA(); + }else { + _wglBindTexture(_wGL_TEXTURE_2D, fxaaSourceTexture); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB8, width, height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer)null); + _wglBindRenderbuffer(framebuffer_depth); + _wglRenderbufferStorage(_wGL_DEPTH_COMPONENT32F, width, height); + } + }else if(state == 2 || state == 3) { + if(isUsingFXAA == true || msaaInit == false) { + initMSAA(); + }else { + _wglBindRenderbuffer(framebuffer_color); + _wglRenderbufferStorageMultisample(state == 2 ? 4 : 8, _wGL_RGB8, width, height); + _wglBindRenderbuffer(framebuffer_depth); + _wglRenderbufferStorageMultisample(state == 2 ? 4 : 8, _wGL_DEPTH_COMPONENT32F, width, height); + } + } + } + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer); + _wglViewport(0, 0, width, height); + if(!EaglerAdapter.isWebGL && (state == 2 || state == 3)) { + _wglEnable(_wGL_MULTISAMPLE); + _wglEnable(_wGL_LINE_SMOOTH); + } + } + + public static void endPipelineRender() { + if(state == 0) return; + _wglBindFramebuffer(_wGL_FRAMEBUFFER, null); + _wglClear(_wGL_COLOR_BUFFER_BIT | _wGL_DEPTH_BUFFER_BIT); + if(state == 1) { + _wglViewport(originalViewport[0], originalViewport[1], originalViewport[2], originalViewport[3]); + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, fxaaSourceTexture); + _wglDisable(_wGL_DEPTH_TEST); + _wglDisable(_wGL_CULL_FACE); + _wglDepthMask(false); + _wglUseProgram(fxaaProgram); + _wglUniform2f(fxaaScreenSize, width, height); + _wglBindVertexArray(renderQuadArray); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + _wglEnable(_wGL_DEPTH_TEST); + _wglDepthMask(true); + }else if(state == 2 || state == 3) { + if(!EaglerAdapter.isWebGL) { + _wglDisable(_wGL_MULTISAMPLE); + _wglDisable(_wGL_LINE_SMOOTH); + } + _wglViewport(originalViewport[0], originalViewport[1], originalViewport[2], originalViewport[3]); + _wglBindFramebuffer(_wGL_READ_FRAMEBUFFER, framebuffer); + _wglBindFramebuffer(_wGL_DRAW_FRAMEBUFFER, null); + _wglDrawBuffer(_wGL_BACK); + _wglBlitFramebuffer(0, 0, width, height, 0, 0, width, height, _wGL_COLOR_BUFFER_BIT, _wGL_NEAREST); + _wglBindFramebuffer(_wGL_READ_FRAMEBUFFER, null); + } + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/FixedFunctionShader.java b/src/main/java/net/lax1dude/eaglercraft/glemu/FixedFunctionShader.java new file mode 100644 index 0000000..294a126 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/FixedFunctionShader.java @@ -0,0 +1,489 @@ +package net.lax1dude.eaglercraft.glemu; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.glemu.vector.Matrix3f; +import net.lax1dude.eaglercraft.glemu.vector.Matrix4f; +import net.lax1dude.eaglercraft.glemu.vector.Vector4f; + +import static net.lax1dude.eaglercraft.glemu.EaglerAdapterGL30.*; + +public class FixedFunctionShader { + + private static final FixedFunctionShader[] instances = new FixedFunctionShader[1024]; //lol + + public static void refreshCoreGL() { + for(int i = 0; i < instances.length; ++i) { + if(instances[i] != null) { + _wglDeleteProgram(instances[i].globject); + instances[i] = null; + } + } + shaderSource = null; + } + + public static final int COLOR = 1; + public static final int NORMAL = 2; + public static final int TEXTURE0 = 4; + public static final int TEXTURE1 = 8; + public static final int TEXGEN = 16; + public static final int LIGHTING = 32; + public static final int FOG = 64; + public static final int ALPHATEST = 128; + public static final int UNIT0 = 256; + public static final int UNIT1 = 512; + + public static FixedFunctionShader instance(int i) { + FixedFunctionShader s = instances[i]; + if(s == null) { + boolean CC_a_color = false; + boolean CC_a_normal = false; + boolean CC_a_texture0 = false; + boolean CC_a_texture1 = false; + boolean CC_TEX_GEN_STRQ = false; + boolean CC_lighting = false; + boolean CC_fog = false; + boolean CC_alphatest = false; + boolean CC_unit0 = false; + boolean CC_unit1 = false; + if((i & COLOR) == COLOR) { + CC_a_color = true; + } + if((i & NORMAL) == NORMAL) { + CC_a_normal = true; + } + if((i & TEXTURE0) == TEXTURE0) { + CC_a_texture0 = true; + } + if((i & TEXTURE1) == TEXTURE1) { + CC_a_texture1 = true; + } + if((i & TEXGEN) == TEXGEN) { + CC_TEX_GEN_STRQ = true; + } + if((i & LIGHTING) == LIGHTING) { + CC_lighting = true; + } + if((i & FOG) == FOG) { + CC_fog = true; + } + if((i & ALPHATEST) == ALPHATEST) { + CC_alphatest = true; + } + if((i & UNIT0) == UNIT0) { + CC_unit0 = true; + } + if((i & UNIT1) == UNIT1) { + CC_unit1 = true; + } + s = new FixedFunctionShader(i, CC_a_color, CC_a_normal, CC_a_texture0, CC_a_texture1, CC_TEX_GEN_STRQ, CC_lighting, CC_fog, CC_alphatest, CC_unit0, CC_unit1); + instances[i] = s; + } + return s; + } + + private static String shaderSource = null; + + private final boolean enable_color; + private final boolean enable_normal; + private final boolean enable_texture0; + private final boolean enable_texture1; + private final boolean enable_TEX_GEN_STRQ; + private final boolean enable_lighting; + private final boolean enable_fog; + private final boolean enable_alphatest; + private final boolean enable_unit0; + private final boolean enable_unit1; + private final ProgramGL globject; + + private UniformGL u_matrix_m = null; + private UniformGL u_matrix_p = null; + private UniformGL u_matrix_mn = null; + private UniformGL u_matrix_t = null; + + private UniformGL u_fogColor = null; + private UniformGL u_fogMode = null; + private UniformGL u_fogStart = null; + private UniformGL u_fogEnd = null; + private UniformGL u_fogDensity = null; + private UniformGL u_fogPremultiply = null; + + private UniformGL u_colorUniform = null; + private UniformGL u_normalUniform = null; + + private UniformGL u_alphaTestF = null; + + private UniformGL u_textureGenS_M = null; + private UniformGL u_textureGenT_M = null; + private UniformGL u_textureGenR_M = null; + private UniformGL u_textureGenQ_M = null; + private UniformGL u_textureGenS_V = null; + private UniformGL u_textureGenT_V = null; + private UniformGL u_textureGenR_V = null; + private UniformGL u_textureGenQ_V = null; + private UniformGL u_matrix_inverse_m = null; + + private UniformGL u_texCoordV0 = null; + private UniformGL u_texCoordV1 = null; + + private UniformGL u_light0Pos = null; + private UniformGL u_light1Pos = null; + + private final int a_position; + private final int a_texture0; + private final int a_color; + private final int a_normal; + private final int a_texture1; + + private final int attributeIndexesToEnable; + + public final BufferArrayGL genericArray; + public final BufferGL genericBuffer; + public boolean bufferIsInitialized = false; + + private FixedFunctionShader(int j, boolean CC_a_color, boolean CC_a_normal, boolean CC_a_texture0, boolean CC_a_texture1, boolean CC_TEX_GEN_STRQ, boolean CC_lighting, boolean CC_fog, boolean CC_alphatest, boolean CC_unit0, boolean CC_unit1) { + enable_color = CC_a_color; + enable_normal = CC_a_normal; + enable_texture0 = CC_a_texture0; + enable_texture1 = CC_a_texture1; + enable_TEX_GEN_STRQ = CC_TEX_GEN_STRQ; + enable_lighting = CC_lighting; + enable_fog = CC_fog; + enable_alphatest = CC_alphatest; + enable_unit0 = CC_unit0; + enable_unit1 = CC_unit1; + + if(shaderSource == null) { + shaderSource = fileContents("/glsl/core.glsl"); + } + + String source = ""; + if(enable_color) source += "\n#define CC_a_color\n"; + if(enable_normal) source += "#define CC_a_normal\n"; + if(enable_texture0) source += "#define CC_a_texture0\n"; + if(enable_texture1) source += "#define CC_a_texture1\n"; + if(enable_TEX_GEN_STRQ) source += "#define CC_TEX_GEN_STRQ\n"; + if(enable_lighting) source += "#define CC_lighting\n"; + if(enable_fog) source += "#define CC_fog\n"; + if(enable_alphatest) source += "#define CC_alphatest\n"; + if(enable_unit0) source += "#define CC_unit0\n"; + if(enable_unit1) source += "#define CC_unit1\n"; + if(!EaglerAdapter._wisAnisotropicPatched()) source += "#define CC_patch_anisotropic\n"; + source += shaderSource; + + ShaderGL v = _wglCreateShader(_wGL_VERTEX_SHADER); + _wglShaderSource(v, _wgetShaderHeader()+"\n#define CC_VERT\n"+source); + _wglCompileShader(v); + + if(!_wglGetShaderCompiled(v)) { + System.err.println(("\n\n"+_wglGetShaderInfoLog(v)).replace("\n", "\n[/glsl/core.glsl][CC_VERT] ")); + throw new RuntimeException("broken shader file"); + } + + ShaderGL f = _wglCreateShader(_wGL_FRAGMENT_SHADER); + _wglShaderSource(f, _wgetShaderHeader()+"\n#define CC_FRAG\n"+source); + _wglCompileShader(f); + + if(!_wglGetShaderCompiled(f)) { + System.err.println(("\n\n"+_wglGetShaderInfoLog(f)).replace("\n", "\n[/glsl/core.glsl][CC_FRAG] ")); + throw new RuntimeException("broken shader file"); + } + + globject = _wglCreateProgram(); + _wglAttachShader(globject, v); + _wglAttachShader(globject, f); + _wglLinkProgram(globject); + + _wglDetachShader(globject, v); + _wglDetachShader(globject, f); + _wglDeleteShader(v); + _wglDeleteShader(f); + + if(!_wglGetProgramLinked(globject)) { + System.err.println(("\n\n"+_wglGetProgramInfoLog(globject)).replace("\n", "\n[LINKER] ")); + throw new RuntimeException("broken shader file"); + } + + _wglUseProgram(globject); + + u_matrix_m = _wglGetUniformLocation(globject, "matrix_m"); + u_matrix_mn = _wglGetUniformLocation(globject, "matrix_mn"); + u_matrix_p = _wglGetUniformLocation(globject, "matrix_p"); + u_matrix_t = _wglGetUniformLocation(globject, "matrix_t"); + + u_colorUniform = _wglGetUniformLocation(globject, "colorUniform"); + + if(enable_lighting) { + u_normalUniform = _wglGetUniformLocation(globject, "normalUniform"); + u_light0Pos = _wglGetUniformLocation(globject, "light0Pos"); + u_light1Pos = _wglGetUniformLocation(globject, "light1Pos"); + } + + if(enable_fog) { + u_fogColor = _wglGetUniformLocation(globject, "fogColor"); + u_fogMode = _wglGetUniformLocation(globject, "fogMode"); + u_fogStart = _wglGetUniformLocation(globject, "fogStart"); + u_fogEnd = _wglGetUniformLocation(globject, "fogEnd"); + u_fogDensity = _wglGetUniformLocation(globject, "fogDensity"); + u_fogPremultiply = _wglGetUniformLocation(globject, "fogPremultiply"); + } + + if(enable_alphatest) { + u_alphaTestF = _wglGetUniformLocation(globject, "alphaTestF"); + } + + if(enable_TEX_GEN_STRQ) { + u_textureGenS_M = _wglGetUniformLocation(globject, "textureGenS_M"); + u_textureGenT_M = _wglGetUniformLocation(globject, "textureGenT_M"); + u_textureGenR_M = _wglGetUniformLocation(globject, "textureGenR_M"); + u_textureGenQ_M = _wglGetUniformLocation(globject, "textureGenQ_M"); + u_textureGenS_V = _wglGetUniformLocation(globject, "textureGenS_V"); + u_textureGenT_V = _wglGetUniformLocation(globject, "textureGenT_V"); + u_textureGenR_V = _wglGetUniformLocation(globject, "textureGenR_V"); + u_textureGenQ_V = _wglGetUniformLocation(globject, "textureGenQ_V"); + u_matrix_inverse_m = _wglGetUniformLocation(globject, "matrix_inverse_m"); + } + + _wglUniform1i(_wglGetUniformLocation(globject, "tex0"), 0); + _wglUniform1i(_wglGetUniformLocation(globject, "tex1"), 1); + + u_texCoordV0 = _wglGetUniformLocation(globject, "texCoordV0"); + u_texCoordV1 = _wglGetUniformLocation(globject, "texCoordV1"); + + int i = 0; + a_position = i++; + _wglBindAttributeLocation(globject, a_position, "a_position"); + + if(enable_texture0) { + a_texture0 = i++; + _wglBindAttributeLocation(globject, a_texture0, "a_texture0"); + }else { + a_texture0 = -1; + } + if(enable_color) { + a_color = i++; + _wglBindAttributeLocation(globject, a_color, "a_color"); + }else { + a_color = -1; + } + if(enable_normal) { + a_normal = i++; + _wglBindAttributeLocation(globject, a_normal, "a_normal"); + }else { + a_normal = -1; + } + if(enable_texture1) { + a_texture1 = i++; + _wglBindAttributeLocation(globject, a_texture1, "a_texture1"); + }else { + a_texture1 = -1; + } + + attributeIndexesToEnable = i; + + genericArray = _wglCreateVertexArray(); + genericBuffer = _wglCreateBuffer(); + _wglBindVertexArray(genericArray); + _wglBindBuffer(_wGL_ARRAY_BUFFER, genericBuffer); + setupArrayForProgram(); + + } + + public void setupArrayForProgram() { + _wglEnableVertexAttribArray(a_position); + _wglVertexAttribPointer(a_position, 3, EaglerAdapter._wGL_FLOAT, false, 32, 0); + if(enable_texture0) { + _wglEnableVertexAttribArray(a_texture0); + _wglVertexAttribPointer(a_texture0, 2, EaglerAdapter._wGL_FLOAT, false, 32, 12); + } + if(enable_color) { + _wglEnableVertexAttribArray(a_color); + _wglVertexAttribPointer(a_color, 4, EaglerAdapter._wGL_UNSIGNED_BYTE, true, 32, 20); + } + if(enable_normal) { + _wglEnableVertexAttribArray(a_normal); + _wglVertexAttribPointer(a_normal, 4, EaglerAdapter._wGL_UNSIGNED_BYTE, true, 32, 24); + } + if(enable_texture1) { + _wglEnableVertexAttribArray(a_texture1); + _wglVertexAttribPointer(a_texture1, 2, EaglerAdapter._wGL_SHORT, false, 32, 28); + } + } + + public void useProgram() { + _wglUseProgram(globject); + } + + public void unuseProgram() { + + } + + private float[] modelBuffer = new float[16]; + private float[] projectionBuffer = new float[16]; + private float[] textureBuffer = new float[16]; + private float[] normalModelBuffer = new float[9]; + + private Matrix4f modelMatrix = (Matrix4f) new Matrix4f().setZero(); + private Matrix4f projectionMatrix = (Matrix4f) new Matrix4f().setZero(); + private Matrix4f textureMatrix = (Matrix4f) new Matrix4f().setZero(); + private Matrix3f normalModelMatrix = (Matrix3f) new Matrix3f().setZero(); + private Matrix4f inverseModelMatrix = (Matrix4f) new Matrix4f().setZero(); + private Vector4f light0Pos = new Vector4f(); + private Vector4f light1Pos = new Vector4f(); + + private boolean bound = false; + + public void setModelMatrix(Matrix4f mat) { + if(!mat.equals(modelMatrix)) { + modelMatrix.load(mat).store(modelBuffer); + _wglUniformMat4fv(u_matrix_m, modelBuffer); + if(enable_TEX_GEN_STRQ) { + inverseModelMatrix.load(mat).invert(); + inverseModelMatrix.store(modelBuffer); + _wglUniformMat4fv(u_matrix_inverse_m, modelBuffer); + } + } + } + public void setModelNormalMatrix(Matrix3f mat) { + if(!mat.equals(normalModelMatrix)) { + normalModelMatrix.load(mat).store(normalModelBuffer); + _wglUniformMat3fv(u_matrix_mn, normalModelBuffer); + } + } + public void setProjectionMatrix(Matrix4f mat) { + if(!mat.equals(projectionMatrix)) { + projectionMatrix.load(mat).store(projectionBuffer); + _wglUniformMat4fv(u_matrix_p, projectionBuffer); + } + } + public void setTextureMatrix(Matrix4f mat) { + if(!mat.equals(textureMatrix)) { + textureMatrix.load(mat).store(textureBuffer); + _wglUniformMat4fv(u_matrix_t, textureBuffer); + } + } + public void setLightPositions(Vector4f pos0, Vector4f pos1) { + if(!pos0.equals(light0Pos) || !pos1.equals(light1Pos)) { + light0Pos.set(pos0); + light1Pos.set(pos1); + _wglUniform3f(u_light0Pos, light0Pos.x, light0Pos.y, light0Pos.z); + _wglUniform3f(u_light1Pos, light1Pos.x, light1Pos.y, light1Pos.z); + } + } + + private int fogMode = 0; + public void setFogMode(int mode) { + if(fogMode != mode) { + fogMode = mode; + _wglUniform1i(u_fogMode, mode % 2); + _wglUniform1f(u_fogPremultiply, mode / 2); + } + } + + private float fogColorR = 0.0f; + private float fogColorG = 0.0f; + private float fogColorB = 0.0f; + private float fogColorA = 0.0f; + public void setFogColor(float r, float g, float b, float a) { + if(fogColorR != r || fogColorG != g || fogColorB != b || fogColorA != a) { + fogColorR = r; + fogColorG = g; + fogColorB = b; + fogColorA = a; + _wglUniform4f(u_fogColor, fogColorR, fogColorG, fogColorB, fogColorA); + } + } + + private float fogStart = 0.0f; + private float fogEnd = 0.0f; + public void setFogStartEnd(float s, float e) { + if(fogStart != s || fogEnd != e) { + fogStart = s; + fogEnd = e; + _wglUniform1f(u_fogStart, fogStart); + _wglUniform1f(u_fogEnd, fogEnd); + } + } + + private float fogDensity = 0.0f; + public void setFogDensity(float d) { + if(fogDensity != d) { + fogDensity = d; + _wglUniform1f(u_fogDensity, fogDensity); + } + } + + private float alphaTestValue = 0.0f; + public void setAlphaTest(float limit) { + if(alphaTestValue != limit) { + alphaTestValue = limit; + _wglUniform1f(u_alphaTestF, alphaTestValue); + } + } + + private float tex0x = 0.0f; + private float tex0y = 0.0f; + public void setTex0Coords(float x, float y) { + if(tex0x != x || tex0y != y) { + tex0x = x; + tex0y = y; + _wglUniform2f(u_texCoordV0, tex0x, tex0y); + } + } + + private float tex1x = 0.0f; + private float tex1y = 0.0f; + public void setTex1Coords(float x, float y) { + if(tex1x != x || tex1y != y) { + tex1x = x; + tex1y = y; + _wglUniform2f(u_texCoordV1, tex1x, tex1y); + } + } + + public void setTexGenS(int plane, float x, float y, float z, float w) { + _wglUniform1i(u_textureGenS_M, plane); + _wglUniform4f(u_textureGenS_V, x, y, z, w); + } + + public void setTexGenT(int plane, float x, float y, float z, float w) { + _wglUniform1i(u_textureGenT_M, plane); + _wglUniform4f(u_textureGenT_V, x, y, z, w); + } + + public void setTexGenR(int plane, float x, float y, float z, float w) { + _wglUniform1i(u_textureGenR_M, plane); + _wglUniform4f(u_textureGenR_V, x, y, z, w); + } + + public void setTexGenQ(int plane, float x, float y, float z, float w) { + _wglUniform1i(u_textureGenQ_M, plane); + _wglUniform4f(u_textureGenQ_V, x, y, z, w); + } + + private float colorUniformR = 0.0f; + private float colorUniformG = 0.0f; + private float colorUniformB = 0.0f; + private float colorUniformA = 0.0f; + public void setColor(float r, float g, float b, float a) { + if(colorUniformR != r || colorUniformG != g || colorUniformB != b || colorUniformA != a) { + colorUniformR = r; + colorUniformG = g; + colorUniformB = b; + colorUniformA = a; + _wglUniform4f(u_colorUniform, colorUniformR, colorUniformG, colorUniformB, colorUniformA); + } + } + + private float normalUniformX = 0.0f; + private float normalUniformY = 0.0f; + private float normalUniformZ = 0.0f; + public void setNormal(float x, float y, float z) { + if(normalUniformX != x || normalUniformY != y || normalUniformZ != z) { + normalUniformX = x; + normalUniformY = y; + normalUniformZ = z; + _wglUniform3f(u_normalUniform, normalUniformX, normalUniformY, normalUniformZ); + } + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/GLObjectMap.java b/src/main/java/net/lax1dude/eaglercraft/glemu/GLObjectMap.java new file mode 100644 index 0000000..6485146 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/GLObjectMap.java @@ -0,0 +1,53 @@ +package net.lax1dude.eaglercraft.glemu; + +public class GLObjectMap { + private Object[] values; + private int size; + private int insertIndex; + public int allocatedObjects; + + public GLObjectMap(int initialSize) { + this.values = new Object[initialSize]; + this.size = initialSize; + this.insertIndex = 0; + this.allocatedObjects = 0; + } + + public int register(T obj) { + int start = insertIndex; + do { + ++insertIndex; + if(insertIndex >= size) { + insertIndex = 0; + } + if(insertIndex == start) { + resize(); + return register(obj); + } + }while(values[insertIndex] != null); + values[insertIndex] = obj; + ++allocatedObjects; + return insertIndex; + } + + public T free(int obj) { + if(obj >= size || obj < 0) return null; + Object ret = values[obj]; + values[obj] = null; + --allocatedObjects; + return (T) ret; + } + + public T get(int obj) { + if(obj >= size || obj < 0) return null; + return (T) values[obj]; + } + + private void resize() { + int oldSize = size; + size += size / 2; + Object[] oldValues = values; + values = new Object[size]; + System.arraycopy(oldValues, 0, values, 0, oldSize); + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix.java new file mode 100644 index 0000000..d27abab --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Base class for matrices. When a matrix is constructed it will be the identity + * matrix unless otherwise stated. + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ +public abstract class Matrix implements Serializable { + + /** + * Constructor for Matrix. + */ + protected Matrix() { + super(); + } + + /** + * Set this matrix to be the identity matrix. + * @return this + */ + public abstract Matrix setIdentity(); + + + /** + * Invert this matrix + * @return this + */ + public abstract Matrix invert(); + + + /** + * Load from a float buffer. The buffer stores the matrix in column major + * (OpenGL) order. + * + * @param buf A float buffer to read from + * @return this + */ + public abstract Matrix load(FloatBuffer buf); + + + /** + * Load from a float buffer. The buffer stores the matrix in row major + * (mathematical) order. + * + * @param buf A float buffer to read from + * @return this + */ + public abstract Matrix loadTranspose(FloatBuffer buf); + + + /** + * Negate this matrix + * @return this + */ + public abstract Matrix negate(); + + + /** + * Store this matrix in a float buffer. The matrix is stored in column + * major (openGL) order. + * @param buf The buffer to store this matrix in + * @return this + */ + public abstract Matrix store(FloatBuffer buf); + + + /** + * Store this matrix in a float buffer. The matrix is stored in row + * major (maths) order. + * @param buf The buffer to store this matrix in + * @return this + */ + public abstract Matrix storeTranspose(FloatBuffer buf); + + + /** + * Transpose this matrix + * @return this + */ + public abstract Matrix transpose(); + + + /** + * Set this matrix to 0. + * @return this + */ + public abstract Matrix setZero(); + + + /** + * @return the determinant of the matrix + */ + public abstract float determinant(); + + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix2f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix2f.java new file mode 100644 index 0000000..10598b9 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix2f.java @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Holds a 2x2 matrix + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ + +public class Matrix2f extends Matrix implements Serializable { + + private static final long serialVersionUID = 1L; + + public float m00, m01, m10, m11; + + /** + * Constructor for Matrix2f. The matrix is initialised to the identity. + */ + public Matrix2f() { + setIdentity(); + } + + /** + * Constructor + */ + public Matrix2f(Matrix2f src) { + load(src); + } + + /** + * Load from another matrix + * @param src The source matrix + * @return this + */ + public Matrix2f load(Matrix2f src) { + return load(src, this); + } + + /** + * Copy the source matrix to the destination matrix. + * @param src The source matrix + * @param dest The destination matrix, or null if a new one should be created. + * @return The copied matrix + */ + public static Matrix2f load(Matrix2f src, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + dest.m00 = src.m00; + dest.m01 = src.m01; + dest.m10 = src.m10; + dest.m11 = src.m11; + + return dest; + } + + /** + * Load from a float buffer. The buffer stores the matrix in column major + * (OpenGL) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix load(FloatBuffer buf) { + + m00 = buf.get(); + m01 = buf.get(); + m10 = buf.get(); + m11 = buf.get(); + + return this; + } + + /** + * Load from a float buffer. The buffer stores the matrix in row major + * (mathematical) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix loadTranspose(FloatBuffer buf) { + + m00 = buf.get(); + m10 = buf.get(); + m01 = buf.get(); + m11 = buf.get(); + + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in column + * major (openGL) order. + * @param buf The buffer to store this matrix in + */ + public Matrix store(FloatBuffer buf) { + buf.put(m00); + buf.put(m01); + buf.put(m10); + buf.put(m11); + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in row + * major (maths) order. + * @param buf The buffer to store this matrix in + */ + public Matrix storeTranspose(FloatBuffer buf) { + buf.put(m00); + buf.put(m10); + buf.put(m01); + buf.put(m11); + return this; + } + + + + /** + * Add two matrices together and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix2f add(Matrix2f left, Matrix2f right, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + dest.m00 = left.m00 + right.m00; + dest.m01 = left.m01 + right.m01; + dest.m10 = left.m10 + right.m10; + dest.m11 = left.m11 + right.m11; + + return dest; + } + + /** + * Subtract the right matrix from the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix2f sub(Matrix2f left, Matrix2f right, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + dest.m00 = left.m00 - right.m00; + dest.m01 = left.m01 - right.m01; + dest.m10 = left.m10 - right.m10; + dest.m11 = left.m11 - right.m11; + + return dest; + } + + /** + * Multiply the right matrix by the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix2f mul(Matrix2f left, Matrix2f right, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + float m00 = left.m00 * right.m00 + left.m10 * right.m01; + float m01 = left.m01 * right.m00 + left.m11 * right.m01; + float m10 = left.m00 * right.m10 + left.m10 * right.m11; + float m11 = left.m01 * right.m10 + left.m11 * right.m11; + + dest.m00 = m00; + dest.m01 = m01; + dest.m10 = m10; + dest.m11 = m11; + + return dest; + } + + /** + * Transform a Vector by a matrix and return the result in a destination + * vector. + * @param left The left matrix + * @param right The right vector + * @param dest The destination vector, or null if a new one is to be created + * @return the destination vector + */ + public static Vector2f transform(Matrix2f left, Vector2f right, Vector2f dest) { + if (dest == null) + dest = new Vector2f(); + + float x = left.m00 * right.x + left.m10 * right.y; + float y = left.m01 * right.x + left.m11 * right.y; + + dest.x = x; + dest.y = y; + + return dest; + } + + /** + * Transpose this matrix + * @return this + */ + public Matrix transpose() { + return transpose(this); + } + + /** + * Transpose this matrix and place the result in another matrix. + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public Matrix2f transpose(Matrix2f dest) { + return transpose(this, dest); + } + + /** + * Transpose the source matrix and place the result in the destination matrix. + * @param src The source matrix or null if a new matrix is to be created + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public static Matrix2f transpose(Matrix2f src, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + float m01 = src.m10; + float m10 = src.m01; + + dest.m01 = m01; + dest.m10 = m10; + + return dest; + } + + /** + * Invert this matrix + * @return this if successful, null otherwise + */ + public Matrix invert() { + return invert(this, this); + } + + /** + * Invert the source matrix and place the result in the destination matrix. + * @param src The source matrix to be inverted + * @param dest The destination matrix or null if a new matrix is to be created + * @return The inverted matrix, or null if source can't be reverted. + */ + public static Matrix2f invert(Matrix2f src, Matrix2f dest) { + /* + *inv(A) = 1/det(A) * adj(A); + */ + + float determinant = src.determinant(); + if (determinant != 0) { + if (dest == null) + dest = new Matrix2f(); + float determinant_inv = 1f/determinant; + float t00 = src.m11*determinant_inv; + float t01 = -src.m01*determinant_inv; + float t11 = src.m00*determinant_inv; + float t10 = -src.m10*determinant_inv; + + dest.m00 = t00; + dest.m01 = t01; + dest.m10 = t10; + dest.m11 = t11; + return dest; + } else + return null; + } + + /** + * Returns a string representation of this matrix + */ + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(m00).append(' ').append(m10).append(' ').append('\n'); + buf.append(m01).append(' ').append(m11).append(' ').append('\n'); + return buf.toString(); + } + + /** + * Negate this matrix + * @return this + */ + public Matrix negate() { + return negate(this); + } + + /** + * Negate this matrix and stash the result in another matrix. + * @param dest The destination matrix, or null if a new matrix is to be created + * @return the negated matrix + */ + public Matrix2f negate(Matrix2f dest) { + return negate(this, dest); + } + + /** + * Negate the source matrix and stash the result in the destination matrix. + * @param src The source matrix to be negated + * @param dest The destination matrix, or null if a new matrix is to be created + * @return the negated matrix + */ + public static Matrix2f negate(Matrix2f src, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + dest.m00 = -src.m00; + dest.m01 = -src.m01; + dest.m10 = -src.m10; + dest.m11 = -src.m11; + + return dest; + } + + /** + * Set this matrix to be the identity matrix. + * @return this + */ + public Matrix setIdentity() { + return setIdentity(this); + } + + /** + * Set the source matrix to be the identity matrix. + * @param src The matrix to set to the identity. + * @return The source matrix + */ + public static Matrix2f setIdentity(Matrix2f src) { + src.m00 = 1.0f; + src.m01 = 0.0f; + src.m10 = 0.0f; + src.m11 = 1.0f; + return src; + } + + /** + * Set this matrix to 0. + * @return this + */ + public Matrix setZero() { + return setZero(this); + } + + public static Matrix2f setZero(Matrix2f src) { + src.m00 = 0.0f; + src.m01 = 0.0f; + src.m10 = 0.0f; + src.m11 = 0.0f; + return src; + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Matrix#determinant() + */ + public float determinant() { + return m00 * m11 - m01*m10; + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix3f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix3f.java new file mode 100644 index 0000000..d743b1d --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix3f.java @@ -0,0 +1,539 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Holds a 3x3 matrix. + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ + +public class Matrix3f extends Matrix implements Serializable { + + private static final long serialVersionUID = 1L; + + public float m00, + m01, + m02, + m10, + m11, + m12, + m20, + m21, + m22; + + /** + * Constructor for Matrix3f. Matrix is initialised to the identity. + */ + public Matrix3f() { + super(); + setIdentity(); + } + + /** + * Load from another matrix + * @param src The source matrix + * @return this + */ + public Matrix3f load(Matrix3f src) { + return load(src, this); + } + + /** + * Copy source matrix to destination matrix + * @param src The source matrix + * @param dest The destination matrix, or null of a new matrix is to be created + * @return The copied matrix + */ + public static Matrix3f load(Matrix3f src, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + + dest.m00 = src.m00; + dest.m10 = src.m10; + dest.m20 = src.m20; + dest.m01 = src.m01; + dest.m11 = src.m11; + dest.m21 = src.m21; + dest.m02 = src.m02; + dest.m12 = src.m12; + dest.m22 = src.m22; + + return dest; + } + + /** + * Load from a float buffer. The buffer stores the matrix in column major + * (OpenGL) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix load(FloatBuffer buf) { + + m00 = buf.get(); + m01 = buf.get(); + m02 = buf.get(); + m10 = buf.get(); + m11 = buf.get(); + m12 = buf.get(); + m20 = buf.get(); + m21 = buf.get(); + m22 = buf.get(); + + return this; + } + + /** + * Load from a float buffer. The buffer stores the matrix in row major + * (maths) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix loadTranspose(FloatBuffer buf) { + + m00 = buf.get(); + m10 = buf.get(); + m20 = buf.get(); + m01 = buf.get(); + m11 = buf.get(); + m21 = buf.get(); + m02 = buf.get(); + m12 = buf.get(); + m22 = buf.get(); + + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in column + * major (openGL) order. + * @param buf The buffer to store this matrix in + */ + public Matrix store(FloatBuffer buf) { + buf.put(m00); + buf.put(m01); + buf.put(m02); + buf.put(m10); + buf.put(m11); + buf.put(m12); + buf.put(m20); + buf.put(m21); + buf.put(m22); + return this; + } + + public Matrix store(float[] buf) { + buf[0] = m00; + buf[1] = m01; + buf[2] = m02; + buf[3] = m10; + buf[4] = m11; + buf[5] = m12; + buf[6] = m20; + buf[7] = m21; + buf[8] = m22; + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in row + * major (maths) order. + * @param buf The buffer to store this matrix in + */ + public Matrix storeTranspose(FloatBuffer buf) { + buf.put(m00); + buf.put(m10); + buf.put(m20); + buf.put(m01); + buf.put(m11); + buf.put(m21); + buf.put(m02); + buf.put(m12); + buf.put(m22); + return this; + } + + /** + * Add two matrices together and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix3f add(Matrix3f left, Matrix3f right, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + + dest.m00 = left.m00 + right.m00; + dest.m01 = left.m01 + right.m01; + dest.m02 = left.m02 + right.m02; + dest.m10 = left.m10 + right.m10; + dest.m11 = left.m11 + right.m11; + dest.m12 = left.m12 + right.m12; + dest.m20 = left.m20 + right.m20; + dest.m21 = left.m21 + right.m21; + dest.m22 = left.m22 + right.m22; + + return dest; + } + + /** + * Subtract the right matrix from the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix3f sub(Matrix3f left, Matrix3f right, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + + dest.m00 = left.m00 - right.m00; + dest.m01 = left.m01 - right.m01; + dest.m02 = left.m02 - right.m02; + dest.m10 = left.m10 - right.m10; + dest.m11 = left.m11 - right.m11; + dest.m12 = left.m12 - right.m12; + dest.m20 = left.m20 - right.m20; + dest.m21 = left.m21 - right.m21; + dest.m22 = left.m22 - right.m22; + + return dest; + } + + /** + * Multiply the right matrix by the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix3f mul(Matrix3f left, Matrix3f right, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + + float m00 = + left.m00 * right.m00 + left.m10 * right.m01 + left.m20 * right.m02; + float m01 = + left.m01 * right.m00 + left.m11 * right.m01 + left.m21 * right.m02; + float m02 = + left.m02 * right.m00 + left.m12 * right.m01 + left.m22 * right.m02; + float m10 = + left.m00 * right.m10 + left.m10 * right.m11 + left.m20 * right.m12; + float m11 = + left.m01 * right.m10 + left.m11 * right.m11 + left.m21 * right.m12; + float m12 = + left.m02 * right.m10 + left.m12 * right.m11 + left.m22 * right.m12; + float m20 = + left.m00 * right.m20 + left.m10 * right.m21 + left.m20 * right.m22; + float m21 = + left.m01 * right.m20 + left.m11 * right.m21 + left.m21 * right.m22; + float m22 = + left.m02 * right.m20 + left.m12 * right.m21 + left.m22 * right.m22; + + dest.m00 = m00; + dest.m01 = m01; + dest.m02 = m02; + dest.m10 = m10; + dest.m11 = m11; + dest.m12 = m12; + dest.m20 = m20; + dest.m21 = m21; + dest.m22 = m22; + + return dest; + } + + /** + * Transform a Vector by a matrix and return the result in a destination + * vector. + * @param left The left matrix + * @param right The right vector + * @param dest The destination vector, or null if a new one is to be created + * @return the destination vector + */ + public static Vector3f transform(Matrix3f left, Vector3f right, Vector3f dest) { + if (dest == null) + dest = new Vector3f(); + + float x = left.m00 * right.x + left.m10 * right.y + left.m20 * right.z; + float y = left.m01 * right.x + left.m11 * right.y + left.m21 * right.z; + float z = left.m02 * right.x + left.m12 * right.y + left.m22 * right.z; + + dest.x = x; + dest.y = y; + dest.z = z; + + return dest; + } + + /** + * Transpose this matrix + * @return this + */ + public Matrix transpose() { + return transpose(this, this); + } + + /** + * Transpose this matrix and place the result in another matrix + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public Matrix3f transpose(Matrix3f dest) { + return transpose(this, dest); + } + + /** + * Transpose the source matrix and place the result into the destination matrix + * @param src The source matrix to be transposed + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public static Matrix3f transpose(Matrix3f src, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + float m00 = src.m00; + float m01 = src.m10; + float m02 = src.m20; + float m10 = src.m01; + float m11 = src.m11; + float m12 = src.m21; + float m20 = src.m02; + float m21 = src.m12; + float m22 = src.m22; + + dest.m00 = m00; + dest.m01 = m01; + dest.m02 = m02; + dest.m10 = m10; + dest.m11 = m11; + dest.m12 = m12; + dest.m20 = m20; + dest.m21 = m21; + dest.m22 = m22; + return dest; + } + + /** + * @return the determinant of the matrix + */ + public float determinant() { + float f = + m00 * (m11 * m22 - m12 * m21) + + m01 * (m12 * m20 - m10 * m22) + + m02 * (m10 * m21 - m11 * m20); + return f; + } + + /** + * Returns a string representation of this matrix + */ + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(m00).append(' ').append(m10).append(' ').append(m20).append(' ').append('\n'); + buf.append(m01).append(' ').append(m11).append(' ').append(m21).append(' ').append('\n'); + buf.append(m02).append(' ').append(m12).append(' ').append(m22).append(' ').append('\n'); + return buf.toString(); + } + + /** + * Invert this matrix + * @return this if successful, null otherwise + */ + public Matrix invert() { + return invert(this, this); + } + + /** + * Invert the source matrix and put the result into the destination matrix + * @param src The source matrix to be inverted + * @param dest The destination matrix, or null if a new one is to be created + * @return The inverted matrix if successful, null otherwise + */ + public static Matrix3f invert(Matrix3f src, Matrix3f dest) { + float determinant = src.determinant(); + + if (determinant != 0) { + if (dest == null) + dest = new Matrix3f(); + /* do it the ordinary way + * + * inv(A) = 1/det(A) * adj(T), where adj(T) = transpose(Conjugate Matrix) + * + * m00 m01 m02 + * m10 m11 m12 + * m20 m21 m22 + */ + float determinant_inv = 1f/determinant; + + // get the conjugate matrix + float t00 = src.m11 * src.m22 - src.m12* src.m21; + float t01 = - src.m10 * src.m22 + src.m12 * src.m20; + float t02 = src.m10 * src.m21 - src.m11 * src.m20; + float t10 = - src.m01 * src.m22 + src.m02 * src.m21; + float t11 = src.m00 * src.m22 - src.m02 * src.m20; + float t12 = - src.m00 * src.m21 + src.m01 * src.m20; + float t20 = src.m01 * src.m12 - src.m02 * src.m11; + float t21 = -src.m00 * src.m12 + src.m02 * src.m10; + float t22 = src.m00 * src.m11 - src.m01 * src.m10; + + dest.m00 = t00*determinant_inv; + dest.m11 = t11*determinant_inv; + dest.m22 = t22*determinant_inv; + dest.m01 = t10*determinant_inv; + dest.m10 = t01*determinant_inv; + dest.m20 = t02*determinant_inv; + dest.m02 = t20*determinant_inv; + dest.m12 = t21*determinant_inv; + dest.m21 = t12*determinant_inv; + return dest; + } else + return null; + } + + + /** + * Negate this matrix + * @return this + */ + public Matrix negate() { + return negate(this); + } + + /** + * Negate this matrix and place the result in a destination matrix. + * @param dest The destination matrix, or null if a new matrix is to be created + * @return the negated matrix + */ + public Matrix3f negate(Matrix3f dest) { + return negate(this, dest); + } + + /** + * Negate the source matrix and place the result in the destination matrix. + * @param src The source matrix + * @param dest The destination matrix, or null if a new matrix is to be created + * @return the negated matrix + */ + public static Matrix3f negate(Matrix3f src, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + + dest.m00 = -src.m00; + dest.m01 = -src.m02; + dest.m02 = -src.m01; + dest.m10 = -src.m10; + dest.m11 = -src.m12; + dest.m12 = -src.m11; + dest.m20 = -src.m20; + dest.m21 = -src.m22; + dest.m22 = -src.m21; + return dest; + } + + /** + * Set this matrix to be the identity matrix. + * @return this + */ + public Matrix setIdentity() { + return setIdentity(this); + } + + /** + * Set the matrix to be the identity matrix. + * @param m The matrix to be set to the identity + * @return m + */ + public static Matrix3f setIdentity(Matrix3f m) { + m.m00 = 1.0f; + m.m01 = 0.0f; + m.m02 = 0.0f; + m.m10 = 0.0f; + m.m11 = 1.0f; + m.m12 = 0.0f; + m.m20 = 0.0f; + m.m21 = 0.0f; + m.m22 = 1.0f; + return m; + } + + /** + * Set this matrix to 0. + * @return this + */ + public Matrix setZero() { + return setZero(this); + } + + /** + * Set the matrix matrix to 0. + * @param m The matrix to be set to 0 + * @return m + */ + public static Matrix3f setZero(Matrix3f m) { + m.m00 = 0.0f; + m.m01 = 0.0f; + m.m02 = 0.0f; + m.m10 = 0.0f; + m.m11 = 0.0f; + m.m12 = 0.0f; + m.m20 = 0.0f; + m.m21 = 0.0f; + m.m22 = 0.0f; + return m; + } + + public boolean equals(Object m) { + return (m instanceof Matrix3f) && equal(this, (Matrix3f)m); + } + + public static boolean equal(Matrix3f a, Matrix3f b) { + return a.m00 == b.m00 && + a.m01 == b.m01 && + a.m02 == b.m02 && + a.m10 == b.m10 && + a.m11 == b.m11 && + a.m12 == b.m12 && + a.m20 == b.m20 && + a.m21 == b.m21 && + a.m22 == b.m22; + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix4f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix4f.java new file mode 100644 index 0000000..d7bd730 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix4f.java @@ -0,0 +1,892 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * Holds a 4x4 float matrix. + * + * @author foo + */ +public class Matrix4f extends Matrix implements Serializable { + private static final long serialVersionUID = 1L; + + public float m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33; + + /** + * Construct a new matrix, initialized to the identity. + */ + public Matrix4f() { + super(); + setIdentity(); + } + + public Matrix4f(final Matrix4f src) { + super(); + load(src); + } + + /** + * Returns a string representation of this matrix + */ + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(m00).append(' ').append(m10).append(' ').append(m20).append(' ').append(m30).append('\n'); + buf.append(m01).append(' ').append(m11).append(' ').append(m21).append(' ').append(m31).append('\n'); + buf.append(m02).append(' ').append(m12).append(' ').append(m22).append(' ').append(m32).append('\n'); + buf.append(m03).append(' ').append(m13).append(' ').append(m23).append(' ').append(m33).append('\n'); + return buf.toString(); + } + + /** + * Set this matrix to be the identity matrix. + * @return this + */ + public Matrix setIdentity() { + return setIdentity(this); + } + + /** + * Set the given matrix to be the identity matrix. + * @param m The matrix to set to the identity + * @return m + */ + public static Matrix4f setIdentity(Matrix4f m) { + m.m00 = 1.0f; + m.m01 = 0.0f; + m.m02 = 0.0f; + m.m03 = 0.0f; + m.m10 = 0.0f; + m.m11 = 1.0f; + m.m12 = 0.0f; + m.m13 = 0.0f; + m.m20 = 0.0f; + m.m21 = 0.0f; + m.m22 = 1.0f; + m.m23 = 0.0f; + m.m30 = 0.0f; + m.m31 = 0.0f; + m.m32 = 0.0f; + m.m33 = 1.0f; + + return m; + } + + /** + * Set this matrix to 0. + * @return this + */ + public Matrix setZero() { + return setZero(this); + } + + /** + * Set the given matrix to 0. + * @param m The matrix to set to 0 + * @return m + */ + public static Matrix4f setZero(Matrix4f m) { + m.m00 = 0.0f; + m.m01 = 0.0f; + m.m02 = 0.0f; + m.m03 = 0.0f; + m.m10 = 0.0f; + m.m11 = 0.0f; + m.m12 = 0.0f; + m.m13 = 0.0f; + m.m20 = 0.0f; + m.m21 = 0.0f; + m.m22 = 0.0f; + m.m23 = 0.0f; + m.m30 = 0.0f; + m.m31 = 0.0f; + m.m32 = 0.0f; + m.m33 = 0.0f; + + return m; + } + + /** + * Load from another matrix4f + * @param src The source matrix + * @return this + */ + public Matrix4f load(Matrix4f src) { + return load(src, this); + } + + /** + * Copy the source matrix to the destination matrix + * @param src The source matrix + * @param dest The destination matrix, or null of a new one is to be created + * @return The copied matrix + */ + public static Matrix4f load(Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + dest.m00 = src.m00; + dest.m01 = src.m01; + dest.m02 = src.m02; + dest.m03 = src.m03; + dest.m10 = src.m10; + dest.m11 = src.m11; + dest.m12 = src.m12; + dest.m13 = src.m13; + dest.m20 = src.m20; + dest.m21 = src.m21; + dest.m22 = src.m22; + dest.m23 = src.m23; + dest.m30 = src.m30; + dest.m31 = src.m31; + dest.m32 = src.m32; + dest.m33 = src.m33; + + return dest; + } + + /** + * Load from a float buffer. The buffer stores the matrix in column major + * (OpenGL) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix load(FloatBuffer buf) { + + m00 = buf.get(); + m01 = buf.get(); + m02 = buf.get(); + m03 = buf.get(); + m10 = buf.get(); + m11 = buf.get(); + m12 = buf.get(); + m13 = buf.get(); + m20 = buf.get(); + m21 = buf.get(); + m22 = buf.get(); + m23 = buf.get(); + m30 = buf.get(); + m31 = buf.get(); + m32 = buf.get(); + m33 = buf.get(); + + return this; + } + + /** + * Load from a float buffer. The buffer stores the matrix in row major + * (maths) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix loadTranspose(FloatBuffer buf) { + + m00 = buf.get(); + m10 = buf.get(); + m20 = buf.get(); + m30 = buf.get(); + m01 = buf.get(); + m11 = buf.get(); + m21 = buf.get(); + m31 = buf.get(); + m02 = buf.get(); + m12 = buf.get(); + m22 = buf.get(); + m32 = buf.get(); + m03 = buf.get(); + m13 = buf.get(); + m23 = buf.get(); + m33 = buf.get(); + + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in column + * major (openGL) order. + * @param buf The buffer to store this matrix in + */ + public Matrix store(FloatBuffer buf) { + buf.put(m00); + buf.put(m01); + buf.put(m02); + buf.put(m03); + buf.put(m10); + buf.put(m11); + buf.put(m12); + buf.put(m13); + buf.put(m20); + buf.put(m21); + buf.put(m22); + buf.put(m23); + buf.put(m30); + buf.put(m31); + buf.put(m32); + buf.put(m33); + return this; + } + + public Matrix store(float[] buf) { + buf[0] = m00; + buf[1] = m01; + buf[2] = m02; + buf[3] = m03; + buf[4] = m10; + buf[5] = m11; + buf[6] = m12; + buf[7] = m13; + buf[8] = m20; + buf[9] = m21; + buf[10] = m22; + buf[11] = m23; + buf[12] = m30; + buf[13] = m31; + buf[14] = m32; + buf[15] = m33; + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in row + * major (maths) order. + * @param buf The buffer to store this matrix in + */ + public Matrix storeTranspose(FloatBuffer buf) { + buf.put(m00); + buf.put(m10); + buf.put(m20); + buf.put(m30); + buf.put(m01); + buf.put(m11); + buf.put(m21); + buf.put(m31); + buf.put(m02); + buf.put(m12); + buf.put(m22); + buf.put(m32); + buf.put(m03); + buf.put(m13); + buf.put(m23); + buf.put(m33); + return this; + } + + /** + * Store the rotation portion of this matrix in a float buffer. The matrix is stored in column + * major (openGL) order. + * @param buf The buffer to store this matrix in + */ + public Matrix store3f(FloatBuffer buf) { + buf.put(m00); + buf.put(m01); + buf.put(m02); + buf.put(m10); + buf.put(m11); + buf.put(m12); + buf.put(m20); + buf.put(m21); + buf.put(m22); + return this; + } + + /** + * Add two matrices together and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix4f add(Matrix4f left, Matrix4f right, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + dest.m00 = left.m00 + right.m00; + dest.m01 = left.m01 + right.m01; + dest.m02 = left.m02 + right.m02; + dest.m03 = left.m03 + right.m03; + dest.m10 = left.m10 + right.m10; + dest.m11 = left.m11 + right.m11; + dest.m12 = left.m12 + right.m12; + dest.m13 = left.m13 + right.m13; + dest.m20 = left.m20 + right.m20; + dest.m21 = left.m21 + right.m21; + dest.m22 = left.m22 + right.m22; + dest.m23 = left.m23 + right.m23; + dest.m30 = left.m30 + right.m30; + dest.m31 = left.m31 + right.m31; + dest.m32 = left.m32 + right.m32; + dest.m33 = left.m33 + right.m33; + + return dest; + } + + /** + * Subtract the right matrix from the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix4f sub(Matrix4f left, Matrix4f right, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + dest.m00 = left.m00 - right.m00; + dest.m01 = left.m01 - right.m01; + dest.m02 = left.m02 - right.m02; + dest.m03 = left.m03 - right.m03; + dest.m10 = left.m10 - right.m10; + dest.m11 = left.m11 - right.m11; + dest.m12 = left.m12 - right.m12; + dest.m13 = left.m13 - right.m13; + dest.m20 = left.m20 - right.m20; + dest.m21 = left.m21 - right.m21; + dest.m22 = left.m22 - right.m22; + dest.m23 = left.m23 - right.m23; + dest.m30 = left.m30 - right.m30; + dest.m31 = left.m31 - right.m31; + dest.m32 = left.m32 - right.m32; + dest.m33 = left.m33 - right.m33; + + return dest; + } + + /** + * Multiply the right matrix by the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix4f mul(Matrix4f left, Matrix4f right, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + float m00 = left.m00 * right.m00 + left.m10 * right.m01 + left.m20 * right.m02 + left.m30 * right.m03; + float m01 = left.m01 * right.m00 + left.m11 * right.m01 + left.m21 * right.m02 + left.m31 * right.m03; + float m02 = left.m02 * right.m00 + left.m12 * right.m01 + left.m22 * right.m02 + left.m32 * right.m03; + float m03 = left.m03 * right.m00 + left.m13 * right.m01 + left.m23 * right.m02 + left.m33 * right.m03; + float m10 = left.m00 * right.m10 + left.m10 * right.m11 + left.m20 * right.m12 + left.m30 * right.m13; + float m11 = left.m01 * right.m10 + left.m11 * right.m11 + left.m21 * right.m12 + left.m31 * right.m13; + float m12 = left.m02 * right.m10 + left.m12 * right.m11 + left.m22 * right.m12 + left.m32 * right.m13; + float m13 = left.m03 * right.m10 + left.m13 * right.m11 + left.m23 * right.m12 + left.m33 * right.m13; + float m20 = left.m00 * right.m20 + left.m10 * right.m21 + left.m20 * right.m22 + left.m30 * right.m23; + float m21 = left.m01 * right.m20 + left.m11 * right.m21 + left.m21 * right.m22 + left.m31 * right.m23; + float m22 = left.m02 * right.m20 + left.m12 * right.m21 + left.m22 * right.m22 + left.m32 * right.m23; + float m23 = left.m03 * right.m20 + left.m13 * right.m21 + left.m23 * right.m22 + left.m33 * right.m23; + float m30 = left.m00 * right.m30 + left.m10 * right.m31 + left.m20 * right.m32 + left.m30 * right.m33; + float m31 = left.m01 * right.m30 + left.m11 * right.m31 + left.m21 * right.m32 + left.m31 * right.m33; + float m32 = left.m02 * right.m30 + left.m12 * right.m31 + left.m22 * right.m32 + left.m32 * right.m33; + float m33 = left.m03 * right.m30 + left.m13 * right.m31 + left.m23 * right.m32 + left.m33 * right.m33; + + dest.m00 = m00; + dest.m01 = m01; + dest.m02 = m02; + dest.m03 = m03; + dest.m10 = m10; + dest.m11 = m11; + dest.m12 = m12; + dest.m13 = m13; + dest.m20 = m20; + dest.m21 = m21; + dest.m22 = m22; + dest.m23 = m23; + dest.m30 = m30; + dest.m31 = m31; + dest.m32 = m32; + dest.m33 = m33; + + return dest; + } + + /** + * Transform a Vector by a matrix and return the result in a destination + * vector. + * @param left The left matrix + * @param right The right vector + * @param dest The destination vector, or null if a new one is to be created + * @return the destination vector + */ + public static Vector4f transform(Matrix4f left, Vector4f right, Vector4f dest) { + if (dest == null) + dest = new Vector4f(); + + float x = left.m00 * right.x + left.m10 * right.y + left.m20 * right.z + left.m30 * right.w; + float y = left.m01 * right.x + left.m11 * right.y + left.m21 * right.z + left.m31 * right.w; + float z = left.m02 * right.x + left.m12 * right.y + left.m22 * right.z + left.m32 * right.w; + float w = left.m03 * right.x + left.m13 * right.y + left.m23 * right.z + left.m33 * right.w; + + dest.x = x; + dest.y = y; + dest.z = z; + dest.w = w; + + return dest; + } + + /** + * Transpose this matrix + * @return this + */ + public Matrix transpose() { + return transpose(this); + } + + /** + * Translate this matrix + * @param vec The vector to translate by + * @return this + */ + public Matrix4f translate(Vector2f vec) { + return translate(vec, this); + } + + /** + * Translate this matrix + * @param vec The vector to translate by + * @return this + */ + public Matrix4f translate(Vector3f vec) { + return translate(vec, this); + } + + /** + * Scales this matrix + * @param vec The vector to scale by + * @return this + */ + public Matrix4f scale(Vector3f vec) { + return scale(vec, this, this); + } + + /** + * Scales the source matrix and put the result in the destination matrix + * @param vec The vector to scale by + * @param src The source matrix + * @param dest The destination matrix, or null if a new matrix is to be created + * @return The scaled matrix + */ + public static Matrix4f scale(Vector3f vec, Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + dest.m00 = src.m00 * vec.x; + dest.m01 = src.m01 * vec.x; + dest.m02 = src.m02 * vec.x; + dest.m03 = src.m03 * vec.x; + dest.m10 = src.m10 * vec.y; + dest.m11 = src.m11 * vec.y; + dest.m12 = src.m12 * vec.y; + dest.m13 = src.m13 * vec.y; + dest.m20 = src.m20 * vec.z; + dest.m21 = src.m21 * vec.z; + dest.m22 = src.m22 * vec.z; + dest.m23 = src.m23 * vec.z; + return dest; + } + + /** + * Rotates the matrix around the given axis the specified angle + * @param angle the angle, in radians. + * @param axis The vector representing the rotation axis. Must be normalized. + * @return this + */ + public Matrix4f rotate(float angle, Vector3f axis) { + return rotate(angle, axis, this); + } + + /** + * Rotates the matrix around the given axis the specified angle + * @param angle the angle, in radians. + * @param axis The vector representing the rotation axis. Must be normalized. + * @param dest The matrix to put the result, or null if a new matrix is to be created + * @return The rotated matrix + */ + public Matrix4f rotate(float angle, Vector3f axis, Matrix4f dest) { + return rotate(angle, axis, this, dest); + } + + /** + * Rotates the source matrix around the given axis the specified angle and + * put the result in the destination matrix. + * @param angle the angle, in radians. + * @param axis The vector representing the rotation axis. Must be normalized. + * @param src The matrix to rotate + * @param dest The matrix to put the result, or null if a new matrix is to be created + * @return The rotated matrix + */ + public static Matrix4f rotate(float angle, Vector3f axis, Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + float c = (float) Math.cos(angle); + float s = (float) Math.sin(angle); + float oneminusc = 1.0f - c; + float xy = axis.x*axis.y; + float yz = axis.y*axis.z; + float xz = axis.x*axis.z; + float xs = axis.x*s; + float ys = axis.y*s; + float zs = axis.z*s; + + float f00 = axis.x*axis.x*oneminusc+c; + float f01 = xy*oneminusc+zs; + float f02 = xz*oneminusc-ys; + // n[3] not used + float f10 = xy*oneminusc-zs; + float f11 = axis.y*axis.y*oneminusc+c; + float f12 = yz*oneminusc+xs; + // n[7] not used + float f20 = xz*oneminusc+ys; + float f21 = yz*oneminusc-xs; + float f22 = axis.z*axis.z*oneminusc+c; + + float t00 = src.m00 * f00 + src.m10 * f01 + src.m20 * f02; + float t01 = src.m01 * f00 + src.m11 * f01 + src.m21 * f02; + float t02 = src.m02 * f00 + src.m12 * f01 + src.m22 * f02; + float t03 = src.m03 * f00 + src.m13 * f01 + src.m23 * f02; + float t10 = src.m00 * f10 + src.m10 * f11 + src.m20 * f12; + float t11 = src.m01 * f10 + src.m11 * f11 + src.m21 * f12; + float t12 = src.m02 * f10 + src.m12 * f11 + src.m22 * f12; + float t13 = src.m03 * f10 + src.m13 * f11 + src.m23 * f12; + dest.m20 = src.m00 * f20 + src.m10 * f21 + src.m20 * f22; + dest.m21 = src.m01 * f20 + src.m11 * f21 + src.m21 * f22; + dest.m22 = src.m02 * f20 + src.m12 * f21 + src.m22 * f22; + dest.m23 = src.m03 * f20 + src.m13 * f21 + src.m23 * f22; + dest.m00 = t00; + dest.m01 = t01; + dest.m02 = t02; + dest.m03 = t03; + dest.m10 = t10; + dest.m11 = t11; + dest.m12 = t12; + dest.m13 = t13; + return dest; + } + + /** + * Translate this matrix and stash the result in another matrix + * @param vec The vector to translate by + * @param dest The destination matrix or null if a new matrix is to be created + * @return the translated matrix + */ + public Matrix4f translate(Vector3f vec, Matrix4f dest) { + return translate(vec, this, dest); + } + + /** + * Translate the source matrix and stash the result in the destination matrix + * @param vec The vector to translate by + * @param src The source matrix + * @param dest The destination matrix or null if a new matrix is to be created + * @return The translated matrix + */ + public static Matrix4f translate(Vector3f vec, Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + dest.m30 += src.m00 * vec.x + src.m10 * vec.y + src.m20 * vec.z; + dest.m31 += src.m01 * vec.x + src.m11 * vec.y + src.m21 * vec.z; + dest.m32 += src.m02 * vec.x + src.m12 * vec.y + src.m22 * vec.z; + dest.m33 += src.m03 * vec.x + src.m13 * vec.y + src.m23 * vec.z; + + return dest; + } + + /** + * Translate this matrix and stash the result in another matrix + * @param vec The vector to translate by + * @param dest The destination matrix or null if a new matrix is to be created + * @return the translated matrix + */ + public Matrix4f translate(Vector2f vec, Matrix4f dest) { + return translate(vec, this, dest); + } + + /** + * Translate the source matrix and stash the result in the destination matrix + * @param vec The vector to translate by + * @param src The source matrix + * @param dest The destination matrix or null if a new matrix is to be created + * @return The translated matrix + */ + public static Matrix4f translate(Vector2f vec, Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + dest.m30 += src.m00 * vec.x + src.m10 * vec.y; + dest.m31 += src.m01 * vec.x + src.m11 * vec.y; + dest.m32 += src.m02 * vec.x + src.m12 * vec.y; + dest.m33 += src.m03 * vec.x + src.m13 * vec.y; + + return dest; + } + + /** + * Transpose this matrix and place the result in another matrix + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public Matrix4f transpose(Matrix4f dest) { + return transpose(this, dest); + } + + /** + * Transpose the source matrix and place the result in the destination matrix + * @param src The source matrix + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public static Matrix4f transpose(Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + float m00 = src.m00; + float m01 = src.m10; + float m02 = src.m20; + float m03 = src.m30; + float m10 = src.m01; + float m11 = src.m11; + float m12 = src.m21; + float m13 = src.m31; + float m20 = src.m02; + float m21 = src.m12; + float m22 = src.m22; + float m23 = src.m32; + float m30 = src.m03; + float m31 = src.m13; + float m32 = src.m23; + float m33 = src.m33; + + dest.m00 = m00; + dest.m01 = m01; + dest.m02 = m02; + dest.m03 = m03; + dest.m10 = m10; + dest.m11 = m11; + dest.m12 = m12; + dest.m13 = m13; + dest.m20 = m20; + dest.m21 = m21; + dest.m22 = m22; + dest.m23 = m23; + dest.m30 = m30; + dest.m31 = m31; + dest.m32 = m32; + dest.m33 = m33; + + return dest; + } + + /** + * @return the determinant of the matrix + */ + public float determinant() { + float f = + m00 + * ((m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32) + - m13 * m22 * m31 + - m11 * m23 * m32 + - m12 * m21 * m33); + f -= m01 + * ((m10 * m22 * m33 + m12 * m23 * m30 + m13 * m20 * m32) + - m13 * m22 * m30 + - m10 * m23 * m32 + - m12 * m20 * m33); + f += m02 + * ((m10 * m21 * m33 + m11 * m23 * m30 + m13 * m20 * m31) + - m13 * m21 * m30 + - m10 * m23 * m31 + - m11 * m20 * m33); + f -= m03 + * ((m10 * m21 * m32 + m11 * m22 * m30 + m12 * m20 * m31) + - m12 * m21 * m30 + - m10 * m22 * m31 + - m11 * m20 * m32); + return f; + } + + /** + * Calculate the determinant of a 3x3 matrix + * @return result + */ + + private static float determinant3x3(float t00, float t01, float t02, + float t10, float t11, float t12, + float t20, float t21, float t22) + { + return t00 * (t11 * t22 - t12 * t21) + + t01 * (t12 * t20 - t10 * t22) + + t02 * (t10 * t21 - t11 * t20); + } + + /** + * Invert this matrix + * @return this if successful, null otherwise + */ + public Matrix invert() { + return invert(this, this); + } + + /** + * Invert the source matrix and put the result in the destination + * @param src The source matrix + * @param dest The destination matrix, or null if a new matrix is to be created + * @return The inverted matrix if successful, null otherwise + */ + public static Matrix4f invert(Matrix4f src, Matrix4f dest) { + float determinant = src.determinant(); + + if (determinant != 0) { + /* + * m00 m01 m02 m03 + * m10 m11 m12 m13 + * m20 m21 m22 m23 + * m30 m31 m32 m33 + */ + if (dest == null) + dest = new Matrix4f(); + float determinant_inv = 1f/determinant; + + // first row + float t00 = determinant3x3(src.m11, src.m12, src.m13, src.m21, src.m22, src.m23, src.m31, src.m32, src.m33); + float t01 = -determinant3x3(src.m10, src.m12, src.m13, src.m20, src.m22, src.m23, src.m30, src.m32, src.m33); + float t02 = determinant3x3(src.m10, src.m11, src.m13, src.m20, src.m21, src.m23, src.m30, src.m31, src.m33); + float t03 = -determinant3x3(src.m10, src.m11, src.m12, src.m20, src.m21, src.m22, src.m30, src.m31, src.m32); + // second row + float t10 = -determinant3x3(src.m01, src.m02, src.m03, src.m21, src.m22, src.m23, src.m31, src.m32, src.m33); + float t11 = determinant3x3(src.m00, src.m02, src.m03, src.m20, src.m22, src.m23, src.m30, src.m32, src.m33); + float t12 = -determinant3x3(src.m00, src.m01, src.m03, src.m20, src.m21, src.m23, src.m30, src.m31, src.m33); + float t13 = determinant3x3(src.m00, src.m01, src.m02, src.m20, src.m21, src.m22, src.m30, src.m31, src.m32); + // third row + float t20 = determinant3x3(src.m01, src.m02, src.m03, src.m11, src.m12, src.m13, src.m31, src.m32, src.m33); + float t21 = -determinant3x3(src.m00, src.m02, src.m03, src.m10, src.m12, src.m13, src.m30, src.m32, src.m33); + float t22 = determinant3x3(src.m00, src.m01, src.m03, src.m10, src.m11, src.m13, src.m30, src.m31, src.m33); + float t23 = -determinant3x3(src.m00, src.m01, src.m02, src.m10, src.m11, src.m12, src.m30, src.m31, src.m32); + // fourth row + float t30 = -determinant3x3(src.m01, src.m02, src.m03, src.m11, src.m12, src.m13, src.m21, src.m22, src.m23); + float t31 = determinant3x3(src.m00, src.m02, src.m03, src.m10, src.m12, src.m13, src.m20, src.m22, src.m23); + float t32 = -determinant3x3(src.m00, src.m01, src.m03, src.m10, src.m11, src.m13, src.m20, src.m21, src.m23); + float t33 = determinant3x3(src.m00, src.m01, src.m02, src.m10, src.m11, src.m12, src.m20, src.m21, src.m22); + + // transpose and divide by the determinant + dest.m00 = t00*determinant_inv; + dest.m11 = t11*determinant_inv; + dest.m22 = t22*determinant_inv; + dest.m33 = t33*determinant_inv; + dest.m01 = t10*determinant_inv; + dest.m10 = t01*determinant_inv; + dest.m20 = t02*determinant_inv; + dest.m02 = t20*determinant_inv; + dest.m12 = t21*determinant_inv; + dest.m21 = t12*determinant_inv; + dest.m03 = t30*determinant_inv; + dest.m30 = t03*determinant_inv; + dest.m13 = t31*determinant_inv; + dest.m31 = t13*determinant_inv; + dest.m32 = t23*determinant_inv; + dest.m23 = t32*determinant_inv; + return dest; + } else + return null; + } + + /** + * Negate this matrix + * @return this + */ + public Matrix negate() { + return negate(this); + } + + /** + * Negate this matrix and place the result in a destination matrix. + * @param dest The destination matrix, or null if a new matrix is to be created + * @return the negated matrix + */ + public Matrix4f negate(Matrix4f dest) { + return negate(this, dest); + } + + /** + * Negate this matrix and place the result in a destination matrix. + * @param src The source matrix + * @param dest The destination matrix, or null if a new matrix is to be created + * @return The negated matrix + */ + public static Matrix4f negate(Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + dest.m00 = -src.m00; + dest.m01 = -src.m01; + dest.m02 = -src.m02; + dest.m03 = -src.m03; + dest.m10 = -src.m10; + dest.m11 = -src.m11; + dest.m12 = -src.m12; + dest.m13 = -src.m13; + dest.m20 = -src.m20; + dest.m21 = -src.m21; + dest.m22 = -src.m22; + dest.m23 = -src.m23; + dest.m30 = -src.m30; + dest.m31 = -src.m31; + dest.m32 = -src.m32; + dest.m33 = -src.m33; + + return dest; + } + + public boolean equals(Object m) { + return (m instanceof Matrix4f) && equal(this, (Matrix4f)m); + } + + public static boolean equal(Matrix4f a, Matrix4f b) { + return a.m00 == b.m00 && + a.m01 == b.m01 && + a.m02 == b.m02 && + a.m03 == b.m03 && + a.m10 == b.m10 && + a.m11 == b.m11 && + a.m12 == b.m12 && + a.m13 == b.m13 && + a.m20 == b.m20 && + a.m21 == b.m21 && + a.m22 == b.m22 && + a.m23 == b.m23 && + a.m30 == b.m30 && + a.m31 == b.m31 && + a.m32 == b.m32 && + a.m33 == b.m33; + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Quaternion.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Quaternion.java new file mode 100644 index 0000000..9a592d2 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Quaternion.java @@ -0,0 +1,530 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +/** + * + * Quaternions for LWJGL! + * + * @author fbi + * @version $Revision$ + * $Id$ + */ + +import java.nio.FloatBuffer; + +public class Quaternion extends Vector implements ReadableVector4f { + private static final long serialVersionUID = 1L; + + public float x, y, z, w; + + /** + * C'tor. The quaternion will be initialized to the identity. + */ + public Quaternion() { + super(); + setIdentity(); + } + + /** + * C'tor + * + * @param src + */ + public Quaternion(ReadableVector4f src) { + set(src); + } + + /** + * C'tor + * + */ + public Quaternion(float x, float y, float z, float w) { + set(x, y, z, w); + } + + /* + * (non-Javadoc) + * + * @see org.lwjgl.util.vector.WritableVector2f#set(float, float) + */ + public void set(float x, float y) { + this.x = x; + this.y = y; + } + + /* + * (non-Javadoc) + * + * @see org.lwjgl.util.vector.WritableVector3f#set(float, float, float) + */ + public void set(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + /* + * (non-Javadoc) + * + * @see org.lwjgl.util.vector.WritableVector4f#set(float, float, float, + * float) + */ + public void set(float x, float y, float z, float w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /** + * Load from another Vector4f + * + * @param src + * The source vector + * @return this + */ + public Quaternion set(ReadableVector4f src) { + x = src.getX(); + y = src.getY(); + z = src.getZ(); + w = src.getW(); + return this; + } + + /** + * Set this quaternion to the multiplication identity. + * @return this + */ + public Quaternion setIdentity() { + return setIdentity(this); + } + + /** + * Set the given quaternion to the multiplication identity. + * @param q The quaternion + * @return q + */ + public static Quaternion setIdentity(Quaternion q) { + q.x = 0; + q.y = 0; + q.z = 0; + q.w = 1; + return q; + } + + /** + * @return the length squared of the quaternion + */ + public float lengthSquared() { + return x * x + y * y + z * z + w * w; + } + + /** + * Normalise the source quaternion and place the result in another quaternion. + * + * @param src + * The source quaternion + * @param dest + * The destination quaternion, or null if a new quaternion is to be + * created + * @return The normalised quaternion + */ + public static Quaternion normalise(Quaternion src, Quaternion dest) { + float inv_l = 1f/src.length(); + + if (dest == null) + dest = new Quaternion(); + + dest.set(src.x * inv_l, src.y * inv_l, src.z * inv_l, src.w * inv_l); + + return dest; + } + + /** + * Normalise this quaternion and place the result in another quaternion. + * + * @param dest + * The destination quaternion, or null if a new quaternion is to be + * created + * @return the normalised quaternion + */ + public Quaternion normalise(Quaternion dest) { + return normalise(this, dest); + } + + /** + * The dot product of two quaternions + * + * @param left + * The LHS quat + * @param right + * The RHS quat + * @return left dot right + */ + public static float dot(Quaternion left, Quaternion right) { + return left.x * right.x + left.y * right.y + left.z * right.z + left.w + * right.w; + } + + /** + * Calculate the conjugate of this quaternion and put it into the given one + * + * @param dest + * The quaternion which should be set to the conjugate of this + * quaternion + */ + public Quaternion negate(Quaternion dest) { + return negate(this, dest); + } + + /** + * Calculate the conjugate of this quaternion and put it into the given one + * + * @param src + * The source quaternion + * @param dest + * The quaternion which should be set to the conjugate of this + * quaternion + */ + public static Quaternion negate(Quaternion src, Quaternion dest) { + if (dest == null) + dest = new Quaternion(); + + dest.x = -src.x; + dest.y = -src.y; + dest.z = -src.z; + dest.w = src.w; + + return dest; + } + + /** + * Calculate the conjugate of this quaternion + */ + public Vector negate() { + return negate(this, this); + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.Vector#load(java.nio.FloatBuffer) + */ + public Vector load(FloatBuffer buf) { + x = buf.get(); + y = buf.get(); + z = buf.get(); + w = buf.get(); + return this; + } + + /* + * (non-Javadoc) + * + * @see org.lwjgl.vector.Vector#scale(float) + */ + public Vector scale(float scale) { + return scale(scale, this, this); + } + + /** + * Scale the source quaternion by scale and put the result in the destination + * @param scale The amount to scale by + * @param src The source quaternion + * @param dest The destination quaternion, or null if a new quaternion is to be created + * @return The scaled quaternion + */ + public static Quaternion scale(float scale, Quaternion src, Quaternion dest) { + if (dest == null) + dest = new Quaternion(); + dest.x = src.x * scale; + dest.y = src.y * scale; + dest.z = src.z * scale; + dest.w = src.w * scale; + return dest; + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.ReadableVector#store(java.nio.FloatBuffer) + */ + public Vector store(FloatBuffer buf) { + buf.put(x); + buf.put(y); + buf.put(z); + buf.put(w); + + return this; + } + + /** + * @return x + */ + public final float getX() { + return x; + } + + /** + * @return y + */ + public final float getY() { + return y; + } + + /** + * Set X + * + * @param x + */ + public final void setX(float x) { + this.x = x; + } + + /** + * Set Y + * + * @param y + */ + public final void setY(float y) { + this.y = y; + } + + /** + * Set Z + * + * @param z + */ + public void setZ(float z) { + this.z = z; + } + + /* + * (Overrides) + * + * @see org.lwjgl.vector.ReadableVector3f#getZ() + */ + public float getZ() { + return z; + } + + /** + * Set W + * + * @param w + */ + public void setW(float w) { + this.w = w; + } + + /* + * (Overrides) + * + * @see org.lwjgl.vector.ReadableVector3f#getW() + */ + public float getW() { + return w; + } + + public String toString() { + return "Quaternion: " + x + " " + y + " " + z + " " + w; + } + + /** + * Sets the value of this quaternion to the quaternion product of + * quaternions left and right (this = left * right). Note that this is safe + * for aliasing (e.g. this can be left or right). + * + * @param left + * the first quaternion + * @param right + * the second quaternion + */ + public static Quaternion mul(Quaternion left, Quaternion right, + Quaternion dest) { + if (dest == null) + dest = new Quaternion(); + dest.set(left.x * right.w + left.w * right.x + left.y * right.z + - left.z * right.y, left.y * right.w + left.w * right.y + + left.z * right.x - left.x * right.z, left.z * right.w + + left.w * right.z + left.x * right.y - left.y * right.x, + left.w * right.w - left.x * right.x - left.y * right.y + - left.z * right.z); + return dest; + } + + /** + * + * Multiplies quaternion left by the inverse of quaternion right and places + * the value into this quaternion. The value of both argument quaternions is + * preservered (this = left * right^-1). + * + * @param left + * the left quaternion + * @param right + * the right quaternion + */ + public static Quaternion mulInverse(Quaternion left, Quaternion right, + Quaternion dest) { + float n = right.lengthSquared(); + // zero-div may occur. + n = (n == 0.0 ? n : 1 / n); + // store on stack once for aliasing-safty + if (dest == null) + dest = new Quaternion(); + dest + .set((left.x * right.w - left.w * right.x - left.y + * right.z + left.z * right.y) + * n, (left.y * right.w - left.w * right.y - left.z + * right.x + left.x * right.z) + * n, (left.z * right.w - left.w * right.z - left.x + * right.y + left.y * right.x) + * n, (left.w * right.w + left.x * right.x + left.y + * right.y + left.z * right.z) + * n); + + return dest; + } + + /** + * Sets the value of this quaternion to the equivalent rotation of the + * Axis-Angle argument. + * + * @param a1 + * the axis-angle: (x,y,z) is the axis and w is the angle + */ + public final void setFromAxisAngle(Vector4f a1) { + x = a1.x; + y = a1.y; + z = a1.z; + float n = (float) Math.sqrt(x * x + y * y + z * z); + // zero-div may occur. + float s = (float) (Math.sin(0.5 * a1.w) / n); + x *= s; + y *= s; + z *= s; + w = (float) Math.cos(0.5 * a1.w); + } + + /** + * Sets the value of this quaternion using the rotational component of the + * passed matrix. + * + * @param m + * The matrix + * @return this + */ + public final Quaternion setFromMatrix(Matrix4f m) { + return setFromMatrix(m, this); + } + + /** + * Sets the value of the source quaternion using the rotational component of the + * passed matrix. + * + * @param m + * The source matrix + * @param q + * The destination quaternion, or null if a new quaternion is to be created + * @return q + */ + public static Quaternion setFromMatrix(Matrix4f m, Quaternion q) { + return q.setFromMat(m.m00, m.m01, m.m02, m.m10, m.m11, m.m12, m.m20, + m.m21, m.m22); + } + + /** + * Sets the value of this quaternion using the rotational component of the + * passed matrix. + * + * @param m + * The source matrix + */ + public final Quaternion setFromMatrix(Matrix3f m) { + return setFromMatrix(m, this); + } + + /** + * Sets the value of the source quaternion using the rotational component of the + * passed matrix. + * + * @param m + * The source matrix + * @param q + * The destination quaternion, or null if a new quaternion is to be created + * @return q + */ + public static Quaternion setFromMatrix(Matrix3f m, Quaternion q) { + return q.setFromMat(m.m00, m.m01, m.m02, m.m10, m.m11, m.m12, m.m20, + m.m21, m.m22); + } + + /** + * Private method to perform the matrix-to-quaternion conversion + */ + private Quaternion setFromMat(float m00, float m01, float m02, float m10, + float m11, float m12, float m20, float m21, float m22) { + + float s; + float tr = m00 + m11 + m22; + if (tr >= 0.0) { + s = (float) Math.sqrt(tr + 1.0); + w = s * 0.5f; + s = 0.5f / s; + x = (m21 - m12) * s; + y = (m02 - m20) * s; + z = (m10 - m01) * s; + } else { + float max = Math.max(Math.max(m00, m11), m22); + if (max == m00) { + s = (float) Math.sqrt(m00 - (m11 + m22) + 1.0); + x = s * 0.5f; + s = 0.5f / s; + y = (m01 + m10) * s; + z = (m20 + m02) * s; + w = (m21 - m12) * s; + } else if (max == m11) { + s = (float) Math.sqrt(m11 - (m22 + m00) + 1.0); + y = s * 0.5f; + s = 0.5f / s; + z = (m12 + m21) * s; + x = (m01 + m10) * s; + w = (m02 - m20) * s; + } else { + s = (float) Math.sqrt(m22 - (m00 + m11) + 1.0); + z = s * 0.5f; + s = 0.5f / s; + x = (m20 + m02) * s; + y = (m12 + m21) * s; + w = (m10 - m01) * s; + } + } + return this; + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector.java new file mode 100644 index 0000000..6ae8f63 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.nio.FloatBuffer; + +/** + * @author foo + */ +public interface ReadableVector { + /** + * @return the length of the vector + */ + float length(); + /** + * @return the length squared of the vector + */ + float lengthSquared(); + /** + * Store this vector in a FloatBuffer + * @param buf The buffer to store it in, at the current position + * @return this + */ + Vector store(FloatBuffer buf); +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector2f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector2f.java new file mode 100644 index 0000000..1d0eb4f --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector2f.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +/** + * @author foo + */ +public interface ReadableVector2f extends ReadableVector { + /** + * @return x + */ + float getX(); + /** + * @return y + */ + float getY(); +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector3f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector3f.java new file mode 100644 index 0000000..216e1dc --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector3f.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +/** + * @author foo + */ +public interface ReadableVector3f extends ReadableVector2f { + /** + * @return z + */ + float getZ(); +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector4f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector4f.java new file mode 100644 index 0000000..81ca284 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector4f.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +/** + * @author foo + */ +public interface ReadableVector4f extends ReadableVector3f { + + /** + * @return w + */ + float getW(); + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector.java new file mode 100644 index 0000000..6d226e6 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Base class for vectors. + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ +public abstract class Vector implements Serializable, ReadableVector { + + /** + * Constructor for Vector. + */ + protected Vector() { + super(); + } + + /** + * @return the length of the vector + */ + public final float length() { + return (float) Math.sqrt(lengthSquared()); + } + + + /** + * @return the length squared of the vector + */ + public abstract float lengthSquared(); + + /** + * Load this vector from a FloatBuffer + * @param buf The buffer to load it from, at the current position + * @return this + */ + public abstract Vector load(FloatBuffer buf); + + /** + * Negate a vector + * @return this + */ + public abstract Vector negate(); + + + /** + * Normalise this vector + * @return this + */ + public final Vector normalise() { + float len = length(); + if (len != 0.0f) { + float l = 1.0f / len; + return scale(l); + } else + throw new IllegalStateException("Zero length vector"); + } + + + /** + * Store this vector in a FloatBuffer + * @param buf The buffer to store it in, at the current position + * @return this + */ + public abstract Vector store(FloatBuffer buf); + + + /** + * Scale this vector + * @param scale The scale factor + * @return this + */ + public abstract Vector scale(float scale); + + + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector2f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector2f.java new file mode 100644 index 0000000..6b77ceb --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector2f.java @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Holds a 2-tuple vector. + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ + +public class Vector2f extends Vector implements Serializable, ReadableVector2f, WritableVector2f { + + private static final long serialVersionUID = 1L; + + public float x, y; + + /** + * Constructor for Vector2f. + */ + public Vector2f() { + super(); + } + + /** + * Constructor. + */ + public Vector2f(ReadableVector2f src) { + set(src); + } + + /** + * Constructor. + */ + public Vector2f(float x, float y) { + set(x, y); + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector2f#set(float, float) + */ + public void set(float x, float y) { + this.x = x; + this.y = y; + } + + /** + * Load from another Vector2f + * @param src The source vector + * @return this + */ + public Vector2f set(ReadableVector2f src) { + x = src.getX(); + y = src.getY(); + return this; + } + + /** + * @return the length squared of the vector + */ + public float lengthSquared() { + return x * x + y * y; + } + + /** + * Translate a vector + * @param x The translation in x + * @param y the translation in y + * @return this + */ + public Vector2f translate(float x, float y) { + this.x += x; + this.y += y; + return this; + } + + /** + * Negate a vector + * @return this + */ + public Vector negate() { + x = -x; + y = -y; + return this; + } + + /** + * Negate a vector and place the result in a destination vector. + * @param dest The destination vector or null if a new vector is to be created + * @return the negated vector + */ + public Vector2f negate(Vector2f dest) { + if (dest == null) + dest = new Vector2f(); + dest.x = -x; + dest.y = -y; + return dest; + } + + + /** + * Normalise this vector and place the result in another vector. + * @param dest The destination vector, or null if a new vector is to be created + * @return the normalised vector + */ + public Vector2f normalise(Vector2f dest) { + float l = length(); + + if (dest == null) + dest = new Vector2f(x / l, y / l); + else + dest.set(x / l, y / l); + + return dest; + } + + /** + * The dot product of two vectors is calculated as + * v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + * @param left The LHS vector + * @param right The RHS vector + * @return left dot right + */ + public static float dot(Vector2f left, Vector2f right) { + return left.x * right.x + left.y * right.y; + } + + + + /** + * Calculate the angle between two vectors, in radians + * @param a A vector + * @param b The other vector + * @return the angle between the two vectors, in radians + */ + public static float angle(Vector2f a, Vector2f b) { + float dls = dot(a, b) / (a.length() * b.length()); + if (dls < -1f) + dls = -1f; + else if (dls > 1.0f) + dls = 1.0f; + return (float)Math.acos(dls); + } + + /** + * Add a vector to another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return the sum of left and right in dest + */ + public static Vector2f add(Vector2f left, Vector2f right, Vector2f dest) { + if (dest == null) + return new Vector2f(left.x + right.x, left.y + right.y); + else { + dest.set(left.x + right.x, left.y + right.y); + return dest; + } + } + + /** + * Subtract a vector from another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return left minus right in dest + */ + public static Vector2f sub(Vector2f left, Vector2f right, Vector2f dest) { + if (dest == null) + return new Vector2f(left.x - right.x, left.y - right.y); + else { + dest.set(left.x - right.x, left.y - right.y); + return dest; + } + } + + /** + * Store this vector in a FloatBuffer + * @param buf The buffer to store it in, at the current position + * @return this + */ + public Vector store(FloatBuffer buf) { + buf.put(x); + buf.put(y); + return this; + } + + /** + * Load this vector from a FloatBuffer + * @param buf The buffer to load it from, at the current position + * @return this + */ + public Vector load(FloatBuffer buf) { + x = buf.get(); + y = buf.get(); + return this; + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#scale(float) + */ + public Vector scale(float scale) { + + x *= scale; + y *= scale; + + return this; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuilder sb = new StringBuilder(64); + + sb.append("Vector2f["); + sb.append(x); + sb.append(", "); + sb.append(y); + sb.append(']'); + return sb.toString(); + } + + /** + * @return x + */ + public final float getX() { + return x; + } + + /** + * @return y + */ + public final float getY() { + return y; + } + + /** + * Set X + * @param x + */ + public final void setX(float x) { + this.x = x; + } + + /** + * Set Y + * @param y + */ + public final void setY(float y) { + this.y = y; + } + + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + Vector2f other = (Vector2f)obj; + + if (x == other.x && y == other.y) return true; + + return false; + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector3f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector3f.java new file mode 100644 index 0000000..b56617f --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector3f.java @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Holds a 3-tuple vector. + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ + +public class Vector3f extends Vector implements Serializable, ReadableVector3f, WritableVector3f { + + private static final long serialVersionUID = 1L; + + public float x, y, z; + + /** + * Constructor for Vector3f. + */ + public Vector3f() { + super(); + } + + /** + * Constructor + */ + public Vector3f(ReadableVector3f src) { + set(src); + } + + /** + * Constructor + */ + public Vector3f(float x, float y, float z) { + set(x, y, z); + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector2f#set(float, float) + */ + public void set(float x, float y) { + this.x = x; + this.y = y; + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector3f#set(float, float, float) + */ + public void set(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Load from another Vector3f + * @param src The source vector + * @return this + */ + public Vector3f set(ReadableVector3f src) { + x = src.getX(); + y = src.getY(); + z = src.getZ(); + return this; + } + + /** + * @return the length squared of the vector + */ + public float lengthSquared() { + return x * x + y * y + z * z; + } + + /** + * Translate a vector + * @param x The translation in x + * @param y the translation in y + * @return this + */ + public Vector3f translate(float x, float y, float z) { + this.x += x; + this.y += y; + this.z += z; + return this; + } + + /** + * Add a vector to another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return the sum of left and right in dest + */ + public static Vector3f add(Vector3f left, Vector3f right, Vector3f dest) { + if (dest == null) + return new Vector3f(left.x + right.x, left.y + right.y, left.z + right.z); + else { + dest.set(left.x + right.x, left.y + right.y, left.z + right.z); + return dest; + } + } + + /** + * Subtract a vector from another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return left minus right in dest + */ + public static Vector3f sub(Vector3f left, Vector3f right, Vector3f dest) { + if (dest == null) + return new Vector3f(left.x - right.x, left.y - right.y, left.z - right.z); + else { + dest.set(left.x - right.x, left.y - right.y, left.z - right.z); + return dest; + } + } + + /** + * The cross product of two vectors. + * + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination result, or null if a new vector is to be created + * @return left cross right + */ + public static Vector3f cross( + Vector3f left, + Vector3f right, + Vector3f dest) + { + + if (dest == null) + dest = new Vector3f(); + + dest.set( + left.y * right.z - left.z * right.y, + right.x * left.z - right.z * left.x, + left.x * right.y - left.y * right.x + ); + + return dest; + } + + + + /** + * Negate a vector + * @return this + */ + public Vector negate() { + x = -x; + y = -y; + z = -z; + return this; + } + + /** + * Negate a vector and place the result in a destination vector. + * @param dest The destination vector or null if a new vector is to be created + * @return the negated vector + */ + public Vector3f negate(Vector3f dest) { + if (dest == null) + dest = new Vector3f(); + dest.x = -x; + dest.y = -y; + dest.z = -z; + return dest; + } + + + /** + * Normalise this vector and place the result in another vector. + * @param dest The destination vector, or null if a new vector is to be created + * @return the normalised vector + */ + public Vector3f normalise(Vector3f dest) { + float l = length(); + + if (dest == null) + dest = new Vector3f(x / l, y / l, z / l); + else + dest.set(x / l, y / l, z / l); + + return dest; + } + + /** + * The dot product of two vectors is calculated as + * v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + * @param left The LHS vector + * @param right The RHS vector + * @return left dot right + */ + public static float dot(Vector3f left, Vector3f right) { + return left.x * right.x + left.y * right.y + left.z * right.z; + } + + /** + * Calculate the angle between two vectors, in radians + * @param a A vector + * @param b The other vector + * @return the angle between the two vectors, in radians + */ + public static float angle(Vector3f a, Vector3f b) { + float dls = dot(a, b) / (a.length() * b.length()); + if (dls < -1f) + dls = -1f; + else if (dls > 1.0f) + dls = 1.0f; + return (float)Math.acos(dls); + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#load(FloatBuffer) + */ + public Vector load(FloatBuffer buf) { + x = buf.get(); + y = buf.get(); + z = buf.get(); + return this; + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#scale(float) + */ + public Vector scale(float scale) { + + x *= scale; + y *= scale; + z *= scale; + + return this; + + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#store(FloatBuffer) + */ + public Vector store(FloatBuffer buf) { + + buf.put(x); + buf.put(y); + buf.put(z); + + return this; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuilder sb = new StringBuilder(64); + + sb.append("Vector3f["); + sb.append(x); + sb.append(", "); + sb.append(y); + sb.append(", "); + sb.append(z); + sb.append(']'); + return sb.toString(); + } + + /** + * @return x + */ + public final float getX() { + return x; + } + + /** + * @return y + */ + public final float getY() { + return y; + } + + /** + * Set X + * @param x + */ + public final void setX(float x) { + this.x = x; + } + + /** + * Set Y + * @param y + */ + public final void setY(float y) { + this.y = y; + } + + /** + * Set Z + * @param z + */ + public void setZ(float z) { + this.z = z; + } + + /* (Overrides) + * @see org.lwjgl.vector.ReadableVector3f#getZ() + */ + public float getZ() { + return z; + } + + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + Vector3f other = (Vector3f)obj; + + if (x == other.x && y == other.y && z == other.z) return true; + + return false; + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector4f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector4f.java new file mode 100644 index 0000000..95b4ea2 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector4f.java @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Holds a 4-tuple vector. + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ + +public class Vector4f extends Vector implements Serializable, ReadableVector4f, WritableVector4f { + + private static final long serialVersionUID = 1L; + + public float x, y, z, w; + + /** + * Constructor for Vector4f. + */ + public Vector4f() { + super(); + } + + /** + * Constructor + */ + public Vector4f(ReadableVector4f src) { + set(src); + } + + /** + * Constructor + */ + public Vector4f(float x, float y, float z, float w) { + set(x, y, z, w); + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector2f#set(float, float) + */ + public void set(float x, float y) { + this.x = x; + this.y = y; + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector3f#set(float, float, float) + */ + public void set(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector4f#set(float, float, float, float) + */ + public void set(float x, float y, float z, float w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /** + * Load from another Vector4f + * @param src The source vector + * @return this + */ + public Vector4f set(ReadableVector4f src) { + x = src.getX(); + y = src.getY(); + z = src.getZ(); + w = src.getW(); + return this; + } + + /** + * @return the length squared of the vector + */ + public float lengthSquared() { + return x * x + y * y + z * z + w * w; + } + + /** + * Translate a vector + * @param x The translation in x + * @param y the translation in y + * @return this + */ + public Vector4f translate(float x, float y, float z, float w) { + this.x += x; + this.y += y; + this.z += z; + this.w += w; + return this; + } + + /** + * Add a vector to another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return the sum of left and right in dest + */ + public static Vector4f add(Vector4f left, Vector4f right, Vector4f dest) { + if (dest == null) + return new Vector4f(left.x + right.x, left.y + right.y, left.z + right.z, left.w + right.w); + else { + dest.set(left.x + right.x, left.y + right.y, left.z + right.z, left.w + right.w); + return dest; + } + } + + /** + * Subtract a vector from another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return left minus right in dest + */ + public static Vector4f sub(Vector4f left, Vector4f right, Vector4f dest) { + if (dest == null) + return new Vector4f(left.x - right.x, left.y - right.y, left.z - right.z, left.w - right.w); + else { + dest.set(left.x - right.x, left.y - right.y, left.z - right.z, left.w - right.w); + return dest; + } + } + + + /** + * Negate a vector + * @return this + */ + public Vector negate() { + x = -x; + y = -y; + z = -z; + w = -w; + return this; + } + + /** + * Negate a vector and place the result in a destination vector. + * @param dest The destination vector or null if a new vector is to be created + * @return the negated vector + */ + public Vector4f negate(Vector4f dest) { + if (dest == null) + dest = new Vector4f(); + dest.x = -x; + dest.y = -y; + dest.z = -z; + dest.w = -w; + return dest; + } + + + /** + * Normalise this vector and place the result in another vector. + * @param dest The destination vector, or null if a new vector is to be created + * @return the normalised vector + */ + public Vector4f normalise(Vector4f dest) { + float l = length(); + + if (dest == null) + dest = new Vector4f(x / l, y / l, z / l, w / l); + else + dest.set(x / l, y / l, z / l, w / l); + + return dest; + } + + /** + * The dot product of two vectors is calculated as + * v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w + * @param left The LHS vector + * @param right The RHS vector + * @return left dot right + */ + public static float dot(Vector4f left, Vector4f right) { + return left.x * right.x + left.y * right.y + left.z * right.z + left.w * right.w; + } + + /** + * Calculate the angle between two vectors, in radians + * @param a A vector + * @param b The other vector + * @return the angle between the two vectors, in radians + */ + public static float angle(Vector4f a, Vector4f b) { + float dls = dot(a, b) / (a.length() * b.length()); + if (dls < -1f) + dls = -1f; + else if (dls > 1.0f) + dls = 1.0f; + return (float)Math.acos(dls); + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#load(FloatBuffer) + */ + public Vector load(FloatBuffer buf) { + x = buf.get(); + y = buf.get(); + z = buf.get(); + w = buf.get(); + return this; + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#scale(float) + */ + public Vector scale(float scale) { + x *= scale; + y *= scale; + z *= scale; + w *= scale; + return this; + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#store(FloatBuffer) + */ + public Vector store(FloatBuffer buf) { + + buf.put(x); + buf.put(y); + buf.put(z); + buf.put(w); + + return this; + } + + public String toString() { + return "Vector4f: " + x + " " + y + " " + z + " " + w; + } + + /** + * @return x + */ + public final float getX() { + return x; + } + + /** + * @return y + */ + public final float getY() { + return y; + } + + /** + * Set X + * @param x + */ + public final void setX(float x) { + this.x = x; + } + + /** + * Set Y + * @param y + */ + public final void setY(float y) { + this.y = y; + } + + /** + * Set Z + * @param z + */ + public void setZ(float z) { + this.z = z; + } + + + /* (Overrides) + * @see org.lwjgl.vector.ReadableVector3f#getZ() + */ + public float getZ() { + return z; + } + + /** + * Set W + * @param w + */ + public void setW(float w) { + this.w = w; + } + + /* (Overrides) + * @see org.lwjgl.vector.ReadableVector3f#getZ() + */ + public float getW() { + return w; + } + + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + Vector4f other = (Vector4f)obj; + + if (x == other.x && y == other.y && z == other.z && w == other.w) return true; + + return false; + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector2f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector2f.java new file mode 100644 index 0000000..e4b478a --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector2f.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +/** + * Writable interface to Vector2fs + * @author $author$ + * @version $revision$ + * $Id$ + */ +public interface WritableVector2f { + + /** + * Set the X value + * @param x + */ + void setX(float x); + + /** + * Set the Y value + * @param y + */ + void setY(float y); + + /** + * Set the X,Y values + * @param x + * @param y + */ + void set(float x, float y); + +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector3f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector3f.java new file mode 100644 index 0000000..2ed00d0 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector3f.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +/** + * Writable interface to Vector3fs + * @author $author$ + * @version $revision$ + * $Id$ + */ +public interface WritableVector3f extends WritableVector2f { + + /** + * Set the Z value + * @param z + */ + void setZ(float z); + + /** + * Set the X,Y,Z values + * @param x + * @param y + * @param z + */ + void set(float x, float y, float z); + +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector4f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector4f.java new file mode 100644 index 0000000..7288c97 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector4f.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +/** + * Writable interface to Vector4fs + * @author $author$ + * @version $revision$ + * $Id$ + */ +public interface WritableVector4f extends WritableVector3f { + + /** + * Set the W value + * @param w + */ + void setW(float w); + + /** + * Set the X,Y,Z,W values + * @param x + * @param y + * @param z + * @param w + */ + void set(float x, float y, float z, float w); + +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/client/ClientBrandRetriever.java b/src/main/java/net/minecraft/client/ClientBrandRetriever.java new file mode 100644 index 0000000..a7ffa62 --- /dev/null +++ b/src/main/java/net/minecraft/client/ClientBrandRetriever.java @@ -0,0 +1,7 @@ +package net.minecraft.client; + +public class ClientBrandRetriever { + public static String getClientModName() { + return "eaglercraft"; + } +} diff --git a/src/main/java/net/minecraft/client/Minecraft.java b/src/main/java/net/minecraft/client/Minecraft.java new file mode 100644 index 0000000..31acb25 --- /dev/null +++ b/src/main/java/net/minecraft/client/Minecraft.java @@ -0,0 +1,1777 @@ +package net.minecraft.client; + +import java.text.DecimalFormat; +import java.util.HashSet; +import java.util.List; + +import net.minecraft.src.*; +import sun.java2d.loops.DrawLine; +import net.lax1dude.eaglercraft.DefaultSkinRenderer; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.EaglerProfile; + +import net.lax1dude.eaglercraft.GuiScreenEditProfile; +import net.lax1dude.eaglercraft.GuiScreenVoiceChannel; +import net.lax1dude.eaglercraft.adapter.Tessellator; +import net.lax1dude.eaglercraft.glemu.EffectPipeline; +import net.lax1dude.eaglercraft.glemu.FixedFunctionShader; + +public class Minecraft implements Runnable { + + private ServerData currentServerData; + + /** + * Set to 'this' in Minecraft constructor; used by some settings get methods + */ + private static Minecraft theMinecraft; + public PlayerControllerMP playerController; + private boolean fullscreen = false; + private boolean hasCrashed = false; + + public int displayWidth; + public int displayHeight; + private Timer timer = new Timer(20.0F); + + public WorldClient theWorld; + public RenderGlobal renderGlobal; + public EntityClientPlayerMP thePlayer; + + /** + * The Entity from which the renderer determines the render viewpoint. Currently + * is always the parent Minecraft class's 'thePlayer' instance. Modification of + * its location, rotation, or other settings at render time will modify the + * camera likewise, with the caveat of triggering chunk rebuilds as it moves, + * making it unsuitable for changing the viewpoint mid-render. + */ + public EntityLiving renderViewEntity; + public EntityLiving pointedEntityLiving; + public EffectRenderer effectRenderer; + public String minecraftUri; + + /** a boolean to hide a Quit button from the main menu */ + public boolean hideQuitButton = false; + public volatile boolean isGamePaused = false; + + /** The RenderEngine instance used by Minecraft */ + public RenderEngine renderEngine; + + /** The font renderer used for displaying and measuring text. */ + public FontRenderer fontRenderer; + public FontRenderer standardGalacticFontRenderer; + + /** The GuiScreen that's being displayed at the moment. */ + public GuiScreen currentScreen = null; + public LoadingScreenRenderer loadingScreen; + public EntityRenderer entityRenderer; + + /** Mouse left click counter */ + private int leftClickCounter = 0; + + /** Display width */ + private int tempDisplayWidth; + + /** Display height */ + private int tempDisplayHeight; + + /** Gui achievement */ + public GuiAchievement guiAchievement; + public GuiIngame ingameGUI; + + /** Skip render world */ + public boolean skipRenderWorld = false; + + /** The ray trace hit that the mouse is over. */ + public MovingObjectPosition objectMouseOver = null; + + /** The game settings that currently hold effect. */ + public GameSettings gameSettings; + public SoundManager sndManager = new SoundManager(); + + /** Mouse helper instance. */ + public MouseHelper mouseHelper; + + /** The TexturePackLister used by this instance of Minecraft... */ + public TexturePackList texturePackList; + + /** + * This is set to fpsCounter every debug screen update, and is shown on the + * debug screen. It's also sent as part of the usage snooping. + */ + public static int debugFPS; + + /** + * When you place a block, it's set to 6, decremented once per tick, when it's + * 0, you can place another block. + */ + private int rightClickDelayTimer = 0; + + /** + * Checked in Minecraft's while(running) loop, if true it's set to false and the + * textures refreshed. + */ + private boolean refreshTexturePacksScheduled; + + private String serverName; + private int serverPort; + + /** + * Makes sure it doesn't keep taking screenshots when both buttons are down. + */ + boolean isTakingScreenshot = false; + + /** + * Does the actual gameplay have focus. If so then mouse and keys will effect + * the player instead of menus. + */ + public boolean inGameHasFocus = false; + long systemTime = getSystemTime(); + + /** Join player counter */ + private int joinPlayerCounter = 0; + private boolean isDemo; + private INetworkManager myNetworkManager; + private boolean integratedServerIsRunning; + + /** The profiler instance */ + public final Profiler mcProfiler = new Profiler(); + private long field_83002_am = -1L; + + public int chunkUpdates = 0; + public static int debugChunkUpdates = 0; + + /** + * Set to true to keep the game loop running. Set to false by shutdown() to + * allow the game loop to exit cleanly. + */ + public volatile boolean running = true; + + /** String that shows the debug information */ + public String debug = ""; + + /** Approximate time (in ms) of last update to debug string */ + long debugUpdateTime = getSystemTime(); + + /** holds the current fps */ + int fpsCounter = 0; + long prevFrameTime = -1L; + + long secondTimer = 0l; + + private HashSet shownPlayerMessages = new HashSet(); + + /** Profiler currently displayed in the debug screen pie chart */ + private String debugProfilerName = "root"; + + public Minecraft() { + this.tempDisplayHeight = 480; + this.fullscreen = false; + Packet3Chat.maxChatLength = 32767; + this.startTimerHackThread(); + this.displayWidth = 854; + this.displayHeight = 480; + this.fullscreen = false; + theMinecraft = this; + } + + private void startTimerHackThread() { + + } + + public void setServer(String par1Str, int par2) { + this.serverName = par1Str; + this.serverPort = par2; + } + + /** + * Starts the game: initializes the canvas, the title, the settings, etcetera. + */ + public void startGame() { + OpenGlHelper.initializeTextures(); + TextureManager.init(); + this.gameSettings = new GameSettings(this); + this.texturePackList = new TexturePackList(this); + this.renderEngine = new RenderEngine(this.texturePackList, this.gameSettings); + + this.loadScreen(); + + ChatAllowedCharacters.getAllowedCharacters(); + this.fontRenderer = new FontRenderer(this.gameSettings, "/font/default.png", this.renderEngine, false); + this.standardGalacticFontRenderer = new FontRenderer(this.gameSettings, "/font/alternate.png", this.renderEngine, false); + + if (this.gameSettings.language != null) { + StringTranslate.getInstance().setLanguage(this.gameSettings.language, false); + //this.fontRenderer.setUnicodeFlag(StringTranslate.getInstance().isUnicode()); + //this.fontRenderer.setBidiFlag(StringTranslate.isBidirectional(this.gameSettings.language)); + } + + this.loadScreen(); + + ColorizerGrass.setGrassBiomeColorizer(this.renderEngine.getTextureContents("/misc/grasscolor.png")); + ColorizerFoliage.setFoliageBiomeColorizer(this.renderEngine.getTextureContents("/misc/foliagecolor.png")); + this.entityRenderer = new EntityRenderer(this); + RenderManager.instance = new RenderManager(); + RenderManager.instance.itemRenderer = new ItemRenderer(this); + AchievementList.openInventory.setStatStringFormatter(new StatStringFormatKeyInv(this)); + this.mouseHelper = new MouseHelper(this.gameSettings); + this.checkGLError("Pre startup"); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glShadeModel(EaglerAdapter.GL_SMOOTH); + EaglerAdapter.glClearDepth(1.0F); + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glDepthFunc(EaglerAdapter.GL_LEQUAL); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glAlphaFunc(EaglerAdapter.GL_GREATER, 0.1F); + EaglerAdapter.glCullFace(EaglerAdapter.GL_BACK); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + this.checkGLError("Startup"); + this.sndManager.loadSoundSettings(this.gameSettings); + this.renderGlobal = new RenderGlobal(this, this.renderEngine); + this.renderEngine.refreshTextureMaps(); + EaglerAdapter.glViewport(0, 0, this.displayWidth, this.displayHeight); + this.effectRenderer = new EffectRenderer(this.theWorld, this.renderEngine); + EffectPipeline.init(); + + this.checkGLError("Post startup"); + this.guiAchievement = new GuiAchievement(this); + this.ingameGUI = new GuiIngame(this); + + //if (this.serverName != null) { + // this.displayGuiScreen(new GuiConnecting(new GuiMainMenu(), this, this.serverName, this.serverPort)); + //} else { + + EaglerProfile.loadFromStorage(); + + this.sndManager.playTheTitleMusic(); + showIntroAnimation(); + + this.displayGuiScreen(new GuiScreenEditProfile(new GuiMainMenu())); + + this.loadingScreen = new LoadingScreenRenderer(this); + + if (this.gameSettings.fullScreen && !this.fullscreen) { + this.toggleFullscreen(); + } + } + + public void showWarningText() { + ScaledResolution var1 = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight); + String s = "warning: early beta, major problems will arise"; + this.fontRenderer.drawString(s, (var1.getScaledWidth() - this.fontRenderer.getStringWidth(s)) / 2, var1.getScaledHeight() - 50, 0xffcccccc); + } + + private void showIntroAnimation() { + ScaledResolution var1 = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight); + EaglerAdapter.glClearColor(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glTranslatef(0.0F, 0.0F, -2000.0F); + EaglerAdapter.glViewport(0, 0, this.displayWidth, this.displayHeight); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glDisable(EaglerAdapter.GL_FOG); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + long t1 = System.currentTimeMillis(); + for(int i = 0; i < 20; i++) { + this.displayWidth = EaglerAdapter.getCanvasWidth(); + this.displayHeight = EaglerAdapter.getCanvasHeight(); + EaglerAdapter.glViewport(0, 0, this.displayWidth, this.displayHeight); + var1 = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glOrtho(0.0F, var1.getScaledWidth(), var1.getScaledHeight(), 0.0F, 1000.0F, 3000.0F); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + + float f = ((float)(System.currentTimeMillis() - t1) / 333f); + + EaglerAdapter.glClear(EaglerAdapter.GL_COLOR_BUFFER_BIT | EaglerAdapter.GL_DEPTH_BUFFER_BIT); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, MathHelper.clamp_float(1.0f - f, 0.0F, 1.0F)); + this.renderEngine.bindTexture("%clamp%/title/eagtek.png"); + EaglerAdapter.glPushMatrix(); + float f1 = 1.0f + 0.025f * f * f; + EaglerAdapter.glTranslatef((var1.getScaledWidth() - 256) / 2, (var1.getScaledHeight() - 256) / 2, 0.0f); + EaglerAdapter.glTranslatef(-128.0f * (f1 - 1.0f), -128.0f * (f1 - 1.0f) , 0.0f); + EaglerAdapter.glScalef(f1, f1, 1.0f); + this.scaledTessellator(0, 0, 0, 0, 256, 256); + EaglerAdapter.glPopMatrix(); + + showWarningText(); + + EaglerAdapter.glFlush(); + EaglerAdapter.updateDisplay(); + + long t = t1 + 17 + 17*i - System.currentTimeMillis(); + if(t > 0) { + try { + Thread.sleep(t); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + t1 = System.currentTimeMillis(); + for(int i = 0; i < 20; i++) { + this.displayWidth = EaglerAdapter.getCanvasWidth(); + this.displayHeight = EaglerAdapter.getCanvasHeight(); + EaglerAdapter.glViewport(0, 0, this.displayWidth, this.displayHeight); + var1 = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glOrtho(0.0F, var1.getScaledWidth(), var1.getScaledHeight(), 0.0F, 1000.0F, 3000.0F); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + + float f = ((float)(System.currentTimeMillis() - t1) / 333f); + + EaglerAdapter.glClear(EaglerAdapter.GL_COLOR_BUFFER_BIT | EaglerAdapter.GL_DEPTH_BUFFER_BIT); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, MathHelper.clamp_float(f*0.6f, 0.0F, 1.0F)); + this.renderEngine.bindTexture("%blur%/title/mojang.png"); + EaglerAdapter.glPushMatrix(); + float f1 = 0.875f + 0.025f * (float)Math.sqrt(f); + EaglerAdapter.glTranslatef((var1.getScaledWidth() - 256) / 2, (var1.getScaledHeight() - 256) / 2, 0.0f); + EaglerAdapter.glTranslatef(-128.0f * (f1 - 1.0f), -128.0f * (f1 - 1.0f) , 0.0f); + EaglerAdapter.glScalef(f1, f1, 1.0f); + this.scaledTessellator(0, 0, 0, 0, 256, 256); + EaglerAdapter.glPopMatrix(); + + showWarningText(); + + EaglerAdapter.glFlush(); + EaglerAdapter.updateDisplay(); + + long t = t1 + 17 + 17*i - System.currentTimeMillis(); + if(t > 0) { + try { + Thread.sleep(t); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + try { + Thread.sleep(1600l); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + t1 = System.currentTimeMillis(); + for(int i = 0; i < 21; i++) { + this.displayWidth = EaglerAdapter.getCanvasWidth(); + this.displayHeight = EaglerAdapter.getCanvasHeight(); + EaglerAdapter.glViewport(0, 0, this.displayWidth, this.displayHeight); + var1 = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight); + + float f = ((float)(System.currentTimeMillis() - t1) / 340f); + + EaglerAdapter.glClear(EaglerAdapter.GL_COLOR_BUFFER_BIT | EaglerAdapter.GL_DEPTH_BUFFER_BIT); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, MathHelper.clamp_float((1.0f - f)*0.6f, 0.0F, 1.0F)); + this.renderEngine.bindTexture("%blur%/title/mojang.png"); + EaglerAdapter.glPushMatrix(); + float f1 = 0.9f + 0.025f * f * f; + EaglerAdapter.glTranslatef((var1.getScaledWidth() - 256) / 2, (var1.getScaledHeight() - 256) / 2, 0.0f); + EaglerAdapter.glTranslatef(-128.0f * (f1 - 1.0f), -128.0f * (f1 - 1.0f) , 0.0f); + EaglerAdapter.glScalef(f1, f1, 1.0f); + this.scaledTessellator(0, 0, 0, 0, 256, 256); + EaglerAdapter.glPopMatrix(); + + showWarningText(); + + EaglerAdapter.glFlush(); + EaglerAdapter.updateDisplay(); + + long t = t1 + 17 + 17*i - System.currentTimeMillis(); + if(t > 0) { + try { + Thread.sleep(t); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + /* + t1 = System.currentTimeMillis(); + for(int i = 0; i < 8; i++) { + float f = 1.0f - ((float)(System.currentTimeMillis() - t1) / 136f); + f = 0.25f + f * f * 0.75f; + EaglerAdapter.glClearColor(f, f, f, 1.0F); + EaglerAdapter.glClear(EaglerAdapter.GL_COLOR_BUFFER_BIT | EaglerAdapter.GL_DEPTH_BUFFER_BIT); + EaglerAdapter.glFlush(); + EaglerAdapter.updateDisplay(); + + long t = t1 + 17 + 17*i - System.currentTimeMillis(); + if(t > 0) { + try { + Thread.sleep(t); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + */ + + EaglerAdapter.glClear(EaglerAdapter.GL_COLOR_BUFFER_BIT | EaglerAdapter.GL_DEPTH_BUFFER_BIT); + showWarningText(); + EaglerAdapter.glFlush(); + EaglerAdapter.updateDisplay(); + + try { + Thread.sleep(100l); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + GuiScreenVoiceChannel.fadeInTimer = System.currentTimeMillis(); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glAlphaFunc(EaglerAdapter.GL_GREATER, 0.1F); + } + + /** + * Displays a new screen. + */ + private void loadScreen() { + this.displayWidth = EaglerAdapter.getCanvasWidth(); + this.displayHeight = EaglerAdapter.getCanvasHeight(); + ScaledResolution var1 = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight); + EaglerAdapter.glColorMask(true, true, true, true); + EaglerAdapter.glClearColor(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glOrtho(0.0F, var1.getScaledWidth(), var1.getScaledHeight(), 0.0F, 1000.0F, 3000.0F); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glTranslatef(0.0F, 0.0F, -2000.0F); + EaglerAdapter.glViewport(0, 0, this.displayWidth, this.displayHeight); + EaglerAdapter.glClear(EaglerAdapter.GL_COLOR_BUFFER_BIT | EaglerAdapter.GL_DEPTH_BUFFER_BIT); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glDisable(EaglerAdapter.GL_FOG); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.renderEngine.bindTexture("%clamp%/title/eagtek.png"); + short var3 = 256; + short var4 = 256; + this.scaledTessellator((var1.getScaledWidth() - var3) / 2, (var1.getScaledHeight() - var4) / 2, 0, 0, var3, var4); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glDisable(EaglerAdapter.GL_FOG); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glAlphaFunc(EaglerAdapter.GL_GREATER, 0.1F); + EaglerAdapter.glFlush(); + EaglerAdapter.updateDisplay(); + } + + /** + * Loads Tessellator with a scaled resolution + */ + public void scaledTessellator(int par1, int par2, int par3, int par4, int par5, int par6) { + float var7 = 0.00390625F; + float var8 = 0.00390625F; + Tessellator var9 = Tessellator.instance; + var9.startDrawingQuads(); + var9.setColorOpaque(255, 255, 255); + var9.addVertexWithUV((double) (par1 + 0), (double) (par2 + par6), 0.0D, (double) ((float) (par3 + 0) * var7), (double) ((float) (par4 + par6) * var8)); + var9.addVertexWithUV((double) (par1 + par5), (double) (par2 + par6), 0.0D, (double) ((float) (par3 + par5) * var7), (double) ((float) (par4 + par6) * var8)); + var9.addVertexWithUV((double) (par1 + par5), (double) (par2 + 0), 0.0D, (double) ((float) (par3 + par5) * var7), (double) ((float) (par4 + 0) * var8)); + var9.addVertexWithUV((double) (par1 + 0), (double) (par2 + 0), 0.0D, (double) ((float) (par3 + 0) * var7), (double) ((float) (par4 + 0) * var8)); + var9.draw(); + } + + public static EnumOS getOs() { + String var0 = System.getProperty("os.name").toLowerCase(); + return var0.contains("win") ? EnumOS.WINDOWS + : (var0.contains("mac") ? EnumOS.MACOS + : (var0.contains("solaris") ? EnumOS.SOLARIS : (var0.contains("sunos") ? EnumOS.SOLARIS : (var0.contains("linux") ? EnumOS.LINUX : (var0.contains("unix") ? EnumOS.LINUX : EnumOS.UNKNOWN))))); + } + + /** + * Sets the argument GuiScreen as the main (topmost visible) screen. + */ + public void displayGuiScreen(GuiScreen par1GuiScreen) { + if (this.currentScreen != null) { + this.currentScreen.onGuiClosed(); + } + + if (par1GuiScreen == null && this.theWorld == null) { + par1GuiScreen = new GuiMainMenu(); + } else if (par1GuiScreen == null && this.thePlayer.getHealth() <= 0) { + par1GuiScreen = new GuiGameOver(); + } + + if (par1GuiScreen instanceof GuiMainMenu) { + this.gameSettings.showDebugInfo = false; + this.ingameGUI.getChatGUI().clearChatMessages(); + } + + this.currentScreen = (GuiScreen) par1GuiScreen; + + if (par1GuiScreen != null) { + this.setIngameNotInFocus(); + ScaledResolution var2 = new ScaledResolution(this.gameSettings, this.displayWidth, this.displayHeight); + int var3 = var2.getScaledWidth(); + int var4 = var2.getScaledHeight(); + ((GuiScreen) par1GuiScreen).setWorldAndResolution(this, var3, var4); + this.skipRenderWorld = false; + } else { + this.setIngameFocus(); + } + } + + /** + * Checks for an OpenGL error. If there is one, prints the error ID and error + * string. + */ + public void checkGLError(String par1Str) { + //int var2 = EaglerAdapter.glGetError(); + + //if (var2 != 0) { + // String var3 = EaglerAdapter.gluErrorString(var2); + // System.err.println("########## GL ERROR ##########"); + // System.err.println("@ " + par1Str); + // System.err.println(var2 + ": " + var3); + //} + } + + /** + * Shuts down the minecraft applet by stopping the resource downloads, and + * clearing up GL stuff; called when the application (or web page) is exited. + */ + public void shutdownMinecraftApplet() { + try { + + System.err.println("Stopping!"); + + try { + this.loadWorld((WorldClient) null); + } catch (Throwable var8) { + ; + } + + try { + GLAllocation.deleteTexturesAndDisplayLists(); + } catch (Throwable var7) { + ; + } + + this.sndManager.closeMinecraft(); + } finally { + EaglerAdapter.destroyContext(); + + if (!this.hasCrashed) { + EaglerAdapter.exit(); + } + } + + System.gc(); + } + + public void run() { + this.running = true; + + //try { + this.startGame(); + //} catch (Exception var11) { + // var11.printStackTrace(); + // return; + //} + + //try { + while (this.running) { + + if (this.refreshTexturePacksScheduled) { + this.refreshTexturePacksScheduled = false; + this.renderEngine.refreshTextures(); + } + + try { + this.runGameLoop(); + } catch (OutOfMemoryError var10) { + this.freeMemory(); + this.displayGuiScreen(new GuiMemoryErrorScreen()); + System.gc(); + } + } + //} catch (MinecraftError var12) { + // ; + //} catch (Throwable var14) { + // var14.printStackTrace(); + //} + + EaglerAdapter.destroyContext(); + EaglerAdapter.exit(); + } + + /** + * Called repeatedly from run() + */ + private void runGameLoop() { + AxisAlignedBB.getAABBPool().cleanPool(); + + if (this.theWorld != null) { + this.theWorld.getWorldVec3Pool().clear(); + } + + this.mcProfiler.startSection("root"); + + if (EaglerAdapter.shouldShutdown()) { + this.shutdown(); + } + + if (this.isGamePaused && this.theWorld != null) { + float var1 = this.timer.renderPartialTicks; + this.timer.updateTimer(); + this.timer.renderPartialTicks = var1; + } else { + this.timer.updateTimer(); + } + + long var6 = System.nanoTime(); + this.mcProfiler.startSection("tick"); + + for (int var3 = 0; var3 < this.timer.elapsedTicks; ++var3) { + this.runTick(); + } + + this.mcProfiler.endStartSection("preRenderErrors"); + long var7 = System.nanoTime() - var6; + this.checkGLError("Pre render"); + RenderBlocks.fancyGrass = this.gameSettings.fancyGraphics; + this.mcProfiler.endStartSection("sound"); + this.sndManager.setListener(this.thePlayer, this.timer.renderPartialTicks); + + if (!this.isGamePaused) { + this.sndManager.func_92071_g(); + } + + this.mcProfiler.endSection(); + this.mcProfiler.startSection("render"); + this.mcProfiler.startSection("display"); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + + if (!EaglerAdapter.isKeyDown(65)) { + EaglerAdapter.updateDisplay(); + } + + if (this.thePlayer != null && this.thePlayer.isEntityInsideOpaqueBlock()) { + this.gameSettings.thirdPersonView = 0; + } + + this.mcProfiler.endSection(); + + EaglerAdapter.glClearStack(); + + if (!this.skipRenderWorld) { + this.mcProfiler.endStartSection("gameRenderer"); + this.entityRenderer.updateCameraAndRender(this.timer.renderPartialTicks); + this.mcProfiler.endSection(); + } + + EaglerAdapter.glFlush(); + this.mcProfiler.endSection(); + + //if (!EaglerAdapter.isFocused() && this.fullscreen) { + // this.toggleFullscreen(); + //} + + if (this.gameSettings.showDebugInfo && this.gameSettings.showDebugProfilerChart) { + if (!this.mcProfiler.profilingEnabled) { + this.mcProfiler.clearProfiling(); + } + + this.mcProfiler.profilingEnabled = true; + this.displayDebugInfo(var7); + } else { + this.mcProfiler.profilingEnabled = false; + this.prevFrameTime = System.nanoTime(); + } + + this.guiAchievement.updateAchievementWindow(); + this.mcProfiler.startSection("root"); + + this.screenshotListener(); + + if (!this.fullscreen && (EaglerAdapter.getCanvasWidth() != this.displayWidth || EaglerAdapter.getCanvasHeight() != this.displayHeight)) { + this.displayWidth = EaglerAdapter.getCanvasWidth(); + this.displayHeight = EaglerAdapter.getCanvasHeight(); + + if (this.displayWidth <= 0) { + this.displayWidth = 1; + } + + if (this.displayHeight <= 0) { + this.displayHeight = 1; + } + + this.resize(this.displayWidth, this.displayHeight); + } + + this.checkGLError("Post render"); + ++this.fpsCounter; + boolean var5 = this.isGamePaused; + this.isGamePaused = false; + + if(System.currentTimeMillis() - secondTimer > 1000l) { + debugFPS = fpsCounter; + fpsCounter = 0; + debugChunkUpdates = chunkUpdates; + chunkUpdates = 0; + secondTimer = System.currentTimeMillis(); + } + this.mcProfiler.startSection("syncDisplay"); + + if (this.func_90020_K() > 0) { + EaglerAdapter.syncDisplay(EntityRenderer.performanceToFps(this.func_90020_K())); + } + + EaglerAdapter.doJavascriptCoroutines(); + + this.mcProfiler.endSection(); + this.mcProfiler.endSection(); + } + + private int func_90020_K() { + return this.currentScreen != null && this.currentScreen instanceof GuiMainMenu ? 2 : this.gameSettings.limitFramerate; + } + + public void freeMemory() { + try { + this.renderGlobal.deleteAllDisplayLists(); + } catch (Throwable var4) { + ; + } + + try { + System.gc(); + AxisAlignedBB.getAABBPool().clearPool(); + this.theWorld.getWorldVec3Pool().clearAndFreeCache(); + } catch (Throwable var3) { + ; + } + + try { + System.gc(); + this.loadWorld((WorldClient) null); + } catch (Throwable var2) { + ; + } + + System.gc(); + } + + /** + * checks if keys are down + */ + private void screenshotListener() { + /* + if (EaglerAdapter.isKeyDown(60)) { + if (!this.isTakingScreenshot) { + this.isTakingScreenshot = true; + this.ingameGUI.getChatGUI().printChatMessage(ScreenShotHelper.saveScreenshot(minecraftDir, this.displayWidth, this.displayHeight)); + } + } else { + this.isTakingScreenshot = false; + } + */ + } + + /** + * Update debugProfilerName in response to number keys in debug screen + */ + private void updateDebugProfilerName(int par1) { + List var2 = this.mcProfiler.getProfilingData(this.debugProfilerName); + + if (var2 != null && !var2.isEmpty()) { + ProfilerResult var3 = (ProfilerResult) var2.remove(0); + + if (par1 == 0) { + if (var3.field_76331_c.length() > 0) { + int var4 = this.debugProfilerName.lastIndexOf("."); + + if (var4 >= 0) { + this.debugProfilerName = this.debugProfilerName.substring(0, var4); + } + } + } else { + --par1; + + if (par1 < var2.size() && !((ProfilerResult) var2.get(par1)).field_76331_c.equals("unspecified")) { + if (this.debugProfilerName.length() > 0) { + this.debugProfilerName = this.debugProfilerName + "."; + } + + this.debugProfilerName = this.debugProfilerName + ((ProfilerResult) var2.get(par1)).field_76331_c; + } + } + } + } + + private void displayDebugInfo(long par1) { + if (this.mcProfiler.profilingEnabled) { + List var3 = this.mcProfiler.getProfilingData(this.debugProfilerName); + ProfilerResult var4 = (ProfilerResult) var3.remove(0); + EaglerAdapter.glClear(EaglerAdapter.GL_DEPTH_BUFFER_BIT); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glEnable(EaglerAdapter.GL_COLOR_MATERIAL); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glOrtho(0.0F, this.displayWidth, this.displayHeight, 0.0F, 1000.0F, 3000.0F); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glTranslatef(0.0F, 0.0F, -2000.0F); + EaglerAdapter.glLineWidth(1.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glColor4f(1f, 1f, 1f, 1f); + Tessellator var5 = Tessellator.instance; + short var6 = 160; + int var7 = this.displayWidth - var6 - 10; + int var8 = this.displayHeight - var6 * 2; + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + var5.startDrawingQuads(); + var5.setColorRGBA_I(0, 200); + var5.addVertex((double) ((float) var7 - (float) var6 * 1.1F), (double) ((float) var8 - (float) var6 * 0.6F - 16.0F), 0.0D); + var5.addVertex((double) ((float) var7 - (float) var6 * 1.1F), (double) (var8 + var6 * 2), 0.0D); + var5.addVertex((double) ((float) var7 + (float) var6 * 1.1F), (double) (var8 + var6 * 2), 0.0D); + var5.addVertex((double) ((float) var7 + (float) var6 * 1.1F), (double) ((float) var8 - (float) var6 * 0.6F - 16.0F), 0.0D); + var5.draw(); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + double var9 = 0.0D; + int var13; + + EaglerAdapter.glDepthMask(true); + + for (int var11 = 0; var11 < var3.size(); ++var11) { + ProfilerResult var12 = (ProfilerResult) var3.get(var11); + var13 = MathHelper.floor_double(var12.field_76332_a / 4.0D) + 1; + var5.startDrawing(EaglerAdapter.GL_TRIANGLE_FAN); + var5.setColorOpaque_I(var12.func_76329_a()); + var5.addVertex((double) var7, (double) var8, 0.0D); + int var14; + float var15; + float var16; + float var17; + + for (var14 = var13; var14 >= 0; --var14) { + var15 = (float) ((var9 + var12.field_76332_a * (double) var14 / (double) var13) * Math.PI * 2.0D / 100.0D); + var16 = MathHelper.sin(var15) * (float) var6; + var17 = MathHelper.cos(var15) * (float) var6 * 0.5F; + var5.addVertex((double) ((float) var7 + var16), (double) ((float) var8 - var17), 0.0D); + } + + var5.draw(); + var5.startDrawing(EaglerAdapter.GL_TRIANGLE_STRIP); + var5.setColorOpaque_I((var12.func_76329_a() & 16711422) >> 1); + + for (var14 = var13; var14 >= 0; --var14) { + var15 = (float) ((var9 + var12.field_76332_a * (double) var14 / (double) var13) * Math.PI * 2.0D / 100.0D); + var16 = MathHelper.sin(var15) * (float) var6; + var17 = MathHelper.cos(var15) * (float) var6 * 0.5F; + var5.addVertex((double) ((float) var7 + var16), (double) ((float) var8 - var17), 0.0D); + var5.addVertex((double) ((float) var7 + var16), (double) ((float) var8 - var17 + 10.0F), 0.0D); + } + + var5.draw(); + var9 += var12.field_76332_a; + } + + DecimalFormat var18 = new DecimalFormat("##0.00"); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + String var19 = ""; + + if (!var4.field_76331_c.equals("unspecified")) { + var19 = var19 + "[0] "; + } + + if (var4.field_76331_c.length() == 0) { + var19 = var19 + "ROOT "; + } else { + var19 = var19 + var4.field_76331_c + " "; + } + + var13 = 16777215; + this.fontRenderer.drawStringWithShadow(var19, var7 - var6, var8 - var6 / 2 - 16, var13); + this.fontRenderer.drawStringWithShadow(var19 = var18.format(var4.field_76330_b) + "%", var7 + var6 - this.fontRenderer.getStringWidth(var19), var8 - var6 / 2 - 16, var13); + + for (int var21 = 0; var21 < var3.size(); ++var21) { + ProfilerResult var20 = (ProfilerResult) var3.get(var21); + String var22 = ""; + + if (var20.field_76331_c.equals("unspecified")) { + var22 = var22 + "[?] "; + } else { + var22 = var22 + "[" + (var21 + 1) + "] "; + } + + var22 = var22 + var20.field_76331_c; + this.fontRenderer.drawStringWithShadow(var22, var7 - var6, var8 + var6 / 2 + var21 * 8 + 20, var20.func_76329_a()); + this.fontRenderer.drawStringWithShadow(var22 = var18.format(var20.field_76332_a) + "%", var7 + var6 - 50 - this.fontRenderer.getStringWidth(var22), var8 + var6 / 2 + var21 * 8 + 20, var20.func_76329_a()); + this.fontRenderer.drawStringWithShadow(var22 = var18.format(var20.field_76330_b) + "%", var7 + var6 - this.fontRenderer.getStringWidth(var22), var8 + var6 / 2 + var21 * 8 + 20, var20.func_76329_a()); + } + } + } + + /** + * Called when the window is closing. Sets 'running' to false which allows the + * game loop to exit cleanly. + */ + public void shutdown() { + this.running = false; + } + + /** + * Will set the focus to ingame if the Minecraft window is the active with + * focus. Also clears any GUI screen currently displayed + */ + public void setIngameFocus() { + //if (EaglerAdapter.isFocused()) { + if (!this.inGameHasFocus) { + this.inGameHasFocus = true; + this.mouseHelper.grabMouseCursor(); + this.displayGuiScreen((GuiScreen) null); + this.leftClickCounter = 10000; + } + //} + } + + /** + * Resets the player keystate, disables the ingame focus, and ungrabs the mouse + * cursor. + */ + public void setIngameNotInFocus() { + if (this.inGameHasFocus) { + KeyBinding.unPressAllKeys(); + this.inGameHasFocus = false; + this.mouseHelper.ungrabMouseCursor(); + } + } + + /** + * Displays the ingame menu + */ + public void displayInGameMenu() { + if (this.currentScreen == null) { + this.displayGuiScreen(new GuiIngameMenu()); + } + } + + private void sendClickBlockToController(int par1, boolean par2) { + if (!par2) { + this.leftClickCounter = 0; + } + + if (par1 != 0 || this.leftClickCounter <= 0) { + if (par2 && this.objectMouseOver != null && this.objectMouseOver.typeOfHit == EnumMovingObjectType.TILE && par1 == 0) { + int var3 = this.objectMouseOver.blockX; + int var4 = this.objectMouseOver.blockY; + int var5 = this.objectMouseOver.blockZ; + this.playerController.onPlayerDamageBlock(var3, var4, var5, this.objectMouseOver.sideHit); + + if (this.thePlayer.canCurrentToolHarvestBlock(var3, var4, var5)) { + this.effectRenderer.addBlockHitEffects(var3, var4, var5, this.objectMouseOver.sideHit); + this.thePlayer.swingItem(); + } + } else { + this.playerController.resetBlockRemoving(); + } + } + } + + public void displayEaglercraftText(String s) { + if(this.thePlayer != null && shownPlayerMessages.add(s)) { + this.thePlayer.sendChatToPlayer("§6notice: §7"+s); + } + } + + /** + * Called whenever the mouse is clicked. Button clicked is 0 for left clicking + * and 1 for right clicking. Args: buttonClicked + */ + private void clickMouse(int par1) { + if (par1 != 0 || this.leftClickCounter <= 0) { + if (par1 == 0) { + this.thePlayer.swingItem(); + } + + if (par1 == 1) { + this.rightClickDelayTimer = 4; + } + + boolean var2 = true; + ItemStack var3 = this.thePlayer.inventory.getCurrentItem(); + + if (this.objectMouseOver == null) { + if (par1 == 0 && this.playerController.isNotCreative()) { + this.leftClickCounter = 10; + } + } else if (this.objectMouseOver.typeOfHit == EnumMovingObjectType.ENTITY) { + if (par1 == 0) { + this.playerController.attackEntity(this.thePlayer, this.objectMouseOver.entityHit); + } + + if (par1 == 1 && this.playerController.func_78768_b(this.thePlayer, this.objectMouseOver.entityHit)) { + var2 = false; + } + } else if (this.objectMouseOver.typeOfHit == EnumMovingObjectType.TILE) { + int var4 = this.objectMouseOver.blockX; + int var5 = this.objectMouseOver.blockY; + int var6 = this.objectMouseOver.blockZ; + int var7 = this.objectMouseOver.sideHit; + + if (par1 == 0) { + this.playerController.clickBlock(var4, var5, var6, this.objectMouseOver.sideHit); + } else { + int var8 = var3 != null ? var3.stackSize : 0; + + if (this.playerController.onPlayerRightClick(this.thePlayer, this.theWorld, var3, var4, var5, var6, var7, this.objectMouseOver.hitVec)) { + var2 = false; + this.thePlayer.swingItem(); + } + + if (var3 == null) { + return; + } + + if (var3.stackSize == 0) { + this.thePlayer.inventory.mainInventory[this.thePlayer.inventory.currentItem] = null; + } else if (var3.stackSize != var8 || this.playerController.isInCreativeMode()) { + this.entityRenderer.itemRenderer.resetEquippedProgress(); + } + } + } + + if (var2 && par1 == 1) { + ItemStack var9 = this.thePlayer.inventory.getCurrentItem(); + + if (var9 != null && this.playerController.sendUseItem(this.thePlayer, this.theWorld, var9)) { + this.entityRenderer.itemRenderer.resetEquippedProgress2(); + } + } + } + } + + /** + * Toggles fullscreen mode. + */ + public void toggleFullscreen() { + + } + + /** + * Called to resize the current screen. + */ + private void resize(int par1, int par2) { + this.displayWidth = par1 <= 0 ? 1 : par1; + this.displayHeight = par2 <= 0 ? 1 : par2; + + if (this.currentScreen != null) { + ScaledResolution var3 = new ScaledResolution(this.gameSettings, par1, par2); + int var4 = var3.getScaledWidth(); + int var5 = var3.getScaledHeight(); + this.currentScreen.setWorldAndResolution(this, var4, var5); + } + } + + /** + * Runs the current tick. + */ + public void runTick() { + if (this.rightClickDelayTimer > 0) { + --this.rightClickDelayTimer; + } + + this.mcProfiler.startSection("stats"); + this.mcProfiler.endStartSection("gui"); + + if (!this.isGamePaused) { + this.ingameGUI.updateTick(); + } + + this.mcProfiler.endStartSection("pick"); + this.entityRenderer.getMouseOver(1.0F); + this.mcProfiler.endStartSection("gameMode"); + + if (!this.isGamePaused && this.theWorld != null) { + this.playerController.updateController(); + } + + this.mcProfiler.endStartSection("textures"); + + if (!this.isGamePaused) { + this.renderEngine.updateDynamicTextures(); + } + + DefaultSkinRenderer.deleteOldSkins(); + + if (this.currentScreen == null && this.thePlayer != null) { + if (this.thePlayer.getHealth() <= 0) { + this.displayGuiScreen((GuiScreen) null); + } else if (this.thePlayer.isPlayerSleeping() && this.theWorld != null) { + this.displayGuiScreen(new GuiSleepMP()); + } + } else if (this.currentScreen != null && this.currentScreen instanceof GuiSleepMP && !this.thePlayer.isPlayerSleeping()) { + this.displayGuiScreen((GuiScreen) null); + } + + if (this.currentScreen != null) { + this.leftClickCounter = 10000; + } + + if (this.currentScreen != null) { + this.currentScreen.handleInput(); + + if (this.currentScreen != null) { + this.currentScreen.guiParticles.update(); + this.currentScreen.updateScreen(); + } + } + + GuiScreenVoiceChannel.tickVoiceConnection(); + + if (this.currentScreen == null || this.currentScreen.allowUserInput) { + this.mcProfiler.endStartSection("mouse"); + + while (EaglerAdapter.mouseNext()) { + KeyBinding.setKeyBindState(EaglerAdapter.mouseGetEventButton() - 100, EaglerAdapter.mouseGetEventButtonState()); + + if (EaglerAdapter.mouseGetEventButtonState()) { + KeyBinding.onTick(EaglerAdapter.mouseGetEventButton() - 100); + } + + long var1 = getSystemTime() - this.systemTime; + + if (var1 <= 200L) { + int var10 = EaglerAdapter.mouseGetEventDWheel(); + + if (var10 != 0) { + this.thePlayer.inventory.changeCurrentItem(var10); + + if (this.gameSettings.noclip) { + if (var10 > 0) { + var10 = 1; + } + + if (var10 < 0) { + var10 = -1; + } + + this.gameSettings.noclipRate += (float) var10 * 0.25F; + } + } + + if (this.currentScreen == null) { + if (!this.inGameHasFocus && EaglerAdapter.mouseGetEventButtonState()) { + this.setIngameFocus(); + } + } else if (this.currentScreen != null) { + this.currentScreen.handleMouseInput(); + } + } + } + + if (this.leftClickCounter > 0) { + --this.leftClickCounter; + } + + this.mcProfiler.endStartSection("keyboard"); + boolean var8; + + while (EaglerAdapter.keysNext()) { + KeyBinding.setKeyBindState(EaglerAdapter.getEventKey(), EaglerAdapter.getEventKeyState()); + + if (EaglerAdapter.getEventKeyState()) { + KeyBinding.onTick(EaglerAdapter.getEventKey()); + } + + boolean F3down = (this.gameSettings.keyBindFunction.pressed && EaglerAdapter.isKeyDown(4)); + + if (this.field_83002_am > 0L) { + if (getSystemTime() - this.field_83002_am >= 6000L) { + throw new RuntimeException("manual crash"); + } + + if (!EaglerAdapter.isKeyDown(46) || !F3down) { + this.field_83002_am = -1L; + } + } else if (F3down && EaglerAdapter.isKeyDown(46)) { + this.field_83002_am = getSystemTime(); + } + + if (EaglerAdapter.getEventKeyState()) { + if (EaglerAdapter.getEventKey() == 87) { + this.toggleFullscreen(); + } else { + if (this.currentScreen != null) { + this.currentScreen.handleKeyboardInput(); + } else { + if (EaglerAdapter.getEventKey() == 1) { + this.displayInGameMenu(); + } + + if (F3down && EaglerAdapter.getEventKey() == 31) { + this.forceReload(); + } + + if (F3down && EaglerAdapter.getEventKey() == 20) { + this.renderEngine.refreshTextures(); + this.renderGlobal.loadRenderers(); + EffectPipeline.reloadPipeline(); + FixedFunctionShader.refreshCoreGL(); + } + + if (F3down && EaglerAdapter.getEventKey() == 33) { + var8 = EaglerAdapter.isKeyDown(42) | EaglerAdapter.isKeyDown(54); + this.gameSettings.setOptionValue(EnumOptions.RENDER_DISTANCE, var8 ? -1 : 1); + } + + if (F3down && EaglerAdapter.getEventKey() == 30) { + this.renderGlobal.loadRenderers(); + } + + if (F3down && EaglerAdapter.getEventKey() == 35) { + this.gameSettings.advancedItemTooltips = !this.gameSettings.advancedItemTooltips; + this.gameSettings.saveOptions(); + } + + if (F3down && EaglerAdapter.getEventKey() == 48) { + RenderManager.field_85095_o = !RenderManager.field_85095_o; + } + + if (F3down && EaglerAdapter.getEventKey() == 25) { + this.gameSettings.pauseOnLostFocus = !this.gameSettings.pauseOnLostFocus; + this.gameSettings.saveOptions(); + } + + if (this.gameSettings.keyBindFunction.pressed && EaglerAdapter.getEventKey() == 2) { + this.gameSettings.hideGUI = !this.gameSettings.hideGUI; + } + + if (EaglerAdapter.getEventKey() == 4 && this.gameSettings.keyBindFunction.pressed) { + this.gameSettings.showDebugInfo = !this.gameSettings.showDebugInfo; + this.gameSettings.showDebugProfilerChart = true; + } + + if (EaglerAdapter.getEventKey() == 6 && this.gameSettings.keyBindFunction.pressed) { + ++this.gameSettings.thirdPersonView; + + if (this.gameSettings.thirdPersonView > 2) { + this.gameSettings.thirdPersonView = 0; + } + } + + if (EaglerAdapter.getEventKey() == 9 && this.gameSettings.keyBindFunction.pressed) { + this.gameSettings.smoothCamera = !this.gameSettings.smoothCamera; + } + } + + if(!this.gameSettings.keyBindFunction.pressed) { + for (int var9 = 0; var9 < 9; ++var9) { + if (EaglerAdapter.getEventKey() == 2 + var9) { + this.thePlayer.inventory.currentItem = var9; + } + } + } + + if (this.gameSettings.showDebugInfo && this.gameSettings.showDebugProfilerChart && !this.gameSettings.keyBindFunction.pressed) { + if (EaglerAdapter.getEventKey() == 11) { + this.updateDebugProfilerName(0); + } + + for (int var9 = 0; var9 < 9; ++var9) { + if (EaglerAdapter.getEventKey() == 2 + var9) { + this.updateDebugProfilerName(var9 + 1); + } + } + } + } + } + } + + var8 = this.gameSettings.chatVisibility != 2; + + while (this.gameSettings.keyBindInventory.isPressed()) { + this.displayGuiScreen(new GuiInventory(this.thePlayer)); + } + + while (this.gameSettings.keyBindDrop.isPressed()) { + this.thePlayer.dropOneItem(GuiScreen.isCtrlKeyDown()); + } + + while (this.gameSettings.keyBindChat.isPressed() && var8) { + this.displayGuiScreen(new GuiChat()); + } + + if (this.currentScreen == null && EaglerAdapter.isKeyDown(53) && var8) { + this.displayGuiScreen(new GuiChat("/")); + } + + if(this.gameSettings.keyBindSprint.pressed && !this.thePlayer.isSprinting() && this.thePlayer.canSprint() && !this.thePlayer.isCollidedHorizontally) { + this.thePlayer.setSprinting(true); + } + + if (this.thePlayer.isUsingItem()) { + if (!this.gameSettings.keyBindUseItem.pressed) { + this.playerController.onStoppedUsingItem(this.thePlayer); + } + + label379: + + while (true) { + if (!this.gameSettings.keyBindAttack.isPressed()) { + while (this.gameSettings.keyBindUseItem.isPressed()) { + ; + } + + while (true) { + if (this.gameSettings.keyBindPickBlock.isPressed()) { + continue; + } + + break label379; + } + } + } + } else { + while (this.gameSettings.keyBindAttack.isPressed()) { + this.clickMouse(0); + } + + while (this.gameSettings.keyBindUseItem.isPressed()) { + this.clickMouse(1); + } + + while (this.gameSettings.keyBindPickBlock.isPressed()) { + this.clickMiddleMouseButton(); + } + } + + if (this.gameSettings.keyBindUseItem.pressed && this.rightClickDelayTimer == 0 && !this.thePlayer.isUsingItem()) { + this.clickMouse(1); + } + + this.sendClickBlockToController(0, this.currentScreen == null && this.gameSettings.keyBindAttack.pressed && this.inGameHasFocus); + } + + if (this.theWorld != null) { + if (this.thePlayer != null) { + ++this.joinPlayerCounter; + + if (this.joinPlayerCounter == 30) { + this.joinPlayerCounter = 0; + this.theWorld.joinEntityInSurroundings(this.thePlayer); + } + } + + this.mcProfiler.endStartSection("gameRenderer"); + + if (!this.isGamePaused) { + this.entityRenderer.updateRenderer(); + } + + this.mcProfiler.endStartSection("levelRenderer"); + + if (!this.isGamePaused) { + this.renderGlobal.updateClouds(); + } + + this.mcProfiler.endStartSection("level"); + + if (!this.isGamePaused) { + if (this.theWorld.lastLightningBolt > 0) { + --this.theWorld.lastLightningBolt; + } + + this.theWorld.updateEntities(); + } + + if (!this.isGamePaused) { + this.theWorld.setAllowedSpawnTypes(this.theWorld.difficultySetting > 0, true); + + this.theWorld.tick(); + } + + this.mcProfiler.endStartSection("animateTick"); + + if (!this.isGamePaused && this.theWorld != null) { + this.theWorld.doVoidFogParticles(MathHelper.floor_double(this.thePlayer.posX), MathHelper.floor_double(this.thePlayer.posY), MathHelper.floor_double(this.thePlayer.posZ)); + } + + this.mcProfiler.endStartSection("particles"); + + if (!this.isGamePaused) { + this.effectRenderer.updateEffects(); + } + } else if (this.myNetworkManager != null) { + this.mcProfiler.endStartSection("pendingConnection"); + this.myNetworkManager.processReadPackets(); + } + + if(this.theWorld == null) { + this.sndManager.playTheTitleMusic(); + }else { + this.sndManager.stopTheTitleMusic(); + } + + this.mcProfiler.endSection(); + this.systemTime = getSystemTime(); + } + + private int titleMusicObj = -1; + + /** + * Forces a reload of the sound manager and all the resources. Called in game by + * holding 'F3' and pressing 'S'. + */ + private void forceReload() { + System.err.println("FORCING RELOAD!"); + + if (this.sndManager != null) { + this.sndManager.stopAllSounds(); + } + + this.sndManager = new SoundManager(); + this.sndManager.loadSoundSettings(this.gameSettings); + } + + /** + * unloads the current world first + */ + public void loadWorld(WorldClient par1WorldClient) { + this.loadWorld(par1WorldClient, ""); + } + + /** + * par2Str is displayed on the loading screen to the user unloads the current + * world first + */ + public void loadWorld(WorldClient par1WorldClient, String par2Str) { + if (par1WorldClient == null) { + NetClientHandler var3 = this.getNetHandler(); + + if (var3 != null) { + var3.cleanup(); + } + + if (this.myNetworkManager != null) { + this.myNetworkManager.closeConnections(); + } + } + + this.renderViewEntity = null; + this.myNetworkManager = null; + + if (this.loadingScreen != null) { + this.loadingScreen.resetProgressAndMessage(par2Str); + this.loadingScreen.resetProgresAndWorkingMessage(""); + } + + if (par1WorldClient == null && this.theWorld != null) { + if (this.texturePackList.getIsDownloading()) { + this.texturePackList.onDownloadFinished(); + } + + this.setServerData((ServerData) null); + this.integratedServerIsRunning = false; + } + + this.sndManager.playStreaming((String) null, 0.0F, 0.0F, 0.0F); + this.sndManager.stopAllSounds(); + this.theWorld = par1WorldClient; + + if (par1WorldClient != null) { + if (this.renderGlobal != null) { + this.renderGlobal.setWorldAndLoadRenderers(par1WorldClient); + } + + if (this.effectRenderer != null) { + this.effectRenderer.clearEffects(par1WorldClient); + } + + if (this.thePlayer == null) { + this.thePlayer = this.playerController.func_78754_a(par1WorldClient); + this.playerController.flipPlayer(this.thePlayer); + } + + if(!EaglerAdapter._wisAnisotropicPatched()) { + displayEaglercraftText("ANGLE Issue #4994 is unpatched on this browser, using fake aliased sampling on linear magnified terrain texture for anisotropic filtering. Chrome patch progress and information available at https://crbug.com/angleproject/4994"); + } + + displayEaglercraftText("go to -> Options -> Video Settings on the pause menu to enable fancy graphics"); + + this.thePlayer.preparePlayerToSpawn(); + par1WorldClient.spawnEntityInWorld(this.thePlayer); + this.thePlayer.movementInput = new MovementInputFromOptions(this.gameSettings); + this.playerController.setPlayerCapabilities(this.thePlayer); + this.renderViewEntity = this.thePlayer; + } else { + this.thePlayer = null; + } + + System.gc(); + this.systemTime = 0L; + } + + /* + public void installResource(String par1Str, File par2File) { + int var3 = par1Str.indexOf("/"); + String var4 = par1Str.substring(0, var3); + par1Str = par1Str.substring(var3 + 1); + + if (var4.equalsIgnoreCase("sound3")) { + this.sndManager.addSound(par1Str, par2File); + } else if (var4.equalsIgnoreCase("streaming")) { + this.sndManager.addStreaming(par1Str, par2File); + } else if (!var4.equalsIgnoreCase("music") && !var4.equalsIgnoreCase("newmusic")) { + if (var4.equalsIgnoreCase("lang")) { + StringTranslate.getInstance().func_94519_a(par1Str, par2File); + } + } else { + this.sndManager.addMusic(par1Str, par2File); + } + } + */ + + /** + * A String of renderGlobal.getDebugInfoRenders + */ + public String debugInfoRenders() { + return this.renderGlobal.getDebugInfoRenders(); + } + + /** + * Gets the information in the F3 menu about how many entities are + * infront/around you + */ + public String getEntityDebug() { + return this.renderGlobal.getDebugInfoEntities(); + } + + /** + * Gets the name of the world's current chunk provider + */ + public String getWorldProviderName() { + return this.theWorld.getProviderName(); + } + + /** + * A String of how many entities are in the world + */ + public String debugInfoEntities() { + return "P: " + this.effectRenderer.getStatistics() + ". T: " + this.theWorld.getDebugLoadedEntities(); + } + + public void setDimensionAndSpawnPlayer(int par1) { + this.theWorld.setSpawnLocation(); + this.theWorld.removeAllEntities(); + int var2 = 0; + + if (this.thePlayer != null) { + var2 = this.thePlayer.entityId; + this.theWorld.removeEntity(this.thePlayer); + } + + this.renderViewEntity = null; + this.thePlayer = this.playerController.func_78754_a(this.theWorld); + this.thePlayer.dimension = par1; + this.renderViewEntity = this.thePlayer; + this.thePlayer.preparePlayerToSpawn(); + this.theWorld.spawnEntityInWorld(this.thePlayer); + this.playerController.flipPlayer(this.thePlayer); + this.thePlayer.movementInput = new MovementInputFromOptions(this.gameSettings); + this.thePlayer.entityId = var2; + this.playerController.setPlayerCapabilities(this.thePlayer); + + if (this.currentScreen instanceof GuiGameOver) { + this.displayGuiScreen((GuiScreen) null); + } + } + + /** + * Sets whether this is a demo or not. + */ + void setDemo(boolean par1) { + this.isDemo = par1; + } + + /** + * Gets whether this is a demo or not. + */ + public final boolean isDemo() { + return this.isDemo; + } + + /** + * Returns the NetClientHandler. + */ + public NetClientHandler getNetHandler() { + return this.thePlayer != null ? this.thePlayer.sendQueue : null; + } + + public static boolean isGuiEnabled() { + return theMinecraft == null || !theMinecraft.gameSettings.hideGUI; + } + + public static boolean isFancyGraphicsEnabled() { + return theMinecraft != null && theMinecraft.gameSettings.fancyGraphics; + } + + /** + * Returns if ambient occlusion is enabled + */ + public static boolean isAmbientOcclusionEnabled() { + return theMinecraft != null && theMinecraft.gameSettings.ambientOcclusion != 0; + } + + /** + * Returns true if the message is a client command and should not be sent to the + * server. However there are no such commands at this point in time. + */ + public boolean handleClientCommand(String par1Str) { + return !par1Str.startsWith("/") ? false : false; + } + + /** + * Called when the middle mouse button gets clicked + */ + private void clickMiddleMouseButton() { + if (this.objectMouseOver != null) { + boolean var1 = this.thePlayer.capabilities.isCreativeMode; + int var3 = 0; + boolean var4 = false; + int var2; + int var5; + + if (this.objectMouseOver.typeOfHit == EnumMovingObjectType.TILE) { + var5 = this.objectMouseOver.blockX; + int var6 = this.objectMouseOver.blockY; + int var7 = this.objectMouseOver.blockZ; + Block var8 = Block.blocksList[this.theWorld.getBlockId(var5, var6, var7)]; + + if (var8 == null) { + return; + } + + var2 = var8.idPicked(this.theWorld, var5, var6, var7); + + if (var2 == 0) { + return; + } + + var4 = Item.itemsList[var2].getHasSubtypes(); + int var9 = var2 < 256 && !Block.blocksList[var8.blockID].isFlowerPot() ? var2 : var8.blockID; + var3 = Block.blocksList[var9].getDamageValue(this.theWorld, var5, var6, var7); + } else { + if (this.objectMouseOver.typeOfHit != EnumMovingObjectType.ENTITY || this.objectMouseOver.entityHit == null || !var1) { + return; + } + + if (this.objectMouseOver.entityHit instanceof EntityPainting) { + var2 = Item.painting.itemID; + } else if (this.objectMouseOver.entityHit instanceof EntityItemFrame) { + EntityItemFrame var10 = (EntityItemFrame) this.objectMouseOver.entityHit; + + if (var10.getDisplayedItem() == null) { + var2 = Item.itemFrame.itemID; + } else { + var2 = var10.getDisplayedItem().itemID; + var3 = var10.getDisplayedItem().getItemDamage(); + var4 = true; + } + } else if (this.objectMouseOver.entityHit instanceof EntityMinecart) { + EntityMinecart var11 = (EntityMinecart) this.objectMouseOver.entityHit; + + if (var11.getMinecartType() == 2) { + var2 = Item.minecartPowered.itemID; + } else if (var11.getMinecartType() == 1) { + var2 = Item.minecartCrate.itemID; + } else if (var11.getMinecartType() == 3) { + var2 = Item.minecartTnt.itemID; + } else if (var11.getMinecartType() == 5) { + var2 = Item.minecartHopper.itemID; + } else { + var2 = Item.minecartEmpty.itemID; + } + } else if (this.objectMouseOver.entityHit instanceof EntityBoat) { + var2 = Item.boat.itemID; + } else { + var2 = Item.monsterPlacer.itemID; + var3 = EntityList.getEntityID(this.objectMouseOver.entityHit); + var4 = true; + + if (var3 <= 0 || !EntityList.entityEggs.containsKey(Integer.valueOf(var3))) { + return; + } + } + } + + this.thePlayer.inventory.setCurrentItem(var2, var3, var4, var1); + + if (var1) { + var5 = this.thePlayer.inventoryContainer.inventorySlots.size() - 9 + this.thePlayer.inventory.currentItem; + this.playerController.sendSlotPacket(this.thePlayer.inventory.getStackInSlot(this.thePlayer.inventory.currentItem), var5); + } + } + } + + /** + * Return the singleton Minecraft instance for the game + */ + public static Minecraft getMinecraft() { + return theMinecraft; + } + + /** + * Sets refreshTexturePacksScheduled to true, triggering a texture pack refresh + * next time the while(running) loop is run + */ + public void scheduleTexturePackRefresh() { + this.refreshTexturePacksScheduled = true; + } + + /** + * Set the current ServerData instance. + */ + public void setServerData(ServerData par1ServerData) { + this.currentServerData = par1ServerData; + } + + /** + * Get the current ServerData instance. + */ + public ServerData getServerData() { + return this.currentServerData; + } + + public boolean isIntegratedServerRunning() { + return this.integratedServerIsRunning; + } + + /** + * Returns true if there is only one player playing, and the current server is + * the integrated one. + */ + public boolean isSingleplayer() { + return false; + } + + /** + * Gets the system time in milliseconds. + */ + public static long getSystemTime() { + return System.currentTimeMillis(); + } + + /** + * Returns whether we're in full screen or not. + */ + public boolean isFullScreen() { + return this.fullscreen; + } + + public static int getGLMaximumTextureSize() { + return 8192; + } +} diff --git a/src/main/java/net/minecraft/src/AABBLocalPool.java b/src/main/java/net/minecraft/src/AABBLocalPool.java new file mode 100644 index 0000000..b0454bb --- /dev/null +++ b/src/main/java/net/minecraft/src/AABBLocalPool.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +final class AABBLocalPool extends ThreadLocal { + protected AABBPool createNewDefaultPool() { + return new AABBPool(300, 2000); + } + + protected Object initialValue() { + return this.createNewDefaultPool(); + } +} diff --git a/src/main/java/net/minecraft/src/AABBPool.java b/src/main/java/net/minecraft/src/AABBPool.java new file mode 100644 index 0000000..58a935a --- /dev/null +++ b/src/main/java/net/minecraft/src/AABBPool.java @@ -0,0 +1,96 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + + + +public class AABBPool { + /** + * Maximum number of times the pool can be "cleaned" before the list is shrunk + */ + private final int maxNumCleans; + + /** + * Number of Pool entries to remove when cleanPool is called maxNumCleans times. + */ + private final int numEntriesToRemove; + + /** List of AABB stored in this Pool */ + private final List listAABB = new ArrayList(); + + /** Next index to use when adding a Pool Entry. */ + private int nextPoolIndex = 0; + + /** + * Largest index reached by this Pool (can be reset to 0 upon calling cleanPool) + */ + private int maxPoolIndex = 0; + + /** Number of times this Pool has been cleaned */ + private int numCleans = 0; + + public AABBPool(int par1, int par2) { + this.maxNumCleans = par1; + this.numEntriesToRemove = par2; + } + + /** + * Creates a new AABB, or reuses one that's no longer in use. Parameters: minX, + * minY, minZ, maxX, maxY, maxZ. AABBs returned from this function should only + * be used for one frame or tick, as after that they will be reused. + */ + public AxisAlignedBB getAABB(double par1, double par3, double par5, double par7, double par9, double par11) { + AxisAlignedBB var13; + + if (this.nextPoolIndex >= this.listAABB.size()) { + var13 = new AxisAlignedBB(par1, par3, par5, par7, par9, par11); + this.listAABB.add(var13); + } else { + var13 = (AxisAlignedBB) this.listAABB.get(this.nextPoolIndex); + var13.setBounds(par1, par3, par5, par7, par9, par11); + } + + ++this.nextPoolIndex; + return var13; + } + + /** + * Marks the pool as "empty", starting over when adding new entries. If this is + * called maxNumCleans times, the list size is reduced + */ + public void cleanPool() { + if (this.nextPoolIndex > this.maxPoolIndex) { + this.maxPoolIndex = this.nextPoolIndex; + } + + if (this.numCleans++ == this.maxNumCleans) { + int var1 = Math.max(this.maxPoolIndex, this.listAABB.size() - this.numEntriesToRemove); + + while (this.listAABB.size() > var1) { + this.listAABB.remove(var1); + } + + this.maxPoolIndex = 0; + this.numCleans = 0; + } + + this.nextPoolIndex = 0; + } + + /** + * Clears the AABBPool + */ + public void clearPool() { + this.nextPoolIndex = 0; + this.listAABB.clear(); + } + + public int getlistAABBsize() { + return this.listAABB.size(); + } + + public int getnextPoolIndex() { + return this.nextPoolIndex; + } +} diff --git a/src/main/java/net/minecraft/src/Achievement.java b/src/main/java/net/minecraft/src/Achievement.java new file mode 100644 index 0000000..a878814 --- /dev/null +++ b/src/main/java/net/minecraft/src/Achievement.java @@ -0,0 +1,153 @@ +package net.minecraft.src; + +public class Achievement extends StatBase { + /** + * Is the column (related to center of achievement gui, in 24 pixels unit) that + * the achievement will be displayed. + */ + public final int displayColumn; + + /** + * Is the row (related to center of achievement gui, in 24 pixels unit) that the + * achievement will be displayed. + */ + public final int displayRow; + + /** + * Holds the parent achievement, that must be taken before this achievement is + * avaiable. + */ + public final Achievement parentAchievement; + + /** + * Holds the description of the achievement, ready to be formatted and/or + * displayed. + */ + private final String achievementDescription; + + /** + * Holds a string formatter for the achievement, some of then needs extra + * dynamic info - like the key used to open the inventory. + */ + private IStatStringFormat statStringFormatter; + + /** + * Holds the ItemStack that will be used to draw the achievement into the GUI. + */ + public final ItemStack theItemStack; + + /** + * Special achievements have a 'spiked' (on normal texture pack) frame, special + * achievements are the hardest ones to achieve. + */ + private boolean isSpecial; + + public Achievement(int par1, String par2Str, int par3, int par4, Item par5Item, Achievement par6Achievement) { + this(par1, par2Str, par3, par4, new ItemStack(par5Item), par6Achievement); + } + + public Achievement(int par1, String par2Str, int par3, int par4, Block par5Block, Achievement par6Achievement) { + this(par1, par2Str, par3, par4, new ItemStack(par5Block), par6Achievement); + } + + public Achievement(int par1, String par2Str, int par3, int par4, ItemStack par5ItemStack, Achievement par6Achievement) { + super(5242880 + par1, "achievement." + par2Str); + this.theItemStack = par5ItemStack; + this.achievementDescription = "achievement." + par2Str + ".desc"; + this.displayColumn = par3; + this.displayRow = par4; + + if (par3 < AchievementList.minDisplayColumn) { + AchievementList.minDisplayColumn = par3; + } + + if (par4 < AchievementList.minDisplayRow) { + AchievementList.minDisplayRow = par4; + } + + if (par3 > AchievementList.maxDisplayColumn) { + AchievementList.maxDisplayColumn = par3; + } + + if (par4 > AchievementList.maxDisplayRow) { + AchievementList.maxDisplayRow = par4; + } + + this.parentAchievement = par6Achievement; + } + + /** + * Indicates whether or not the given achievement or statistic is independent + * (i.e., lacks prerequisites for being update). + */ + public Achievement setIndependent() { + this.isIndependent = true; + return this; + } + + /** + * Special achievements have a 'spiked' (on normal texture pack) frame, special + * achievements are the hardest ones to achieve. + */ + public Achievement setSpecial() { + this.isSpecial = true; + return this; + } + + /** + * Adds the achievement on the internal list of registered achievements, also, + * it's check for duplicated id's. + */ + public Achievement registerAchievement() { + super.registerStat(); + AchievementList.achievementList.add(this); + return this; + } + + /** + * Returns whether or not the StatBase-derived class is a statistic (running + * counter) or an achievement (one-shot). + */ + public boolean isAchievement() { + return true; + } + + /** + * Returns the fully description of the achievement - ready to be displayed on + * screen. + */ + public String getDescription() { + return this.statStringFormatter != null ? this.statStringFormatter.formatString(StatCollector.translateToLocal(this.achievementDescription)) : StatCollector.translateToLocal(this.achievementDescription); + } + + /** + * Defines a string formatter for the achievement. + */ + public Achievement setStatStringFormatter(IStatStringFormat par1IStatStringFormat) { + this.statStringFormatter = par1IStatStringFormat; + return this; + } + + /** + * Special achievements have a 'spiked' (on normal texture pack) frame, special + * achievements are the hardest ones to achieve. + */ + public boolean getSpecial() { + return this.isSpecial; + } + + /** + * Register the stat into StatList. + */ + public StatBase registerStat() { + return this.registerAchievement(); + } + + /** + * Initializes the current stat as independent (i.e., lacking prerequisites for + * being updated) and returns the current instance. + */ + public StatBase initIndependentStat() { + return this.setIndependent(); + } +} diff --git a/src/main/java/net/minecraft/src/AchievementList.java b/src/main/java/net/minecraft/src/AchievementList.java new file mode 100644 index 0000000..249b52e --- /dev/null +++ b/src/main/java/net/minecraft/src/AchievementList.java @@ -0,0 +1,110 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +public class AchievementList { + /** Is the smallest column used to display a achievement on the GUI. */ + public static int minDisplayColumn; + + /** Is the smallest row used to display a achievement on the GUI. */ + public static int minDisplayRow; + + /** Is the biggest column used to display a achievement on the GUI. */ + public static int maxDisplayColumn; + + /** Is the biggest row used to display a achievement on the GUI. */ + public static int maxDisplayRow; + + /** Holds a list of all registered achievements. */ + public static List achievementList = new ArrayList(); + + /** Is the 'open inventory' achievement. */ + public static Achievement openInventory = (new Achievement(0, "openInventory", 0, 0, Item.book, (Achievement) null)).setIndependent().registerAchievement(); + + /** Is the 'getting wood' achievement. */ + public static Achievement mineWood = (new Achievement(1, "mineWood", 2, 1, Block.wood, openInventory)).registerAchievement(); + + /** Is the 'benchmarking' achievement. */ + public static Achievement buildWorkBench = (new Achievement(2, "buildWorkBench", 4, -1, Block.workbench, mineWood)).registerAchievement(); + + /** Is the 'time to mine' achievement. */ + public static Achievement buildPickaxe = (new Achievement(3, "buildPickaxe", 4, 2, Item.pickaxeWood, buildWorkBench)).registerAchievement(); + + /** Is the 'hot topic' achievement. */ + public static Achievement buildFurnace = (new Achievement(4, "buildFurnace", 3, 4, Block.furnaceIdle, buildPickaxe)).registerAchievement(); + + /** Is the 'acquire hardware' achievement. */ + public static Achievement acquireIron = (new Achievement(5, "acquireIron", 1, 4, Item.ingotIron, buildFurnace)).registerAchievement(); + + /** Is the 'time to farm' achievement. */ + public static Achievement buildHoe = (new Achievement(6, "buildHoe", 2, -3, Item.hoeWood, buildWorkBench)).registerAchievement(); + + /** Is the 'bake bread' achievement. */ + public static Achievement makeBread = (new Achievement(7, "makeBread", -1, -3, Item.bread, buildHoe)).registerAchievement(); + + /** Is the 'the lie' achievement. */ + public static Achievement bakeCake = (new Achievement(8, "bakeCake", 0, -5, Item.cake, buildHoe)).registerAchievement(); + + /** Is the 'getting a upgrade' achievement. */ + public static Achievement buildBetterPickaxe = (new Achievement(9, "buildBetterPickaxe", 6, 2, Item.pickaxeStone, buildPickaxe)).registerAchievement(); + + /** Is the 'delicious fish' achievement. */ + public static Achievement cookFish = (new Achievement(10, "cookFish", 2, 6, Item.fishCooked, buildFurnace)).registerAchievement(); + + /** Is the 'on a rail' achievement */ + public static Achievement onARail = (new Achievement(11, "onARail", 2, 3, Block.rail, acquireIron)).setSpecial().registerAchievement(); + + /** Is the 'time to strike' achievement. */ + public static Achievement buildSword = (new Achievement(12, "buildSword", 6, -1, Item.swordWood, buildWorkBench)).registerAchievement(); + + /** Is the 'monster hunter' achievement. */ + public static Achievement killEnemy = (new Achievement(13, "killEnemy", 8, -1, Item.bone, buildSword)).registerAchievement(); + + /** is the 'cow tipper' achievement. */ + public static Achievement killCow = (new Achievement(14, "killCow", 7, -3, Item.leather, buildSword)).registerAchievement(); + + /** Is the 'when pig fly' achievement. */ + public static Achievement flyPig = (new Achievement(15, "flyPig", 8, -4, Item.saddle, killCow)).setSpecial().registerAchievement(); + + /** The achievement for killing a Skeleton from 50 meters aways. */ + public static Achievement snipeSkeleton = (new Achievement(16, "snipeSkeleton", 7, 0, Item.bow, killEnemy)).setSpecial().registerAchievement(); + + /** Is the 'DIAMONDS!' achievement */ + public static Achievement diamonds = (new Achievement(17, "diamonds", -1, 5, Item.diamond, acquireIron)).registerAchievement(); + + /** Is the 'We Need to Go Deeper' achievement */ + public static Achievement portal = (new Achievement(18, "portal", -1, 7, Block.obsidian, diamonds)).registerAchievement(); + + /** Is the 'Return to Sender' achievement */ + public static Achievement ghast = (new Achievement(19, "ghast", -4, 8, Item.ghastTear, portal)).setSpecial().registerAchievement(); + + /** Is the 'Into Fire' achievement */ + public static Achievement blazeRod = (new Achievement(20, "blazeRod", 0, 9, Item.blazeRod, portal)).registerAchievement(); + + /** Is the 'Local Brewery' achievement */ + public static Achievement potion = (new Achievement(21, "potion", 2, 8, Item.potion, blazeRod)).registerAchievement(); + + /** Is the 'The End?' achievement */ + public static Achievement theEnd = (new Achievement(22, "theEnd", 3, 10, Item.eyeOfEnder, blazeRod)).setSpecial().registerAchievement(); + + /** Is the 'The End.' achievement */ + public static Achievement theEnd2 = (new Achievement(23, "theEnd2", 4, 13, Block.dragonEgg, theEnd)).setSpecial().registerAchievement(); + + /** Is the 'Enchanter' achievement */ + public static Achievement enchantments = (new Achievement(24, "enchantments", -4, 4, Block.enchantmentTable, diamonds)).registerAchievement(); + public static Achievement overkill = (new Achievement(25, "overkill", -4, 1, Item.swordDiamond, enchantments)).setSpecial().registerAchievement(); + + /** Is the 'Librarian' achievement */ + public static Achievement bookcase = (new Achievement(26, "bookcase", -3, 6, Block.bookShelf, enchantments)).registerAchievement(); + + /** + * A stub functions called to make the static initializer for this class run. + */ + public static void init() { + } + + static { + System.out.println(achievementList.size() + " achievements"); + } +} diff --git a/src/main/java/net/minecraft/src/AchievementMap.java b/src/main/java/net/minecraft/src/AchievementMap.java new file mode 100644 index 0000000..78c273f --- /dev/null +++ b/src/main/java/net/minecraft/src/AchievementMap.java @@ -0,0 +1,33 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.Map; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +public class AchievementMap { + /** Holds the singleton instance of AchievementMap. */ + public static AchievementMap instance = new AchievementMap(); + + /** Maps a achievement id with it's unique GUID. */ + private Map guidMap = new HashMap(); + + private AchievementMap() { + try { + for(String str : EaglerAdapter.fileContentsLines("/achievement/map.txt")) { + String[] var3 = str.split(","); + int var4 = Integer.parseInt(var3[0]); + this.guidMap.put(Integer.valueOf(var4), var3[1]); + } + } catch (Exception var5) { + var5.printStackTrace(); + } + } + + /** + * Returns the unique GUID of a achievement id. + */ + public static String getGuid(int par0) { + return (String) instance.guidMap.get(Integer.valueOf(par0)); + } +} diff --git a/src/main/java/net/minecraft/src/ActiveRenderInfo.java b/src/main/java/net/minecraft/src/ActiveRenderInfo.java new file mode 100644 index 0000000..54a4964 --- /dev/null +++ b/src/main/java/net/minecraft/src/ActiveRenderInfo.java @@ -0,0 +1,110 @@ +package net.minecraft.src; + +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +import net.lax1dude.eaglercraft.EaglerAdapter; + + +public class ActiveRenderInfo { + /** The calculated view object X coordinate */ + public static float objectX = 0.0F; + + /** The calculated view object Y coordinate */ + public static float objectY = 0.0F; + + /** The calculated view object Z coordinate */ + public static float objectZ = 0.0F; + + /** The current GL viewport */ + private static int[] viewport = new int[4]; + + /** The current GL modelview matrix */ + private static FloatBuffer modelview = GLAllocation.createDirectFloatBuffer(16); + + /** The current GL projection matrix */ + private static FloatBuffer projection = GLAllocation.createDirectFloatBuffer(16); + + /** The computed view object coordinates */ + private static FloatBuffer objectCoords = GLAllocation.createDirectFloatBuffer(3); + + /** The X component of the entity's yaw rotation */ + public static float rotationX; + + /** The combined X and Z components of the entity's pitch rotation */ + public static float rotationXZ; + + /** The Z component of the entity's yaw rotation */ + public static float rotationZ; + + /** + * The Y component (scaled along the Z axis) of the entity's pitch rotation + */ + public static float rotationYZ; + + /** + * The Y component (scaled along the X axis) of the entity's pitch rotation + */ + public static float rotationXY; + + /** + * Updates the current render info and camera location based on entity look + * angles and 1st/3rd person view mode + */ + public static void updateRenderInfo(EntityPlayer par0EntityPlayer, boolean par1) { + modelview.clear(); projection.clear(); + EaglerAdapter.glGetFloat(EaglerAdapter.GL_MODELVIEW_MATRIX, modelview); + EaglerAdapter.glGetFloat(EaglerAdapter.GL_PROJECTION_MATRIX, projection); + EaglerAdapter.glGetInteger(EaglerAdapter.GL_VIEWPORT, viewport); + modelview.position(0); projection.position(0); objectCoords.position(0); + float var2 = (float) ((viewport[0] + viewport[2]) / 2); + float var3 = (float) ((viewport[1] + viewport[3]) / 2); + EaglerAdapter.gluUnProject(var2, var3, 0.0F, modelview, projection, viewport, objectCoords); + objectX = objectCoords.get(0); + objectY = objectCoords.get(1); + objectZ = objectCoords.get(2); + int var4 = par1 ? 1 : 0; + float var5 = par0EntityPlayer.rotationPitch; + float var6 = par0EntityPlayer.rotationYaw; + rotationX = MathHelper.cos(var6 * (float) Math.PI / 180.0F) * (float) (1 - var4 * 2); + rotationZ = MathHelper.sin(var6 * (float) Math.PI / 180.0F) * (float) (1 - var4 * 2); + rotationYZ = -rotationZ * MathHelper.sin(var5 * (float) Math.PI / 180.0F) * (float) (1 - var4 * 2); + rotationXY = rotationX * MathHelper.sin(var5 * (float) Math.PI / 180.0F) * (float) (1 - var4 * 2); + rotationXZ = MathHelper.cos(var5 * (float) Math.PI / 180.0F); + } + + /** + * Returns a vector representing the projection along the given entity's view + * for the given distance + */ + public static Vec3 projectViewFromEntity(EntityLiving par0EntityLiving, double par1) { + double var3 = par0EntityLiving.prevPosX + (par0EntityLiving.posX - par0EntityLiving.prevPosX) * par1; + double var5 = par0EntityLiving.prevPosY + (par0EntityLiving.posY - par0EntityLiving.prevPosY) * par1 + (double) par0EntityLiving.getEyeHeight(); + double var7 = par0EntityLiving.prevPosZ + (par0EntityLiving.posZ - par0EntityLiving.prevPosZ) * par1; + double var9 = var3 + (double) (objectX * 1.0F); + double var11 = var5 + (double) (objectY * 1.0F); + double var13 = var7 + (double) (objectZ * 1.0F); + return par0EntityLiving.worldObj.getWorldVec3Pool().getVecFromPool(var9, var11, var13); + } + + /** + * Returns the block ID at the current camera location (either air or fluid), + * taking into account the height of fluid blocks + */ + public static int getBlockIdAtEntityViewpoint(World par0World, EntityLiving par1EntityLiving, float par2) { + Vec3 var3 = projectViewFromEntity(par1EntityLiving, (double) par2); + ChunkPosition var4 = new ChunkPosition(var3); + int var5 = par0World.getBlockId(var4.x, var4.y, var4.z); + + if (var5 != 0 && Block.blocksList[var5].blockMaterial.isLiquid()) { + float var6 = BlockFluid.getFluidHeightPercent(par0World.getBlockMetadata(var4.x, var4.y, var4.z)) - 0.11111111F; + float var7 = (float) (var4.y + 1) - var6; + + if (var3.yCoord >= (double) var7) { + var5 = par0World.getBlockId(var4.x, var4.y + 1, var4.z); + } + } + + return var5; + } +} diff --git a/src/main/java/net/minecraft/src/AxisAlignedBB.java b/src/main/java/net/minecraft/src/AxisAlignedBB.java new file mode 100644 index 0000000..1b9802e --- /dev/null +++ b/src/main/java/net/minecraft/src/AxisAlignedBB.java @@ -0,0 +1,410 @@ +package net.minecraft.src; + +public class AxisAlignedBB { + /** ThreadLocal AABBPool */ + private static final ThreadLocal theAABBLocalPool = new AABBLocalPool(); + public double minX; + public double minY; + public double minZ; + public double maxX; + public double maxY; + public double maxZ; + + /** + * Returns a bounding box with the specified bounds. Args: minX, minY, minZ, + * maxX, maxY, maxZ + */ + public static AxisAlignedBB getBoundingBox(double par0, double par2, double par4, double par6, double par8, double par10) { + return new AxisAlignedBB(par0, par2, par4, par6, par8, par10); + } + + /** + * Gets the ThreadLocal AABBPool + */ + public static AABBPool getAABBPool() { + return (AABBPool) theAABBLocalPool.get(); + } + + protected AxisAlignedBB(double par1, double par3, double par5, double par7, double par9, double par11) { + this.minX = par1; + this.minY = par3; + this.minZ = par5; + this.maxX = par7; + this.maxY = par9; + this.maxZ = par11; + } + + /** + * Sets the bounds of the bounding box. Args: minX, minY, minZ, maxX, maxY, maxZ + */ + public AxisAlignedBB setBounds(double par1, double par3, double par5, double par7, double par9, double par11) { + this.minX = par1; + this.minY = par3; + this.minZ = par5; + this.maxX = par7; + this.maxY = par9; + this.maxZ = par11; + return this; + } + + /** + * Adds the coordinates to the bounding box extending it if the point lies + * outside the current ranges. Args: x, y, z + */ + public AxisAlignedBB addCoord(double par1, double par3, double par5) { + double var7 = this.minX; + double var9 = this.minY; + double var11 = this.minZ; + double var13 = this.maxX; + double var15 = this.maxY; + double var17 = this.maxZ; + + if (par1 < 0.0D) { + var7 += par1; + } + + if (par1 > 0.0D) { + var13 += par1; + } + + if (par3 < 0.0D) { + var9 += par3; + } + + if (par3 > 0.0D) { + var15 += par3; + } + + if (par5 < 0.0D) { + var11 += par5; + } + + if (par5 > 0.0D) { + var17 += par5; + } + + return getAABBPool().getAABB(var7, var9, var11, var13, var15, var17); + } + + /** + * Returns a bounding box expanded by the specified vector (if negative numbers + * are given it will shrink). Args: x, y, z + */ + public AxisAlignedBB expand(double par1, double par3, double par5) { + double var7 = this.minX - par1; + double var9 = this.minY - par3; + double var11 = this.minZ - par5; + double var13 = this.maxX + par1; + double var15 = this.maxY + par3; + double var17 = this.maxZ + par5; + return getAABBPool().getAABB(var7, var9, var11, var13, var15, var17); + } + + /** + * Returns a bounding box offseted by the specified vector (if negative numbers + * are given it will shrink). Args: x, y, z + */ + public AxisAlignedBB getOffsetBoundingBox(double par1, double par3, double par5) { + return getAABBPool().getAABB(this.minX + par1, this.minY + par3, this.minZ + par5, this.maxX + par1, this.maxY + par3, this.maxZ + par5); + } + + /** + * if instance and the argument bounding boxes overlap in the Y and Z + * dimensions, calculate the offset between them in the X dimension. return var2 + * if the bounding boxes do not overlap or if var2 is closer to 0 then the + * calculated offset. Otherwise return the calculated offset. + */ + public double calculateXOffset(AxisAlignedBB par1AxisAlignedBB, double par2) { + if (par1AxisAlignedBB.maxY > this.minY && par1AxisAlignedBB.minY < this.maxY) { + if (par1AxisAlignedBB.maxZ > this.minZ && par1AxisAlignedBB.minZ < this.maxZ) { + double var4; + + if (par2 > 0.0D && par1AxisAlignedBB.maxX <= this.minX) { + var4 = this.minX - par1AxisAlignedBB.maxX; + + if (var4 < par2) { + par2 = var4; + } + } + + if (par2 < 0.0D && par1AxisAlignedBB.minX >= this.maxX) { + var4 = this.maxX - par1AxisAlignedBB.minX; + + if (var4 > par2) { + par2 = var4; + } + } + + return par2; + } else { + return par2; + } + } else { + return par2; + } + } + + /** + * if instance and the argument bounding boxes overlap in the X and Z + * dimensions, calculate the offset between them in the Y dimension. return var2 + * if the bounding boxes do not overlap or if var2 is closer to 0 then the + * calculated offset. Otherwise return the calculated offset. + */ + public double calculateYOffset(AxisAlignedBB par1AxisAlignedBB, double par2) { + if (par1AxisAlignedBB.maxX > this.minX && par1AxisAlignedBB.minX < this.maxX) { + if (par1AxisAlignedBB.maxZ > this.minZ && par1AxisAlignedBB.minZ < this.maxZ) { + double var4; + + if (par2 > 0.0D && par1AxisAlignedBB.maxY <= this.minY) { + var4 = this.minY - par1AxisAlignedBB.maxY; + + if (var4 < par2) { + par2 = var4; + } + } + + if (par2 < 0.0D && par1AxisAlignedBB.minY >= this.maxY) { + var4 = this.maxY - par1AxisAlignedBB.minY; + + if (var4 > par2) { + par2 = var4; + } + } + + return par2; + } else { + return par2; + } + } else { + return par2; + } + } + + /** + * if instance and the argument bounding boxes overlap in the Y and X + * dimensions, calculate the offset between them in the Z dimension. return var2 + * if the bounding boxes do not overlap or if var2 is closer to 0 then the + * calculated offset. Otherwise return the calculated offset. + */ + public double calculateZOffset(AxisAlignedBB par1AxisAlignedBB, double par2) { + if (par1AxisAlignedBB.maxX > this.minX && par1AxisAlignedBB.minX < this.maxX) { + if (par1AxisAlignedBB.maxY > this.minY && par1AxisAlignedBB.minY < this.maxY) { + double var4; + + if (par2 > 0.0D && par1AxisAlignedBB.maxZ <= this.minZ) { + var4 = this.minZ - par1AxisAlignedBB.maxZ; + + if (var4 < par2) { + par2 = var4; + } + } + + if (par2 < 0.0D && par1AxisAlignedBB.minZ >= this.maxZ) { + var4 = this.maxZ - par1AxisAlignedBB.minZ; + + if (var4 > par2) { + par2 = var4; + } + } + + return par2; + } else { + return par2; + } + } else { + return par2; + } + } + + /** + * Returns whether the given bounding box intersects with this one. Args: + * axisAlignedBB + */ + public boolean intersectsWith(AxisAlignedBB par1AxisAlignedBB) { + return par1AxisAlignedBB.maxX > this.minX && par1AxisAlignedBB.minX < this.maxX + ? (par1AxisAlignedBB.maxY > this.minY && par1AxisAlignedBB.minY < this.maxY ? par1AxisAlignedBB.maxZ > this.minZ && par1AxisAlignedBB.minZ < this.maxZ : false) + : false; + } + + /** + * Offsets the current bounding box by the specified coordinates. Args: x, y, z + */ + public AxisAlignedBB offset(double par1, double par3, double par5) { + this.minX += par1; + this.minY += par3; + this.minZ += par5; + this.maxX += par1; + this.maxY += par3; + this.maxZ += par5; + return this; + } + + /** + * Returns if the supplied Vec3D is completely inside the bounding box + */ + public boolean isVecInside(Vec3 par1Vec3) { + return par1Vec3.xCoord > this.minX && par1Vec3.xCoord < this.maxX ? (par1Vec3.yCoord > this.minY && par1Vec3.yCoord < this.maxY ? par1Vec3.zCoord > this.minZ && par1Vec3.zCoord < this.maxZ : false) : false; + } + + /** + * Returns the average length of the edges of the bounding box. + */ + public double getAverageEdgeLength() { + double var1 = this.maxX - this.minX; + double var3 = this.maxY - this.minY; + double var5 = this.maxZ - this.minZ; + return (var1 + var3 + var5) / 3.0D; + } + + /** + * Returns a bounding box that is inset by the specified amounts + */ + public AxisAlignedBB contract(double par1, double par3, double par5) { + double var7 = this.minX + par1; + double var9 = this.minY + par3; + double var11 = this.minZ + par5; + double var13 = this.maxX - par1; + double var15 = this.maxY - par3; + double var17 = this.maxZ - par5; + return getAABBPool().getAABB(var7, var9, var11, var13, var15, var17); + } + + /** + * Returns a copy of the bounding box. + */ + public AxisAlignedBB copy() { + return getAABBPool().getAABB(this.minX, this.minY, this.minZ, this.maxX, this.maxY, this.maxZ); + } + + public MovingObjectPosition calculateIntercept(Vec3 par1Vec3, Vec3 par2Vec3) { + Vec3 var3 = par1Vec3.getIntermediateWithXValue(par2Vec3, this.minX); + Vec3 var4 = par1Vec3.getIntermediateWithXValue(par2Vec3, this.maxX); + Vec3 var5 = par1Vec3.getIntermediateWithYValue(par2Vec3, this.minY); + Vec3 var6 = par1Vec3.getIntermediateWithYValue(par2Vec3, this.maxY); + Vec3 var7 = par1Vec3.getIntermediateWithZValue(par2Vec3, this.minZ); + Vec3 var8 = par1Vec3.getIntermediateWithZValue(par2Vec3, this.maxZ); + + if (!this.isVecInYZ(var3)) { + var3 = null; + } + + if (!this.isVecInYZ(var4)) { + var4 = null; + } + + if (!this.isVecInXZ(var5)) { + var5 = null; + } + + if (!this.isVecInXZ(var6)) { + var6 = null; + } + + if (!this.isVecInXY(var7)) { + var7 = null; + } + + if (!this.isVecInXY(var8)) { + var8 = null; + } + + Vec3 var9 = null; + + if (var3 != null && (var9 == null || par1Vec3.squareDistanceTo(var3) < par1Vec3.squareDistanceTo(var9))) { + var9 = var3; + } + + if (var4 != null && (var9 == null || par1Vec3.squareDistanceTo(var4) < par1Vec3.squareDistanceTo(var9))) { + var9 = var4; + } + + if (var5 != null && (var9 == null || par1Vec3.squareDistanceTo(var5) < par1Vec3.squareDistanceTo(var9))) { + var9 = var5; + } + + if (var6 != null && (var9 == null || par1Vec3.squareDistanceTo(var6) < par1Vec3.squareDistanceTo(var9))) { + var9 = var6; + } + + if (var7 != null && (var9 == null || par1Vec3.squareDistanceTo(var7) < par1Vec3.squareDistanceTo(var9))) { + var9 = var7; + } + + if (var8 != null && (var9 == null || par1Vec3.squareDistanceTo(var8) < par1Vec3.squareDistanceTo(var9))) { + var9 = var8; + } + + if (var9 == null) { + return null; + } else { + byte var10 = -1; + + if (var9 == var3) { + var10 = 4; + } + + if (var9 == var4) { + var10 = 5; + } + + if (var9 == var5) { + var10 = 0; + } + + if (var9 == var6) { + var10 = 1; + } + + if (var9 == var7) { + var10 = 2; + } + + if (var9 == var8) { + var10 = 3; + } + + return new MovingObjectPosition(0, 0, 0, var10, var9); + } + } + + /** + * Checks if the specified vector is within the YZ dimensions of the bounding + * box. Args: Vec3D + */ + private boolean isVecInYZ(Vec3 par1Vec3) { + return par1Vec3 == null ? false : par1Vec3.yCoord >= this.minY && par1Vec3.yCoord <= this.maxY && par1Vec3.zCoord >= this.minZ && par1Vec3.zCoord <= this.maxZ; + } + + /** + * Checks if the specified vector is within the XZ dimensions of the bounding + * box. Args: Vec3D + */ + private boolean isVecInXZ(Vec3 par1Vec3) { + return par1Vec3 == null ? false : par1Vec3.xCoord >= this.minX && par1Vec3.xCoord <= this.maxX && par1Vec3.zCoord >= this.minZ && par1Vec3.zCoord <= this.maxZ; + } + + /** + * Checks if the specified vector is within the XY dimensions of the bounding + * box. Args: Vec3D + */ + private boolean isVecInXY(Vec3 par1Vec3) { + return par1Vec3 == null ? false : par1Vec3.xCoord >= this.minX && par1Vec3.xCoord <= this.maxX && par1Vec3.yCoord >= this.minY && par1Vec3.yCoord <= this.maxY; + } + + /** + * Sets the bounding box to the same bounds as the bounding box passed in. Args: + * axisAlignedBB + */ + public void setBB(AxisAlignedBB par1AxisAlignedBB) { + this.minX = par1AxisAlignedBB.minX; + this.minY = par1AxisAlignedBB.minY; + this.minZ = par1AxisAlignedBB.minZ; + this.maxX = par1AxisAlignedBB.maxX; + this.maxY = par1AxisAlignedBB.maxY; + this.maxZ = par1AxisAlignedBB.maxZ; + } + + public String toString() { + return "box[" + this.minX + ", " + this.minY + ", " + this.minZ + " -> " + this.maxX + ", " + this.maxY + ", " + this.maxZ + "]"; + } +} diff --git a/src/main/java/net/minecraft/src/BiomeGenBase.java b/src/main/java/net/minecraft/src/BiomeGenBase.java new file mode 100644 index 0000000..945d336 --- /dev/null +++ b/src/main/java/net/minecraft/src/BiomeGenBase.java @@ -0,0 +1,323 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + + + +public class BiomeGenBase { + /** An array of all the biomes, indexed by biome id. */ + public static final BiomeGenBase[] biomeList = new BiomeGenBase[256]; + public static final BiomeGenBase ocean = (new BiomeGenBase(0)).setColor(112).setBiomeName("Ocean").setMinMaxHeight(-1.0F, 0.4F); + public static final BiomeGenBase plains = (new BiomeGenBase(1)).setColor(9286496).setBiomeName("Plains").setTemperatureRainfall(0.8F, 0.4F); + public static final BiomeGenBase desert = (new BiomeGenBase(2)).setColor(16421912).setBiomeName("Desert").setDisableRain().setTemperatureRainfall(2.0F, 0.0F).setMinMaxHeight(0.1F, 0.2F); + public static final BiomeGenBase extremeHills = (new BiomeGenBase(3)).setColor(6316128).setBiomeName("Extreme Hills").setMinMaxHeight(0.3F, 1.5F).setTemperatureRainfall(0.2F, 0.3F); + public static final BiomeGenBase forest = (new BiomeGenBase(4)).setColor(353825).setBiomeName("Forest").func_76733_a(5159473).setTemperatureRainfall(0.7F, 0.8F); + public static final BiomeGenBase taiga = (new BiomeGenBase(5)).setColor(747097).setBiomeName("Taiga").func_76733_a(5159473).setEnableSnow().setTemperatureRainfall(0.05F, 0.8F).setMinMaxHeight(0.1F, 0.4F); + public static final BiomeGenBase swampland = (new BiomeGenBase(6)).setColor(522674).setBiomeName("Swampland").func_76733_a(9154376).setMinMaxHeight(-0.2F, 0.1F).setTemperatureRainfall(0.8F, 0.9F); + public static final BiomeGenBase river = (new BiomeGenBase(7)).setColor(255).setBiomeName("River").setMinMaxHeight(-0.5F, 0.0F); + public static final BiomeGenBase hell = (new BiomeGenBase(8)).setColor(16711680).setBiomeName("Hell").setDisableRain().setTemperatureRainfall(2.0F, 0.0F); + + /** Is the biome used for sky world. */ + public static final BiomeGenBase sky = (new BiomeGenBase(9)).setColor(8421631).setBiomeName("Sky").setDisableRain(); + public static final BiomeGenBase frozenOcean = (new BiomeGenBase(10)).setColor(9474208).setBiomeName("FrozenOcean").setEnableSnow().setMinMaxHeight(-1.0F, 0.5F).setTemperatureRainfall(0.0F, 0.5F); + public static final BiomeGenBase frozenRiver = (new BiomeGenBase(11)).setColor(10526975).setBiomeName("FrozenRiver").setEnableSnow().setMinMaxHeight(-0.5F, 0.0F).setTemperatureRainfall(0.0F, 0.5F); + public static final BiomeGenBase icePlains = (new BiomeGenBase(12)).setColor(16777215).setBiomeName("Ice Plains").setEnableSnow().setTemperatureRainfall(0.0F, 0.5F); + public static final BiomeGenBase iceMountains = (new BiomeGenBase(13)).setColor(10526880).setBiomeName("Ice Mountains").setEnableSnow().setMinMaxHeight(0.3F, 1.3F).setTemperatureRainfall(0.0F, 0.5F); + public static final BiomeGenBase mushroomIsland = (new BiomeGenBase(14)).setColor(16711935).setBiomeName("MushroomIsland").setTemperatureRainfall(0.9F, 1.0F).setMinMaxHeight(0.2F, 1.0F); + public static final BiomeGenBase mushroomIslandShore = (new BiomeGenBase(15)).setColor(10486015).setBiomeName("MushroomIslandShore").setTemperatureRainfall(0.9F, 1.0F).setMinMaxHeight(-1.0F, 0.1F); + + /** Beach biome. */ + public static final BiomeGenBase beach = (new BiomeGenBase(16)).setColor(16440917).setBiomeName("Beach").setTemperatureRainfall(0.8F, 0.4F).setMinMaxHeight(0.0F, 0.1F); + + /** Desert Hills biome. */ + public static final BiomeGenBase desertHills = (new BiomeGenBase(17)).setColor(13786898).setBiomeName("DesertHills").setDisableRain().setTemperatureRainfall(2.0F, 0.0F).setMinMaxHeight(0.3F, 0.8F); + + /** Forest Hills biome. */ + public static final BiomeGenBase forestHills = (new BiomeGenBase(18)).setColor(2250012).setBiomeName("ForestHills").func_76733_a(5159473).setTemperatureRainfall(0.7F, 0.8F).setMinMaxHeight(0.3F, 0.7F); + + /** Taiga Hills biome. */ + public static final BiomeGenBase taigaHills = (new BiomeGenBase(19)).setColor(1456435).setBiomeName("TaigaHills").setEnableSnow().func_76733_a(5159473).setTemperatureRainfall(0.05F, 0.8F).setMinMaxHeight(0.3F, 0.8F); + + /** Extreme Hills Edge biome. */ + public static final BiomeGenBase extremeHillsEdge = (new BiomeGenBase(20)).setColor(7501978).setBiomeName("Extreme Hills Edge").setMinMaxHeight(0.2F, 0.8F).setTemperatureRainfall(0.2F, 0.3F); + + /** Jungle biome identifier */ + public static final BiomeGenBase jungle = (new BiomeGenBase(21)).setColor(5470985).setBiomeName("Jungle").func_76733_a(5470985).setTemperatureRainfall(1.2F, 0.9F).setMinMaxHeight(0.2F, 0.4F); + public static final BiomeGenBase jungleHills = (new BiomeGenBase(22)).setColor(2900485).setBiomeName("JungleHills").func_76733_a(5470985).setTemperatureRainfall(1.2F, 0.9F).setMinMaxHeight(1.8F, 0.5F); + public String biomeName; + public int color; + + /** The block expected to be on the top of this biome */ + public byte topBlock; + + /** The block to fill spots in when not on the top */ + public byte fillerBlock; + public int field_76754_C; + + /** The minimum height of this biome. Default 0.1. */ + public float minHeight; + + /** The maximum height of this biome. Default 0.3. */ + public float maxHeight; + + /** The temperature of this biome. */ + public float temperature; + + /** The rainfall in this biome. */ + public float rainfall; + + /** Color tint applied to water depending on biome */ + public int waterColorMultiplier; + + /** + * Holds the classes of IMobs (hostile mobs) that can be spawned in the biome. + */ + protected List spawnableMonsterList; + + /** + * Holds the classes of any creature that can be spawned in the biome as + * friendly creature. + */ + protected List spawnableCreatureList; + + /** + * Holds the classes of any aquatic creature that can be spawned in the water of + * the biome. + */ + protected List spawnableWaterCreatureList; + protected List spawnableCaveCreatureList; + + /** Set to true if snow is enabled for this biome. */ + private boolean enableSnow; + + /** + * Is true (default) if the biome support rain (desert and nether can't have + * rain) + */ + private boolean enableRain; + + /** The id number to this biome, and its index in the biomeList array. */ + public final int biomeID; + + protected BiomeGenBase(int par1) { + this.topBlock = (byte) Block.grass.blockID; + this.fillerBlock = (byte) Block.dirt.blockID; + this.field_76754_C = 5169201; + this.minHeight = 0.1F; + this.maxHeight = 0.3F; + this.temperature = 0.5F; + this.rainfall = 0.5F; + this.waterColorMultiplier = 16777215; + this.spawnableMonsterList = new ArrayList(); + this.spawnableCreatureList = new ArrayList(); + this.spawnableWaterCreatureList = new ArrayList(); + this.spawnableCaveCreatureList = new ArrayList(); + this.enableRain = true; + this.biomeID = par1; + biomeList[par1] = this; + } + + /** + * Sets the temperature and rainfall of this biome. + */ + private BiomeGenBase setTemperatureRainfall(float par1, float par2) { + if (par1 > 0.1F && par1 < 0.2F) { + throw new IllegalArgumentException("Please avoid temperatures in the range 0.1 - 0.2 because of snow"); + } else { + this.temperature = par1; + this.rainfall = par2; + return this; + } + } + + /** + * Sets the minimum and maximum height of this biome. Seems to go from -2.0 to + * 2.0. + */ + private BiomeGenBase setMinMaxHeight(float par1, float par2) { + this.minHeight = par1; + this.maxHeight = par2; + return this; + } + + /** + * Disable the rain for the biome. + */ + private BiomeGenBase setDisableRain() { + this.enableRain = false; + return this; + } + + /** + * sets enableSnow to true during biome initialization. returns BiomeGenBase. + */ + protected BiomeGenBase setEnableSnow() { + this.enableSnow = true; + return this; + } + + protected BiomeGenBase setBiomeName(String par1Str) { + this.biomeName = par1Str; + return this; + } + + protected BiomeGenBase func_76733_a(int par1) { + this.field_76754_C = par1; + return this; + } + + protected BiomeGenBase setColor(int par1) { + this.color = par1; + return this; + } + + /** + * takes temperature, returns color + */ + public int getSkyColorByTemp(float par1) { + par1 /= 3.0F; + + if (par1 < -1.0F) { + par1 = -1.0F; + } + + if (par1 > 1.0F) { + par1 = 1.0F; + } + + return HSBtoRGB(0.62222224F - par1 * 0.05F, 0.5F + par1 * 0.1F, 1.0F); + } + + public static int HSBtoRGB(float hue, float saturation, float brightness) { + int r = 0, g = 0, b = 0; + if (saturation == 0) { + r = g = b = (int) (brightness * 255.0f + 0.5f); + } else { + float h = (hue - (float) Math.floor(hue)) * 6.0f; + float f = h - (float) Math.floor(h); + float p = brightness * (1.0f - saturation); + float q = brightness * (1.0f - saturation * f); + float t = brightness * (1.0f - (saturation * (1.0f - f))); + switch ((int) h) { + case 0: + r = (int) (brightness * 255.0f + 0.5f); + g = (int) (t * 255.0f + 0.5f); + b = (int) (p * 255.0f + 0.5f); + break; + case 1: + r = (int) (q * 255.0f + 0.5f); + g = (int) (brightness * 255.0f + 0.5f); + b = (int) (p * 255.0f + 0.5f); + break; + case 2: + r = (int) (p * 255.0f + 0.5f); + g = (int) (brightness * 255.0f + 0.5f); + b = (int) (t * 255.0f + 0.5f); + break; + case 3: + r = (int) (p * 255.0f + 0.5f); + g = (int) (q * 255.0f + 0.5f); + b = (int) (brightness * 255.0f + 0.5f); + break; + case 4: + r = (int) (t * 255.0f + 0.5f); + g = (int) (p * 255.0f + 0.5f); + b = (int) (brightness * 255.0f + 0.5f); + break; + case 5: + r = (int) (brightness * 255.0f + 0.5f); + g = (int) (p * 255.0f + 0.5f); + b = (int) (q * 255.0f + 0.5f); + break; + } + } + return 0xff000000 | (r << 16) | (g << 8) | (b << 0); + } + + /** + * Returns the correspondent list of the EnumCreatureType informed. + */ + public List getSpawnableList(EnumCreatureType par1EnumCreatureType) { + return par1EnumCreatureType == EnumCreatureType.monster ? this.spawnableMonsterList + : (par1EnumCreatureType == EnumCreatureType.creature ? this.spawnableCreatureList + : (par1EnumCreatureType == EnumCreatureType.waterCreature ? this.spawnableWaterCreatureList : (par1EnumCreatureType == EnumCreatureType.ambient ? this.spawnableCaveCreatureList : null))); + } + + /** + * Returns true if the biome have snowfall instead a normal rain. + */ + public boolean getEnableSnow() { + return this.enableSnow; + } + + /** + * Return true if the biome supports lightning bolt spawn, either by have the + * bolts enabled and have rain enabled. + */ + public boolean canSpawnLightningBolt() { + return this.enableSnow ? false : this.enableRain; + } + + /** + * Checks to see if the rainfall level of the biome is extremely high + */ + public boolean isHighHumidity() { + return this.rainfall > 0.85F; + } + + /** + * returns the chance a creature has to spawn. + */ + public float getSpawningChance() { + return 0.1F; + } + + /** + * Gets an integer representation of this biome's rainfall + */ + public final int getIntRainfall() { + return (int) (this.rainfall * 65536.0F); + } + + /** + * Gets an integer representation of this biome's temperature + */ + public final int getIntTemperature() { + return (int) (this.temperature * 65536.0F); + } + + /** + * Gets a floating point representation of this biome's rainfall + */ + public final float getFloatRainfall() { + return this.rainfall; + } + + /** + * Gets a floating point representation of this biome's temperature + */ + public final float getFloatTemperature() { + return this.temperature; + } + + /** + * Provides the basic grass color based on the biome temperature and rainfall + */ + public int getBiomeGrassColor() { + if(biomeID == 6) return 6975545; + double var1 = (double) MathHelper.clamp_float(this.getFloatTemperature(), 0.0F, 1.0F); + double var3 = (double) MathHelper.clamp_float(this.getFloatRainfall(), 0.0F, 1.0F); + return ColorizerGrass.getGrassColor(var1, var3); + } + + /** + * Provides the basic foliage color based on the biome temperature and rainfall + */ + public int getBiomeFoliageColor() { + if(biomeID == 6) return 6975545; + double var1 = (double) MathHelper.clamp_float(this.getFloatTemperature(), 0.0F, 1.0F); + double var3 = (double) MathHelper.clamp_float(this.getFloatRainfall(), 0.0F, 1.0F); + return ColorizerFoliage.getFoliageColor(var1, var3); + } +} diff --git a/src/main/java/net/minecraft/src/Block.java b/src/main/java/net/minecraft/src/Block.java new file mode 100644 index 0000000..954c6bc --- /dev/null +++ b/src/main/java/net/minecraft/src/Block.java @@ -0,0 +1,1328 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class Block { + /** + * used as foreach item, if item.tab = current tab, display it on the screen + */ + private CreativeTabs displayOnCreativeTab; + public static final StepSound soundPowderFootstep = new StepSound("stone", 1.0F, 1.0F); + public static final StepSound soundWoodFootstep = new StepSound("wood", 1.0F, 1.0F); + public static final StepSound soundGravelFootstep = new StepSound("gravel", 1.0F, 1.0F); + public static final StepSound soundGrassFootstep = new StepSound("grass", 1.0F, 1.0F); + public static final StepSound soundStoneFootstep = new StepSound("stone", 1.0F, 1.0F); + public static final StepSound soundMetalFootstep = new StepSound("stone", 1.0F, 1.5F); + public static final StepSound soundGlassFootstep = new StepSoundStone("stone", 1.0F, 1.0F); + public static final StepSound soundClothFootstep = new StepSound("cloth", 1.0F, 1.0F); + public static final StepSound soundSandFootstep = new StepSound("sand", 1.0F, 1.0F); + public static final StepSound soundSnowFootstep = new StepSound("snow", 1.0F, 1.0F); + public static final StepSound soundLadderFootstep = new StepSoundSand("ladder", 1.0F, 1.0F); + public static final StepSound soundAnvilFootstep = new StepSoundAnvil("anvil", 0.3F, 1.0F); + + public static final NoiseGeneratorPerlin grassNoise = new NoiseGeneratorPerlin(new Random("methamphetamine".hashCode())); + public static final double[] grassNoiseArray = new double[256]; + private static int noiseChunkX = Integer.MIN_VALUE; + private static int noiseChunkZ = Integer.MIN_VALUE; + + public static final void initNoiseField(int cx, int cz) { + if(noiseChunkX != cx || noiseChunkZ != cz) { + noiseChunkX = cx; + noiseChunkZ = cz; + initNoiseField0(cx, cz); + } + } + + public static void initNoiseField0(int cx, int cz) { + double scale = 0.05D; + for(int i = 0; i < grassNoiseArray.length; ++i) { + grassNoiseArray[i] = 0.0D; + } + grassNoise.populateNoiseArray(grassNoiseArray, cx * 16.0D * scale, 16.0D * scale, cz * 16.0D * scale, 16, 1, 16, scale, 1.0D, scale, 1.0D); + } + + /** List of ly/ff (BlockType) containing the already registered blocks. */ + public static final Block[] blocksList = new Block[4096]; + + /** + * An array of 4096 booleans corresponding to the result of the isOpaqueCube() + * method for each block ID + */ + public static final boolean[] opaqueCubeLookup = new boolean[4096]; + + /** How much light is subtracted for going through this block */ + public static final int[] lightOpacity = new int[4096]; + + /** Array of booleans that tells if a block can grass */ + public static final boolean[] canBlockGrass = new boolean[4096]; + + /** Amount of light emitted */ + public static final int[] lightValue = new int[4096]; + + /** + * Flag if block ID should use the brightest neighbor light value as its own + */ + public static boolean[] useNeighborBrightness = new boolean[4096]; + public static final Block stone = (new BlockStone(1)).setHardness(1.5F).setResistance(10.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("stone"); + public static final BlockGrass grass = (BlockGrass) (new BlockGrass(2)).setHardness(0.6F).setStepSound(soundGrassFootstep).setUnlocalizedName("grass"); + public static final Block dirt = (new BlockDirt(3)).setHardness(0.5F).setStepSound(soundGravelFootstep).setUnlocalizedName("dirt"); + public static final Block cobblestone = (new Block(4, Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("stonebrick").setCreativeTab(CreativeTabs.tabBlock); + public static final Block planks = (new BlockWood(5)).setHardness(2.0F).setResistance(5.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("wood"); + public static final Block sapling = (new BlockSapling(6)).setHardness(0.0F).setStepSound(soundGrassFootstep).setUnlocalizedName("sapling"); + public static final Block bedrock = (new Block(7, Material.rock)).setBlockUnbreakable().setResistance(6000000.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("bedrock").disableStats().setCreativeTab(CreativeTabs.tabBlock); + public static final BlockFluid waterMoving = (BlockFluid) (new BlockFlowing(8, Material.water)).setHardness(100.0F).setLightOpacity(3).setUnlocalizedName("water").disableStats(); + public static final Block waterStill = (new BlockStationary(9, Material.water)).setHardness(100.0F).setLightOpacity(3).setUnlocalizedName("water").disableStats(); + public static final BlockFluid lavaMoving = (BlockFluid) (new BlockFlowing(10, Material.lava)).setHardness(0.0F).setLightValue(1.0F).setUnlocalizedName("lava").disableStats(); + + /** Stationary lava source block */ + public static final Block lavaStill = (new BlockStationary(11, Material.lava)).setHardness(100.0F).setLightValue(1.0F).setUnlocalizedName("lava").disableStats(); + public static final Block sand = (new BlockSand(12)).setHardness(0.5F).setStepSound(soundSandFootstep).setUnlocalizedName("sand"); + public static final Block gravel = (new BlockGravel(13)).setHardness(0.6F).setStepSound(soundGravelFootstep).setUnlocalizedName("gravel"); + public static final Block oreGold = (new BlockOre(14)).setHardness(3.0F).setResistance(5.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("oreGold"); + public static final Block oreIron = (new BlockOre(15)).setHardness(3.0F).setResistance(5.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("oreIron"); + public static final Block oreCoal = (new BlockOre(16)).setHardness(3.0F).setResistance(5.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("oreCoal"); + public static final Block wood = (new BlockLog(17)).setHardness(2.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("log"); + public static final BlockLeaves leaves = (BlockLeaves) (new BlockLeaves(18)).setHardness(0.2F).setLightOpacity(1).setStepSound(soundGrassFootstep).setUnlocalizedName("leaves"); + public static final Block sponge = (new BlockSponge(19)).setHardness(0.6F).setStepSound(soundGrassFootstep).setUnlocalizedName("sponge"); + public static final Block glass = (new BlockGlass(20, Material.glass, false)).setHardness(0.3F).setStepSound(soundGlassFootstep).setUnlocalizedName("glass"); + public static final Block oreLapis = (new BlockOre(21)).setHardness(3.0F).setResistance(5.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("oreLapis"); + public static final Block blockLapis = (new Block(22, Material.rock)).setHardness(3.0F).setResistance(5.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("blockLapis").setCreativeTab(CreativeTabs.tabBlock); + public static final Block dispenser = (new BlockDispenser(23)).setHardness(3.5F).setStepSound(soundStoneFootstep).setUnlocalizedName("dispenser"); + public static final Block sandStone = (new BlockSandStone(24)).setStepSound(soundStoneFootstep).setHardness(0.8F).setUnlocalizedName("sandStone"); + public static final Block music = (new BlockNote(25)).setHardness(0.8F).setUnlocalizedName("musicBlock"); + public static final Block bed = (new BlockBed(26)).setHardness(0.2F).setUnlocalizedName("bed").disableStats(); + public static final Block railPowered = (new BlockRailPowered(27)).setHardness(0.7F).setStepSound(soundMetalFootstep).setUnlocalizedName("goldenRail"); + public static final Block railDetector = (new BlockDetectorRail(28)).setHardness(0.7F).setStepSound(soundMetalFootstep).setUnlocalizedName("detectorRail"); + public static final BlockPistonBase pistonStickyBase = (BlockPistonBase) (new BlockPistonBase(29, true)).setUnlocalizedName("pistonStickyBase"); + public static final Block web = (new BlockWeb(30)).setLightOpacity(1).setHardness(4.0F).setUnlocalizedName("web"); + public static final BlockTallGrass tallGrass = (BlockTallGrass) (new BlockTallGrass(31)).setHardness(0.0F).setStepSound(soundGrassFootstep).setUnlocalizedName("tallgrass"); + public static final BlockDeadBush deadBush = (BlockDeadBush) (new BlockDeadBush(32)).setHardness(0.0F).setStepSound(soundGrassFootstep).setUnlocalizedName("deadbush"); + public static final BlockPistonBase pistonBase = (BlockPistonBase) (new BlockPistonBase(33, false)).setUnlocalizedName("pistonBase"); + public static final BlockPistonExtension pistonExtension = new BlockPistonExtension(34); + public static final Block cloth = (new BlockCloth()).setHardness(0.8F).setStepSound(soundClothFootstep).setUnlocalizedName("cloth"); + public static final BlockPistonMoving pistonMoving = new BlockPistonMoving(36); + public static final BlockFlower plantYellow = (BlockFlower) (new BlockFlower(37)).setHardness(0.0F).setStepSound(soundGrassFootstep).setUnlocalizedName("flower"); + public static final BlockFlower plantRed = (BlockFlower) (new BlockFlower(38)).setHardness(0.0F).setStepSound(soundGrassFootstep).setUnlocalizedName("rose"); + public static final BlockFlower mushroomBrown = (BlockFlower) (new BlockMushroom(39, "mushroom_brown")).setHardness(0.0F).setStepSound(soundGrassFootstep).setLightValue(0.125F).setUnlocalizedName("mushroom"); + public static final BlockFlower mushroomRed = (BlockFlower) (new BlockMushroom(40, "mushroom_red")).setHardness(0.0F).setStepSound(soundGrassFootstep).setUnlocalizedName("mushroom"); + public static final Block blockGold = (new BlockOreStorage(41)).setHardness(3.0F).setResistance(10.0F).setStepSound(soundMetalFootstep).setUnlocalizedName("blockGold"); + public static final Block blockIron = (new BlockOreStorage(42)).setHardness(5.0F).setResistance(10.0F).setStepSound(soundMetalFootstep).setUnlocalizedName("blockIron"); + + /** stoneDoubleSlab */ + public static final BlockHalfSlab stoneDoubleSlab = (BlockHalfSlab) (new BlockStep(43, true)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("stoneSlab"); + + /** stoneSingleSlab */ + public static final BlockHalfSlab stoneSingleSlab = (BlockHalfSlab) (new BlockStep(44, false)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("stoneSlab"); + public static final Block brick = (new Block(45, Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("brick").setCreativeTab(CreativeTabs.tabBlock); + public static final Block tnt = (new BlockTNT(46)).setHardness(0.0F).setStepSound(soundGrassFootstep).setUnlocalizedName("tnt"); + public static final Block bookShelf = (new BlockBookshelf(47)).setHardness(1.5F).setStepSound(soundWoodFootstep).setUnlocalizedName("bookshelf"); + public static final Block cobblestoneMossy = (new Block(48, Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("stoneMoss").setCreativeTab(CreativeTabs.tabBlock); + public static final Block obsidian = (new BlockObsidian(49)).setHardness(50.0F).setResistance(2000.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("obsidian"); + public static final Block torchWood = (new BlockTorch(50)).setHardness(0.0F).setLightValue(0.9375F).setStepSound(soundWoodFootstep).setUnlocalizedName("torch"); + public static final BlockFire fire = (BlockFire) (new BlockFire(51)).setHardness(0.0F).setLightValue(1.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("fire").disableStats(); + public static final Block mobSpawner = (new BlockMobSpawner(52)).setHardness(5.0F).setStepSound(soundMetalFootstep).setUnlocalizedName("mobSpawner").disableStats(); + public static final Block stairsWoodOak = (new BlockStairs(53, planks, 0)).setUnlocalizedName("stairsWood"); + public static final BlockChest chest = (BlockChest) (new BlockChest(54, 0)).setHardness(2.5F).setStepSound(soundWoodFootstep).setUnlocalizedName("chest"); + public static final BlockRedstoneWire redstoneWire = (BlockRedstoneWire) (new BlockRedstoneWire(55)).setHardness(0.0F).setStepSound(soundPowderFootstep).setUnlocalizedName("redstoneDust").disableStats(); + public static final Block oreDiamond = (new BlockOre(56)).setHardness(3.0F).setResistance(5.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("oreDiamond"); + public static final Block blockDiamond = (new BlockOreStorage(57)).setHardness(5.0F).setResistance(10.0F).setStepSound(soundMetalFootstep).setUnlocalizedName("blockDiamond"); + public static final Block workbench = (new BlockWorkbench(58)).setHardness(2.5F).setStepSound(soundWoodFootstep).setUnlocalizedName("workbench"); + public static final Block crops = (new BlockCrops(59)).setUnlocalizedName("crops"); + public static final Block tilledField = (new BlockFarmland(60)).setHardness(0.6F).setStepSound(soundGravelFootstep).setUnlocalizedName("farmland"); + public static final Block furnaceIdle = (new BlockFurnace(61, false)).setHardness(3.5F).setStepSound(soundStoneFootstep).setUnlocalizedName("furnace").setCreativeTab(CreativeTabs.tabDecorations); + public static final Block furnaceBurning = (new BlockFurnace(62, true)).setHardness(3.5F).setStepSound(soundStoneFootstep).setLightValue(0.875F).setUnlocalizedName("furnace"); + public static final Block signPost = (new BlockSign(63, TileEntitySign.class, true)).setHardness(1.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("sign").disableStats(); + public static final Block doorWood = (new BlockDoor(64, Material.wood)).setHardness(3.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("doorWood").disableStats(); + public static final Block ladder = (new BlockLadder(65)).setHardness(0.4F).setStepSound(soundLadderFootstep).setUnlocalizedName("ladder"); + public static final Block rail = (new BlockRail(66)).setHardness(0.7F).setStepSound(soundMetalFootstep).setUnlocalizedName("rail"); + public static final Block stairsCobblestone = (new BlockStairs(67, cobblestone, 0)).setUnlocalizedName("stairsStone"); + public static final Block signWall = (new BlockSign(68, TileEntitySign.class, false)).setHardness(1.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("sign").disableStats(); + public static final Block lever = (new BlockLever(69)).setHardness(0.5F).setStepSound(soundWoodFootstep).setUnlocalizedName("lever"); + public static final Block pressurePlateStone = (new BlockPressurePlate(70, "stone", Material.rock, EnumMobType.mobs)).setHardness(0.5F).setStepSound(soundStoneFootstep).setUnlocalizedName("pressurePlate"); + public static final Block doorIron = (new BlockDoor(71, Material.iron)).setHardness(5.0F).setStepSound(soundMetalFootstep).setUnlocalizedName("doorIron").disableStats(); + public static final Block pressurePlatePlanks = (new BlockPressurePlate(72, "wood", Material.wood, EnumMobType.everything)).setHardness(0.5F).setStepSound(soundWoodFootstep).setUnlocalizedName("pressurePlate"); + public static final Block oreRedstone = (new BlockRedstoneOre(73, false)).setHardness(3.0F).setResistance(5.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("oreRedstone").setCreativeTab(CreativeTabs.tabBlock); + public static final Block oreRedstoneGlowing = (new BlockRedstoneOre(74, true)).setLightValue(0.625F).setHardness(3.0F).setResistance(5.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("oreRedstone"); + public static final Block torchRedstoneIdle = (new BlockRedstoneTorch(75, false)).setHardness(0.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("notGate"); + public static final Block torchRedstoneActive = (new BlockRedstoneTorch(76, true)).setHardness(0.0F).setLightValue(0.5F).setStepSound(soundWoodFootstep).setUnlocalizedName("notGate").setCreativeTab(CreativeTabs.tabRedstone); + public static final Block stoneButton = (new BlockButtonStone(77)).setHardness(0.5F).setStepSound(soundStoneFootstep).setUnlocalizedName("button"); + public static final Block snow = (new BlockSnow(78)).setHardness(0.1F).setStepSound(soundSnowFootstep).setUnlocalizedName("snow").setLightOpacity(0); + public static final Block ice = (new BlockIce(79)).setHardness(0.5F).setLightOpacity(3).setStepSound(soundGlassFootstep).setUnlocalizedName("ice"); + public static final Block blockSnow = (new BlockSnowBlock(80)).setHardness(0.2F).setStepSound(soundSnowFootstep).setUnlocalizedName("snow"); + public static final Block cactus = (new BlockCactus(81)).setHardness(0.4F).setStepSound(soundClothFootstep).setUnlocalizedName("cactus"); + public static final Block blockClay = (new BlockClay(82)).setHardness(0.6F).setStepSound(soundGravelFootstep).setUnlocalizedName("clay"); + public static final Block reed = (new BlockReed(83)).setHardness(0.0F).setStepSound(soundGrassFootstep).setUnlocalizedName("reeds").disableStats(); + public static final Block jukebox = (new BlockJukeBox(84)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("jukebox"); + public static final Block fence = (new BlockFence(85, "wood", Material.wood)).setHardness(2.0F).setResistance(5.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("fence"); + public static final Block pumpkin = (new BlockPumpkin(86, false)).setHardness(1.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("pumpkin"); + public static final Block netherrack = (new BlockNetherrack(87)).setHardness(0.4F).setStepSound(soundStoneFootstep).setUnlocalizedName("hellrock"); + public static final Block slowSand = (new BlockSoulSand(88)).setHardness(0.5F).setStepSound(soundSandFootstep).setUnlocalizedName("hellsand"); + public static final Block glowStone = (new BlockGlowStone(89, Material.glass)).setHardness(0.3F).setStepSound(soundGlassFootstep).setLightValue(1.0F).setUnlocalizedName("lightgem"); + + /** The purple teleport blocks inside the obsidian circle */ + public static final BlockPortal portal = (BlockPortal) (new BlockPortal(90)).setHardness(-1.0F).setStepSound(soundGlassFootstep).setLightValue(0.75F).setUnlocalizedName("portal"); + public static final Block pumpkinLantern = (new BlockPumpkin(91, true)).setHardness(1.0F).setStepSound(soundWoodFootstep).setLightValue(1.0F).setUnlocalizedName("litpumpkin"); + public static final Block cake = (new BlockCake(92)).setHardness(0.5F).setStepSound(soundClothFootstep).setUnlocalizedName("cake").disableStats(); + public static final BlockRedstoneRepeater redstoneRepeaterIdle = (BlockRedstoneRepeater) (new BlockRedstoneRepeater(93, false)).setHardness(0.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("diode").disableStats(); + public static final BlockRedstoneRepeater redstoneRepeaterActive = (BlockRedstoneRepeater) (new BlockRedstoneRepeater(94, true)).setHardness(0.0F).setLightValue(0.625F).setStepSound(soundWoodFootstep).setUnlocalizedName("diode") + .disableStats(); + + /** + * April fools secret locked chest, only spawns on new chunks on 1st April. + */ + public static final Block lockedChest = (new BlockLockedChest(95)).setHardness(0.0F).setLightValue(1.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("lockedchest").setTickRandomly(true); + public static final Block trapdoor = (new BlockTrapDoor(96, Material.wood)).setHardness(3.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("trapdoor").disableStats(); + public static final Block silverfish = (new BlockSilverfish(97)).setHardness(0.75F).setUnlocalizedName("monsterStoneEgg"); + public static final Block stoneBrick = (new BlockStoneBrick(98)).setHardness(1.5F).setResistance(10.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("stonebricksmooth"); + public static final Block mushroomCapBrown = (new BlockMushroomCap(99, Material.wood, 0)).setHardness(0.2F).setStepSound(soundWoodFootstep).setUnlocalizedName("mushroom"); + public static final Block mushroomCapRed = (new BlockMushroomCap(100, Material.wood, 1)).setHardness(0.2F).setStepSound(soundWoodFootstep).setUnlocalizedName("mushroom"); + public static final Block fenceIron = (new BlockPane(101, "fenceIron", "fenceIron", Material.iron, true)).setHardness(5.0F).setResistance(10.0F).setStepSound(soundMetalFootstep).setUnlocalizedName("fenceIron"); + public static final Block thinGlass = (new BlockPane(102, "glass", "thinglass_top", Material.glass, false)).setHardness(0.3F).setStepSound(soundGlassFootstep).setUnlocalizedName("thinGlass"); + public static final Block melon = (new BlockMelon(103)).setHardness(1.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("melon"); + public static final Block pumpkinStem = (new BlockStem(104, pumpkin)).setHardness(0.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("pumpkinStem"); + public static final Block melonStem = (new BlockStem(105, melon)).setHardness(0.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("pumpkinStem"); + public static final Block vine = (new BlockVine(106)).setHardness(0.2F).setStepSound(soundGrassFootstep).setUnlocalizedName("vine"); + public static final Block fenceGate = (new BlockFenceGate(107)).setHardness(2.0F).setResistance(5.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("fenceGate"); + public static final Block stairsBrick = (new BlockStairs(108, brick, 0)).setUnlocalizedName("stairsBrick"); + public static final Block stairsStoneBrick = (new BlockStairs(109, stoneBrick, 0)).setUnlocalizedName("stairsStoneBrickSmooth"); + public static final BlockMycelium mycelium = (BlockMycelium) (new BlockMycelium(110)).setHardness(0.6F).setStepSound(soundGrassFootstep).setUnlocalizedName("mycel"); + public static final Block waterlily = (new BlockLilyPad(111)).setHardness(0.0F).setStepSound(soundGrassFootstep).setUnlocalizedName("waterlily"); + public static final Block netherBrick = (new Block(112, Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("netherBrick").setCreativeTab(CreativeTabs.tabBlock); + public static final Block netherFence = (new BlockFence(113, "netherBrick", Material.rock)).setHardness(2.0F).setResistance(10.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("netherFence"); + public static final Block stairsNetherBrick = (new BlockStairs(114, netherBrick, 0)).setUnlocalizedName("stairsNetherBrick"); + public static final Block netherStalk = (new BlockNetherStalk(115)).setUnlocalizedName("netherStalk"); + public static final Block enchantmentTable = (new BlockEnchantmentTable(116)).setHardness(5.0F).setResistance(2000.0F).setUnlocalizedName("enchantmentTable"); + public static final Block brewingStand = (new BlockBrewingStand(117)).setHardness(0.5F).setLightValue(0.125F).setUnlocalizedName("brewingStand"); + public static final BlockCauldron cauldron = (BlockCauldron) (new BlockCauldron(118)).setHardness(2.0F).setUnlocalizedName("cauldron"); + public static final Block endPortal = (new BlockEndPortal(119, Material.portal)).setHardness(-1.0F).setResistance(6000000.0F); + public static final Block endPortalFrame = (new BlockEndPortalFrame(120)).setStepSound(soundGlassFootstep).setLightValue(0.125F).setHardness(-1.0F).setUnlocalizedName("endPortalFrame").setResistance(6000000.0F) + .setCreativeTab(CreativeTabs.tabDecorations); + + /** The rock found in The End. */ + public static final Block whiteStone = (new Block(121, Material.rock)).setHardness(3.0F).setResistance(15.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("whiteStone").setCreativeTab(CreativeTabs.tabBlock); + public static final Block dragonEgg = (new BlockDragonEgg(122)).setHardness(3.0F).setResistance(15.0F).setStepSound(soundStoneFootstep).setLightValue(0.125F).setUnlocalizedName("dragonEgg"); + public static final Block redstoneLampIdle = (new BlockRedstoneLight(123, false)).setHardness(0.3F).setStepSound(soundGlassFootstep).setUnlocalizedName("redstoneLight").setCreativeTab(CreativeTabs.tabRedstone); + public static final Block redstoneLampActive = (new BlockRedstoneLight(124, true)).setHardness(0.3F).setStepSound(soundGlassFootstep).setUnlocalizedName("redstoneLight"); + public static final BlockHalfSlab woodDoubleSlab = (BlockHalfSlab) (new BlockWoodSlab(125, true)).setHardness(2.0F).setResistance(5.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("woodSlab"); + public static final BlockHalfSlab woodSingleSlab = (BlockHalfSlab) (new BlockWoodSlab(126, false)).setHardness(2.0F).setResistance(5.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("woodSlab"); + public static final Block cocoaPlant = (new BlockCocoa(127)).setHardness(0.2F).setResistance(5.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("cocoa"); + public static final Block stairsSandStone = (new BlockStairs(128, sandStone, 0)).setUnlocalizedName("stairsSandStone"); + public static final Block oreEmerald = (new BlockOre(129)).setHardness(3.0F).setResistance(5.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("oreEmerald"); + public static final Block enderChest = (new BlockEnderChest(130)).setHardness(22.5F).setResistance(1000.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("enderChest").setLightValue(0.5F); + public static final BlockTripWireSource tripWireSource = (BlockTripWireSource) (new BlockTripWireSource(131)).setUnlocalizedName("tripWireSource"); + public static final Block tripWire = (new BlockTripWire(132)).setUnlocalizedName("tripWire"); + public static final Block blockEmerald = (new BlockOreStorage(133)).setHardness(5.0F).setResistance(10.0F).setStepSound(soundMetalFootstep).setUnlocalizedName("blockEmerald"); + public static final Block stairsWoodSpruce = (new BlockStairs(134, planks, 1)).setUnlocalizedName("stairsWoodSpruce"); + public static final Block stairsWoodBirch = (new BlockStairs(135, planks, 2)).setUnlocalizedName("stairsWoodBirch"); + public static final Block stairsWoodJungle = (new BlockStairs(136, planks, 3)).setUnlocalizedName("stairsWoodJungle"); + public static final Block commandBlock = (new BlockCommandBlock(137)).setUnlocalizedName("commandBlock"); + public static final BlockBeacon beacon = (BlockBeacon) (new BlockBeacon(138)).setUnlocalizedName("beacon").setLightValue(1.0F); + public static final Block cobblestoneWall = (new BlockWall(139, cobblestone)).setUnlocalizedName("cobbleWall"); + public static final Block flowerPot = (new BlockFlowerPot(140)).setHardness(0.0F).setStepSound(soundPowderFootstep).setUnlocalizedName("flowerPot"); + public static final Block carrot = (new BlockCarrot(141)).setUnlocalizedName("carrots"); + public static final Block potato = (new BlockPotato(142)).setUnlocalizedName("potatoes"); + public static final Block woodenButton = (new BlockButtonWood(143)).setHardness(0.5F).setStepSound(soundWoodFootstep).setUnlocalizedName("button"); + public static final Block skull = (new BlockSkull(144)).setHardness(1.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("skull"); + public static final Block anvil = (new BlockAnvil(145)).setHardness(5.0F).setStepSound(soundAnvilFootstep).setResistance(2000.0F).setUnlocalizedName("anvil"); + public static final Block chestTrapped = (new BlockChest(146, 1)).setHardness(2.5F).setStepSound(soundWoodFootstep).setUnlocalizedName("chestTrap"); + public static final Block pressurePlateGold = (new BlockPressurePlateWeighted(147, "blockGold", Material.iron, 64)).setHardness(0.5F).setStepSound(soundWoodFootstep).setUnlocalizedName("weightedPlate_light"); + public static final Block pressurePlateIron = (new BlockPressurePlateWeighted(148, "blockIron", Material.iron, 640)).setHardness(0.5F).setStepSound(soundWoodFootstep).setUnlocalizedName("weightedPlate_heavy"); + public static final BlockComparator redstoneComparatorIdle = (BlockComparator) (new BlockComparator(149, false)).setHardness(0.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("comparator").disableStats(); + public static final BlockComparator redstoneComparatorActive = (BlockComparator) (new BlockComparator(150, true)).setHardness(0.0F).setLightValue(0.625F).setStepSound(soundWoodFootstep).setUnlocalizedName("comparator").disableStats(); + public static final BlockDaylightDetector daylightSensor = (BlockDaylightDetector) (new BlockDaylightDetector(151)).setHardness(0.2F).setStepSound(soundWoodFootstep).setUnlocalizedName("daylightDetector"); + public static final Block blockRedstone = (new BlockPoweredOre(152)).setHardness(5.0F).setResistance(10.0F).setStepSound(soundMetalFootstep).setUnlocalizedName("blockRedstone"); + public static final Block oreNetherQuartz = (new BlockOre(153)).setHardness(3.0F).setResistance(5.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("netherquartz"); + public static final BlockHopper hopperBlock = (BlockHopper) (new BlockHopper(154)).setHardness(3.0F).setResistance(8.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("hopper"); + public static final Block blockNetherQuartz = (new BlockQuartz(155)).setStepSound(soundStoneFootstep).setHardness(0.8F).setUnlocalizedName("quartzBlock"); + public static final Block stairsNetherQuartz = (new BlockStairs(156, blockNetherQuartz, 0)).setUnlocalizedName("stairsQuartz"); + public static final Block railActivator = (new BlockRailPowered(157)).setHardness(0.7F).setStepSound(soundMetalFootstep).setUnlocalizedName("activatorRail"); + public static final Block dropper = (new BlockDropper(158)).setHardness(3.5F).setStepSound(soundStoneFootstep).setUnlocalizedName("dropper"); + + /** ID of the block. */ + public final int blockID; + + /** Indicates how many hits it takes to break a block. */ + protected float blockHardness; + + /** Indicates the blocks resistance to explosions. */ + protected float blockResistance; + + /** + * set to true when Block's constructor is called through the chain of + * super()'s. Note: Never used + */ + protected boolean blockConstructorCalled = true; + + /** + * If this field is true, the block is counted for statistics (mined or placed) + */ + protected boolean enableStats = true; + + /** + * Flags whether or not this block is of a type that needs random ticking. + * Ref-counted by ExtendedBlockStorage in order to broadly cull a chunk from the + * random chunk update list for efficiency's sake. + */ + protected boolean needsRandomTick; + + /** true if the Block contains a Tile Entity */ + protected boolean isBlockContainer; + + /** minimum X for the block bounds (local coordinates) */ + protected double minX; + + /** minimum Y for the block bounds (local coordinates) */ + protected double minY; + + /** minimum Z for the block bounds (local coordinates) */ + protected double minZ; + + /** maximum X for the block bounds (local coordinates) */ + protected double maxX; + + /** maximum Y for the block bounds (local coordinates) */ + protected double maxY; + + /** maximum Z for the block bounds (local coordinates) */ + protected double maxZ; + + /** Sound of stepping on the block */ + public StepSound stepSound; + public float blockParticleGravity; + + /** Block material definition. */ + public final Material blockMaterial; + + /** + * Determines how much velocity is maintained while moving on top of this block + */ + public float slipperiness; + + /** The unlocalized name of this block. */ + private String unlocalizedName; + protected Icon blockIcon; + + protected Block(int par1, Material par2Material) { + this.stepSound = soundPowderFootstep; + this.blockParticleGravity = 1.0F; + this.slipperiness = 0.6F; + + if (blocksList[par1] != null) { + throw new IllegalArgumentException("Slot " + par1 + " is already occupied by " + blocksList[par1] + " when adding " + this); + } else { + this.blockMaterial = par2Material; + blocksList[par1] = this; + this.blockID = par1; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + opaqueCubeLookup[par1] = this.isOpaqueCube(); + lightOpacity[par1] = this.isOpaqueCube() ? 255 : 0; + canBlockGrass[par1] = !par2Material.getCanBlockGrass(); + } + } + + /** + * This method is called on a block after all other blocks gets already created. + * You can use it to reference and configure something on the block that needs + * the others ones. + */ + protected void initializeBlock() { + } + + /** + * Sets the footstep sound for the block. Returns the object for convenience in + * constructing. + */ + protected Block setStepSound(StepSound par1StepSound) { + this.stepSound = par1StepSound; + return this; + } + + /** + * Sets how much light is blocked going through this block. Returns the object + * for convenience in constructing. + */ + protected Block setLightOpacity(int par1) { + lightOpacity[this.blockID] = par1; + return this; + } + + /** + * Sets the amount of light emitted by a block from 0.0f to 1.0f (converts + * internally to 0-15). Returns the object for convenience in constructing. + */ + protected Block setLightValue(float par1) { + lightValue[this.blockID] = (int) (15.0F * par1); + return this; + } + + /** + * Sets the the blocks resistance to explosions. Returns the object for + * convenience in constructing. + */ + protected Block setResistance(float par1) { + this.blockResistance = par1 * 3.0F; + return this; + } + + public static boolean isNormalCube(int par0) { + Block var1 = blocksList[par0]; + return var1 == null ? false : var1.blockMaterial.isOpaque() && var1.renderAsNormalBlock() && !var1.canProvidePower(); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return true; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return !this.blockMaterial.blocksMovement(); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 0; + } + + /** + * Sets how many hits it takes to break a block. + */ + protected Block setHardness(float par1) { + this.blockHardness = par1; + + if (this.blockResistance < par1 * 5.0F) { + this.blockResistance = par1 * 5.0F; + } + + return this; + } + + /** + * This method will make the hardness of the block equals to -1, and the block + * is indestructible. + */ + protected Block setBlockUnbreakable() { + this.setHardness(-1.0F); + return this; + } + + /** + * Returns the block hardness at a location. Args: world, x, y, z + */ + public float getBlockHardness(World par1World, int par2, int par3, int par4) { + return this.blockHardness; + } + + /** + * Sets whether this block type will receive random update ticks + */ + protected Block setTickRandomly(boolean par1) { + this.needsRandomTick = par1; + return this; + } + + /** + * Returns whether or not this block is of a type that needs random ticking. + * Called for ref-counting purposes by ExtendedBlockStorage in order to broadly + * cull a chunk from the random chunk update list for efficiency's sake. + */ + public boolean getTickRandomly() { + return this.needsRandomTick; + } + + public boolean hasTileEntity() { + return this.isBlockContainer; + } + + /** + * Sets the bounds of the block. minX, minY, minZ, maxX, maxY, maxZ + */ + protected final void setBlockBounds(float par1, float par2, float par3, float par4, float par5, float par6) { + this.minX = (double) par1; + this.minY = (double) par2; + this.minZ = (double) par3; + this.maxX = (double) par4; + this.maxY = (double) par5; + this.maxZ = (double) par6; + } + + /** + * How bright to render this block based on the light its receiving. Args: + * iBlockAccess, x, y, z + */ + public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return par1IBlockAccess.getBrightness(par2, par3, par4, lightValue[par1IBlockAccess.getBlockId(par2, par3, par4)]); + } + + /** + * Goes straight to getLightBrightnessForSkyBlocks for Blocks, does some fancy + * computing for Fluids + */ + public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return par1IBlockAccess.getLightBrightnessForSkyBlocks(par2, par3, par4, lightValue[par1IBlockAccess.getBlockId(par2, par3, par4)]); + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return par5 == 0 && this.minY > 0.0D ? true + : (par5 == 1 && this.maxY < 1.0D ? true + : (par5 == 2 && this.minZ > 0.0D ? true + : (par5 == 3 && this.maxZ < 1.0D ? true : (par5 == 4 && this.minX > 0.0D ? true : (par5 == 5 && this.maxX < 1.0D ? true : !par1IBlockAccess.isBlockOpaqueCube(par2, par3, par4)))))); + } + + /** + * Returns Returns true if the given side of this block type should be rendered + * (if it's solid or not), if the adjacent block is at the given coordinates. + * Args: blockAccess, x, y, z, side + */ + public boolean isBlockSolid(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return par1IBlockAccess.getBlockMaterial(par2, par3, par4).isSolid(); + } + + /** + * Retrieves the block texture to use based on the display side. Args: + * iBlockAccess, x, y, z, side + */ + public Icon getBlockTexture(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return this.getIcon(par5, par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return this.blockIcon; + } + + /** + * Returns the block texture based on the side being looked at. Args: side + */ + public final Icon getBlockTextureFromSide(int par1) { + return this.getIcon(par1, 0); + } + + /** + * Returns the bounding box of the wired rectangular prism to render. + */ + public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return AxisAlignedBB.getAABBPool().getAABB((double) par2 + this.minX, (double) par3 + this.minY, (double) par4 + this.minZ, (double) par2 + this.maxX, (double) par3 + this.maxY, (double) par4 + this.maxZ); + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity) { + AxisAlignedBB var8 = this.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + + if (var8 != null && par5AxisAlignedBB.intersectsWith(var8)) { + par6List.add(var8); + } + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return AxisAlignedBB.getAABBPool().getAABB((double) par2 + this.minX, (double) par3 + this.minY, (double) par4 + this.minZ, (double) par2 + this.maxX, (double) par3 + this.maxY, (double) par4 + this.maxZ); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return true; + } + + /** + * Returns whether this block is collideable based on the arguments passed in + * Args: blockMetaData, unknownFlag + */ + public boolean canCollideCheck(int par1, boolean par2) { + return this.isCollidable(); + } + + /** + * Returns if this block is collidable (only used by Fire). Args: x, y, z + */ + public boolean isCollidable() { + return true; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + } + + /** + * Called right before the block is destroyed by a player. Args: world, x, y, z, + * metaData + */ + public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) { + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 10; + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return this.blockID; + } + + /** + * Gets the hardness of block at the given coordinates in the given world, + * relative to the ability of the given EntityPlayer. + */ + public float getPlayerRelativeBlockHardness(EntityPlayer par1EntityPlayer, World par2World, int par3, int par4, int par5) { + float var6 = this.getBlockHardness(par2World, par3, par4, par5); + return var6 < 0.0F ? 0.0F : (!par1EntityPlayer.canHarvestBlock(this) ? par1EntityPlayer.getCurrentPlayerStrVsBlock(this, false) / var6 / 100.0F : par1EntityPlayer.getCurrentPlayerStrVsBlock(this, true) / var6 / 30.0F); + } + + /** + * Drops the specified block items + */ + public final void dropBlockAsItem(World par1World, int par2, int par3, int par4, int par5, int par6) { + this.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, 1.0F, par6); + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + if (!par1World.isRemote) { + int var8 = this.quantityDroppedWithBonus(par7, par1World.rand); + + for (int var9 = 0; var9 < var8; ++var9) { + if (par1World.rand.nextFloat() <= par6) { + int var10 = this.idDropped(par5, par1World.rand, par7); + + if (var10 > 0) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(var10, 1, this.damageDropped(par5))); + } + } + } + } + } + + /** + * Spawns EntityItem in the world for the given ItemStack if the world is not + * remote. + */ + protected void dropBlockAsItem_do(World par1World, int par2, int par3, int par4, ItemStack par5ItemStack) { + if (!par1World.isRemote && par1World.getGameRules().getGameRuleBooleanValue("doTileDrops")) { + float var6 = 0.7F; + double var7 = (double) (par1World.rand.nextFloat() * var6) + (double) (1.0F - var6) * 0.5D; + double var9 = (double) (par1World.rand.nextFloat() * var6) + (double) (1.0F - var6) * 0.5D; + double var11 = (double) (par1World.rand.nextFloat() * var6) + (double) (1.0F - var6) * 0.5D; + EntityItem var13 = new EntityItem(par1World, (double) par2 + var7, (double) par3 + var9, (double) par4 + var11, par5ItemStack); + var13.delayBeforeCanPickup = 10; + par1World.spawnEntityInWorld(var13); + } + } + + /** + * called by spawner, ore, redstoneOre blocks + */ + protected void dropXpOnBlockBreak(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + while (par5 > 0) { + int var6 = EntityXPOrb.getXPSplit(par5); + par5 -= var6; + par1World.spawnEntityInWorld(new EntityXPOrb(par1World, (double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, var6)); + } + } + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return 0; + } + + /** + * Returns how much this block can resist explosions from the passed in entity. + */ + public float getExplosionResistance(Entity par1Entity) { + return this.blockResistance / 5.0F; + } + + /** + * Ray traces through the blocks collision from start vector to end vector + * returning a ray trace hit. Args: world, x, y, z, startVec, endVec + */ + public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, Vec3 par6Vec3) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + par5Vec3 = par5Vec3.addVector((double) (-par2), (double) (-par3), (double) (-par4)); + par6Vec3 = par6Vec3.addVector((double) (-par2), (double) (-par3), (double) (-par4)); + Vec3 var7 = par5Vec3.getIntermediateWithXValue(par6Vec3, this.minX); + Vec3 var8 = par5Vec3.getIntermediateWithXValue(par6Vec3, this.maxX); + Vec3 var9 = par5Vec3.getIntermediateWithYValue(par6Vec3, this.minY); + Vec3 var10 = par5Vec3.getIntermediateWithYValue(par6Vec3, this.maxY); + Vec3 var11 = par5Vec3.getIntermediateWithZValue(par6Vec3, this.minZ); + Vec3 var12 = par5Vec3.getIntermediateWithZValue(par6Vec3, this.maxZ); + + if (!this.isVecInsideYZBounds(var7)) { + var7 = null; + } + + if (!this.isVecInsideYZBounds(var8)) { + var8 = null; + } + + if (!this.isVecInsideXZBounds(var9)) { + var9 = null; + } + + if (!this.isVecInsideXZBounds(var10)) { + var10 = null; + } + + if (!this.isVecInsideXYBounds(var11)) { + var11 = null; + } + + if (!this.isVecInsideXYBounds(var12)) { + var12 = null; + } + + Vec3 var13 = null; + + if (var7 != null && (var13 == null || par5Vec3.squareDistanceTo(var7) < par5Vec3.squareDistanceTo(var13))) { + var13 = var7; + } + + if (var8 != null && (var13 == null || par5Vec3.squareDistanceTo(var8) < par5Vec3.squareDistanceTo(var13))) { + var13 = var8; + } + + if (var9 != null && (var13 == null || par5Vec3.squareDistanceTo(var9) < par5Vec3.squareDistanceTo(var13))) { + var13 = var9; + } + + if (var10 != null && (var13 == null || par5Vec3.squareDistanceTo(var10) < par5Vec3.squareDistanceTo(var13))) { + var13 = var10; + } + + if (var11 != null && (var13 == null || par5Vec3.squareDistanceTo(var11) < par5Vec3.squareDistanceTo(var13))) { + var13 = var11; + } + + if (var12 != null && (var13 == null || par5Vec3.squareDistanceTo(var12) < par5Vec3.squareDistanceTo(var13))) { + var13 = var12; + } + + if (var13 == null) { + return null; + } else { + byte var14 = -1; + + if (var13 == var7) { + var14 = 4; + } + + if (var13 == var8) { + var14 = 5; + } + + if (var13 == var9) { + var14 = 0; + } + + if (var13 == var10) { + var14 = 1; + } + + if (var13 == var11) { + var14 = 2; + } + + if (var13 == var12) { + var14 = 3; + } + + return new MovingObjectPosition(par2, par3, par4, var14, var13.addVector((double) par2, (double) par3, (double) par4)); + } + } + + /** + * Checks if a vector is within the Y and Z bounds of the block. + */ + private boolean isVecInsideYZBounds(Vec3 par1Vec3) { + return par1Vec3 == null ? false : par1Vec3.yCoord >= this.minY && par1Vec3.yCoord <= this.maxY && par1Vec3.zCoord >= this.minZ && par1Vec3.zCoord <= this.maxZ; + } + + /** + * Checks if a vector is within the X and Z bounds of the block. + */ + private boolean isVecInsideXZBounds(Vec3 par1Vec3) { + return par1Vec3 == null ? false : par1Vec3.xCoord >= this.minX && par1Vec3.xCoord <= this.maxX && par1Vec3.zCoord >= this.minZ && par1Vec3.zCoord <= this.maxZ; + } + + /** + * Checks if a vector is within the X and Y bounds of the block. + */ + private boolean isVecInsideXYBounds(Vec3 par1Vec3) { + return par1Vec3 == null ? false : par1Vec3.xCoord >= this.minX && par1Vec3.xCoord <= this.maxX && par1Vec3.yCoord >= this.minY && par1Vec3.yCoord <= this.maxY; + } + + /** + * Called upon the block being destroyed by an explosion + */ + public void onBlockDestroyedByExplosion(World par1World, int par2, int par3, int par4, Explosion par5Explosion) { + } + + /** + * Returns which pass should this block be rendered on. 0 for solids and 1 for + * alpha + */ + public int getRenderBlockPass() { + return 0; + } + + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5, ItemStack par6ItemStack) { + return this.canPlaceBlockOnSide(par1World, par2, par3, par4, par5); + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + return this.canPlaceBlockAt(par1World, par2, par3, par4); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockId(par2, par3, par4); + return var5 == 0 || blocksList[var5].blockMaterial.isReplaceable(); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + return false; + } + + /** + * Called whenever an entity is walking on top of this block. Args: world, x, y, + * z, entity + */ + public void onEntityWalking(World par1World, int par2, int par3, int par4, Entity par5Entity) { + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9) { + return par9; + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + } + + /** + * Can add to the passed in vector for a movement vector to be applied to the + * entity. Args: x, y, z, entity, vec3d + */ + public void velocityToAddToEntity(World par1World, int par2, int par3, int par4, Entity par5Entity, Vec3 par6Vec3) { + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + } + + /** + * returns the block bounderies minX value + */ + public final double getBlockBoundsMinX() { + return this.minX; + } + + /** + * returns the block bounderies maxX value + */ + public final double getBlockBoundsMaxX() { + return this.maxX; + } + + /** + * returns the block bounderies minY value + */ + public final double getBlockBoundsMinY() { + return this.minY; + } + + /** + * returns the block bounderies maxY value + */ + public final double getBlockBoundsMaxY() { + return this.maxY; + } + + /** + * returns the block bounderies minZ value + */ + public final double getBlockBoundsMinZ() { + return this.minZ; + } + + /** + * returns the block bounderies maxZ value + */ + public final double getBlockBoundsMaxZ() { + return this.maxZ; + } + + public int getBlockColor() { + return 16777215; + } + + /** + * Returns the color this block should be rendered. Used by leaves. + */ + public int getRenderColor(int par1) { + return 16777215; + } + + /** + * Returns a integer with hex for 0xrrggbb with this color multiplied against + * the blocks color. Note only called when first determining what to render. + */ + public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return 16777215; + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return 0; + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return false; + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return 0; + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + } + + /** + * Called when the player destroys a block with an item that can harvest it. (i, + * j, k) are the coordinates of the block and l is the block's subtype/damage. + */ + public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) { + par2EntityPlayer.addExhaustion(0.025F); + + if (this.canSilkHarvest() && EnchantmentHelper.getSilkTouchModifier(par2EntityPlayer)) { + ItemStack var8 = this.createStackedBlock(par6); + + if (var8 != null) { + this.dropBlockAsItem_do(par1World, par3, par4, par5, var8); + } + } else { + int var7 = EnchantmentHelper.getFortuneModifier(par2EntityPlayer); + this.dropBlockAsItem(par1World, par3, par4, par5, par6, var7); + } + } + + /** + * Return true if a player with Silk Touch can harvest this block directly, and + * not its normal drops. + */ + protected boolean canSilkHarvest() { + return this.renderAsNormalBlock() && !this.isBlockContainer; + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + int var2 = 0; + + if (this.blockID >= 0 && this.blockID < Item.itemsList.length && Item.itemsList[this.blockID].getHasSubtypes()) { + var2 = par1; + } + + return new ItemStack(this.blockID, 1, var2); + } + + /** + * Returns the usual quantity dropped by the block plus a bonus of 1 to 'i' + * (inclusive). + */ + public int quantityDroppedWithBonus(int par1, Random par2Random) { + return this.quantityDropped(par2Random); + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + return true; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + } + + /** + * Called after a block is placed + */ + public void onPostBlockPlaced(World par1World, int par2, int par3, int par4, int par5) { + } + + public Block setUnlocalizedName(String par1Str) { + this.unlocalizedName = par1Str; + return this; + } + + /** + * Gets the localized name of this block. Used for the statistics page. + */ + public String getLocalizedName() { + return StatCollector.translateToLocal(this.getUnlocalizedName() + ".name"); + } + + /** + * Returns the unlocalized name of this block. + */ + public String getUnlocalizedName() { + return "tile." + this.unlocalizedName; + } + + /** + * Returns the unlocalized name without the tile. prefix. Caution: client-only. + */ + public String getUnlocalizedName2() { + return this.unlocalizedName; + } + + /** + * Called when the block receives a BlockEvent - see World.addBlockEvent. By + * default, passes it on to the tile entity at this location. Args: world, x, y, + * z, blockID, EventID, event parameter + */ + public boolean onBlockEventReceived(World par1World, int par2, int par3, int par4, int par5, int par6) { + return false; + } + + /** + * Return the state of blocks statistics flags - if the block is counted for + * mined and placed. + */ + public boolean getEnableStats() { + return this.enableStats; + } + + /** + * Disable statistics for the block, the block will no count for mined or + * placed. + */ + protected Block disableStats() { + this.enableStats = false; + return this; + } + + /** + * Returns the mobility information of the block, 0 = free, 1 = can't push but + * can move over, 2 = total immobility and stop pistons + */ + public int getMobilityFlag() { + return this.blockMaterial.getMaterialMobility(); + } + + /** + * Returns the default ambient occlusion value based on block opacity + */ + public float getAmbientOcclusionLightValue(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return par1IBlockAccess.isBlockNormalCube(par2, par3, par4) ? 0.2F : 1.0F; + } + + /** + * Block's chance to react to an entity falling on it. + */ + public void onFallenUpon(World par1World, int par2, int par3, int par4, Entity par5Entity, float par6) { + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return this.blockID; + } + + /** + * Get the block's damage value (for use with pick block). + */ + public int getDamageValue(World par1World, int par2, int par3, int par4) { + return this.damageDropped(par1World.getBlockMetadata(par2, par3, par4)); + } + + /** + * returns a list of blocks with the same ID, but different meta (eg: wood + * returns 4 blocks) + */ + public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + par3List.add(new ItemStack(par1, 1, 0)); + } + + /** + * Returns the CreativeTab to display the given block on. + */ + public CreativeTabs getCreativeTabToDisplayOn() { + return this.displayOnCreativeTab; + } + + /** + * Sets the CreativeTab to display this block on. + */ + public Block setCreativeTab(CreativeTabs par1CreativeTabs) { + this.displayOnCreativeTab = par1CreativeTabs; + return this; + } + + /** + * Called when the block is attempted to be harvested + */ + public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer) { + } + + /** + * Called when this block is set (with meta data). + */ + public void onSetBlockIDWithMetaData(World par1World, int par2, int par3, int par4, int par5) { + } + + /** + * currently only used by BlockCauldron to incrament meta-data during rain + */ + public void fillWithRain(World par1World, int par2, int par3, int par4) { + } + + /** + * Returns true only if block is flowerPot + */ + public boolean isFlowerPot() { + return false; + } + + public boolean func_82506_l() { + return true; + } + + /** + * Return whether this block can drop from an explosion. + */ + public boolean canDropFromExplosion(Explosion par1Explosion) { + return true; + } + + /** + * Returns true if the given block ID is equivalent to this one. Example: + * redstoneTorchOn matches itself and redstoneTorchOff, and vice versa. Most + * blocks only match themselves. + */ + public boolean isAssociatedBlockID(int par1) { + return this.blockID == par1; + } + + /** + * Static version of isAssociatedBlockID. + */ + public static boolean isAssociatedBlockID(int par0, int par1) { + return par0 == par1 ? true : (par0 != 0 && par1 != 0 && blocksList[par0] != null && blocksList[par1] != null ? blocksList[par0].isAssociatedBlockID(par1) : false); + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return false; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + return 0; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon(this.unlocalizedName); + } + + /** + * Gets the icon name of the ItemBlock corresponding to this block. Used by + * hoppers. + */ + public String getItemIconName() { + return null; + } + + static { + Item.itemsList[cloth.blockID] = (new ItemCloth(cloth.blockID - 256)).setUnlocalizedName("cloth"); + Item.itemsList[wood.blockID] = (new ItemMultiTextureTile(wood.blockID - 256, wood, BlockLog.woodType)).setUnlocalizedName("log"); + Item.itemsList[planks.blockID] = (new ItemMultiTextureTile(planks.blockID - 256, planks, BlockWood.woodType)).setUnlocalizedName("wood"); + Item.itemsList[silverfish.blockID] = (new ItemMultiTextureTile(silverfish.blockID - 256, silverfish, BlockSilverfish.silverfishStoneTypes)).setUnlocalizedName("monsterStoneEgg"); + Item.itemsList[stoneBrick.blockID] = (new ItemMultiTextureTile(stoneBrick.blockID - 256, stoneBrick, BlockStoneBrick.STONE_BRICK_TYPES)).setUnlocalizedName("stonebricksmooth"); + Item.itemsList[sandStone.blockID] = (new ItemMultiTextureTile(sandStone.blockID - 256, sandStone, BlockSandStone.SAND_STONE_TYPES)).setUnlocalizedName("sandStone"); + Item.itemsList[blockNetherQuartz.blockID] = (new ItemMultiTextureTile(blockNetherQuartz.blockID - 256, blockNetherQuartz, BlockQuartz.quartzBlockTypes)).setUnlocalizedName("quartzBlock"); + Item.itemsList[stoneSingleSlab.blockID] = (new ItemSlab(stoneSingleSlab.blockID - 256, stoneSingleSlab, stoneDoubleSlab, false)).setUnlocalizedName("stoneSlab"); + Item.itemsList[stoneDoubleSlab.blockID] = (new ItemSlab(stoneDoubleSlab.blockID - 256, stoneSingleSlab, stoneDoubleSlab, true)).setUnlocalizedName("stoneSlab"); + Item.itemsList[woodSingleSlab.blockID] = (new ItemSlab(woodSingleSlab.blockID - 256, woodSingleSlab, woodDoubleSlab, false)).setUnlocalizedName("woodSlab"); + Item.itemsList[woodDoubleSlab.blockID] = (new ItemSlab(woodDoubleSlab.blockID - 256, woodSingleSlab, woodDoubleSlab, true)).setUnlocalizedName("woodSlab"); + Item.itemsList[sapling.blockID] = (new ItemMultiTextureTile(sapling.blockID - 256, sapling, BlockSapling.WOOD_TYPES)).setUnlocalizedName("sapling"); + Item.itemsList[leaves.blockID] = (new ItemLeaves(leaves.blockID - 256)).setUnlocalizedName("leaves"); + Item.itemsList[vine.blockID] = new ItemColored(vine.blockID - 256, false); + Item.itemsList[tallGrass.blockID] = (new ItemColored(tallGrass.blockID - 256, true)).setBlockNames(new String[] { "shrub", "grass", "fern" }); + Item.itemsList[snow.blockID] = new ItemSnow(snow.blockID - 256, snow); + Item.itemsList[waterlily.blockID] = new ItemLilyPad(waterlily.blockID - 256); + Item.itemsList[pistonBase.blockID] = new ItemPiston(pistonBase.blockID - 256); + Item.itemsList[pistonStickyBase.blockID] = new ItemPiston(pistonStickyBase.blockID - 256); + Item.itemsList[cobblestoneWall.blockID] = (new ItemMultiTextureTile(cobblestoneWall.blockID - 256, cobblestoneWall, BlockWall.types)).setUnlocalizedName("cobbleWall"); + Item.itemsList[anvil.blockID] = (new ItemAnvilBlock(anvil)).setUnlocalizedName("anvil"); + + for (int var0 = 0; var0 < 256; ++var0) { + if (blocksList[var0] != null) { + if (Item.itemsList[var0] == null) { + Item.itemsList[var0] = new ItemBlock(var0 - 256); + blocksList[var0].initializeBlock(); + } + + boolean var1 = false; + + if (var0 > 0 && blocksList[var0].getRenderType() == 10) { + var1 = true; + } + + if (var0 > 0 && blocksList[var0] instanceof BlockHalfSlab) { + var1 = true; + } + + if (var0 == tilledField.blockID) { + var1 = true; + } + + if (canBlockGrass[var0]) { + var1 = true; + } + + if (lightOpacity[var0] == 0) { + var1 = true; + } + + useNeighborBrightness[var0] = var1; + } + } + + canBlockGrass[0] = true; + } +} diff --git a/src/main/java/net/minecraft/src/BlockAnvil.java b/src/main/java/net/minecraft/src/BlockAnvil.java new file mode 100644 index 0000000..3efd15d --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockAnvil.java @@ -0,0 +1,159 @@ +package net.minecraft.src; + +import java.util.List; + +public class BlockAnvil extends BlockSand { + /** List of types/statues the Anvil can be in. */ + public static final String[] statuses = new String[] { "intact", "slightlyDamaged", "veryDamaged" }; + private static final String[] anvilIconNames = new String[] { "anvil_top", "anvil_top_damaged_1", "anvil_top_damaged_2" }; + public int field_82521_b = 0; + private Icon[] iconArray; + + protected BlockAnvil(int par1) { + super(par1, Material.anvil); + this.setLightOpacity(0); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + if (this.field_82521_b == 3 && par1 == 1) { + int var3 = (par2 >> 2) % this.iconArray.length; + return this.iconArray[var3]; + } else { + return this.blockIcon; + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("anvil_base"); + this.iconArray = new Icon[anvilIconNames.length]; + + for (int var2 = 0; var2 < this.iconArray.length; ++var2) { + this.iconArray[var2] = par1IconRegister.registerIcon(anvilIconNames[var2]); + } + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + int var7 = MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + int var8 = par1World.getBlockMetadata(par2, par3, par4) >> 2; + ++var7; + var7 %= 4; + + if (var7 == 0) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 2 | var8 << 2, 2); + } + + if (var7 == 1) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 3 | var8 << 2, 2); + } + + if (var7 == 2) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 0 | var8 << 2, 2); + } + + if (var7 == 3) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 1 | var8 << 2, 2); + } + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + par5EntityPlayer.displayGUIAnvil(par2, par3, par4); + return true; + } + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 35; + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1 >> 2; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 3; + + if (var5 != 3 && var5 != 1) { + this.setBlockBounds(0.125F, 0.0F, 0.0F, 0.875F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.125F, 1.0F, 1.0F, 0.875F); + } + } + + /** + * returns a list of blocks with the same ID, but different meta (eg: wood + * returns 4 blocks) + */ + public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + par3List.add(new ItemStack(par1, 1, 0)); + par3List.add(new ItemStack(par1, 1, 1)); + par3List.add(new ItemStack(par1, 1, 2)); + } + + /** + * Called when the falling block entity for this block is created + */ + protected void onStartFalling(EntityFallingSand par1EntityFallingSand) { + par1EntityFallingSand.setIsAnvil(true); + } + + /** + * Called when the falling block entity for this block hits the ground and turns + * back into a block + */ + public void onFinishFalling(World par1World, int par2, int par3, int par4, int par5) { + par1World.playAuxSFX(1022, par2, par3, par4, 0); + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/BlockBasePressurePlate.java b/src/main/java/net/minecraft/src/BlockBasePressurePlate.java new file mode 100644 index 0000000..42dbcd6 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockBasePressurePlate.java @@ -0,0 +1,241 @@ +package net.minecraft.src; + +import java.util.Random; + +public abstract class BlockBasePressurePlate extends Block { + private String pressurePlateIconName; + + protected BlockBasePressurePlate(int par1, String par2Str, Material par3Material) { + super(par1, par3Material); + this.pressurePlateIconName = par2Str; + this.setCreativeTab(CreativeTabs.tabRedstone); + this.setTickRandomly(true); + this.func_94353_c_(this.getMetaFromWeight(15)); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.func_94353_c_(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + protected void func_94353_c_(int par1) { + boolean var2 = this.getPowerSupply(par1) > 0; + float var3 = 0.0625F; + + if (var2) { + this.setBlockBounds(var3, 0.0F, var3, 1.0F - var3, 0.03125F, 1.0F - var3); + } else { + this.setBlockBounds(var3, 0.0F, var3, 1.0F - var3, 0.0625F, 1.0F - var3); + } + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 20; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return true; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) || BlockFence.isIdAFence(par1World.getBlockId(par2, par3 - 1, par4)); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + boolean var6 = false; + + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) && !BlockFence.isIdAFence(par1World.getBlockId(par2, par3 - 1, par4))) { + var6 = true; + } + + if (var6) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + int var6 = this.getPowerSupply(par1World.getBlockMetadata(par2, par3, par4)); + + if (var6 > 0) { + this.setStateIfMobInteractsWithPlate(par1World, par2, par3, par4, var6); + } + } + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + if (!par1World.isRemote) { + int var6 = this.getPowerSupply(par1World.getBlockMetadata(par2, par3, par4)); + + if (var6 == 0) { + this.setStateIfMobInteractsWithPlate(par1World, par2, par3, par4, var6); + } + } + } + + /** + * Checks if there are mobs on the plate. If a mob is on the plate and it is + * off, it turns it on, and vice versa. + */ + protected void setStateIfMobInteractsWithPlate(World par1World, int par2, int par3, int par4, int par5) { + int var6 = this.getPlateState(par1World, par2, par3, par4); + boolean var7 = par5 > 0; + boolean var8 = var6 > 0; + + if (par5 != var6) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, this.getMetaFromWeight(var6), 2); + this.func_94354_b_(par1World, par2, par3, par4); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + } + + if (!var8 && var7) { + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.1D, (double) par4 + 0.5D, "random.click", 0.3F, 0.5F); + } else if (var8 && !var7) { + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.1D, (double) par4 + 0.5D, "random.click", 0.3F, 0.6F); + } + + if (var8) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + } + + protected AxisAlignedBB getSensitiveAABB(int par1, int par2, int par3) { + float var4 = 0.125F; + return AxisAlignedBB.getAABBPool().getAABB((double) ((float) par1 + var4), (double) par2, (double) ((float) par3 + var4), (double) ((float) (par1 + 1) - var4), (double) par2 + 0.25D, (double) ((float) (par3 + 1) - var4)); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + if (this.getPowerSupply(par6) > 0) { + this.func_94354_b_(par1World, par2, par3, par4); + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + protected void func_94354_b_(World par1World, int par2, int par3, int par4) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return this.getPowerSupply(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return par5 == 1 ? this.getPowerSupply(par1IBlockAccess.getBlockMetadata(par2, par3, par4)) : 0; + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + float var1 = 0.5F; + float var2 = 0.125F; + float var3 = 0.5F; + this.setBlockBounds(0.5F - var1, 0.5F - var2, 0.5F - var3, 0.5F + var1, 0.5F + var2, 0.5F + var3); + } + + /** + * Returns the mobility information of the block, 0 = free, 1 = can't push but + * can move over, 2 = total immobility and stop pistons + */ + public int getMobilityFlag() { + return 1; + } + + /** + * Returns the current state of the pressure plate. Returns a value between 0 + * and 15 based on the number of items on it. + */ + protected abstract int getPlateState(World var1, int var2, int var3, int var4); + + /** + * Argument is metadata. Returns power level (0-15) + */ + protected abstract int getPowerSupply(int var1); + + /** + * Argument is weight (0-15). Return the metadata to be set because of it. + */ + protected abstract int getMetaFromWeight(int var1); + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon(this.pressurePlateIconName); + } +} diff --git a/src/main/java/net/minecraft/src/BlockBaseRailLogic.java b/src/main/java/net/minecraft/src/BlockBaseRailLogic.java new file mode 100644 index 0000000..2681f55 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockBaseRailLogic.java @@ -0,0 +1,357 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +public class BlockBaseRailLogic { + private World logicWorld; + private int railX; + private int railY; + private int railZ; + private final boolean isStraightRail; + + /** The chunk position the rail is at. */ + private List railChunkPosition; + + final BlockRailBase theRail; + + public BlockBaseRailLogic(BlockRailBase par1, World par2, int par3, int par4, int par5) { + this.theRail = par1; + this.railChunkPosition = new ArrayList(); + this.logicWorld = par2; + this.railX = par3; + this.railY = par4; + this.railZ = par5; + int var6 = par2.getBlockId(par3, par4, par5); + int var7 = par2.getBlockMetadata(par3, par4, par5); + + if (((BlockRailBase) Block.blocksList[var6]).isPowered) { + this.isStraightRail = true; + var7 &= -9; + } else { + this.isStraightRail = false; + } + + this.setBasicRail(var7); + } + + private void setBasicRail(int par1) { + this.railChunkPosition.clear(); + + if (par1 == 0) { + this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ - 1)); + this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ + 1)); + } else if (par1 == 1) { + this.railChunkPosition.add(new ChunkPosition(this.railX - 1, this.railY, this.railZ)); + this.railChunkPosition.add(new ChunkPosition(this.railX + 1, this.railY, this.railZ)); + } else if (par1 == 2) { + this.railChunkPosition.add(new ChunkPosition(this.railX - 1, this.railY, this.railZ)); + this.railChunkPosition.add(new ChunkPosition(this.railX + 1, this.railY + 1, this.railZ)); + } else if (par1 == 3) { + this.railChunkPosition.add(new ChunkPosition(this.railX - 1, this.railY + 1, this.railZ)); + this.railChunkPosition.add(new ChunkPosition(this.railX + 1, this.railY, this.railZ)); + } else if (par1 == 4) { + this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY + 1, this.railZ - 1)); + this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ + 1)); + } else if (par1 == 5) { + this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ - 1)); + this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY + 1, this.railZ + 1)); + } else if (par1 == 6) { + this.railChunkPosition.add(new ChunkPosition(this.railX + 1, this.railY, this.railZ)); + this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ + 1)); + } else if (par1 == 7) { + this.railChunkPosition.add(new ChunkPosition(this.railX - 1, this.railY, this.railZ)); + this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ + 1)); + } else if (par1 == 8) { + this.railChunkPosition.add(new ChunkPosition(this.railX - 1, this.railY, this.railZ)); + this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ - 1)); + } else if (par1 == 9) { + this.railChunkPosition.add(new ChunkPosition(this.railX + 1, this.railY, this.railZ)); + this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ - 1)); + } + } + + private void refreshConnectedTracks() { + for (int var1 = 0; var1 < this.railChunkPosition.size(); ++var1) { + BlockBaseRailLogic var2 = this.getRailLogic((ChunkPosition) this.railChunkPosition.get(var1)); + + if (var2 != null && var2.isRailChunkPositionCorrect(this)) { + this.railChunkPosition.set(var1, new ChunkPosition(var2.railX, var2.railY, var2.railZ)); + } else { + this.railChunkPosition.remove(var1--); + } + } + } + + private boolean isMinecartTrack(int par1, int par2, int par3) { + return BlockRailBase.isRailBlockAt(this.logicWorld, par1, par2, par3) ? true : (BlockRailBase.isRailBlockAt(this.logicWorld, par1, par2 + 1, par3) ? true : BlockRailBase.isRailBlockAt(this.logicWorld, par1, par2 - 1, par3)); + } + + private BlockBaseRailLogic getRailLogic(ChunkPosition par1ChunkPosition) { + return BlockRailBase.isRailBlockAt(this.logicWorld, par1ChunkPosition.x, par1ChunkPosition.y, par1ChunkPosition.z) + ? new BlockBaseRailLogic(this.theRail, this.logicWorld, par1ChunkPosition.x, par1ChunkPosition.y, par1ChunkPosition.z) + : (BlockRailBase.isRailBlockAt(this.logicWorld, par1ChunkPosition.x, par1ChunkPosition.y + 1, par1ChunkPosition.z) + ? new BlockBaseRailLogic(this.theRail, this.logicWorld, par1ChunkPosition.x, par1ChunkPosition.y + 1, par1ChunkPosition.z) + : (BlockRailBase.isRailBlockAt(this.logicWorld, par1ChunkPosition.x, par1ChunkPosition.y - 1, par1ChunkPosition.z) + ? new BlockBaseRailLogic(this.theRail, this.logicWorld, par1ChunkPosition.x, par1ChunkPosition.y - 1, par1ChunkPosition.z) + : null)); + } + + /** + * Checks if the rail is at the chunk position it is expected to be. + */ + private boolean isRailChunkPositionCorrect(BlockBaseRailLogic par1BlockBaseRailLogic) { + for (int var2 = 0; var2 < this.railChunkPosition.size(); ++var2) { + ChunkPosition var3 = (ChunkPosition) this.railChunkPosition.get(var2); + + if (var3.x == par1BlockBaseRailLogic.railX && var3.z == par1BlockBaseRailLogic.railZ) { + return true; + } + } + + return false; + } + + private boolean isPartOfTrack(int par1, int par2, int par3) { + for (int var4 = 0; var4 < this.railChunkPosition.size(); ++var4) { + ChunkPosition var5 = (ChunkPosition) this.railChunkPosition.get(var4); + + if (var5.x == par1 && var5.z == par3) { + return true; + } + } + + return false; + } + + protected int getNumberOfAdjacentTracks() { + int var1 = 0; + + if (this.isMinecartTrack(this.railX, this.railY, this.railZ - 1)) { + ++var1; + } + + if (this.isMinecartTrack(this.railX, this.railY, this.railZ + 1)) { + ++var1; + } + + if (this.isMinecartTrack(this.railX - 1, this.railY, this.railZ)) { + ++var1; + } + + if (this.isMinecartTrack(this.railX + 1, this.railY, this.railZ)) { + ++var1; + } + + return var1; + } + + private boolean canConnectTo(BlockBaseRailLogic par1BlockBaseRailLogic) { + return this.isRailChunkPositionCorrect(par1BlockBaseRailLogic) ? true : (this.railChunkPosition.size() == 2 ? false : (this.railChunkPosition.isEmpty() ? true : true)); + } + + private void connectToNeighbor(BlockBaseRailLogic par1BlockBaseRailLogic) { + this.railChunkPosition.add(new ChunkPosition(par1BlockBaseRailLogic.railX, par1BlockBaseRailLogic.railY, par1BlockBaseRailLogic.railZ)); + boolean var2 = this.isPartOfTrack(this.railX, this.railY, this.railZ - 1); + boolean var3 = this.isPartOfTrack(this.railX, this.railY, this.railZ + 1); + boolean var4 = this.isPartOfTrack(this.railX - 1, this.railY, this.railZ); + boolean var5 = this.isPartOfTrack(this.railX + 1, this.railY, this.railZ); + byte var6 = -1; + + if (var2 || var3) { + var6 = 0; + } + + if (var4 || var5) { + var6 = 1; + } + + if (!this.isStraightRail) { + if (var3 && var5 && !var2 && !var4) { + var6 = 6; + } + + if (var3 && var4 && !var2 && !var5) { + var6 = 7; + } + + if (var2 && var4 && !var3 && !var5) { + var6 = 8; + } + + if (var2 && var5 && !var3 && !var4) { + var6 = 9; + } + } + + if (var6 == 0) { + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX, this.railY + 1, this.railZ - 1)) { + var6 = 4; + } + + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX, this.railY + 1, this.railZ + 1)) { + var6 = 5; + } + } + + if (var6 == 1) { + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX + 1, this.railY + 1, this.railZ)) { + var6 = 2; + } + + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX - 1, this.railY + 1, this.railZ)) { + var6 = 3; + } + } + + if (var6 < 0) { + var6 = 0; + } + + int var7 = var6; + + if (this.isStraightRail) { + var7 = this.logicWorld.getBlockMetadata(this.railX, this.railY, this.railZ) & 8 | var6; + } + + this.logicWorld.setBlockMetadataWithNotify(this.railX, this.railY, this.railZ, var7, 3); + } + + private boolean canConnectFrom(int par1, int par2, int par3) { + BlockBaseRailLogic var4 = this.getRailLogic(new ChunkPosition(par1, par2, par3)); + + if (var4 == null) { + return false; + } else { + var4.refreshConnectedTracks(); + return var4.canConnectTo(this); + } + } + + public void func_94511_a(boolean par1, boolean par2) { + boolean var3 = this.canConnectFrom(this.railX, this.railY, this.railZ - 1); + boolean var4 = this.canConnectFrom(this.railX, this.railY, this.railZ + 1); + boolean var5 = this.canConnectFrom(this.railX - 1, this.railY, this.railZ); + boolean var6 = this.canConnectFrom(this.railX + 1, this.railY, this.railZ); + byte var7 = -1; + + if ((var3 || var4) && !var5 && !var6) { + var7 = 0; + } + + if ((var5 || var6) && !var3 && !var4) { + var7 = 1; + } + + if (!this.isStraightRail) { + if (var4 && var6 && !var3 && !var5) { + var7 = 6; + } + + if (var4 && var5 && !var3 && !var6) { + var7 = 7; + } + + if (var3 && var5 && !var4 && !var6) { + var7 = 8; + } + + if (var3 && var6 && !var4 && !var5) { + var7 = 9; + } + } + + if (var7 == -1) { + if (var3 || var4) { + var7 = 0; + } + + if (var5 || var6) { + var7 = 1; + } + + if (!this.isStraightRail) { + if (par1) { + if (var4 && var6) { + var7 = 6; + } + + if (var5 && var4) { + var7 = 7; + } + + if (var6 && var3) { + var7 = 9; + } + + if (var3 && var5) { + var7 = 8; + } + } else { + if (var3 && var5) { + var7 = 8; + } + + if (var6 && var3) { + var7 = 9; + } + + if (var5 && var4) { + var7 = 7; + } + + if (var4 && var6) { + var7 = 6; + } + } + } + } + + if (var7 == 0) { + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX, this.railY + 1, this.railZ - 1)) { + var7 = 4; + } + + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX, this.railY + 1, this.railZ + 1)) { + var7 = 5; + } + } + + if (var7 == 1) { + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX + 1, this.railY + 1, this.railZ)) { + var7 = 2; + } + + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX - 1, this.railY + 1, this.railZ)) { + var7 = 3; + } + } + + if (var7 < 0) { + var7 = 0; + } + + this.setBasicRail(var7); + int var8 = var7; + + if (this.isStraightRail) { + var8 = this.logicWorld.getBlockMetadata(this.railX, this.railY, this.railZ) & 8 | var7; + } + + if (par2 || this.logicWorld.getBlockMetadata(this.railX, this.railY, this.railZ) != var8) { + this.logicWorld.setBlockMetadataWithNotify(this.railX, this.railY, this.railZ, var8, 3); + + for (int var9 = 0; var9 < this.railChunkPosition.size(); ++var9) { + BlockBaseRailLogic var10 = this.getRailLogic((ChunkPosition) this.railChunkPosition.get(var9)); + + if (var10 != null) { + var10.refreshConnectedTracks(); + + if (var10.canConnectTo(this)) { + var10.connectToNeighbor(this); + } + } + } + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockBeacon.java b/src/main/java/net/minecraft/src/BlockBeacon.java new file mode 100644 index 0000000..506128b --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockBeacon.java @@ -0,0 +1,85 @@ +package net.minecraft.src; + +public class BlockBeacon extends BlockContainer { + private Icon theIcon; + + public BlockBeacon(int par1) { + super(par1, Material.glass); + this.setHardness(3.0F); + this.setCreativeTab(CreativeTabs.tabMisc); + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityBeacon(); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + TileEntityBeacon var10 = (TileEntityBeacon) par1World.getBlockTileEntity(par2, par3, par4); + + if (var10 != null) { + par5EntityPlayer.displayGUIBeacon(var10); + } + + return true; + } + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 34; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + super.registerIcons(par1IconRegister); + this.theIcon = par1IconRegister.registerIcon("beacon"); + } + + public Icon getBeaconIcon() { + return this.theIcon; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + super.onBlockPlacedBy(par1World, par2, par3, par4, par5EntityLiving, par6ItemStack); + + if (par6ItemStack.hasDisplayName()) { + ((TileEntityBeacon) par1World.getBlockTileEntity(par2, par3, par4)).func_94047_a(par6ItemStack.getDisplayName()); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockBed.java b/src/main/java/net/minecraft/src/BlockBed.java new file mode 100644 index 0000000..043da76 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockBed.java @@ -0,0 +1,291 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.Random; + +public class BlockBed extends BlockDirectional { + /** Maps the foot-of-bed block to the head-of-bed block. */ + public static final int[][] footBlockToHeadBlockMap = new int[][] { { 0, 1 }, { -1, 0 }, { 0, -1 }, { 1, 0 } }; + private Icon[] field_94472_b; + private Icon[] bedSideIcons; + private Icon[] bedTopIcons; + + public BlockBed(int par1) { + super(par1, Material.cloth); + this.setBounds(); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + + if (!isBlockHeadOfBed(var10)) { + int var11 = getDirection(var10); + par2 += footBlockToHeadBlockMap[var11][0]; + par4 += footBlockToHeadBlockMap[var11][1]; + + if (par1World.getBlockId(par2, par3, par4) != this.blockID) { + return true; + } + + var10 = par1World.getBlockMetadata(par2, par3, par4); + } + + if (par1World.provider.canRespawnHere() && par1World.getBiomeGenForCoords(par2, par4) != BiomeGenBase.hell) { + if (isBedOccupied(var10)) { + EntityPlayer var19 = null; + Iterator var12 = par1World.playerEntities.iterator(); + + while (var12.hasNext()) { + EntityPlayer var21 = (EntityPlayer) var12.next(); + + if (var21.isPlayerSleeping()) { + ChunkCoordinates var14 = var21.playerLocation; + + if (var14.posX == par2 && var14.posY == par3 && var14.posZ == par4) { + var19 = var21; + } + } + } + + if (var19 != null) { + par5EntityPlayer.addChatMessage("tile.bed.occupied"); + return true; + } + + setBedOccupied(par1World, par2, par3, par4, false); + } + + EnumStatus var20 = par5EntityPlayer.sleepInBedAt(par2, par3, par4); + + if (var20 == EnumStatus.OK) { + setBedOccupied(par1World, par2, par3, par4, true); + return true; + } else { + if (var20 == EnumStatus.NOT_POSSIBLE_NOW) { + par5EntityPlayer.addChatMessage("tile.bed.noSleep"); + } else if (var20 == EnumStatus.NOT_SAFE) { + par5EntityPlayer.addChatMessage("tile.bed.notSafe"); + } + + return true; + } + } else { + double var18 = (double) par2 + 0.5D; + double var13 = (double) par3 + 0.5D; + double var15 = (double) par4 + 0.5D; + par1World.setBlockToAir(par2, par3, par4); + int var17 = getDirection(var10); + par2 += footBlockToHeadBlockMap[var17][0]; + par4 += footBlockToHeadBlockMap[var17][1]; + + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + par1World.setBlockToAir(par2, par3, par4); + var18 = (var18 + (double) par2 + 0.5D) / 2.0D; + var13 = (var13 + (double) par3 + 0.5D) / 2.0D; + var15 = (var15 + (double) par4 + 0.5D) / 2.0D; + } + + par1World.newExplosion((Entity) null, (double) ((float) par2 + 0.5F), (double) ((float) par3 + 0.5F), (double) ((float) par4 + 0.5F), 5.0F, true, true); + return true; + } + } + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + if (par1 == 0) { + return Block.planks.getBlockTextureFromSide(par1); + } else { + int var3 = getDirection(par2); + int var4 = Direction.bedDirection[var3][par1]; + int var5 = isBlockHeadOfBed(par2) ? 1 : 0; + return (var5 != 1 || var4 != 2) && (var5 != 0 || var4 != 3) ? (var4 != 5 && var4 != 4 ? this.bedTopIcons[var5] : this.bedSideIcons[var5]) : this.field_94472_b[var5]; + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.bedTopIcons = new Icon[] { par1IconRegister.registerIcon("bed_feet_top"), par1IconRegister.registerIcon("bed_head_top") }; + this.field_94472_b = new Icon[] { par1IconRegister.registerIcon("bed_feet_end"), par1IconRegister.registerIcon("bed_head_end") }; + this.bedSideIcons = new Icon[] { par1IconRegister.registerIcon("bed_feet_side"), par1IconRegister.registerIcon("bed_head_side") }; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 14; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.setBounds(); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + int var7 = getDirection(var6); + + if (isBlockHeadOfBed(var6)) { + if (par1World.getBlockId(par2 - footBlockToHeadBlockMap[var7][0], par3, par4 - footBlockToHeadBlockMap[var7][1]) != this.blockID) { + par1World.setBlockToAir(par2, par3, par4); + } + } else if (par1World.getBlockId(par2 + footBlockToHeadBlockMap[var7][0], par3, par4 + footBlockToHeadBlockMap[var7][1]) != this.blockID) { + par1World.setBlockToAir(par2, par3, par4); + + if (!par1World.isRemote) { + this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0); + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return isBlockHeadOfBed(par1) ? 0 : Item.bed.itemID; + } + + /** + * Set the bounds of the bed block. + */ + private void setBounds() { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5625F, 1.0F); + } + + /** + * Returns whether or not this bed block is the head of the bed. + */ + public static boolean isBlockHeadOfBed(int par0) { + return (par0 & 8) != 0; + } + + /** + * Return whether or not the bed is occupied. + */ + public static boolean isBedOccupied(int par0) { + return (par0 & 4) != 0; + } + + /** + * Sets whether or not the bed is occupied. + */ + public static void setBedOccupied(World par0World, int par1, int par2, int par3, boolean par4) { + int var5 = par0World.getBlockMetadata(par1, par2, par3); + + if (par4) { + var5 |= 4; + } else { + var5 &= -5; + } + + par0World.setBlockMetadataWithNotify(par1, par2, par3, var5, 4); + } + + /** + * Gets the nearest empty chunk coordinates for the player to wake up from a bed + * into. + */ + public static ChunkCoordinates getNearestEmptyChunkCoordinates(World par0World, int par1, int par2, int par3, int par4) { + int var5 = par0World.getBlockMetadata(par1, par2, par3); + int var6 = BlockDirectional.getDirection(var5); + + for (int var7 = 0; var7 <= 1; ++var7) { + int var8 = par1 - footBlockToHeadBlockMap[var6][0] * var7 - 1; + int var9 = par3 - footBlockToHeadBlockMap[var6][1] * var7 - 1; + int var10 = var8 + 2; + int var11 = var9 + 2; + + for (int var12 = var8; var12 <= var10; ++var12) { + for (int var13 = var9; var13 <= var11; ++var13) { + if (par0World.doesBlockHaveSolidTopSurface(var12, par2 - 1, var13) && par0World.isAirBlock(var12, par2, var13) && par0World.isAirBlock(var12, par2 + 1, var13)) { + if (par4 <= 0) { + return new ChunkCoordinates(var12, par2, var13); + } + + --par4; + } + } + } + } + + return null; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + if (!isBlockHeadOfBed(par5)) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0); + } + } + + /** + * Returns the mobility information of the block, 0 = free, 1 = can't push but + * can move over, 2 = total immobility and stop pistons + */ + public int getMobilityFlag() { + return 1; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Item.bed.itemID; + } + + /** + * Called when the block is attempted to be harvested + */ + public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer) { + if (par6EntityPlayer.capabilities.isCreativeMode && isBlockHeadOfBed(par5)) { + int var7 = getDirection(par5); + par2 -= footBlockToHeadBlockMap[var7][0]; + par4 -= footBlockToHeadBlockMap[var7][1]; + + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + par1World.setBlockToAir(par2, par3, par4); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockBookshelf.java b/src/main/java/net/minecraft/src/BlockBookshelf.java new file mode 100644 index 0000000..0b6900a --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockBookshelf.java @@ -0,0 +1,32 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockBookshelf extends Block { + public BlockBookshelf(int par1) { + super(par1, Material.wood); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 != 1 && par1 != 0 ? super.getIcon(par1, par2) : Block.planks.getBlockTextureFromSide(par1); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 3; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.book.itemID; + } +} diff --git a/src/main/java/net/minecraft/src/BlockBreakable.java b/src/main/java/net/minecraft/src/BlockBreakable.java new file mode 100644 index 0000000..0faa671 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockBreakable.java @@ -0,0 +1,39 @@ +package net.minecraft.src; + +public class BlockBreakable extends Block { + private boolean localFlag; + private String breakableBlockIcon; + + protected BlockBreakable(int par1, String par2Str, Material par3Material, boolean par4) { + super(par1, par3Material); + this.localFlag = par4; + this.breakableBlockIcon = par2Str; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = par1IBlockAccess.getBlockId(par2, par3, par4); + return !this.localFlag && var6 == this.blockID ? false : super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon(this.breakableBlockIcon); + } +} diff --git a/src/main/java/net/minecraft/src/BlockBrewingStand.java b/src/main/java/net/minecraft/src/BlockBrewingStand.java new file mode 100644 index 0000000..d67b1a9 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockBrewingStand.java @@ -0,0 +1,188 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockBrewingStand extends BlockContainer { + private Random rand = new Random(); + private Icon theIcon; + + public BlockBrewingStand(int par1) { + super(par1, Material.iron); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 25; + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityBrewingStand(); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity) { + this.setBlockBounds(0.4375F, 0.0F, 0.4375F, 0.5625F, 0.875F, 0.5625F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBoundsForItemRender(); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + TileEntityBrewingStand var10 = (TileEntityBrewingStand) par1World.getBlockTileEntity(par2, par3, par4); + + if (var10 != null) { + par5EntityPlayer.displayGUIBrewingStand(var10); + } + + return true; + } + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + if (par6ItemStack.hasDisplayName()) { + ((TileEntityBrewingStand) par1World.getBlockTileEntity(par2, par3, par4)).func_94131_a(par6ItemStack.getDisplayName()); + } + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + double var6 = (double) ((float) par2 + 0.4F + par5Random.nextFloat() * 0.2F); + double var8 = (double) ((float) par3 + 0.7F + par5Random.nextFloat() * 0.3F); + double var10 = (double) ((float) par4 + 0.4F + par5Random.nextFloat() * 0.2F); + par1World.spawnParticle("smoke", var6, var8, var10, 0.0D, 0.0D, 0.0D); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + TileEntity var7 = par1World.getBlockTileEntity(par2, par3, par4); + + if (var7 instanceof TileEntityBrewingStand) { + TileEntityBrewingStand var8 = (TileEntityBrewingStand) var7; + + for (int var9 = 0; var9 < var8.getSizeInventory(); ++var9) { + ItemStack var10 = var8.getStackInSlot(var9); + + if (var10 != null) { + float var11 = this.rand.nextFloat() * 0.8F + 0.1F; + float var12 = this.rand.nextFloat() * 0.8F + 0.1F; + float var13 = this.rand.nextFloat() * 0.8F + 0.1F; + + while (var10.stackSize > 0) { + int var14 = this.rand.nextInt(21) + 10; + + if (var14 > var10.stackSize) { + var14 = var10.stackSize; + } + + var10.stackSize -= var14; + EntityItem var15 = new EntityItem(par1World, (double) ((float) par2 + var11), (double) ((float) par3 + var12), (double) ((float) par4 + var13), new ItemStack(var10.itemID, var14, var10.getItemDamage())); + float var16 = 0.05F; + var15.motionX = (double) ((float) this.rand.nextGaussian() * var16); + var15.motionY = (double) ((float) this.rand.nextGaussian() * var16 + 0.2F); + var15.motionZ = (double) ((float) this.rand.nextGaussian() * var16); + par1World.spawnEntityInWorld(var15); + } + } + } + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.brewingStand.itemID; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Item.brewingStand.itemID; + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + return Container.calcRedstoneFromInventory((IInventory) par1World.getBlockTileEntity(par2, par3, par4)); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + super.registerIcons(par1IconRegister); + this.theIcon = par1IconRegister.registerIcon("brewingStand_base"); + } + + public Icon getBrewingStandIcon() { + return this.theIcon; + } +} diff --git a/src/main/java/net/minecraft/src/BlockButton.java b/src/main/java/net/minecraft/src/BlockButton.java new file mode 100644 index 0000000..7a9adb2 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockButton.java @@ -0,0 +1,346 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public abstract class BlockButton extends Block { + /** Whether this button is sensible to arrows, used by wooden buttons. */ + private final boolean sensible; + + protected BlockButton(int par1, boolean par2) { + super(par1, Material.circuits); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabRedstone); + this.sensible = par2; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return this.sensible ? 30 : 20; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + return par5 == 2 && par1World.isBlockNormalCube(par2, par3, par4 + 1) ? true + : (par5 == 3 && par1World.isBlockNormalCube(par2, par3, par4 - 1) ? true : (par5 == 4 && par1World.isBlockNormalCube(par2 + 1, par3, par4) ? true : par5 == 5 && par1World.isBlockNormalCube(par2 - 1, par3, par4))); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.isBlockNormalCube(par2 - 1, par3, par4) ? true + : (par1World.isBlockNormalCube(par2 + 1, par3, par4) ? true : (par1World.isBlockNormalCube(par2, par3, par4 - 1) ? true : par1World.isBlockNormalCube(par2, par3, par4 + 1))); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9) { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + int var11 = var10 & 8; + var10 &= 7; + + if (par5 == 2 && par1World.isBlockNormalCube(par2, par3, par4 + 1)) { + var10 = 4; + } else if (par5 == 3 && par1World.isBlockNormalCube(par2, par3, par4 - 1)) { + var10 = 3; + } else if (par5 == 4 && par1World.isBlockNormalCube(par2 + 1, par3, par4)) { + var10 = 2; + } else if (par5 == 5 && par1World.isBlockNormalCube(par2 - 1, par3, par4)) { + var10 = 1; + } else { + var10 = this.getOrientation(par1World, par2, par3, par4); + } + + return var10 + var11; + } + + /** + * Get side which this button is facing. + */ + private int getOrientation(World par1World, int par2, int par3, int par4) { + return par1World.isBlockNormalCube(par2 - 1, par3, par4) ? 1 + : (par1World.isBlockNormalCube(par2 + 1, par3, par4) ? 2 : (par1World.isBlockNormalCube(par2, par3, par4 - 1) ? 3 : (par1World.isBlockNormalCube(par2, par3, par4 + 1) ? 4 : 1))); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (this.redundantCanPlaceBlockAt(par1World, par2, par3, par4)) { + int var6 = par1World.getBlockMetadata(par2, par3, par4) & 7; + boolean var7 = false; + + if (!par1World.isBlockNormalCube(par2 - 1, par3, par4) && var6 == 1) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2 + 1, par3, par4) && var6 == 2) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3, par4 - 1) && var6 == 3) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3, par4 + 1) && var6 == 4) { + var7 = true; + } + + if (var7) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + } + + /** + * This method is redundant, check it out... + */ + private boolean redundantCanPlaceBlockAt(World par1World, int par2, int par3, int par4) { + if (!this.canPlaceBlockAt(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + return false; + } else { + return true; + } + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + this.func_82534_e(var5); + } + + private void func_82534_e(int par1) { + int var2 = par1 & 7; + boolean var3 = (par1 & 8) > 0; + float var4 = 0.375F; + float var5 = 0.625F; + float var6 = 0.1875F; + float var7 = 0.125F; + + if (var3) { + var7 = 0.0625F; + } + + if (var2 == 1) { + this.setBlockBounds(0.0F, var4, 0.5F - var6, var7, var5, 0.5F + var6); + } else if (var2 == 2) { + this.setBlockBounds(1.0F - var7, var4, 0.5F - var6, 1.0F, var5, 0.5F + var6); + } else if (var2 == 3) { + this.setBlockBounds(0.5F - var6, var4, 0.0F, 0.5F + var6, var5, var7); + } else if (var2 == 4) { + this.setBlockBounds(0.5F - var6, var4, 1.0F - var7, 0.5F + var6, var5, 1.0F); + } + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + int var11 = var10 & 7; + int var12 = 8 - (var10 & 8); + + if (var12 == 0) { + return true; + } else { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var11 + var12, 3); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "random.click", 0.3F, 0.6F); + this.func_82536_d(par1World, par2, par3, par4, var11); + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + return true; + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + if ((par6 & 8) > 0) { + int var7 = par6 & 7; + this.func_82536_d(par1World, par2, par3, par4, var7); + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) > 0 ? 15 : 0; + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) == 0) { + return 0; + } else { + int var7 = var6 & 7; + return var7 == 5 && par5 == 1 ? 15 : (var7 == 4 && par5 == 2 ? 15 : (var7 == 3 && par5 == 3 ? 15 : (var7 == 2 && par5 == 4 ? 15 : (var7 == 1 && par5 == 5 ? 15 : 0)))); + } + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) != 0) { + if (this.sensible) { + this.func_82535_o(par1World, par2, par3, par4); + } else { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 & 7, 3); + int var7 = var6 & 7; + this.func_82536_d(par1World, par2, par3, par4, var7); + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "random.click", 0.3F, 0.5F); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + } + } + } + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + float var1 = 0.1875F; + float var2 = 0.125F; + float var3 = 0.125F; + this.setBlockBounds(0.5F - var1, 0.5F - var2, 0.5F - var3, 0.5F + var1, 0.5F + var2, 0.5F + var3); + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + if (!par1World.isRemote) { + if (this.sensible) { + if ((par1World.getBlockMetadata(par2, par3, par4) & 8) == 0) { + this.func_82535_o(par1World, par2, par3, par4); + } + } + } + } + + private void func_82535_o(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + int var6 = var5 & 7; + boolean var7 = (var5 & 8) != 0; + this.func_82534_e(var5); + List var9 = par1World.getEntitiesWithinAABB(EntityArrow.class, + AxisAlignedBB.getAABBPool().getAABB((double) par2 + this.minX, (double) par3 + this.minY, (double) par4 + this.minZ, (double) par2 + this.maxX, (double) par3 + this.maxY, (double) par4 + this.maxZ)); + boolean var8 = !var9.isEmpty(); + + if (var8 && !var7) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 | 8, 3); + this.func_82536_d(par1World, par2, par3, par4, var6); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "random.click", 0.3F, 0.6F); + } + + if (!var8 && var7) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6, 3); + this.func_82536_d(par1World, par2, par3, par4, var6); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "random.click", 0.3F, 0.5F); + } + + if (var8) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + } + + private void func_82536_d(World par1World, int par2, int par3, int par4, int par5) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + + if (par5 == 1) { + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + } else if (par5 == 2) { + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + } else if (par5 == 3) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + } else if (par5 == 4) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + } else { + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + } +} diff --git a/src/main/java/net/minecraft/src/BlockButtonStone.java b/src/main/java/net/minecraft/src/BlockButtonStone.java new file mode 100644 index 0000000..b3d6e75 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockButtonStone.java @@ -0,0 +1,15 @@ +package net.minecraft.src; + +public class BlockButtonStone extends BlockButton { + protected BlockButtonStone(int par1) { + super(par1, false); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return Block.stone.getBlockTextureFromSide(1); + } +} diff --git a/src/main/java/net/minecraft/src/BlockButtonWood.java b/src/main/java/net/minecraft/src/BlockButtonWood.java new file mode 100644 index 0000000..774dccd --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockButtonWood.java @@ -0,0 +1,15 @@ +package net.minecraft.src; + +public class BlockButtonWood extends BlockButton { + protected BlockButtonWood(int par1) { + super(par1, true); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return Block.planks.getBlockTextureFromSide(1); + } +} diff --git a/src/main/java/net/minecraft/src/BlockCactus.java b/src/main/java/net/minecraft/src/BlockCactus.java new file mode 100644 index 0000000..4c92acf --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockCactus.java @@ -0,0 +1,146 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockCactus extends Block { + private Icon cactusTopIcon; + private Icon cactusBottomIcon; + + protected BlockCactus(int par1) { + super(par1, Material.cactus); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par1World.isAirBlock(par2, par3 + 1, par4)) { + int var6; + + for (var6 = 1; par1World.getBlockId(par2, par3 - var6, par4) == this.blockID; ++var6) { + ; + } + + if (var6 < 3) { + int var7 = par1World.getBlockMetadata(par2, par3, par4); + + if (var7 == 15) { + par1World.setBlock(par2, par3 + 1, par4, this.blockID); + par1World.setBlockMetadataWithNotify(par2, par3, par4, 0, 4); + this.onNeighborBlockChange(par1World, par2, par3 + 1, par4, this.blockID); + } else { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7 + 1, 4); + } + } + } + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + float var5 = 0.0625F; + return AxisAlignedBB.getAABBPool().getAABB((double) ((float) par2 + var5), (double) par3, (double) ((float) par4 + var5), (double) ((float) (par2 + 1) - var5), (double) ((float) (par3 + 1) - var5), + (double) ((float) (par4 + 1) - var5)); + } + + /** + * Returns the bounding box of the wired rectangular prism to render. + */ + public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + float var5 = 0.0625F; + return AxisAlignedBB.getAABBPool().getAABB((double) ((float) par2 + var5), (double) par3, (double) ((float) par4 + var5), (double) ((float) (par2 + 1) - var5), (double) (par3 + 1), (double) ((float) (par4 + 1) - var5)); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 1 ? this.cactusTopIcon : (par1 == 0 ? this.cactusBottomIcon : this.blockIcon); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 13; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return !super.canPlaceBlockAt(par1World, par2, par3, par4) ? false : this.canBlockStay(par1World, par2, par3, par4); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!this.canBlockStay(par1World, par2, par3, par4)) { + par1World.destroyBlock(par2, par3, par4, true); + } + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + if (par1World.getBlockMaterial(par2 - 1, par3, par4).isSolid()) { + return false; + } else if (par1World.getBlockMaterial(par2 + 1, par3, par4).isSolid()) { + return false; + } else if (par1World.getBlockMaterial(par2, par3, par4 - 1).isSolid()) { + return false; + } else if (par1World.getBlockMaterial(par2, par3, par4 + 1).isSolid()) { + return false; + } else { + int var5 = par1World.getBlockId(par2, par3 - 1, par4); + return var5 == Block.cactus.blockID || var5 == Block.sand.blockID; + } + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + par5Entity.attackEntityFrom(DamageSource.cactus, 1); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("cactus_side"); + this.cactusTopIcon = par1IconRegister.registerIcon("cactus_top"); + this.cactusBottomIcon = par1IconRegister.registerIcon("cactus_bottom"); + } +} diff --git a/src/main/java/net/minecraft/src/BlockCake.java b/src/main/java/net/minecraft/src/BlockCake.java new file mode 100644 index 0000000..76d772d --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockCake.java @@ -0,0 +1,175 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockCake extends Block { + private Icon cakeTopIcon; + private Icon cakeBottomIcon; + private Icon field_94382_c; + + protected BlockCake(int par1) { + super(par1, Material.cake); + this.setTickRandomly(true); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + float var6 = 0.0625F; + float var7 = (float) (1 + var5 * 2) / 16.0F; + float var8 = 0.5F; + this.setBlockBounds(var7, 0.0F, var6, 1.0F - var6, var8, 1.0F - var6); + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + float var1 = 0.0625F; + float var2 = 0.5F; + this.setBlockBounds(var1, 0.0F, var1, 1.0F - var1, var2, 1.0F - var1); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + float var6 = 0.0625F; + float var7 = (float) (1 + var5 * 2) / 16.0F; + float var8 = 0.5F; + return AxisAlignedBB.getAABBPool().getAABB((double) ((float) par2 + var7), (double) par3, (double) ((float) par4 + var6), (double) ((float) (par2 + 1) - var6), (double) ((float) par3 + var8 - var6), + (double) ((float) (par4 + 1) - var6)); + } + + /** + * Returns the bounding box of the wired rectangular prism to render. + */ + public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + float var6 = 0.0625F; + float var7 = (float) (1 + var5 * 2) / 16.0F; + float var8 = 0.5F; + return AxisAlignedBB.getAABBPool().getAABB((double) ((float) par2 + var7), (double) par3, (double) ((float) par4 + var6), (double) ((float) (par2 + 1) - var6), (double) ((float) par3 + var8), (double) ((float) (par4 + 1) - var6)); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 1 ? this.cakeTopIcon : (par1 == 0 ? this.cakeBottomIcon : (par2 > 0 && par1 == 4 ? this.field_94382_c : this.blockIcon)); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("cake_side"); + this.field_94382_c = par1IconRegister.registerIcon("cake_inner"); + this.cakeTopIcon = par1IconRegister.registerIcon("cake_top"); + this.cakeBottomIcon = par1IconRegister.registerIcon("cake_bottom"); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + this.eatCakeSlice(par1World, par2, par3, par4, par5EntityPlayer); + return true; + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + this.eatCakeSlice(par1World, par2, par3, par4, par5EntityPlayer); + } + + /** + * Heals the player and removes a slice from the cake. + */ + private void eatCakeSlice(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + if (par5EntityPlayer.canEat(false)) { + par5EntityPlayer.getFoodStats().addStats(2, 0.1F); + int var6 = par1World.getBlockMetadata(par2, par3, par4) + 1; + + if (var6 >= 6) { + par1World.setBlockToAir(par2, par3, par4); + } else { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6, 2); + } + } + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return !super.canPlaceBlockAt(par1World, par2, par3, par4) ? false : this.canBlockStay(par1World, par2, par3, par4); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!this.canBlockStay(par1World, par2, par3, par4)) { + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + return par1World.getBlockMaterial(par2, par3 - 1, par4).isSolid(); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return 0; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Item.cake.itemID; + } +} diff --git a/src/main/java/net/minecraft/src/BlockCarrot.java b/src/main/java/net/minecraft/src/BlockCarrot.java new file mode 100644 index 0000000..d3411f1 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockCarrot.java @@ -0,0 +1,52 @@ +package net.minecraft.src; + +public class BlockCarrot extends BlockCrops { + private Icon[] iconArray; + + public BlockCarrot(int par1) { + super(par1); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + if (par2 < 7) { + if (par2 == 6) { + par2 = 5; + } + + return this.iconArray[par2 >> 1]; + } else { + return this.iconArray[3]; + } + } + + /** + * Generate a seed ItemStack for this crop. + */ + protected int getSeedItem() { + return Item.carrot.itemID; + } + + /** + * Generate a crop produce ItemStack for this crop. + */ + protected int getCropItem() { + return Item.carrot.itemID; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.iconArray = new Icon[4]; + + for (int var2 = 0; var2 < this.iconArray.length; ++var2) { + this.iconArray[var2] = par1IconRegister.registerIcon("carrots_" + var2); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockCauldron.java b/src/main/java/net/minecraft/src/BlockCauldron.java new file mode 100644 index 0000000..5d3765a --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockCauldron.java @@ -0,0 +1,168 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockCauldron extends Block { + private Icon field_94378_a; + private Icon cauldronTopIcon; + private Icon cauldronBottomIcon; + + public BlockCauldron(int par1) { + super(par1, Material.iron); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 1 ? this.cauldronTopIcon : (par1 == 0 ? this.cauldronBottomIcon : this.blockIcon); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.field_94378_a = par1IconRegister.registerIcon("cauldron_inner"); + this.cauldronTopIcon = par1IconRegister.registerIcon("cauldron_top"); + this.cauldronBottomIcon = par1IconRegister.registerIcon("cauldron_bottom"); + this.blockIcon = par1IconRegister.registerIcon("cauldron_side"); + } + + public static Icon func_94375_b(String par0Str) { + return par0Str == "cauldron_inner" ? Block.cauldron.field_94378_a : (par0Str == "cauldron_bottom" ? Block.cauldron.cauldronBottomIcon : null); + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.3125F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + float var8 = 0.125F; + this.setBlockBounds(0.0F, 0.0F, 0.0F, var8, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var8); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(1.0F - var8, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.0F, 0.0F, 1.0F - var8, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBoundsForItemRender(); + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 24; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + ItemStack var10 = par5EntityPlayer.inventory.getCurrentItem(); + + if (var10 == null) { + return true; + } else { + int var11 = par1World.getBlockMetadata(par2, par3, par4); + + if (var10.itemID == Item.bucketWater.itemID) { + if (var11 < 3) { + if (!par5EntityPlayer.capabilities.isCreativeMode) { + par5EntityPlayer.inventory.setInventorySlotContents(par5EntityPlayer.inventory.currentItem, new ItemStack(Item.bucketEmpty)); + } + + par1World.setBlockMetadataWithNotify(par2, par3, par4, 3, 2); + } + + return true; + } else { + if (var10.itemID == Item.glassBottle.itemID) { + if (var11 > 0) { + ItemStack var12 = new ItemStack(Item.potion, 1, 0); + par1World.spawnEntityInWorld(new EntityItem(par1World, (double) par2 + 0.5D, (double) par3 + 1.5D, (double) par4 + 0.5D, var12)); + + --var10.stackSize; + + if (var10.stackSize <= 0) { + par5EntityPlayer.inventory.setInventorySlotContents(par5EntityPlayer.inventory.currentItem, (ItemStack) null); + } + + par1World.setBlockMetadataWithNotify(par2, par3, par4, var11 - 1, 2); + } + } else if (var11 > 0 && var10.getItem() instanceof ItemArmor && ((ItemArmor) var10.getItem()).getArmorMaterial() == EnumArmorMaterial.CLOTH) { + ItemArmor var13 = (ItemArmor) var10.getItem(); + var13.removeColor(var10); + par1World.setBlockMetadataWithNotify(par2, par3, par4, var11 - 1, 2); + return true; + } + + return true; + } + } + } + } + + /** + * currently only used by BlockCauldron to incrament meta-data during rain + */ + public void fillWithRain(World par1World, int par2, int par3, int par4) { + if (par1World.rand.nextInt(20) == 1) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + + if (var5 < 3) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var5 + 1, 2); + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.cauldron.itemID; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Item.cauldron.itemID; + } +} diff --git a/src/main/java/net/minecraft/src/BlockChest.java b/src/main/java/net/minecraft/src/BlockChest.java new file mode 100644 index 0000000..ff295a0 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockChest.java @@ -0,0 +1,474 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.Random; + +public class BlockChest extends BlockContainer { + private final Random random = new Random(); + + /** Determines whether of not the chest is trapped. */ + public final int isTrapped; + + protected BlockChest(int par1, int par2) { + super(par1, Material.wood); + this.isTrapped = par2; + this.setCreativeTab(CreativeTabs.tabDecorations); + this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 22; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + if (par1IBlockAccess.getBlockId(par2, par3, par4 - 1) == this.blockID) { + this.setBlockBounds(0.0625F, 0.0F, 0.0F, 0.9375F, 0.875F, 0.9375F); + } else if (par1IBlockAccess.getBlockId(par2, par3, par4 + 1) == this.blockID) { + this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 1.0F); + } else if (par1IBlockAccess.getBlockId(par2 - 1, par3, par4) == this.blockID) { + this.setBlockBounds(0.0F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F); + } else if (par1IBlockAccess.getBlockId(par2 + 1, par3, par4) == this.blockID) { + this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 1.0F, 0.875F, 0.9375F); + } else { + this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + this.unifyAdjacentChests(par1World, par2, par3, par4); + int var5 = par1World.getBlockId(par2, par3, par4 - 1); + int var6 = par1World.getBlockId(par2, par3, par4 + 1); + int var7 = par1World.getBlockId(par2 - 1, par3, par4); + int var8 = par1World.getBlockId(par2 + 1, par3, par4); + + if (var5 == this.blockID) { + this.unifyAdjacentChests(par1World, par2, par3, par4 - 1); + } + + if (var6 == this.blockID) { + this.unifyAdjacentChests(par1World, par2, par3, par4 + 1); + } + + if (var7 == this.blockID) { + this.unifyAdjacentChests(par1World, par2 - 1, par3, par4); + } + + if (var8 == this.blockID) { + this.unifyAdjacentChests(par1World, par2 + 1, par3, par4); + } + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + int var7 = par1World.getBlockId(par2, par3, par4 - 1); + int var8 = par1World.getBlockId(par2, par3, par4 + 1); + int var9 = par1World.getBlockId(par2 - 1, par3, par4); + int var10 = par1World.getBlockId(par2 + 1, par3, par4); + byte var11 = 0; + int var12 = MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + + if (var12 == 0) { + var11 = 2; + } + + if (var12 == 1) { + var11 = 5; + } + + if (var12 == 2) { + var11 = 3; + } + + if (var12 == 3) { + var11 = 4; + } + + if (var7 != this.blockID && var8 != this.blockID && var9 != this.blockID && var10 != this.blockID) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var11, 3); + } else { + if ((var7 == this.blockID || var8 == this.blockID) && (var11 == 4 || var11 == 5)) { + if (var7 == this.blockID) { + par1World.setBlockMetadataWithNotify(par2, par3, par4 - 1, var11, 3); + } else { + par1World.setBlockMetadataWithNotify(par2, par3, par4 + 1, var11, 3); + } + + par1World.setBlockMetadataWithNotify(par2, par3, par4, var11, 3); + } + + if ((var9 == this.blockID || var10 == this.blockID) && (var11 == 2 || var11 == 3)) { + if (var9 == this.blockID) { + par1World.setBlockMetadataWithNotify(par2 - 1, par3, par4, var11, 3); + } else { + par1World.setBlockMetadataWithNotify(par2 + 1, par3, par4, var11, 3); + } + + par1World.setBlockMetadataWithNotify(par2, par3, par4, var11, 3); + } + } + + if (par6ItemStack.hasDisplayName()) { + ((TileEntityChest) par1World.getBlockTileEntity(par2, par3, par4)).func_94043_a(par6ItemStack.getDisplayName()); + } + } + + /** + * Turns the adjacent chests to a double chest. + */ + public void unifyAdjacentChests(World par1World, int par2, int par3, int par4) { + if (!par1World.isRemote) { + int var5 = par1World.getBlockId(par2, par3, par4 - 1); + int var6 = par1World.getBlockId(par2, par3, par4 + 1); + int var7 = par1World.getBlockId(par2 - 1, par3, par4); + int var8 = par1World.getBlockId(par2 + 1, par3, par4); + boolean var9 = true; + int var10; + int var11; + boolean var12; + byte var13; + int var14; + + if (var5 != this.blockID && var6 != this.blockID) { + if (var7 != this.blockID && var8 != this.blockID) { + var13 = 3; + + if (Block.opaqueCubeLookup[var5] && !Block.opaqueCubeLookup[var6]) { + var13 = 3; + } + + if (Block.opaqueCubeLookup[var6] && !Block.opaqueCubeLookup[var5]) { + var13 = 2; + } + + if (Block.opaqueCubeLookup[var7] && !Block.opaqueCubeLookup[var8]) { + var13 = 5; + } + + if (Block.opaqueCubeLookup[var8] && !Block.opaqueCubeLookup[var7]) { + var13 = 4; + } + } else { + var10 = par1World.getBlockId(var7 == this.blockID ? par2 - 1 : par2 + 1, par3, par4 - 1); + var11 = par1World.getBlockId(var7 == this.blockID ? par2 - 1 : par2 + 1, par3, par4 + 1); + var13 = 3; + var12 = true; + + if (var7 == this.blockID) { + var14 = par1World.getBlockMetadata(par2 - 1, par3, par4); + } else { + var14 = par1World.getBlockMetadata(par2 + 1, par3, par4); + } + + if (var14 == 2) { + var13 = 2; + } + + if ((Block.opaqueCubeLookup[var5] || Block.opaqueCubeLookup[var10]) && !Block.opaqueCubeLookup[var6] && !Block.opaqueCubeLookup[var11]) { + var13 = 3; + } + + if ((Block.opaqueCubeLookup[var6] || Block.opaqueCubeLookup[var11]) && !Block.opaqueCubeLookup[var5] && !Block.opaqueCubeLookup[var10]) { + var13 = 2; + } + } + } else { + var10 = par1World.getBlockId(par2 - 1, par3, var5 == this.blockID ? par4 - 1 : par4 + 1); + var11 = par1World.getBlockId(par2 + 1, par3, var5 == this.blockID ? par4 - 1 : par4 + 1); + var13 = 5; + var12 = true; + + if (var5 == this.blockID) { + var14 = par1World.getBlockMetadata(par2, par3, par4 - 1); + } else { + var14 = par1World.getBlockMetadata(par2, par3, par4 + 1); + } + + if (var14 == 4) { + var13 = 4; + } + + if ((Block.opaqueCubeLookup[var7] || Block.opaqueCubeLookup[var10]) && !Block.opaqueCubeLookup[var8] && !Block.opaqueCubeLookup[var11]) { + var13 = 5; + } + + if ((Block.opaqueCubeLookup[var8] || Block.opaqueCubeLookup[var11]) && !Block.opaqueCubeLookup[var7] && !Block.opaqueCubeLookup[var10]) { + var13 = 4; + } + } + + par1World.setBlockMetadataWithNotify(par2, par3, par4, var13, 3); + } + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + int var5 = 0; + + if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID) { + ++var5; + } + + if (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID) { + ++var5; + } + + if (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID) { + ++var5; + } + + if (par1World.getBlockId(par2, par3, par4 + 1) == this.blockID) { + ++var5; + } + + return var5 > 1 ? false + : (this.isThereANeighborChest(par1World, par2 - 1, par3, par4) ? false + : (this.isThereANeighborChest(par1World, par2 + 1, par3, par4) ? false : (this.isThereANeighborChest(par1World, par2, par3, par4 - 1) ? false : !this.isThereANeighborChest(par1World, par2, par3, par4 + 1)))); + } + + /** + * Checks the neighbor blocks to see if there is a chest there. Args: world, x, + * y, z + */ + private boolean isThereANeighborChest(World par1World, int par2, int par3, int par4) { + return par1World.getBlockId(par2, par3, par4) != this.blockID ? false + : (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID ? true + : (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID ? true : (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID ? true : par1World.getBlockId(par2, par3, par4 + 1) == this.blockID))); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + super.onNeighborBlockChange(par1World, par2, par3, par4, par5); + TileEntityChest var6 = (TileEntityChest) par1World.getBlockTileEntity(par2, par3, par4); + + if (var6 != null) { + var6.updateContainingBlockInfo(); + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + TileEntityChest var7 = (TileEntityChest) par1World.getBlockTileEntity(par2, par3, par4); + + if (var7 != null) { + for (int var8 = 0; var8 < var7.getSizeInventory(); ++var8) { + ItemStack var9 = var7.getStackInSlot(var8); + + if (var9 != null) { + float var10 = this.random.nextFloat() * 0.8F + 0.1F; + float var11 = this.random.nextFloat() * 0.8F + 0.1F; + EntityItem var14; + + for (float var12 = this.random.nextFloat() * 0.8F + 0.1F; var9.stackSize > 0; par1World.spawnEntityInWorld(var14)) { + int var13 = this.random.nextInt(21) + 10; + + if (var13 > var9.stackSize) { + var13 = var9.stackSize; + } + + var9.stackSize -= var13; + var14 = new EntityItem(par1World, (double) ((float) par2 + var10), (double) ((float) par3 + var11), (double) ((float) par4 + var12), new ItemStack(var9.itemID, var13, var9.getItemDamage())); + float var15 = 0.05F; + var14.motionX = (double) ((float) this.random.nextGaussian() * var15); + var14.motionY = (double) ((float) this.random.nextGaussian() * var15 + 0.2F); + var14.motionZ = (double) ((float) this.random.nextGaussian() * var15); + + if (var9.hasTagCompound()) { + var14.getEntityItem().setTagCompound((NBTTagCompound) var9.getTagCompound().copy()); + } + } + } + } + + par1World.func_96440_m(par2, par3, par4, par5); + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + IInventory var10 = this.getInventory(par1World, par2, par3, par4); + + if (var10 != null) { + par5EntityPlayer.displayGUIChest(var10); + } + + return true; + } + } + + /** + * Gets the inventory of the chest at the specified coords, accounting for + * blocks or ocelots on top of the chest, and double chests. + */ + public IInventory getInventory(World par1World, int par2, int par3, int par4) { + Object var5 = (TileEntityChest) par1World.getBlockTileEntity(par2, par3, par4); + + if (var5 == null) { + return null; + } else if (par1World.isBlockNormalCube(par2, par3 + 1, par4)) { + return null; + } else if (isOcelotBlockingChest(par1World, par2, par3, par4)) { + return null; + } else if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID && (par1World.isBlockNormalCube(par2 - 1, par3 + 1, par4) || isOcelotBlockingChest(par1World, par2 - 1, par3, par4))) { + return null; + } else if (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID && (par1World.isBlockNormalCube(par2 + 1, par3 + 1, par4) || isOcelotBlockingChest(par1World, par2 + 1, par3, par4))) { + return null; + } else if (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID && (par1World.isBlockNormalCube(par2, par3 + 1, par4 - 1) || isOcelotBlockingChest(par1World, par2, par3, par4 - 1))) { + return null; + } else if (par1World.getBlockId(par2, par3, par4 + 1) == this.blockID && (par1World.isBlockNormalCube(par2, par3 + 1, par4 + 1) || isOcelotBlockingChest(par1World, par2, par3, par4 + 1))) { + return null; + } else { + if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID) { + var5 = new InventoryLargeChest("container.chestDouble", (TileEntityChest) par1World.getBlockTileEntity(par2 - 1, par3, par4), (IInventory) var5); + } + + if (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID) { + var5 = new InventoryLargeChest("container.chestDouble", (IInventory) var5, (TileEntityChest) par1World.getBlockTileEntity(par2 + 1, par3, par4)); + } + + if (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID) { + var5 = new InventoryLargeChest("container.chestDouble", (TileEntityChest) par1World.getBlockTileEntity(par2, par3, par4 - 1), (IInventory) var5); + } + + if (par1World.getBlockId(par2, par3, par4 + 1) == this.blockID) { + var5 = new InventoryLargeChest("container.chestDouble", (IInventory) var5, (TileEntityChest) par1World.getBlockTileEntity(par2, par3, par4 + 1)); + } + + return (IInventory) var5; + } + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + TileEntityChest var2 = new TileEntityChest(); + return var2; + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return this.isTrapped == 1; + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + if (!this.canProvidePower()) { + return 0; + } else { + int var6 = ((TileEntityChest) par1IBlockAccess.getBlockTileEntity(par2, par3, par4)).numUsingPlayers; + return MathHelper.clamp_int(var6, 0, 15); + } + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return par5 == 1 ? this.isProvidingWeakPower(par1IBlockAccess, par2, par3, par4, par5) : 0; + } + + /** + * Looks for a sitting ocelot within certain bounds. Such an ocelot is + * considered to be blocking access to the chest. + */ + private static boolean isOcelotBlockingChest(World par0World, int par1, int par2, int par3) { + Iterator var4 = par0World.getEntitiesWithinAABB(EntityOcelot.class, AxisAlignedBB.getAABBPool().getAABB((double) par1, (double) (par2 + 1), (double) par3, (double) (par1 + 1), (double) (par2 + 2), (double) (par3 + 1))).iterator(); + EntityOcelot var6; + + do { + if (!var4.hasNext()) { + return false; + } + + EntityOcelot var5 = (EntityOcelot) var4.next(); + var6 = (EntityOcelot) var5; + } while (!var6.isSitting()); + + return true; + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + return Container.calcRedstoneFromInventory(this.getInventory(par1World, par2, par3, par4)); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("wood"); + } +} diff --git a/src/main/java/net/minecraft/src/BlockClay.java b/src/main/java/net/minecraft/src/BlockClay.java new file mode 100644 index 0000000..4ec5626 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockClay.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockClay extends Block { + public BlockClay(int par1) { + super(par1, Material.clay); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.clay.itemID; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 4; + } +} diff --git a/src/main/java/net/minecraft/src/BlockCloth.java b/src/main/java/net/minecraft/src/BlockCloth.java new file mode 100644 index 0000000..0279b6a --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockCloth.java @@ -0,0 +1,64 @@ +package net.minecraft.src; + +import java.util.List; + +public class BlockCloth extends Block { + private Icon[] iconArray; + + public BlockCloth() { + super(35, Material.cloth); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return this.iconArray[par2 % this.iconArray.length]; + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1; + } + + /** + * Takes a dye damage value and returns the block damage value to match + */ + public static int getBlockFromDye(int par0) { + return ~par0 & 15; + } + + /** + * Takes a block damage value and returns the dye damage value to match + */ + public static int getDyeFromBlock(int par0) { + return ~par0 & 15; + } + + /** + * returns a list of blocks with the same ID, but different meta (eg: wood + * returns 4 blocks) + */ + public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + for (int var4 = 0; var4 < 16; ++var4) { + par3List.add(new ItemStack(par1, 1, var4)); + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.iconArray = new Icon[16]; + + for (int var2 = 0; var2 < this.iconArray.length; ++var2) { + this.iconArray[var2] = par1IconRegister.registerIcon("cloth_" + var2); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockCocoa.java b/src/main/java/net/minecraft/src/BlockCocoa.java new file mode 100644 index 0000000..c96f75e --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockCocoa.java @@ -0,0 +1,209 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockCocoa extends BlockDirectional { + public static final String[] cocoaIcons = new String[] { "cocoa_0", "cocoa_1", "cocoa_2" }; + private Icon[] iconArray; + + public BlockCocoa(int par1) { + super(par1, Material.plants); + this.setTickRandomly(true); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return this.iconArray[2]; + } + + public Icon func_94468_i_(int par1) { + if (par1 < 0 || par1 >= this.iconArray.length) { + par1 = this.iconArray.length - 1; + } + + return this.iconArray[par1]; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!this.canBlockStay(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } else if (par1World.rand.nextInt(5) == 0) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + int var7 = func_72219_c(var6); + + if (var7 < 2) { + ++var7; + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7 << 2 | getDirection(var6), 2); + } + } + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + int var5 = getDirection(par1World.getBlockMetadata(par2, par3, par4)); + par2 += Direction.offsetX[var5]; + par4 += Direction.offsetZ[var5]; + int var6 = par1World.getBlockId(par2, par3, par4); + return var6 == Block.wood.blockID && BlockLog.limitToValidMetadata(par1World.getBlockMetadata(par2, par3, par4)) == 3; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 28; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Returns the bounding box of the wired rectangular prism to render. + */ + public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getSelectedBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + int var6 = getDirection(var5); + int var7 = func_72219_c(var5); + int var8 = 4 + var7 * 2; + int var9 = 5 + var7 * 2; + float var10 = (float) var8 / 2.0F; + + switch (var6) { + case 0: + this.setBlockBounds((8.0F - var10) / 16.0F, (12.0F - (float) var9) / 16.0F, (15.0F - (float) var8) / 16.0F, (8.0F + var10) / 16.0F, 0.75F, 0.9375F); + break; + + case 1: + this.setBlockBounds(0.0625F, (12.0F - (float) var9) / 16.0F, (8.0F - var10) / 16.0F, (1.0F + (float) var8) / 16.0F, 0.75F, (8.0F + var10) / 16.0F); + break; + + case 2: + this.setBlockBounds((8.0F - var10) / 16.0F, (12.0F - (float) var9) / 16.0F, 0.0625F, (8.0F + var10) / 16.0F, 0.75F, (1.0F + (float) var8) / 16.0F); + break; + + case 3: + this.setBlockBounds((15.0F - (float) var8) / 16.0F, (12.0F - (float) var9) / 16.0F, (8.0F - var10) / 16.0F, 0.9375F, 0.75F, (8.0F + var10) / 16.0F); + } + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + int var7 = ((MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) + 0) % 4; + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7, 2); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9) { + if (par5 == 1 || par5 == 0) { + par5 = 2; + } + + return Direction.rotateOpposite[Direction.facingToDirection[par5]]; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!this.canBlockStay(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + + public static int func_72219_c(int par0) { + return (par0 & 12) >> 2; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + int var8 = func_72219_c(par5); + byte var9 = 1; + + if (var8 >= 2) { + var9 = 3; + } + + for (int var10 = 0; var10 < var9; ++var10) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(Item.dyePowder, 1, 3)); + } + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Item.dyePowder.itemID; + } + + /** + * Get the block's damage value (for use with pick block). + */ + public int getDamageValue(World par1World, int par2, int par3, int par4) { + return 3; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.iconArray = new Icon[cocoaIcons.length]; + + for (int var2 = 0; var2 < this.iconArray.length; ++var2) { + this.iconArray[var2] = par1IconRegister.registerIcon(cocoaIcons[var2]); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockCommandBlock.java b/src/main/java/net/minecraft/src/BlockCommandBlock.java new file mode 100644 index 0000000..4b0c973 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockCommandBlock.java @@ -0,0 +1,100 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockCommandBlock extends BlockContainer { + public BlockCommandBlock(int par1) { + super(par1, Material.iron); + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityCommandBlock(); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + boolean var6 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4); + int var7 = par1World.getBlockMetadata(par2, par3, par4); + boolean var8 = (var7 & 1) != 0; + + if (var6 && !var8) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7 | 1, 4); + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } else if (!var6 && var8) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7 & -2, 4); + } + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + TileEntity var6 = par1World.getBlockTileEntity(par2, par3, par4); + + if (var6 != null && var6 instanceof TileEntityCommandBlock) { + TileEntityCommandBlock var7 = (TileEntityCommandBlock) var6; + var7.func_96102_a(var7.executeCommandOnPowered(par1World)); + par1World.func_96440_m(par2, par3, par4, this.blockID); + } + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 1; + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + TileEntityCommandBlock var10 = (TileEntityCommandBlock) par1World.getBlockTileEntity(par2, par3, par4); + + if (var10 != null) { + par5EntityPlayer.displayGUIEditSign(var10); + } + + return true; + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + TileEntity var6 = par1World.getBlockTileEntity(par2, par3, par4); + return var6 != null && var6 instanceof TileEntityCommandBlock ? ((TileEntityCommandBlock) var6).func_96103_d() : 0; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + TileEntityCommandBlock var7 = (TileEntityCommandBlock) par1World.getBlockTileEntity(par2, par3, par4); + + if (par6ItemStack.hasDisplayName()) { + var7.setCommandSenderName(par6ItemStack.getDisplayName()); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockComparator.java b/src/main/java/net/minecraft/src/BlockComparator.java new file mode 100644 index 0000000..8711ccf --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockComparator.java @@ -0,0 +1,229 @@ +package net.minecraft.src; + +import java.util.Random; + + + +public class BlockComparator extends BlockRedstoneLogic implements ITileEntityProvider { + public BlockComparator(int par1, boolean par2) { + super(par1, par2); + this.isBlockContainer = true; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.comparator.itemID; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Item.comparator.itemID; + } + + protected int func_94481_j_(int par1) { + return 2; + } + + protected BlockRedstoneLogic func_94485_e() { + return Block.redstoneComparatorActive; + } + + protected BlockRedstoneLogic func_94484_i() { + return Block.redstoneComparatorIdle; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 37; + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + boolean var3 = this.isRepeaterPowered || (par2 & 8) != 0; + return par1 == 0 ? (var3 ? Block.torchRedstoneActive.getBlockTextureFromSide(par1) : Block.torchRedstoneIdle.getBlockTextureFromSide(par1)) + : (par1 == 1 ? (var3 ? Block.redstoneComparatorActive.blockIcon : this.blockIcon) : Block.stoneDoubleSlab.getBlockTextureFromSide(1)); + } + + protected boolean func_96470_c(int par1) { + return this.isRepeaterPowered || (par1 & 8) != 0; + } + + protected int func_94480_d(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return this.getTileEntityComparator(par1IBlockAccess, par2, par3, par4).func_96100_a(); + } + + private int func_94491_m(World par1World, int par2, int par3, int par4, int par5) { + return !this.func_94490_c(par5) ? this.getInputStrength(par1World, par2, par3, par4, par5) : Math.max(this.getInputStrength(par1World, par2, par3, par4, par5) - this.func_94482_f(par1World, par2, par3, par4, par5), 0); + } + + public boolean func_94490_c(int par1) { + return (par1 & 4) == 4; + } + + protected boolean func_94478_d(World par1World, int par2, int par3, int par4, int par5) { + int var6 = this.getInputStrength(par1World, par2, par3, par4, par5); + + if (var6 >= 15) { + return true; + } else if (var6 == 0) { + return false; + } else { + int var7 = this.func_94482_f(par1World, par2, par3, par4, par5); + return var7 == 0 ? true : var6 >= var7; + } + } + + /** + * Returns the signal strength at one input of the block. Args: world, X, Y, Z, + * side + */ + protected int getInputStrength(World par1World, int par2, int par3, int par4, int par5) { + int var6 = super.getInputStrength(par1World, par2, par3, par4, par5); + int var7 = getDirection(par5); + int var8 = par2 + Direction.offsetX[var7]; + int var9 = par4 + Direction.offsetZ[var7]; + int var10 = par1World.getBlockId(var8, par3, var9); + + if (var10 > 0) { + if (Block.blocksList[var10].hasComparatorInputOverride()) { + var6 = Block.blocksList[var10].getComparatorInputOverride(par1World, var8, par3, var9, Direction.rotateOpposite[var7]); + } else if (var6 < 15 && Block.isNormalCube(var10)) { + var8 += Direction.offsetX[var7]; + var9 += Direction.offsetZ[var7]; + var10 = par1World.getBlockId(var8, par3, var9); + + if (var10 > 0 && Block.blocksList[var10].hasComparatorInputOverride()) { + var6 = Block.blocksList[var10].getComparatorInputOverride(par1World, var8, par3, var9, Direction.rotateOpposite[var7]); + } + } + } + + return var6; + } + + /** + * Returns the blockTileEntity at given coordinates. + */ + public TileEntityComparator getTileEntityComparator(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return (TileEntityComparator) par1IBlockAccess.getBlockTileEntity(par2, par3, par4); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + boolean var11 = this.isRepeaterPowered | (var10 & 8) != 0; + boolean var12 = !this.func_94490_c(var10); + int var13 = var12 ? 4 : 0; + var13 |= var11 ? 8 : 0; + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "random.click", 0.3F, var12 ? 0.55F : 0.5F); + par1World.setBlockMetadataWithNotify(par2, par3, par4, var13 | var10 & 3, 2); + this.func_96476_c(par1World, par2, par3, par4, par1World.rand); + return true; + } + + protected void func_94479_f(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isBlockTickScheduled(par2, par3, par4, this.blockID)) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + int var7 = this.func_94491_m(par1World, par2, par3, par4, var6); + int var8 = this.getTileEntityComparator(par1World, par2, par3, par4).func_96100_a(); + + if (var7 != var8 || this.func_96470_c(var6) != this.func_94478_d(par1World, par2, par3, par4, var6)) { + if (this.func_83011_d(par1World, par2, par3, par4, var6)) { + par1World.func_82740_a(par2, par3, par4, this.blockID, this.func_94481_j_(0), -1); + } else { + par1World.func_82740_a(par2, par3, par4, this.blockID, this.func_94481_j_(0), 0); + } + } + } + } + + private void func_96476_c(World par1World, int par2, int par3, int par4, Random par5Random) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + int var7 = this.func_94491_m(par1World, par2, par3, par4, var6); + int var8 = this.getTileEntityComparator(par1World, par2, par3, par4).func_96100_a(); + this.getTileEntityComparator(par1World, par2, par3, par4).func_96099_a(var7); + + if (var8 != var7 || !this.func_94490_c(var6)) { + boolean var9 = this.func_94478_d(par1World, par2, par3, par4, var6); + boolean var10 = this.isRepeaterPowered || (var6 & 8) != 0; + + if (var10 && !var9) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 & -9, 2); + } else if (!var10 && var9) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 | 8, 2); + } + + this.func_94483_i_(par1World, par2, par3, par4); + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (this.isRepeaterPowered) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + par1World.setBlock(par2, par3, par4, this.func_94484_i().blockID, var6 | 8, 4); + } + + this.func_96476_c(par1World, par2, par3, par4, par5Random); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + par1World.setBlockTileEntity(par2, par3, par4, this.createNewTileEntity(par1World)); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + super.breakBlock(par1World, par2, par3, par4, par5, par6); + par1World.removeBlockTileEntity(par2, par3, par4); + this.func_94483_i_(par1World, par2, par3, par4); + } + + /** + * Called when the block receives a BlockEvent - see World.addBlockEvent. By + * default, passes it on to the tile entity at this location. Args: world, x, y, + * z, blockID, EventID, event parameter + */ + public boolean onBlockEventReceived(World par1World, int par2, int par3, int par4, int par5, int par6) { + super.onBlockEventReceived(par1World, par2, par3, par4, par5, par6); + TileEntity var7 = par1World.getBlockTileEntity(par2, par3, par4); + return var7 != null ? var7.receiveClientEvent(par5, par6) : false; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon(this.isRepeaterPowered ? "comparator_lit" : "comparator"); + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityComparator(); + } +} diff --git a/src/main/java/net/minecraft/src/BlockContainer.java b/src/main/java/net/minecraft/src/BlockContainer.java new file mode 100644 index 0000000..038323a --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockContainer.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +public abstract class BlockContainer extends Block implements ITileEntityProvider { + protected BlockContainer(int par1, Material par2Material) { + super(par1, par2Material); + this.isBlockContainer = true; + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + super.breakBlock(par1World, par2, par3, par4, par5, par6); + par1World.removeBlockTileEntity(par2, par3, par4); + } + + /** + * Called when the block receives a BlockEvent - see World.addBlockEvent. By + * default, passes it on to the tile entity at this location. Args: world, x, y, + * z, blockID, EventID, event parameter + */ + public boolean onBlockEventReceived(World par1World, int par2, int par3, int par4, int par5, int par6) { + super.onBlockEventReceived(par1World, par2, par3, par4, par5, par6); + TileEntity var7 = par1World.getBlockTileEntity(par2, par3, par4); + return var7 != null ? var7.receiveClientEvent(par5, par6) : false; + } +} diff --git a/src/main/java/net/minecraft/src/BlockCrops.java b/src/main/java/net/minecraft/src/BlockCrops.java new file mode 100644 index 0000000..a0d8bbf --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockCrops.java @@ -0,0 +1,194 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockCrops extends BlockFlower { + private Icon[] iconArray; + + protected BlockCrops(int par1) { + super(par1); + this.setTickRandomly(true); + float var2 = 0.5F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, 0.25F, 0.5F + var2); + this.setCreativeTab((CreativeTabs) null); + this.setHardness(0.0F); + this.setStepSound(soundGrassFootstep); + this.disableStats(); + } + + /** + * Gets passed in the blockID of the block below and supposed to return true if + * its allowed to grow on the type of blockID passed in. Args: blockID + */ + protected boolean canThisPlantGrowOnThisBlockID(int par1) { + return par1 == Block.tilledField.blockID; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + super.updateTick(par1World, par2, par3, par4, par5Random); + + if (par1World.getBlockLightValue(par2, par3 + 1, par4) >= 9) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (var6 < 7) { + float var7 = this.getGrowthRate(par1World, par2, par3, par4); + + if (par5Random.nextInt((int) (25.0F / var7) + 1) == 0) { + ++var6; + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6, 2); + } + } + } + } + + /** + * Apply bonemeal to the crops. + */ + public void fertilize(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4) + MathHelper.getRandomIntegerInRange(par1World.rand, 2, 5); + + if (var5 > 7) { + var5 = 7; + } + + par1World.setBlockMetadataWithNotify(par2, par3, par4, var5, 2); + } + + /** + * Gets the growth rate for the crop. Setup to encourage rows by halving growth + * rate if there is diagonals, crops on different sides that aren't opposing, + * and by adding growth for every crop next to this one (and for crop below this + * one). Args: x, y, z + */ + private float getGrowthRate(World par1World, int par2, int par3, int par4) { + float var5 = 1.0F; + int var6 = par1World.getBlockId(par2, par3, par4 - 1); + int var7 = par1World.getBlockId(par2, par3, par4 + 1); + int var8 = par1World.getBlockId(par2 - 1, par3, par4); + int var9 = par1World.getBlockId(par2 + 1, par3, par4); + int var10 = par1World.getBlockId(par2 - 1, par3, par4 - 1); + int var11 = par1World.getBlockId(par2 + 1, par3, par4 - 1); + int var12 = par1World.getBlockId(par2 + 1, par3, par4 + 1); + int var13 = par1World.getBlockId(par2 - 1, par3, par4 + 1); + boolean var14 = var8 == this.blockID || var9 == this.blockID; + boolean var15 = var6 == this.blockID || var7 == this.blockID; + boolean var16 = var10 == this.blockID || var11 == this.blockID || var12 == this.blockID || var13 == this.blockID; + + for (int var17 = par2 - 1; var17 <= par2 + 1; ++var17) { + for (int var18 = par4 - 1; var18 <= par4 + 1; ++var18) { + int var19 = par1World.getBlockId(var17, par3 - 1, var18); + float var20 = 0.0F; + + if (var19 == Block.tilledField.blockID) { + var20 = 1.0F; + + if (par1World.getBlockMetadata(var17, par3 - 1, var18) > 0) { + var20 = 3.0F; + } + } + + if (var17 != par2 || var18 != par4) { + var20 /= 4.0F; + } + + var5 += var20; + } + } + + if (var16 || var14 && var15) { + var5 /= 2.0F; + } + + return var5; + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + if (par2 < 0 || par2 > 7) { + par2 = 7; + } + + return this.iconArray[par2]; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 6; + } + + /** + * Generate a seed ItemStack for this crop. + */ + protected int getSeedItem() { + return Item.seeds.itemID; + } + + /** + * Generate a crop produce ItemStack for this crop. + */ + protected int getCropItem() { + return Item.wheat.itemID; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0); + + if (!par1World.isRemote) { + if (par5 >= 7) { + int var8 = 3 + par7; + + for (int var9 = 0; var9 < var8; ++var9) { + if (par1World.rand.nextInt(15) <= par5) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(this.getSeedItem(), 1, 0)); + } + } + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return par1 == 7 ? this.getCropItem() : this.getSeedItem(); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return this.getSeedItem(); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.iconArray = new Icon[8]; + + for (int var2 = 0; var2 < this.iconArray.length; ++var2) { + this.iconArray[var2] = par1IconRegister.registerIcon("crops_" + var2); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockDaylightDetector.java b/src/main/java/net/minecraft/src/BlockDaylightDetector.java new file mode 100644 index 0000000..efcf701 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockDaylightDetector.java @@ -0,0 +1,132 @@ +package net.minecraft.src; + +import java.util.Random; + + + +public class BlockDaylightDetector extends BlockContainer { + private Icon[] iconArray = new Icon[2]; + + public BlockDaylightDetector(int par1) { + super(par1, Material.wood); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.375F, 1.0F); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.375F, 1.0F); + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return par1IBlockAccess.getBlockMetadata(par2, par3, par4); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + } + + public void updateLightLevel(World par1World, int par2, int par3, int par4) { + if (!par1World.provider.hasNoSky) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + int var6 = par1World.getSavedLightValue(EnumSkyBlock.Sky, par2, par3, par4) - par1World.skylightSubtracted; + float var7 = par1World.getCelestialAngleRadians(1.0F); + + if (var7 < (float) Math.PI) { + var7 += (0.0F - var7) * 0.2F; + } else { + var7 += (((float) Math.PI * 2F) - var7) * 0.2F; + } + + var6 = Math.round((float) var6 * MathHelper.cos(var7)); + + if (var6 < 0) { + var6 = 0; + } + + if (var6 > 15) { + var6 = 15; + } + + if (var5 != var6) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6, 3); + } + } + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityDaylightDetector(); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 1 ? this.iconArray[0] : this.iconArray[1]; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.iconArray[0] = par1IconRegister.registerIcon("daylightDetector_top"); + this.iconArray[1] = par1IconRegister.registerIcon("daylightDetector_side"); + } +} diff --git a/src/main/java/net/minecraft/src/BlockDeadBush.java b/src/main/java/net/minecraft/src/BlockDeadBush.java new file mode 100644 index 0000000..ff6aae7 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockDeadBush.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockDeadBush extends BlockFlower { + protected BlockDeadBush(int par1) { + super(par1, Material.vine); + float var2 = 0.4F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, 0.8F, 0.5F + var2); + } + + /** + * Gets passed in the blockID of the block below and supposed to return true if + * its allowed to grow on the type of blockID passed in. Args: blockID + */ + protected boolean canThisPlantGrowOnThisBlockID(int par1) { + return par1 == Block.sand.blockID; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return -1; + } + + /** + * Called when the player destroys a block with an item that can harvest it. (i, + * j, k) are the coordinates of the block and l is the block's subtype/damage. + */ + public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) { + if (!par1World.isRemote && par2EntityPlayer.getCurrentEquippedItem() != null && par2EntityPlayer.getCurrentEquippedItem().itemID == Item.shears.itemID) { + this.dropBlockAsItem_do(par1World, par3, par4, par5, new ItemStack(Block.deadBush, 1, par6)); + } else { + super.harvestBlock(par1World, par2EntityPlayer, par3, par4, par5, par6); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockDetectorRail.java b/src/main/java/net/minecraft/src/BlockDetectorRail.java new file mode 100644 index 0000000..770c11d --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockDetectorRail.java @@ -0,0 +1,166 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockDetectorRail extends BlockRailBase { + private Icon[] iconArray; + + public BlockDetectorRail(int par1) { + super(par1, true); + this.setTickRandomly(true); + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 20; + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + if (!par1World.isRemote) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) == 0) { + this.setStateIfMinecartInteractsWithRail(par1World, par2, par3, par4, var6); + } + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) != 0) { + this.setStateIfMinecartInteractsWithRail(par1World, par2, par3, par4, var6); + } + } + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) != 0 ? 15 : 0; + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) == 0 ? 0 : (par5 == 1 ? 15 : 0); + } + + /** + * Update the detector rail power state if a minecart enter, stays or leave the + * block. + */ + private void setStateIfMinecartInteractsWithRail(World par1World, int par2, int par3, int par4, int par5) { + boolean var6 = (par5 & 8) != 0; + boolean var7 = false; + float var8 = 0.125F; + List var9 = par1World.getEntitiesWithinAABB(EntityMinecart.class, AxisAlignedBB.getAABBPool().getAABB((double) ((float) par2 + var8), (double) par3, (double) ((float) par4 + var8), (double) ((float) (par2 + 1) - var8), + (double) ((float) (par3 + 1) - var8), (double) ((float) (par4 + 1) - var8))); + + if (!var9.isEmpty()) { + var7 = true; + } + + if (var7 && !var6) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, par5 | 8, 3); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + } + + if (!var7 && var6) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, par5 & 7, 3); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + } + + if (var7) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + + par1World.func_96440_m(par2, par3, par4, this.blockID); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + this.setStateIfMinecartInteractsWithRail(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4)); + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + if ((par1World.getBlockMetadata(par2, par3, par4) & 8) > 0) { + float var6 = 0.125F; + List var7 = par1World.selectEntitiesWithinAABB(EntityMinecart.class, AxisAlignedBB.getAABBPool().getAABB((double) ((float) par2 + var6), (double) par3, (double) ((float) par4 + var6), (double) ((float) (par2 + 1) - var6), + (double) ((float) (par3 + 1) - var6), (double) ((float) (par4 + 1) - var6)), IEntitySelector.selectInventories); + + if (var7.size() > 0) { + return Container.calcRedstoneFromInventory((IInventory) var7.get(0)); + } + } + + return 0; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.iconArray = new Icon[2]; + this.iconArray[0] = par1IconRegister.registerIcon("detectorRail"); + this.iconArray[1] = par1IconRegister.registerIcon("detectorRail_on"); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return (par2 & 8) != 0 ? this.iconArray[1] : this.iconArray[0]; + } +} diff --git a/src/main/java/net/minecraft/src/BlockDirectional.java b/src/main/java/net/minecraft/src/BlockDirectional.java new file mode 100644 index 0000000..886f59b --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockDirectional.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +public abstract class BlockDirectional extends Block { + protected BlockDirectional(int par1, Material par2Material) { + super(par1, par2Material); + } + + /** + * Returns the orentation value from the specified metadata + */ + public static int getDirection(int par0) { + return par0 & 3; + } +} diff --git a/src/main/java/net/minecraft/src/BlockDirt.java b/src/main/java/net/minecraft/src/BlockDirt.java new file mode 100644 index 0000000..8e1bfcd --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockDirt.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public class BlockDirt extends Block { + protected BlockDirt(int par1) { + super(par1, Material.ground); + this.setCreativeTab(CreativeTabs.tabBlock); + } +} diff --git a/src/main/java/net/minecraft/src/BlockDispenser.java b/src/main/java/net/minecraft/src/BlockDispenser.java new file mode 100644 index 0000000..4e743aa --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockDispenser.java @@ -0,0 +1,234 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockDispenser extends BlockContainer { + /** Registry for all dispense behaviors. */ + protected Random random = new Random(); + protected Icon furnaceTopIcon; + protected Icon furnaceFrontIcon; + protected Icon field_96473_e; + + protected BlockDispenser(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 4; + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + this.setDispenserDefaultDirection(par1World, par2, par3, par4); + } + + /** + * sets Dispenser block direction so that the front faces an non-opaque block; + * chooses west to be direction if all surrounding blocks are opaque. + */ + private void setDispenserDefaultDirection(World par1World, int par2, int par3, int par4) { + if (!par1World.isRemote) { + int var5 = par1World.getBlockId(par2, par3, par4 - 1); + int var6 = par1World.getBlockId(par2, par3, par4 + 1); + int var7 = par1World.getBlockId(par2 - 1, par3, par4); + int var8 = par1World.getBlockId(par2 + 1, par3, par4); + byte var9 = 3; + + if (Block.opaqueCubeLookup[var5] && !Block.opaqueCubeLookup[var6]) { + var9 = 3; + } + + if (Block.opaqueCubeLookup[var6] && !Block.opaqueCubeLookup[var5]) { + var9 = 2; + } + + if (Block.opaqueCubeLookup[var7] && !Block.opaqueCubeLookup[var8]) { + var9 = 5; + } + + if (Block.opaqueCubeLookup[var8] && !Block.opaqueCubeLookup[var7]) { + var9 = 4; + } + + par1World.setBlockMetadataWithNotify(par2, par3, par4, var9, 2); + } + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + int var3 = par2 & 7; + return par1 == var3 ? (var3 != 1 && var3 != 0 ? this.furnaceFrontIcon : this.field_96473_e) : (var3 != 1 && var3 != 0 ? (par1 != 1 && par1 != 0 ? this.blockIcon : this.furnaceTopIcon) : this.furnaceTopIcon); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("furnace_side"); + this.furnaceTopIcon = par1IconRegister.registerIcon("furnace_top"); + this.furnaceFrontIcon = par1IconRegister.registerIcon("dispenser_front"); + this.field_96473_e = par1IconRegister.registerIcon("dispenser_front_vertical"); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + TileEntityDispenser var10 = (TileEntityDispenser) par1World.getBlockTileEntity(par2, par3, par4); + + if (var10 != null) { + par5EntityPlayer.displayGUIDispenser(var10); + } + + return true; + } + } + + protected void dispense(World par1World, int par2, int par3, int par4) { + + } + + /** + * Returns the behavior for the given ItemStack. + */ + protected IBehaviorDispenseItem getBehaviorForItemStack(ItemStack par1ItemStack) { + return null; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + boolean var6 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4) || par1World.isBlockIndirectlyGettingPowered(par2, par3 + 1, par4); + int var7 = par1World.getBlockMetadata(par2, par3, par4); + boolean var8 = (var7 & 8) != 0; + + if (var6 && !var8) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7 | 8, 4); + } else if (!var6 && var8) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7 & -9, 4); + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + this.dispense(par1World, par2, par3, par4); + } + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityDispenser(); + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + int var7 = BlockPistonBase.determineOrientation(par1World, par2, par3, par4, par5EntityLiving); + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7, 2); + + if (par6ItemStack.hasDisplayName()) { + ((TileEntityDispenser) par1World.getBlockTileEntity(par2, par3, par4)).setCustomName(par6ItemStack.getDisplayName()); + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + TileEntityDispenser var7 = (TileEntityDispenser) par1World.getBlockTileEntity(par2, par3, par4); + + if (var7 != null) { + for (int var8 = 0; var8 < var7.getSizeInventory(); ++var8) { + ItemStack var9 = var7.getStackInSlot(var8); + + if (var9 != null) { + float var10 = this.random.nextFloat() * 0.8F + 0.1F; + float var11 = this.random.nextFloat() * 0.8F + 0.1F; + float var12 = this.random.nextFloat() * 0.8F + 0.1F; + + while (var9.stackSize > 0) { + int var13 = this.random.nextInt(21) + 10; + + if (var13 > var9.stackSize) { + var13 = var9.stackSize; + } + + var9.stackSize -= var13; + EntityItem var14 = new EntityItem(par1World, (double) ((float) par2 + var10), (double) ((float) par3 + var11), (double) ((float) par4 + var12), new ItemStack(var9.itemID, var13, var9.getItemDamage())); + + if (var9.hasTagCompound()) { + var14.getEntityItem().setTagCompound((NBTTagCompound) var9.getTagCompound().copy()); + } + + float var15 = 0.05F; + var14.motionX = (double) ((float) this.random.nextGaussian() * var15); + var14.motionY = (double) ((float) this.random.nextGaussian() * var15 + 0.2F); + var14.motionZ = (double) ((float) this.random.nextGaussian() * var15); + par1World.spawnEntityInWorld(var14); + } + } + } + + par1World.func_96440_m(par2, par3, par4, par5); + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + public static IPosition getIPositionFromBlockSource(IBlockSource par0IBlockSource) { + EnumFacing var1 = getFacing(par0IBlockSource.getBlockMetadata()); + double var2 = par0IBlockSource.getX() + 0.7D * (double) var1.getFrontOffsetX(); + double var4 = par0IBlockSource.getY() + 0.7D * (double) var1.getFrontOffsetY(); + double var6 = par0IBlockSource.getZ() + 0.7D * (double) var1.getFrontOffsetZ(); + return new PositionImpl(var2, var4, var6); + } + + public static EnumFacing getFacing(int par0) { + return EnumFacing.getFront(par0 & 7); + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + return Container.calcRedstoneFromInventory((IInventory) par1World.getBlockTileEntity(par2, par3, par4)); + } +} diff --git a/src/main/java/net/minecraft/src/BlockDoor.java b/src/main/java/net/minecraft/src/BlockDoor.java new file mode 100644 index 0000000..bf93fe7 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockDoor.java @@ -0,0 +1,376 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockDoor extends Block { + private static final String[] doorIconNames = new String[] { "doorWood_lower", "doorWood_upper", "doorIron_lower", "doorIron_upper" }; + + /** Used for pointing at icon names. */ + private final int doorTypeForIcon; + private Icon[] iconArray; + + protected BlockDoor(int par1, Material par2Material) { + super(par1, par2Material); + + if (par2Material == Material.iron) { + this.doorTypeForIcon = 2; + } else { + this.doorTypeForIcon = 0; + } + + float var3 = 0.5F; + float var4 = 1.0F; + this.setBlockBounds(0.5F - var3, 0.0F, 0.5F - var3, 0.5F + var3, var4, 0.5F + var3); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return this.iconArray[this.doorTypeForIcon]; + } + + /** + * Retrieves the block texture to use based on the display side. Args: + * iBlockAccess, x, y, z, side + */ + public Icon getBlockTexture(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + if (par5 != 1 && par5 != 0) { + int var6 = this.getFullMetadata(par1IBlockAccess, par2, par3, par4); + int var7 = var6 & 3; + boolean var8 = (var6 & 4) != 0; + boolean var9 = false; + boolean var10 = (var6 & 8) != 0; + + if (var8) { + if (var7 == 0 && par5 == 2) { + var9 = !var9; + } else if (var7 == 1 && par5 == 5) { + var9 = !var9; + } else if (var7 == 2 && par5 == 3) { + var9 = !var9; + } else if (var7 == 3 && par5 == 4) { + var9 = !var9; + } + } else { + if (var7 == 0 && par5 == 5) { + var9 = !var9; + } else if (var7 == 1 && par5 == 3) { + var9 = !var9; + } else if (var7 == 2 && par5 == 4) { + var9 = !var9; + } else if (var7 == 3 && par5 == 2) { + var9 = !var9; + } + + if ((var6 & 16) != 0) { + var9 = !var9; + } + } + + return this.iconArray[this.doorTypeForIcon + (var9 ? doorIconNames.length : 0) + (var10 ? 1 : 0)]; + } else { + return this.iconArray[this.doorTypeForIcon]; + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.iconArray = new Icon[doorIconNames.length * 2]; + + for (int var2 = 0; var2 < doorIconNames.length; ++var2) { + this.iconArray[var2] = par1IconRegister.registerIcon(doorIconNames[var2]); + this.iconArray[var2 + doorIconNames.length] = new IconFlipped(this.iconArray[var2], true, false); + } + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = this.getFullMetadata(par1IBlockAccess, par2, par3, par4); + return (var5 & 4) != 0; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 7; + } + + /** + * Returns the bounding box of the wired rectangular prism to render. + */ + public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getSelectedBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.setDoorRotation(this.getFullMetadata(par1IBlockAccess, par2, par3, par4)); + } + + /** + * Returns 0, 1, 2 or 3 depending on where the hinge is. + */ + public int getDoorOrientation(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return this.getFullMetadata(par1IBlockAccess, par2, par3, par4) & 3; + } + + public boolean isDoorOpen(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return (this.getFullMetadata(par1IBlockAccess, par2, par3, par4) & 4) != 0; + } + + private void setDoorRotation(int par1) { + float var2 = 0.1875F; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 2.0F, 1.0F); + int var3 = par1 & 3; + boolean var4 = (par1 & 4) != 0; + boolean var5 = (par1 & 16) != 0; + + if (var3 == 0) { + if (var4) { + if (!var5) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var2); + } else { + this.setBlockBounds(0.0F, 0.0F, 1.0F - var2, 1.0F, 1.0F, 1.0F); + } + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, var2, 1.0F, 1.0F); + } + } else if (var3 == 1) { + if (var4) { + if (!var5) { + this.setBlockBounds(1.0F - var2, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, var2, 1.0F, 1.0F); + } + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var2); + } + } else if (var3 == 2) { + if (var4) { + if (!var5) { + this.setBlockBounds(0.0F, 0.0F, 1.0F - var2, 1.0F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var2); + } + } else { + this.setBlockBounds(1.0F - var2, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + } else if (var3 == 3) { + if (var4) { + if (!var5) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, var2, 1.0F, 1.0F); + } else { + this.setBlockBounds(1.0F - var2, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + } else { + this.setBlockBounds(0.0F, 0.0F, 1.0F - var2, 1.0F, 1.0F, 1.0F); + } + } + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (this.blockMaterial == Material.iron) { + return true; + } else { + int var10 = this.getFullMetadata(par1World, par2, par3, par4); + int var11 = var10 & 7; + var11 ^= 4; + + if ((var10 & 8) == 0) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var11, 2); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + } else { + par1World.setBlockMetadataWithNotify(par2, par3 - 1, par4, var11, 2); + par1World.markBlockRangeForRenderUpdate(par2, par3 - 1, par4, par2, par3, par4); + } + + par1World.playAuxSFXAtEntity(par5EntityPlayer, 1003, par2, par3, par4, 0); + return true; + } + } + + /** + * A function to open a door. + */ + public void onPoweredBlockChange(World par1World, int par2, int par3, int par4, boolean par5) { + int var6 = this.getFullMetadata(par1World, par2, par3, par4); + boolean var7 = (var6 & 4) != 0; + + if (var7 != par5) { + int var8 = var6 & 7; + var8 ^= 4; + + if ((var6 & 8) == 0) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var8, 2); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + } else { + par1World.setBlockMetadataWithNotify(par2, par3 - 1, par4, var8, 2); + par1World.markBlockRangeForRenderUpdate(par2, par3 - 1, par4, par2, par3, par4); + } + + par1World.playAuxSFXAtEntity((EntityPlayer) null, 1003, par2, par3, par4, 0); + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) == 0) { + boolean var7 = false; + + if (par1World.getBlockId(par2, par3 + 1, par4) != this.blockID) { + par1World.setBlockToAir(par2, par3, par4); + var7 = true; + } + + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4)) { + par1World.setBlockToAir(par2, par3, par4); + var7 = true; + + if (par1World.getBlockId(par2, par3 + 1, par4) == this.blockID) { + par1World.setBlockToAir(par2, par3 + 1, par4); + } + } + + if (var7) { + if (!par1World.isRemote) { + this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0); + } + } else { + boolean var8 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4) || par1World.isBlockIndirectlyGettingPowered(par2, par3 + 1, par4); + + if ((var8 || par5 > 0 && Block.blocksList[par5].canProvidePower()) && par5 != this.blockID) { + this.onPoweredBlockChange(par1World, par2, par3, par4, var8); + } + } + } else { + if (par1World.getBlockId(par2, par3 - 1, par4) != this.blockID) { + par1World.setBlockToAir(par2, par3, par4); + } + + if (par5 > 0 && par5 != this.blockID) { + this.onNeighborBlockChange(par1World, par2, par3 - 1, par4, par5); + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return (par1 & 8) != 0 ? 0 : (this.blockMaterial == Material.iron ? Item.doorIron.itemID : Item.doorWood.itemID); + } + + /** + * Ray traces through the blocks collision from start vector to end vector + * returning a ray trace hit. Args: world, x, y, z, startVec, endVec + */ + public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, Vec3 par6Vec3) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par3 >= 255 ? false : par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) && super.canPlaceBlockAt(par1World, par2, par3, par4) && super.canPlaceBlockAt(par1World, par2, par3 + 1, par4); + } + + /** + * Returns the mobility information of the block, 0 = free, 1 = can't push but + * can move over, 2 = total immobility and stop pistons + */ + public int getMobilityFlag() { + return 1; + } + + /** + * Returns the full metadata value created by combining the metadata of both + * blocks the door takes up. + */ + public int getFullMetadata(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + boolean var6 = (var5 & 8) != 0; + int var7; + int var8; + + if (var6) { + var7 = par1IBlockAccess.getBlockMetadata(par2, par3 - 1, par4); + var8 = var5; + } else { + var7 = var5; + var8 = par1IBlockAccess.getBlockMetadata(par2, par3 + 1, par4); + } + + boolean var9 = (var8 & 1) != 0; + return var7 & 7 | (var6 ? 8 : 0) | (var9 ? 16 : 0); + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return this.blockMaterial == Material.iron ? Item.doorIron.itemID : Item.doorWood.itemID; + } + + /** + * Called when the block is attempted to be harvested + */ + public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer) { + if (par6EntityPlayer.capabilities.isCreativeMode && (par5 & 8) != 0 && par1World.getBlockId(par2, par3 - 1, par4) == this.blockID) { + par1World.setBlockToAir(par2, par3 - 1, par4); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockDragonEgg.java b/src/main/java/net/minecraft/src/BlockDragonEgg.java new file mode 100644 index 0000000..a36bbea --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockDragonEgg.java @@ -0,0 +1,155 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockDragonEgg extends Block { + public BlockDragonEgg(int par1) { + super(par1, Material.dragonEgg); + this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 1.0F, 0.9375F); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + this.fallIfPossible(par1World, par2, par3, par4); + } + + /** + * Checks if the dragon egg can fall down, and if so, makes it fall. + */ + private void fallIfPossible(World par1World, int par2, int par3, int par4) { + if (BlockSand.canFallBelow(par1World, par2, par3 - 1, par4) && par3 >= 0) { + byte var5 = 32; + + if (!BlockSand.fallInstantly && par1World.checkChunksExist(par2 - var5, par3 - var5, par4 - var5, par2 + var5, par3 + var5, par4 + var5)) { + EntityFallingSand var6 = new EntityFallingSand(par1World, (double) ((float) par2 + 0.5F), (double) ((float) par3 + 0.5F), (double) ((float) par4 + 0.5F), this.blockID); + par1World.spawnEntityInWorld(var6); + } else { + par1World.setBlockToAir(par2, par3, par4); + + while (BlockSand.canFallBelow(par1World, par2, par3 - 1, par4) && par3 > 0) { + --par3; + } + + if (par3 > 0) { + par1World.setBlock(par2, par3, par4, this.blockID, 0, 2); + } + } + } + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + this.teleportNearby(par1World, par2, par3, par4); + return true; + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + this.teleportNearby(par1World, par2, par3, par4); + } + + /** + * Teleports the dragon egg somewhere else in a 31x19x31 area centered on the + * egg. + */ + private void teleportNearby(World par1World, int par2, int par3, int par4) { + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + for (int var5 = 0; var5 < 1000; ++var5) { + int var6 = par2 + par1World.rand.nextInt(16) - par1World.rand.nextInt(16); + int var7 = par3 + par1World.rand.nextInt(8) - par1World.rand.nextInt(8); + int var8 = par4 + par1World.rand.nextInt(16) - par1World.rand.nextInt(16); + + if (par1World.getBlockId(var6, var7, var8) == 0) { + if (!par1World.isRemote) { + par1World.setBlock(var6, var7, var8, this.blockID, par1World.getBlockMetadata(par2, par3, par4), 2); + par1World.setBlockToAir(par2, par3, par4); + } else { + short var9 = 128; + + for (int var10 = 0; var10 < var9; ++var10) { + double var11 = par1World.rand.nextDouble(); + float var13 = (par1World.rand.nextFloat() - 0.5F) * 0.2F; + float var14 = (par1World.rand.nextFloat() - 0.5F) * 0.2F; + float var15 = (par1World.rand.nextFloat() - 0.5F) * 0.2F; + double var16 = (double) var6 + (double) (par2 - var6) * var11 + (par1World.rand.nextDouble() - 0.5D) * 1.0D + 0.5D; + double var18 = (double) var7 + (double) (par3 - var7) * var11 + par1World.rand.nextDouble() * 1.0D - 0.5D; + double var20 = (double) var8 + (double) (par4 - var8) * var11 + (par1World.rand.nextDouble() - 0.5D) * 1.0D + 0.5D; + par1World.spawnParticle("portal", var16, var18, var20, (double) var13, (double) var14, (double) var15); + } + } + + return; + } + } + } + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 5; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return true; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 27; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return 0; + } +} diff --git a/src/main/java/net/minecraft/src/BlockDropper.java b/src/main/java/net/minecraft/src/BlockDropper.java new file mode 100644 index 0000000..8c84515 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockDropper.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +public class BlockDropper extends BlockDispenser { + + protected BlockDropper(int par1) { + super(par1); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("furnace_side"); + this.furnaceTopIcon = par1IconRegister.registerIcon("furnace_top"); + this.furnaceFrontIcon = par1IconRegister.registerIcon("dropper_front"); + this.field_96473_e = par1IconRegister.registerIcon("dropper_front_vertical"); + } + + /** + * Returns the behavior for the given ItemStack. + */ + protected IBehaviorDispenseItem getBehaviorForItemStack(ItemStack par1ItemStack) { + return null; + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityDropper(); + } + + protected void dispense(World par1World, int par2, int par3, int par4) { + BlockSourceImpl var5 = new BlockSourceImpl(par1World, par2, par3, par4); + TileEntityDispenser var6 = (TileEntityDispenser) var5.getBlockTileEntity(); + + if (var6 != null) { + int var7 = var6.getRandomStackFromInventory(); + + if (var7 < 0) { + par1World.playAuxSFX(1001, par2, par3, par4, 0); + } else { + ItemStack var8 = var6.getStackInSlot(var7); + int var9 = par1World.getBlockMetadata(par2, par3, par4) & 7; + IInventory var10 = TileEntityHopper.getInventoryAtLocation(par1World, (double) (par2 + Facing.offsetsXForSide[var9]), (double) (par3 + Facing.offsetsYForSide[var9]), (double) (par4 + Facing.offsetsZForSide[var9])); + ItemStack var11; + + if (var10 != null) { + var11 = TileEntityHopper.insertStack(var10, var8.copy().splitStack(1), Facing.oppositeSide[var9]); + + if (var11 == null) { + var11 = var8.copy(); + + if (--var11.stackSize == 0) { + var11 = null; + } + } else { + var11 = var8.copy(); + } + } else { + var11 = null; + } + + var6.setInventorySlotContents(var7, var11); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockEnchantmentTable.java b/src/main/java/net/minecraft/src/BlockEnchantmentTable.java new file mode 100644 index 0000000..595b5fb --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockEnchantmentTable.java @@ -0,0 +1,112 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockEnchantmentTable extends BlockContainer { + private Icon field_94461_a; + private Icon field_94460_b; + + protected BlockEnchantmentTable(int par1) { + super(par1, Material.rock); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F); + this.setLightOpacity(0); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + super.randomDisplayTick(par1World, par2, par3, par4, par5Random); + + for (int var6 = par2 - 2; var6 <= par2 + 2; ++var6) { + for (int var7 = par4 - 2; var7 <= par4 + 2; ++var7) { + if (var6 > par2 - 2 && var6 < par2 + 2 && var7 == par4 - 1) { + var7 = par4 + 2; + } + + if (par5Random.nextInt(16) == 0) { + for (int var8 = par3; var8 <= par3 + 1; ++var8) { + if (par1World.getBlockId(var6, var8, var7) == Block.bookShelf.blockID) { + if (!par1World.isAirBlock((var6 - par2) / 2 + par2, var8, (var7 - par4) / 2 + par4)) { + break; + } + + par1World.spawnParticle("enchantmenttable", (double) par2 + 0.5D, (double) par3 + 2.0D, (double) par4 + 0.5D, (double) ((float) (var6 - par2) + par5Random.nextFloat()) - 0.5D, + (double) ((float) (var8 - par3) - par5Random.nextFloat() - 1.0F), (double) ((float) (var7 - par4) + par5Random.nextFloat()) - 0.5D); + } + } + } + } + } + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 0 ? this.field_94460_b : (par1 == 1 ? this.field_94461_a : this.blockIcon); + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityEnchantmentTable(); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + TileEntityEnchantmentTable var10 = (TileEntityEnchantmentTable) par1World.getBlockTileEntity(par2, par3, par4); + par5EntityPlayer.displayGUIEnchantment(par2, par3, par4, var10.func_94135_b() ? var10.func_94133_a() : null); + return true; + } + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + super.onBlockPlacedBy(par1World, par2, par3, par4, par5EntityLiving, par6ItemStack); + + if (par6ItemStack.hasDisplayName()) { + ((TileEntityEnchantmentTable) par1World.getBlockTileEntity(par2, par3, par4)).func_94134_a(par6ItemStack.getDisplayName()); + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("enchantment_side"); + this.field_94461_a = par1IconRegister.registerIcon("enchantment_top"); + this.field_94460_b = par1IconRegister.registerIcon("enchantment_bottom"); + } +} diff --git a/src/main/java/net/minecraft/src/BlockEndPortal.java b/src/main/java/net/minecraft/src/BlockEndPortal.java new file mode 100644 index 0000000..7d8828f --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockEndPortal.java @@ -0,0 +1,132 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockEndPortal extends BlockContainer { + /** + * true if the enderdragon has been killed - allows end portal blocks to be + * created in the end + */ + public static boolean bossDefeated = false; + + protected BlockEndPortal(int par1, Material par2Material) { + super(par1, par2Material); + this.setLightValue(1.0F); + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityEndPortal(); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + float var5 = 0.0625F; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, var5, 1.0F); + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return par5 != 0 ? false : super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5); + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity) { + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + if (par5Entity.ridingEntity == null && par5Entity.riddenByEntity == null && !par1World.isRemote) { + par5Entity.travelToDimension(1); + } + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + double var6 = (double) ((float) par2 + par5Random.nextFloat()); + double var8 = (double) ((float) par3 + 0.8F); + double var10 = (double) ((float) par4 + par5Random.nextFloat()); + double var12 = 0.0D; + double var14 = 0.0D; + double var16 = 0.0D; + par1World.spawnParticle("smoke", var6, var8, var10, var12, var14, var16); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return -1; + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + if (!bossDefeated) { + if (par1World.provider.dimensionId != 0) { + par1World.setBlockToAir(par2, par3, par4); + } + } + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return 0; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("portal"); + } +} diff --git a/src/main/java/net/minecraft/src/BlockEndPortalFrame.java b/src/main/java/net/minecraft/src/BlockEndPortalFrame.java new file mode 100644 index 0000000..d38680b --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockEndPortalFrame.java @@ -0,0 +1,100 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockEndPortalFrame extends Block { + private Icon field_94400_a; + private Icon field_94399_b; + + public BlockEndPortalFrame(int par1) { + super(par1, Material.rock); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 1 ? this.field_94400_a : (par1 == 0 ? Block.whiteStone.getBlockTextureFromSide(par1) : this.blockIcon); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("endframe_side"); + this.field_94400_a = par1IconRegister.registerIcon("endframe_top"); + this.field_94399_b = par1IconRegister.registerIcon("endframe_eye"); + } + + public Icon func_94398_p() { + return this.field_94399_b; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 26; + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.8125F, 1.0F); + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.8125F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + int var8 = par1World.getBlockMetadata(par2, par3, par4); + + if (isEnderEyeInserted(var8)) { + this.setBlockBounds(0.3125F, 0.8125F, 0.3125F, 0.6875F, 1.0F, 0.6875F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + this.setBlockBoundsForItemRender(); + } + + /** + * checks if an ender eye has been inserted into the frame block. parameters: + * metadata + */ + public static boolean isEnderEyeInserted(int par0) { + return (par0 & 4) != 0; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return 0; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + int var7 = ((MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) + 2) % 4; + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7, 2); + } +} diff --git a/src/main/java/net/minecraft/src/BlockEnderChest.java b/src/main/java/net/minecraft/src/BlockEnderChest.java new file mode 100644 index 0000000..95fae4b --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockEnderChest.java @@ -0,0 +1,147 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockEnderChest extends BlockContainer { + protected BlockEnderChest(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabDecorations); + this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 22; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.obsidian.blockID; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 8; + } + + /** + * Return true if a player with Silk Touch can harvest this block directly, and + * not its normal drops. + */ + protected boolean canSilkHarvest() { + return true; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + byte var7 = 0; + int var8 = MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + + if (var8 == 0) { + var7 = 2; + } + + if (var8 == 1) { + var7 = 5; + } + + if (var8 == 2) { + var7 = 3; + } + + if (var8 == 3) { + var7 = 4; + } + + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7, 2); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + InventoryEnderChest var10 = par5EntityPlayer.getInventoryEnderChest(); + TileEntityEnderChest var11 = (TileEntityEnderChest) par1World.getBlockTileEntity(par2, par3, par4); + + if (var10 != null && var11 != null) { + if (par1World.isBlockNormalCube(par2, par3 + 1, par4)) { + return true; + } else if (par1World.isRemote) { + return true; + } else { + var10.setAssociatedChest(var11); + par5EntityPlayer.displayGUIChest(var10); + return true; + } + } else { + return true; + } + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityEnderChest(); + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + for (int var6 = 0; var6 < 3; ++var6) { + double var10000 = (double) ((float) par2 + par5Random.nextFloat()); + double var9 = (double) ((float) par3 + par5Random.nextFloat()); + var10000 = (double) ((float) par4 + par5Random.nextFloat()); + double var13 = 0.0D; + double var15 = 0.0D; + double var17 = 0.0D; + int var19 = par5Random.nextInt(2) * 2 - 1; + int var20 = par5Random.nextInt(2) * 2 - 1; + var13 = ((double) par5Random.nextFloat() - 0.5D) * 0.125D; + var15 = ((double) par5Random.nextFloat() - 0.5D) * 0.125D; + var17 = ((double) par5Random.nextFloat() - 0.5D) * 0.125D; + double var11 = (double) par4 + 0.5D + 0.25D * (double) var20; + var17 = (double) (par5Random.nextFloat() * 1.0F * (float) var20); + double var7 = (double) par2 + 0.5D + 0.25D * (double) var19; + var13 = (double) (par5Random.nextFloat() * 1.0F * (float) var19); + par1World.spawnParticle("portal", var7, var9, var11, var13, var15, var17); + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("obsidian"); + } +} diff --git a/src/main/java/net/minecraft/src/BlockEventData.java b/src/main/java/net/minecraft/src/BlockEventData.java new file mode 100644 index 0000000..833043f --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockEventData.java @@ -0,0 +1,78 @@ +package net.minecraft.src; + +public class BlockEventData { + private int coordX; + private int coordY; + private int coordZ; + private int blockID; + + /** Different for each blockID */ + private int eventID; + + /** Different for each blockID, eventID */ + private int eventParameter; + + public BlockEventData(int par1, int par2, int par3, int par4, int par5, int par6) { + this.coordX = par1; + this.coordY = par2; + this.coordZ = par3; + this.eventID = par5; + this.eventParameter = par6; + this.blockID = par4; + } + + /** + * Get the X coordinate. + */ + public int getX() { + return this.coordX; + } + + /** + * Get the Y coordinate. + */ + public int getY() { + return this.coordY; + } + + /** + * Get the Z coordinate. + */ + public int getZ() { + return this.coordZ; + } + + /** + * Get the Event ID (different for each BlockID) + */ + public int getEventID() { + return this.eventID; + } + + /** + * Get the Event Parameter (different for each BlockID,EventID) + */ + public int getEventParameter() { + return this.eventParameter; + } + + /** + * Gets the BlockID for this BlockEventData + */ + public int getBlockID() { + return this.blockID; + } + + public boolean equals(Object par1Obj) { + if (!(par1Obj instanceof BlockEventData)) { + return false; + } else { + BlockEventData var2 = (BlockEventData) par1Obj; + return this.coordX == var2.coordX && this.coordY == var2.coordY && this.coordZ == var2.coordZ && this.eventID == var2.eventID && this.eventParameter == var2.eventParameter && this.blockID == var2.blockID; + } + } + + public String toString() { + return "TE(" + this.coordX + "," + this.coordY + "," + this.coordZ + ")," + this.eventID + "," + this.eventParameter + "," + this.blockID; + } +} diff --git a/src/main/java/net/minecraft/src/BlockFarmland.java b/src/main/java/net/minecraft/src/BlockFarmland.java new file mode 100644 index 0000000..4710f00 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockFarmland.java @@ -0,0 +1,154 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockFarmland extends Block { + private Icon field_94441_a; + private Icon field_94440_b; + + protected BlockFarmland(int par1) { + super(par1, Material.ground); + this.setTickRandomly(true); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.9375F, 1.0F); + this.setLightOpacity(255); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return AxisAlignedBB.getAABBPool().getAABB((double) (par2 + 0), (double) (par3 + 0), (double) (par4 + 0), (double) (par2 + 1), (double) (par3 + 1), (double) (par4 + 1)); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 1 ? (par2 > 0 ? this.field_94441_a : this.field_94440_b) : Block.dirt.getBlockTextureFromSide(par1); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!this.isWaterNearby(par1World, par2, par3, par4) && !par1World.canLightningStrikeAt(par2, par3 + 1, par4)) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (var6 > 0) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 - 1, 2); + } else if (!this.isCropsNearby(par1World, par2, par3, par4)) { + par1World.setBlock(par2, par3, par4, Block.dirt.blockID); + } + } else { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 7, 2); + } + } + + /** + * Block's chance to react to an entity falling on it. + */ + public void onFallenUpon(World par1World, int par2, int par3, int par4, Entity par5Entity, float par6) { + if (!par1World.isRemote && par1World.rand.nextFloat() < par6 - 0.5F) { + if (!(par5Entity instanceof EntityPlayer) && !par1World.getGameRules().getGameRuleBooleanValue("mobGriefing")) { + return; + } + + par1World.setBlock(par2, par3, par4, Block.dirt.blockID); + } + } + + /** + * returns true if there is at least one cropblock nearby (x-1 to x+1, y+1, z-1 + * to z+1) + */ + private boolean isCropsNearby(World par1World, int par2, int par3, int par4) { + byte var5 = 0; + + for (int var6 = par2 - var5; var6 <= par2 + var5; ++var6) { + for (int var7 = par4 - var5; var7 <= par4 + var5; ++var7) { + int var8 = par1World.getBlockId(var6, par3 + 1, var7); + + if (var8 == Block.crops.blockID || var8 == Block.melonStem.blockID || var8 == Block.pumpkinStem.blockID || var8 == Block.potato.blockID || var8 == Block.carrot.blockID) { + return true; + } + } + } + + return false; + } + + /** + * returns true if there's water nearby (x-4 to x+4, y to y+1, k-4 to k+4) + */ + private boolean isWaterNearby(World par1World, int par2, int par3, int par4) { + for (int var5 = par2 - 4; var5 <= par2 + 4; ++var5) { + for (int var6 = par3; var6 <= par3 + 1; ++var6) { + for (int var7 = par4 - 4; var7 <= par4 + 4; ++var7) { + if (par1World.getBlockMaterial(var5, var6, var7) == Material.water) { + return true; + } + } + } + } + + return false; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + super.onNeighborBlockChange(par1World, par2, par3, par4, par5); + Material var6 = par1World.getBlockMaterial(par2, par3 + 1, par4); + + if (var6.isSolid()) { + par1World.setBlock(par2, par3, par4, Block.dirt.blockID); + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.dirt.idDropped(0, par2Random, par3); + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Block.dirt.blockID; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.field_94441_a = par1IconRegister.registerIcon("farmland_wet"); + this.field_94440_b = par1IconRegister.registerIcon("farmland_dry"); + } +} diff --git a/src/main/java/net/minecraft/src/BlockFence.java b/src/main/java/net/minecraft/src/BlockFence.java new file mode 100644 index 0000000..b58dae4 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockFence.java @@ -0,0 +1,163 @@ +package net.minecraft.src; + +import java.util.List; + +public class BlockFence extends Block { + private final String field_94464_a; + + public BlockFence(int par1, String par2Str, Material par3Material) { + super(par1, par3Material); + this.field_94464_a = par2Str; + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity) { + boolean var8 = this.canConnectFenceTo(par1World, par2, par3, par4 - 1); + boolean var9 = this.canConnectFenceTo(par1World, par2, par3, par4 + 1); + boolean var10 = this.canConnectFenceTo(par1World, par2 - 1, par3, par4); + boolean var11 = this.canConnectFenceTo(par1World, par2 + 1, par3, par4); + float var12 = 0.375F; + float var13 = 0.625F; + float var14 = 0.375F; + float var15 = 0.625F; + + if (var8) { + var14 = 0.0F; + } + + if (var9) { + var15 = 1.0F; + } + + if (var8 || var9) { + this.setBlockBounds(var12, 0.0F, var14, var13, 1.5F, var15); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + var14 = 0.375F; + var15 = 0.625F; + + if (var10) { + var12 = 0.0F; + } + + if (var11) { + var13 = 1.0F; + } + + if (var10 || var11 || !var8 && !var9) { + this.setBlockBounds(var12, 0.0F, var14, var13, 1.5F, var15); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + if (var8) { + var14 = 0.0F; + } + + if (var9) { + var15 = 1.0F; + } + + this.setBlockBounds(var12, 0.0F, var14, var13, 1.0F, var15); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + boolean var5 = this.canConnectFenceTo(par1IBlockAccess, par2, par3, par4 - 1); + boolean var6 = this.canConnectFenceTo(par1IBlockAccess, par2, par3, par4 + 1); + boolean var7 = this.canConnectFenceTo(par1IBlockAccess, par2 - 1, par3, par4); + boolean var8 = this.canConnectFenceTo(par1IBlockAccess, par2 + 1, par3, par4); + float var9 = 0.375F; + float var10 = 0.625F; + float var11 = 0.375F; + float var12 = 0.625F; + + if (var5) { + var11 = 0.0F; + } + + if (var6) { + var12 = 1.0F; + } + + if (var7) { + var9 = 0.0F; + } + + if (var8) { + var10 = 1.0F; + } + + this.setBlockBounds(var9, 0.0F, var11, var10, 1.0F, var12); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 11; + } + + /** + * Returns true if the specified block can be connected by a fence + */ + public boolean canConnectFenceTo(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockId(par2, par3, par4); + + if (var5 != this.blockID && var5 != Block.fenceGate.blockID) { + Block var6 = Block.blocksList[var5]; + return var6 != null && var6.blockMaterial.isOpaque() && var6.renderAsNormalBlock() ? var6.blockMaterial != Material.pumpkin : false; + } else { + return true; + } + } + + public static boolean isIdAFence(int par0) { + return par0 == Block.fence.blockID || par0 == Block.netherFence.blockID; + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return true; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon(this.field_94464_a); + } +} diff --git a/src/main/java/net/minecraft/src/BlockFenceGate.java b/src/main/java/net/minecraft/src/BlockFenceGate.java new file mode 100644 index 0000000..c59a0f4 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockFenceGate.java @@ -0,0 +1,152 @@ +package net.minecraft.src; + +public class BlockFenceGate extends BlockDirectional { + public BlockFenceGate(int par1) { + super(par1, Material.wood); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return Block.planks.getBlockTextureFromSide(par1); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return !par1World.getBlockMaterial(par2, par3 - 1, par4).isSolid() ? false : super.canPlaceBlockAt(par1World, par2, par3, par4); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + return isFenceGateOpen(var5) ? null + : (var5 != 2 && var5 != 0 ? AxisAlignedBB.getAABBPool().getAABB((double) ((float) par2 + 0.375F), (double) par3, (double) par4, (double) ((float) par2 + 0.625F), (double) ((float) par3 + 1.5F), (double) (par4 + 1)) + : AxisAlignedBB.getAABBPool().getAABB((double) par2, (double) par3, (double) ((float) par4 + 0.375F), (double) (par2 + 1), (double) ((float) par3 + 1.5F), (double) ((float) par4 + 0.625F))); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = getDirection(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + + if (var5 != 2 && var5 != 0) { + this.setBlockBounds(0.375F, 0.0F, 0.0F, 0.625F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.375F, 1.0F, 1.0F, 0.625F); + } + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return isFenceGateOpen(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 21; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + int var7 = (MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) % 4; + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7, 2); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + + if (isFenceGateOpen(var10)) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var10 & -5, 2); + } else { + int var11 = (MathHelper.floor_double((double) (par5EntityPlayer.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) % 4; + int var12 = getDirection(var10); + + if (var12 == (var11 + 2) % 4) { + var10 = var11; + } + + par1World.setBlockMetadataWithNotify(par2, par3, par4, var10 | 4, 2); + } + + par1World.playAuxSFXAtEntity(par5EntityPlayer, 1003, par2, par3, par4, 0); + return true; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + boolean var7 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4); + + if (var7 || par5 > 0 && Block.blocksList[par5].canProvidePower()) { + if (var7 && !isFenceGateOpen(var6)) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 | 4, 2); + par1World.playAuxSFXAtEntity((EntityPlayer) null, 1003, par2, par3, par4, 0); + } else if (!var7 && isFenceGateOpen(var6)) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 & -5, 2); + par1World.playAuxSFXAtEntity((EntityPlayer) null, 1003, par2, par3, par4, 0); + } + } + } + } + + /** + * Returns if the fence gate is open according to its metadata. + */ + public static boolean isFenceGateOpen(int par0) { + return (par0 & 4) != 0; + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return true; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + } +} diff --git a/src/main/java/net/minecraft/src/BlockFire.java b/src/main/java/net/minecraft/src/BlockFire.java new file mode 100644 index 0000000..1d4cc00 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockFire.java @@ -0,0 +1,393 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockFire extends Block { + /** The chance this block will encourage nearby blocks to catch on fire */ + private int[] chanceToEncourageFire = new int[256]; + + /** + * This is an array indexed by block ID the larger the number in the array the + * more likely a block type will catch fires + */ + private int[] abilityToCatchFire = new int[256]; + private Icon[] iconArray; + + protected BlockFire(int par1) { + super(par1, Material.fire); + this.setTickRandomly(true); + } + + /** + * This method is called on a block after all other blocks gets already created. + * You can use it to reference and configure something on the block that needs + * the others ones. + */ + public void initializeBlock() { + this.setBurnRate(Block.planks.blockID, 5, 20); + this.setBurnRate(Block.woodDoubleSlab.blockID, 5, 20); + this.setBurnRate(Block.woodSingleSlab.blockID, 5, 20); + this.setBurnRate(Block.fence.blockID, 5, 20); + this.setBurnRate(Block.stairsWoodOak.blockID, 5, 20); + this.setBurnRate(Block.stairsWoodBirch.blockID, 5, 20); + this.setBurnRate(Block.stairsWoodSpruce.blockID, 5, 20); + this.setBurnRate(Block.stairsWoodJungle.blockID, 5, 20); + this.setBurnRate(Block.wood.blockID, 5, 5); + this.setBurnRate(Block.leaves.blockID, 30, 60); + this.setBurnRate(Block.bookShelf.blockID, 30, 20); + this.setBurnRate(Block.tnt.blockID, 15, 100); + this.setBurnRate(Block.tallGrass.blockID, 60, 100); + this.setBurnRate(Block.cloth.blockID, 30, 60); + this.setBurnRate(Block.vine.blockID, 15, 100); + } + + /** + * Sets the burn rate for a block. The larger abilityToCatchFire the more easily + * it will catch. The larger chanceToEncourageFire the faster it will burn and + * spread to other blocks. Args: blockID, chanceToEncourageFire, + * abilityToCatchFire + */ + private void setBurnRate(int par1, int par2, int par3) { + this.chanceToEncourageFire[par1] = par2; + this.abilityToCatchFire[par1] = par3; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 3; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 30; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par1World.getGameRules().getGameRuleBooleanValue("doFireTick")) { + boolean var6 = par1World.getBlockId(par2, par3 - 1, par4) == Block.netherrack.blockID; + + if (par1World.provider instanceof WorldProviderEnd && par1World.getBlockId(par2, par3 - 1, par4) == Block.bedrock.blockID) { + var6 = true; + } + + if (!this.canPlaceBlockAt(par1World, par2, par3, par4)) { + par1World.setBlockToAir(par2, par3, par4); + } + + if (!var6 && par1World.isRaining() && (par1World.canLightningStrikeAt(par2, par3, par4) || par1World.canLightningStrikeAt(par2 - 1, par3, par4) || par1World.canLightningStrikeAt(par2 + 1, par3, par4) + || par1World.canLightningStrikeAt(par2, par3, par4 - 1) || par1World.canLightningStrikeAt(par2, par3, par4 + 1))) { + par1World.setBlockToAir(par2, par3, par4); + } else { + int var7 = par1World.getBlockMetadata(par2, par3, par4); + + if (var7 < 15) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7 + par5Random.nextInt(3) / 2, 4); + } + + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World) + par5Random.nextInt(10)); + + if (!var6 && !this.canNeighborBurn(par1World, par2, par3, par4)) { + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) || var7 > 3) { + par1World.setBlockToAir(par2, par3, par4); + } + } else if (!var6 && !this.canBlockCatchFire(par1World, par2, par3 - 1, par4) && var7 == 15 && par5Random.nextInt(4) == 0) { + par1World.setBlockToAir(par2, par3, par4); + } else { + boolean var8 = par1World.isBlockHighHumidity(par2, par3, par4); + byte var9 = 0; + + if (var8) { + var9 = -50; + } + + this.tryToCatchBlockOnFire(par1World, par2 + 1, par3, par4, 300 + var9, par5Random, var7); + this.tryToCatchBlockOnFire(par1World, par2 - 1, par3, par4, 300 + var9, par5Random, var7); + this.tryToCatchBlockOnFire(par1World, par2, par3 - 1, par4, 250 + var9, par5Random, var7); + this.tryToCatchBlockOnFire(par1World, par2, par3 + 1, par4, 250 + var9, par5Random, var7); + this.tryToCatchBlockOnFire(par1World, par2, par3, par4 - 1, 300 + var9, par5Random, var7); + this.tryToCatchBlockOnFire(par1World, par2, par3, par4 + 1, 300 + var9, par5Random, var7); + + for (int var10 = par2 - 1; var10 <= par2 + 1; ++var10) { + for (int var11 = par4 - 1; var11 <= par4 + 1; ++var11) { + for (int var12 = par3 - 1; var12 <= par3 + 4; ++var12) { + if (var10 != par2 || var12 != par3 || var11 != par4) { + int var13 = 100; + + if (var12 > par3 + 1) { + var13 += (var12 - (par3 + 1)) * 100; + } + + int var14 = this.getChanceOfNeighborsEncouragingFire(par1World, var10, var12, var11); + + if (var14 > 0) { + int var15 = (var14 + 40 + par1World.difficultySetting * 7) / (var7 + 30); + + if (var8) { + var15 /= 2; + } + + if (var15 > 0 && par5Random.nextInt(var13) <= var15 && (!par1World.isRaining() || !par1World.canLightningStrikeAt(var10, var12, var11)) && !par1World.canLightningStrikeAt(var10 - 1, var12, par4) + && !par1World.canLightningStrikeAt(var10 + 1, var12, var11) && !par1World.canLightningStrikeAt(var10, var12, var11 - 1) && !par1World.canLightningStrikeAt(var10, var12, var11 + 1)) { + int var16 = var7 + par5Random.nextInt(5) / 4; + + if (var16 > 15) { + var16 = 15; + } + + par1World.setBlock(var10, var12, var11, this.blockID, var16, 3); + } + } + } + } + } + } + } + } + } + } + + public boolean func_82506_l() { + return false; + } + + private void tryToCatchBlockOnFire(World par1World, int par2, int par3, int par4, int par5, Random par6Random, int par7) { + int var8 = this.abilityToCatchFire[par1World.getBlockId(par2, par3, par4)]; + + if (par6Random.nextInt(par5) < var8) { + boolean var9 = par1World.getBlockId(par2, par3, par4) == Block.tnt.blockID; + + if (par6Random.nextInt(par7 + 10) < 5 && !par1World.canLightningStrikeAt(par2, par3, par4)) { + int var10 = par7 + par6Random.nextInt(5) / 4; + + if (var10 > 15) { + var10 = 15; + } + + par1World.setBlock(par2, par3, par4, this.blockID, var10, 3); + } else { + par1World.setBlockToAir(par2, par3, par4); + } + + if (var9) { + Block.tnt.onBlockDestroyedByPlayer(par1World, par2, par3, par4, 1); + } + } + } + + /** + * Returns true if at least one block next to this one can burn. + */ + private boolean canNeighborBurn(World par1World, int par2, int par3, int par4) { + return this.canBlockCatchFire(par1World, par2 + 1, par3, par4) ? true + : (this.canBlockCatchFire(par1World, par2 - 1, par3, par4) ? true + : (this.canBlockCatchFire(par1World, par2, par3 - 1, par4) ? true + : (this.canBlockCatchFire(par1World, par2, par3 + 1, par4) ? true : (this.canBlockCatchFire(par1World, par2, par3, par4 - 1) ? true : this.canBlockCatchFire(par1World, par2, par3, par4 + 1))))); + } + + /** + * Gets the highest chance of a neighbor block encouraging this block to catch + * fire + */ + private int getChanceOfNeighborsEncouragingFire(World par1World, int par2, int par3, int par4) { + byte var5 = 0; + + if (!par1World.isAirBlock(par2, par3, par4)) { + return 0; + } else { + int var6 = this.getChanceToEncourageFire(par1World, par2 + 1, par3, par4, var5); + var6 = this.getChanceToEncourageFire(par1World, par2 - 1, par3, par4, var6); + var6 = this.getChanceToEncourageFire(par1World, par2, par3 - 1, par4, var6); + var6 = this.getChanceToEncourageFire(par1World, par2, par3 + 1, par4, var6); + var6 = this.getChanceToEncourageFire(par1World, par2, par3, par4 - 1, var6); + var6 = this.getChanceToEncourageFire(par1World, par2, par3, par4 + 1, var6); + return var6; + } + } + + /** + * Returns if this block is collidable (only used by Fire). Args: x, y, z + */ + public boolean isCollidable() { + return false; + } + + /** + * Checks the specified block coordinate to see if it can catch fire. Args: + * blockAccess, x, y, z + */ + public boolean canBlockCatchFire(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return this.chanceToEncourageFire[par1IBlockAccess.getBlockId(par2, par3, par4)] > 0; + } + + /** + * Retrieves a specified block's chance to encourage their neighbors to burn and + * if the number is greater than the current number passed in it will return its + * number instead of the passed in one. Args: world, x, y, z, + * curChanceToEncourageFire + */ + public int getChanceToEncourageFire(World par1World, int par2, int par3, int par4, int par5) { + int var6 = this.chanceToEncourageFire[par1World.getBlockId(par2, par3, par4)]; + return var6 > par5 ? var6 : par5; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) || this.canNeighborBurn(par1World, par2, par3, par4); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) && !this.canNeighborBurn(par1World, par2, par3, par4)) { + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + if (par1World.provider.dimensionId > 0 || par1World.getBlockId(par2, par3 - 1, par4) != Block.obsidian.blockID || !Block.portal.tryToCreatePortal(par1World, par2, par3, par4)) { + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) && !this.canNeighborBurn(par1World, par2, par3, par4)) { + par1World.setBlockToAir(par2, par3, par4); + } else { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World) + par1World.rand.nextInt(10)); + } + } + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par5Random.nextInt(24) == 0) { + par1World.playSound((double) ((float) par2 + 0.5F), (double) ((float) par3 + 0.5F), (double) ((float) par4 + 0.5F), "fire.fire", 1.0F + par5Random.nextFloat(), par5Random.nextFloat() * 0.7F + 0.3F, false); + } + + int var6; + float var7; + float var8; + float var9; + + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) && !Block.fire.canBlockCatchFire(par1World, par2, par3 - 1, par4)) { + if (Block.fire.canBlockCatchFire(par1World, par2 - 1, par3, par4)) { + for (var6 = 0; var6 < 2; ++var6) { + var7 = (float) par2 + par5Random.nextFloat() * 0.1F; + var8 = (float) par3 + par5Random.nextFloat(); + var9 = (float) par4 + par5Random.nextFloat(); + par1World.spawnParticle("largesmoke", (double) var7, (double) var8, (double) var9, 0.0D, 0.0D, 0.0D); + } + } + + if (Block.fire.canBlockCatchFire(par1World, par2 + 1, par3, par4)) { + for (var6 = 0; var6 < 2; ++var6) { + var7 = (float) (par2 + 1) - par5Random.nextFloat() * 0.1F; + var8 = (float) par3 + par5Random.nextFloat(); + var9 = (float) par4 + par5Random.nextFloat(); + par1World.spawnParticle("largesmoke", (double) var7, (double) var8, (double) var9, 0.0D, 0.0D, 0.0D); + } + } + + if (Block.fire.canBlockCatchFire(par1World, par2, par3, par4 - 1)) { + for (var6 = 0; var6 < 2; ++var6) { + var7 = (float) par2 + par5Random.nextFloat(); + var8 = (float) par3 + par5Random.nextFloat(); + var9 = (float) par4 + par5Random.nextFloat() * 0.1F; + par1World.spawnParticle("largesmoke", (double) var7, (double) var8, (double) var9, 0.0D, 0.0D, 0.0D); + } + } + + if (Block.fire.canBlockCatchFire(par1World, par2, par3, par4 + 1)) { + for (var6 = 0; var6 < 2; ++var6) { + var7 = (float) par2 + par5Random.nextFloat(); + var8 = (float) par3 + par5Random.nextFloat(); + var9 = (float) (par4 + 1) - par5Random.nextFloat() * 0.1F; + par1World.spawnParticle("largesmoke", (double) var7, (double) var8, (double) var9, 0.0D, 0.0D, 0.0D); + } + } + + if (Block.fire.canBlockCatchFire(par1World, par2, par3 + 1, par4)) { + for (var6 = 0; var6 < 2; ++var6) { + var7 = (float) par2 + par5Random.nextFloat(); + var8 = (float) (par3 + 1) - par5Random.nextFloat() * 0.1F; + var9 = (float) par4 + par5Random.nextFloat(); + par1World.spawnParticle("largesmoke", (double) var7, (double) var8, (double) var9, 0.0D, 0.0D, 0.0D); + } + } + } else { + for (var6 = 0; var6 < 3; ++var6) { + var7 = (float) par2 + par5Random.nextFloat(); + var8 = (float) par3 + par5Random.nextFloat() * 0.5F + 0.5F; + var9 = (float) par4 + par5Random.nextFloat(); + par1World.spawnParticle("largesmoke", (double) var7, (double) var8, (double) var9, 0.0D, 0.0D, 0.0D); + } + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.iconArray = new Icon[] { par1IconRegister.registerIcon("fire_0"), par1IconRegister.registerIcon("fire_1") }; + } + + public Icon func_94438_c(int par1) { + return this.iconArray[par1]; + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return this.iconArray[0]; + } +} diff --git a/src/main/java/net/minecraft/src/BlockFlower.java b/src/main/java/net/minecraft/src/BlockFlower.java new file mode 100644 index 0000000..0e04493 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockFlower.java @@ -0,0 +1,97 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockFlower extends Block { + protected BlockFlower(int par1, Material par2Material) { + super(par1, par2Material); + this.setTickRandomly(true); + float var3 = 0.2F; + this.setBlockBounds(0.5F - var3, 0.0F, 0.5F - var3, 0.5F + var3, var3 * 3.0F, 0.5F + var3); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + protected BlockFlower(int par1) { + this(par1, Material.plants); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return super.canPlaceBlockAt(par1World, par2, par3, par4) && this.canThisPlantGrowOnThisBlockID(par1World.getBlockId(par2, par3 - 1, par4)); + } + + /** + * Gets passed in the blockID of the block below and supposed to return true if + * its allowed to grow on the type of blockID passed in. Args: blockID + */ + protected boolean canThisPlantGrowOnThisBlockID(int par1) { + return par1 == Block.grass.blockID || par1 == Block.dirt.blockID || par1 == Block.tilledField.blockID; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + super.onNeighborBlockChange(par1World, par2, par3, par4, par5); + this.checkFlowerChange(par1World, par2, par3, par4); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + this.checkFlowerChange(par1World, par2, par3, par4); + } + + protected final void checkFlowerChange(World par1World, int par2, int par3, int par4) { + if (!this.canBlockStay(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + return (par1World.getFullBlockLightValue(par2, par3, par4) >= 8 || par1World.canBlockSeeTheSky(par2, par3, par4)) && this.canThisPlantGrowOnThisBlockID(par1World.getBlockId(par2, par3 - 1, par4)); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 1; + } +} diff --git a/src/main/java/net/minecraft/src/BlockFlowerPot.java b/src/main/java/net/minecraft/src/BlockFlowerPot.java new file mode 100644 index 0000000..5c7cc80 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockFlowerPot.java @@ -0,0 +1,225 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockFlowerPot extends Block { + public BlockFlowerPot(int par1) { + super(par1, Material.circuits); + this.setBlockBoundsForItemRender(); + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + float var1 = 0.375F; + float var2 = var1 / 2.0F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, var1, 0.5F + var2); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 33; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + ItemStack var10 = par5EntityPlayer.inventory.getCurrentItem(); + + if (var10 == null) { + return false; + } else if (par1World.getBlockMetadata(par2, par3, par4) != 0) { + return false; + } else { + int var11 = getMetaForPlant(var10); + + if (var11 > 0) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var11, 2); + + if (!par5EntityPlayer.capabilities.isCreativeMode && --var10.stackSize <= 0) { + par5EntityPlayer.inventory.setInventorySlotContents(par5EntityPlayer.inventory.currentItem, (ItemStack) null); + } + + return true; + } else { + return false; + } + } + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + ItemStack var5 = getPlantForMeta(par1World.getBlockMetadata(par2, par3, par4)); + return var5 == null ? Item.flowerPot.itemID : var5.itemID; + } + + /** + * Get the block's damage value (for use with pick block). + */ + public int getDamageValue(World par1World, int par2, int par3, int par4) { + ItemStack var5 = getPlantForMeta(par1World.getBlockMetadata(par2, par3, par4)); + return var5 == null ? Item.flowerPot.itemID : var5.getItemDamage(); + } + + /** + * Returns true only if block is flowerPot + */ + public boolean isFlowerPot() { + return true; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return super.canPlaceBlockAt(par1World, par2, par3, par4) && par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7); + + if (par5 > 0) { + ItemStack var8 = getPlantForMeta(par5); + + if (var8 != null) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, var8); + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.flowerPot.itemID; + } + + /** + * Return the item associated with the specified flower pot metadata value. + */ + public static ItemStack getPlantForMeta(int par0) { + switch (par0) { + case 1: + return new ItemStack(Block.plantRed); + + case 2: + return new ItemStack(Block.plantYellow); + + case 3: + return new ItemStack(Block.sapling, 1, 0); + + case 4: + return new ItemStack(Block.sapling, 1, 1); + + case 5: + return new ItemStack(Block.sapling, 1, 2); + + case 6: + return new ItemStack(Block.sapling, 1, 3); + + case 7: + return new ItemStack(Block.mushroomRed); + + case 8: + return new ItemStack(Block.mushroomBrown); + + case 9: + return new ItemStack(Block.cactus); + + case 10: + return new ItemStack(Block.deadBush); + + case 11: + return new ItemStack(Block.tallGrass, 1, 2); + + default: + return null; + } + } + + /** + * Return the flower pot metadata value associated with the specified item. + */ + public static int getMetaForPlant(ItemStack par0ItemStack) { + int var1 = par0ItemStack.getItem().itemID; + + if (var1 == Block.plantRed.blockID) { + return 1; + } else if (var1 == Block.plantYellow.blockID) { + return 2; + } else if (var1 == Block.cactus.blockID) { + return 9; + } else if (var1 == Block.mushroomBrown.blockID) { + return 8; + } else if (var1 == Block.mushroomRed.blockID) { + return 7; + } else if (var1 == Block.deadBush.blockID) { + return 10; + } else { + if (var1 == Block.sapling.blockID) { + switch (par0ItemStack.getItemDamage()) { + case 0: + return 3; + + case 1: + return 4; + + case 2: + return 5; + + case 3: + return 6; + } + } + + if (var1 == Block.tallGrass.blockID) { + switch (par0ItemStack.getItemDamage()) { + case 2: + return 11; + } + } + + return 0; + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockFlowing.java b/src/main/java/net/minecraft/src/BlockFlowing.java new file mode 100644 index 0000000..2259c58 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockFlowing.java @@ -0,0 +1,342 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockFlowing extends BlockFluid { + /** + * Number of horizontally adjacent liquid source blocks. Diagonal doesn't count. + * Only source blocks of the same liquid as the block using the field are + * counted. + */ + int numAdjacentSources = 0; + + /** + * Indicates whether the flow direction is optimal. Each array index corresponds + * to one of the four cardinal directions. + */ + boolean[] isOptimalFlowDirection = new boolean[4]; + + /** + * The estimated cost to flow in a given direction from the current point. Each + * array index corresponds to one of the four cardinal directions. + */ + int[] flowCost = new int[4]; + + protected BlockFlowing(int par1, Material par2Material) { + super(par1, par2Material); + } + + /** + * Updates the flow for the BlockFlowing object. + */ + private void updateFlow(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + par1World.setBlock(par2, par3, par4, this.blockID + 1, var5, 2); + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return this.blockMaterial != Material.lava; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + int var6 = this.getFlowDecay(par1World, par2, par3, par4); + byte var7 = 1; + + if (this.blockMaterial == Material.lava && !par1World.provider.isHellWorld) { + var7 = 2; + } + + boolean var8 = true; + int var10; + + if (var6 > 0) { + byte var9 = -100; + this.numAdjacentSources = 0; + int var12 = this.getSmallestFlowDecay(par1World, par2 - 1, par3, par4, var9); + var12 = this.getSmallestFlowDecay(par1World, par2 + 1, par3, par4, var12); + var12 = this.getSmallestFlowDecay(par1World, par2, par3, par4 - 1, var12); + var12 = this.getSmallestFlowDecay(par1World, par2, par3, par4 + 1, var12); + var10 = var12 + var7; + + if (var10 >= 8 || var12 < 0) { + var10 = -1; + } + + if (this.getFlowDecay(par1World, par2, par3 + 1, par4) >= 0) { + int var11 = this.getFlowDecay(par1World, par2, par3 + 1, par4); + + if (var11 >= 8) { + var10 = var11; + } else { + var10 = var11 + 8; + } + } + + if (this.numAdjacentSources >= 2 && this.blockMaterial == Material.water) { + if (par1World.getBlockMaterial(par2, par3 - 1, par4).isSolid()) { + var10 = 0; + } else if (par1World.getBlockMaterial(par2, par3 - 1, par4) == this.blockMaterial && par1World.getBlockMetadata(par2, par3 - 1, par4) == 0) { + var10 = 0; + } + } + + if (this.blockMaterial == Material.lava && var6 < 8 && var10 < 8 && var10 > var6 && par5Random.nextInt(4) != 0) { + var10 = var6; + var8 = false; + } + + if (var10 == var6) { + if (var8) { + this.updateFlow(par1World, par2, par3, par4); + } + } else { + var6 = var10; + + if (var10 < 0) { + par1World.setBlockToAir(par2, par3, par4); + } else { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var10, 2); + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + } + } + } else { + this.updateFlow(par1World, par2, par3, par4); + } + + if (this.liquidCanDisplaceBlock(par1World, par2, par3 - 1, par4)) { + if (this.blockMaterial == Material.lava && par1World.getBlockMaterial(par2, par3 - 1, par4) == Material.water) { + par1World.setBlock(par2, par3 - 1, par4, Block.stone.blockID); + this.triggerLavaMixEffects(par1World, par2, par3 - 1, par4); + return; + } + + if (var6 >= 8) { + this.flowIntoBlock(par1World, par2, par3 - 1, par4, var6); + } else { + this.flowIntoBlock(par1World, par2, par3 - 1, par4, var6 + 8); + } + } else if (var6 >= 0 && (var6 == 0 || this.blockBlocksFlow(par1World, par2, par3 - 1, par4))) { + boolean[] var13 = this.getOptimalFlowDirections(par1World, par2, par3, par4); + var10 = var6 + var7; + + if (var6 >= 8) { + var10 = 1; + } + + if (var10 >= 8) { + return; + } + + if (var13[0]) { + this.flowIntoBlock(par1World, par2 - 1, par3, par4, var10); + } + + if (var13[1]) { + this.flowIntoBlock(par1World, par2 + 1, par3, par4, var10); + } + + if (var13[2]) { + this.flowIntoBlock(par1World, par2, par3, par4 - 1, var10); + } + + if (var13[3]) { + this.flowIntoBlock(par1World, par2, par3, par4 + 1, var10); + } + } + } + + /** + * flowIntoBlock(World world, int x, int y, int z, int newFlowDecay) - Flows + * into the block at the coordinates and changes the block type to the liquid. + */ + private void flowIntoBlock(World par1World, int par2, int par3, int par4, int par5) { + if (this.liquidCanDisplaceBlock(par1World, par2, par3, par4)) { + int var6 = par1World.getBlockId(par2, par3, par4); + + if (var6 > 0) { + if (this.blockMaterial == Material.lava) { + this.triggerLavaMixEffects(par1World, par2, par3, par4); + } else { + Block.blocksList[var6].dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + } + } + + par1World.setBlock(par2, par3, par4, this.blockID, par5, 3); + } + } + + /** + * calculateFlowCost(World world, int x, int y, int z, int accumulatedCost, int + * previousDirectionOfFlow) - Used to determine the path of least resistance, + * this method returns the lowest possible flow cost for the direction of flow + * indicated. Each necessary horizontal flow adds to the flow cost. + */ + private int calculateFlowCost(World par1World, int par2, int par3, int par4, int par5, int par6) { + int var7 = 1000; + + for (int var8 = 0; var8 < 4; ++var8) { + if ((var8 != 0 || par6 != 1) && (var8 != 1 || par6 != 0) && (var8 != 2 || par6 != 3) && (var8 != 3 || par6 != 2)) { + int var9 = par2; + int var11 = par4; + + if (var8 == 0) { + var9 = par2 - 1; + } + + if (var8 == 1) { + ++var9; + } + + if (var8 == 2) { + var11 = par4 - 1; + } + + if (var8 == 3) { + ++var11; + } + + if (!this.blockBlocksFlow(par1World, var9, par3, var11) && (par1World.getBlockMaterial(var9, par3, var11) != this.blockMaterial || par1World.getBlockMetadata(var9, par3, var11) != 0)) { + if (!this.blockBlocksFlow(par1World, var9, par3 - 1, var11)) { + return par5; + } + + if (par5 < 4) { + int var12 = this.calculateFlowCost(par1World, var9, par3, var11, par5 + 1, var8); + + if (var12 < var7) { + var7 = var12; + } + } + } + } + } + + return var7; + } + + /** + * Returns a boolean array indicating which flow directions are optimal based on + * each direction's calculated flow cost. Each array index corresponds to one of + * the four cardinal directions. A value of true indicates the direction is + * optimal. + */ + private boolean[] getOptimalFlowDirections(World par1World, int par2, int par3, int par4) { + int var5; + int var6; + + for (var5 = 0; var5 < 4; ++var5) { + this.flowCost[var5] = 1000; + var6 = par2; + int var8 = par4; + + if (var5 == 0) { + var6 = par2 - 1; + } + + if (var5 == 1) { + ++var6; + } + + if (var5 == 2) { + var8 = par4 - 1; + } + + if (var5 == 3) { + ++var8; + } + + if (!this.blockBlocksFlow(par1World, var6, par3, var8) && (par1World.getBlockMaterial(var6, par3, var8) != this.blockMaterial || par1World.getBlockMetadata(var6, par3, var8) != 0)) { + if (this.blockBlocksFlow(par1World, var6, par3 - 1, var8)) { + this.flowCost[var5] = this.calculateFlowCost(par1World, var6, par3, var8, 1, var5); + } else { + this.flowCost[var5] = 0; + } + } + } + + var5 = this.flowCost[0]; + + for (var6 = 1; var6 < 4; ++var6) { + if (this.flowCost[var6] < var5) { + var5 = this.flowCost[var6]; + } + } + + for (var6 = 0; var6 < 4; ++var6) { + this.isOptimalFlowDirection[var6] = this.flowCost[var6] == var5; + } + + return this.isOptimalFlowDirection; + } + + /** + * Returns true if block at coords blocks fluids + */ + private boolean blockBlocksFlow(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockId(par2, par3, par4); + + if (var5 != Block.doorWood.blockID && var5 != Block.doorIron.blockID && var5 != Block.signPost.blockID && var5 != Block.ladder.blockID && var5 != Block.reed.blockID) { + if (var5 == 0) { + return false; + } else { + Material var6 = Block.blocksList[var5].blockMaterial; + return var6 == Material.portal ? true : var6.blocksMovement(); + } + } else { + return true; + } + } + + /** + * getSmallestFlowDecay(World world, intx, int y, int z, int + * currentSmallestFlowDecay) - Looks up the flow decay at the coordinates given + * and returns the smaller of this value or the provided + * currentSmallestFlowDecay. If one value is valid and the other isn't, the + * valid value will be returned. Valid values are >= 0. Flow decay is the amount + * that a liquid has dissipated. 0 indicates a source block. + */ + protected int getSmallestFlowDecay(World par1World, int par2, int par3, int par4, int par5) { + int var6 = this.getFlowDecay(par1World, par2, par3, par4); + + if (var6 < 0) { + return par5; + } else { + if (var6 == 0) { + ++this.numAdjacentSources; + } + + if (var6 >= 8) { + var6 = 0; + } + + return par5 >= 0 && var6 >= par5 ? par5 : var6; + } + } + + /** + * Returns true if the block at the coordinates can be displaced by the liquid. + */ + private boolean liquidCanDisplaceBlock(World par1World, int par2, int par3, int par4) { + Material var5 = par1World.getBlockMaterial(par2, par3, par4); + return var5 == this.blockMaterial ? false : (var5 == Material.lava ? false : !this.blockBlocksFlow(par1World, par2, par3, par4)); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + } + + public boolean func_82506_l() { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/BlockFluid.java b/src/main/java/net/minecraft/src/BlockFluid.java new file mode 100644 index 0000000..749ddc9 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockFluid.java @@ -0,0 +1,537 @@ +package net.minecraft.src; + +import java.util.Random; + + + +public abstract class BlockFluid extends Block { + private Icon[] theIcon; + + protected BlockFluid(int par1, Material par2Material) { + super(par1, par2Material); + float var3 = 0.0F; + float var4 = 0.0F; + this.setBlockBounds(0.0F + var4, 0.0F + var3, 0.0F + var4, 1.0F + var4, 1.0F + var3, 1.0F + var4); + this.setTickRandomly(true); + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return this.blockMaterial != Material.lava; + } + + public int getBlockColor() { + return 16777215; + } + + /** + * Returns a integer with hex for 0xrrggbb with this color multiplied against + * the blocks color. Note only called when first determining what to render. + */ + public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + if (this.blockMaterial != Material.water) { + return 16777215; + } else { + int var5 = 0; + int var6 = 0; + int var7 = 0; + + for (int var8 = -1; var8 <= 1; ++var8) { + for (int var9 = -1; var9 <= 1; ++var9) { + int var10 = par1IBlockAccess.getBiomeGenForCoords(par2 + var9, par4 + var8).waterColorMultiplier; + var5 += (var10 & 16711680) >> 16; + var6 += (var10 & 65280) >> 8; + var7 += var10 & 255; + } + } + + return (var5 / 9 & 255) << 16 | (var6 / 9 & 255) << 8 | var7 / 9 & 255; + } + } + + /** + * Returns the percentage of the fluid block that is air, based on the given + * flow decay of the fluid. + */ + public static float getFluidHeightPercent(int par0) { + if (par0 >= 8) { + par0 = 0; + } + + return (float) (par0 + 1) / 9.0F; + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 != 0 && par1 != 1 ? this.theIcon[1] : this.theIcon[0]; + } + + /** + * Returns the amount of fluid decay at the coordinates, or -1 if the block at + * the coordinates is not the same material as the fluid. + */ + protected int getFlowDecay(World par1World, int par2, int par3, int par4) { + return par1World.getBlockMaterial(par2, par3, par4) == this.blockMaterial ? par1World.getBlockMetadata(par2, par3, par4) : -1; + } + + /** + * Returns the flow decay but converts values indicating falling liquid (values + * >=8) to their effective source block value of zero. + */ + protected int getEffectiveFlowDecay(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + if (par1IBlockAccess.getBlockMaterial(par2, par3, par4) != this.blockMaterial) { + return -1; + } else { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if (var5 >= 8) { + var5 = 0; + } + + return var5; + } + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Returns whether this block is collideable based on the arguments passed in + * Args: blockMetaData, unknownFlag + */ + public boolean canCollideCheck(int par1, boolean par2) { + return par2 && par1 == 0; + } + + /** + * Returns Returns true if the given side of this block type should be rendered + * (if it's solid or not), if the adjacent block is at the given coordinates. + * Args: blockAccess, x, y, z, side + */ + public boolean isBlockSolid(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + Material var6 = par1IBlockAccess.getBlockMaterial(par2, par3, par4); + return var6 == this.blockMaterial ? false : (par5 == 1 ? true : (var6 == Material.ice ? false : super.isBlockSolid(par1IBlockAccess, par2, par3, par4, par5))); + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + Material var6 = par1IBlockAccess.getBlockMaterial(par2, par3, par4); + return var6 == this.blockMaterial ? false : (par5 == 1 ? true : (var6 == Material.ice ? false : super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5))); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 4; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return 0; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Returns a vector indicating the direction and intensity of fluid flow. + */ + private Vec3 getFlowVector(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + Vec3 var5 = par1IBlockAccess.getWorldVec3Pool().getVecFromPool(0.0D, 0.0D, 0.0D); + int var6 = this.getEffectiveFlowDecay(par1IBlockAccess, par2, par3, par4); + + for (int var7 = 0; var7 < 4; ++var7) { + int var8 = par2; + int var10 = par4; + + if (var7 == 0) { + var8 = par2 - 1; + } + + if (var7 == 1) { + var10 = par4 - 1; + } + + if (var7 == 2) { + ++var8; + } + + if (var7 == 3) { + ++var10; + } + + int var11 = this.getEffectiveFlowDecay(par1IBlockAccess, var8, par3, var10); + int var12; + + if (var11 < 0) { + if (!par1IBlockAccess.getBlockMaterial(var8, par3, var10).blocksMovement()) { + var11 = this.getEffectiveFlowDecay(par1IBlockAccess, var8, par3 - 1, var10); + + if (var11 >= 0) { + var12 = var11 - (var6 - 8); + var5 = var5.addVector((double) ((var8 - par2) * var12), (double) ((par3 - par3) * var12), (double) ((var10 - par4) * var12)); + } + } + } else if (var11 >= 0) { + var12 = var11 - var6; + var5 = var5.addVector((double) ((var8 - par2) * var12), (double) ((par3 - par3) * var12), (double) ((var10 - par4) * var12)); + } + } + + if (par1IBlockAccess.getBlockMetadata(par2, par3, par4) >= 8) { + boolean var13 = false; + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2, par3, par4 - 1, 2)) { + var13 = true; + } + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2, par3, par4 + 1, 3)) { + var13 = true; + } + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2 - 1, par3, par4, 4)) { + var13 = true; + } + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2 + 1, par3, par4, 5)) { + var13 = true; + } + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2, par3 + 1, par4 - 1, 2)) { + var13 = true; + } + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2, par3 + 1, par4 + 1, 3)) { + var13 = true; + } + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2 - 1, par3 + 1, par4, 4)) { + var13 = true; + } + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2 + 1, par3 + 1, par4, 5)) { + var13 = true; + } + + if (var13) { + var5 = var5.normalize().addVector(0.0D, -6.0D, 0.0D); + } + } + + var5 = var5.normalize(); + return var5; + } + + /** + * Can add to the passed in vector for a movement vector to be applied to the + * entity. Args: x, y, z, entity, vec3d + */ + public void velocityToAddToEntity(World par1World, int par2, int par3, int par4, Entity par5Entity, Vec3 par6Vec3) { + Vec3 var7 = this.getFlowVector(par1World, par2, par3, par4); + par6Vec3.xCoord += var7.xCoord; + par6Vec3.yCoord += var7.yCoord; + par6Vec3.zCoord += var7.zCoord; + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return this.blockMaterial == Material.water ? 5 : (this.blockMaterial == Material.lava ? (par1World.provider.hasNoSky ? 10 : 30) : 0); + } + + /** + * Goes straight to getLightBrightnessForSkyBlocks for Blocks, does some fancy + * computing for Fluids + */ + public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getLightBrightnessForSkyBlocks(par2, par3, par4, 0); + int var6 = par1IBlockAccess.getLightBrightnessForSkyBlocks(par2, par3 + 1, par4, 0); + int var7 = var5 & 255; + int var8 = var6 & 255; + int var9 = var5 >> 16 & 255; + int var10 = var6 >> 16 & 255; + return (var7 > var8 ? var7 : var8) | (var9 > var10 ? var9 : var10) << 16; + } + + /** + * How bright to render this block based on the light its receiving. Args: + * iBlockAccess, x, y, z + */ + public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + float var5 = par1IBlockAccess.getLightBrightness(par2, par3, par4); + float var6 = par1IBlockAccess.getLightBrightness(par2, par3 + 1, par4); + return var5 > var6 ? var5 : var6; + } + + /** + * Returns which pass should this block be rendered on. 0 for solids and 1 for + * alpha + */ + public int getRenderBlockPass() { + return this.blockMaterial == Material.water ? 1 : 0; + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + int var6; + + if (this.blockMaterial == Material.water) { + if (par5Random.nextInt(10) == 0) { + var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (var6 <= 0 || var6 >= 8) { + par1World.spawnParticle("suspended", (double) ((float) par2 + par5Random.nextFloat()), (double) ((float) par3 + par5Random.nextFloat()), (double) ((float) par4 + par5Random.nextFloat()), 0.0D, 0.0D, 0.0D); + } + } + + for (var6 = 0; var6 < 0; ++var6) { + int var7 = par5Random.nextInt(4); + int var8 = par2; + int var9 = par4; + + if (var7 == 0) { + var8 = par2 - 1; + } + + if (var7 == 1) { + ++var8; + } + + if (var7 == 2) { + var9 = par4 - 1; + } + + if (var7 == 3) { + ++var9; + } + + if (par1World.getBlockMaterial(var8, par3, var9) == Material.air && (par1World.getBlockMaterial(var8, par3 - 1, var9).blocksMovement() || par1World.getBlockMaterial(var8, par3 - 1, var9).isLiquid())) { + float var10 = 0.0625F; + double var11 = (double) ((float) par2 + par5Random.nextFloat()); + double var13 = (double) ((float) par3 + par5Random.nextFloat()); + double var15 = (double) ((float) par4 + par5Random.nextFloat()); + + if (var7 == 0) { + var11 = (double) ((float) par2 - var10); + } + + if (var7 == 1) { + var11 = (double) ((float) (par2 + 1) + var10); + } + + if (var7 == 2) { + var15 = (double) ((float) par4 - var10); + } + + if (var7 == 3) { + var15 = (double) ((float) (par4 + 1) + var10); + } + + double var17 = 0.0D; + double var19 = 0.0D; + + if (var7 == 0) { + var17 = (double) (-var10); + } + + if (var7 == 1) { + var17 = (double) var10; + } + + if (var7 == 2) { + var19 = (double) (-var10); + } + + if (var7 == 3) { + var19 = (double) var10; + } + + par1World.spawnParticle("splash", var11, var13, var15, var17, 0.0D, var19); + } + } + } + + if (this.blockMaterial == Material.water && par5Random.nextInt(64) == 0) { + var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (var6 > 0 && var6 < 8) { + par1World.playSound((double) ((float) par2 + 0.5F), (double) ((float) par3 + 0.5F), (double) ((float) par4 + 0.5F), "liquid.water", par5Random.nextFloat() * 0.25F + 0.75F, par5Random.nextFloat() * 1.0F + 0.5F, false); + } + } + + double var21; + double var22; + double var23; + + if (this.blockMaterial == Material.lava && par1World.getBlockMaterial(par2, par3 + 1, par4) == Material.air && !par1World.isBlockOpaqueCube(par2, par3 + 1, par4)) { + if (par5Random.nextInt(100) == 0) { + var21 = (double) ((float) par2 + par5Random.nextFloat()); + var22 = (double) par3 + this.maxY; + var23 = (double) ((float) par4 + par5Random.nextFloat()); + par1World.spawnParticle("lava", var21, var22, var23, 0.0D, 0.0D, 0.0D); + par1World.playSound(var21, var22, var23, "liquid.lavapop", 0.2F + par5Random.nextFloat() * 0.2F, 0.9F + par5Random.nextFloat() * 0.15F, false); + } + + if (par5Random.nextInt(200) == 0) { + par1World.playSound((double) par2, (double) par3, (double) par4, "liquid.lava", 0.2F + par5Random.nextFloat() * 0.2F, 0.9F + par5Random.nextFloat() * 0.15F, false); + } + } + + if (par5Random.nextInt(10) == 0 && par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) && !par1World.getBlockMaterial(par2, par3 - 2, par4).blocksMovement()) { + var21 = (double) ((float) par2 + par5Random.nextFloat()); + var22 = (double) par3 - 1.05D; + var23 = (double) ((float) par4 + par5Random.nextFloat()); + + if (this.blockMaterial == Material.water) { + par1World.spawnParticle("dripWater", var21, var22, var23, 0.0D, 0.0D, 0.0D); + } else { + par1World.spawnParticle("dripLava", var21, var22, var23, 0.0D, 0.0D, 0.0D); + } + } + } + + /** + * the sin and cos of this number determine the surface gradient of the flowing + * block. + */ + public static double getFlowDirection(IBlockAccess par0IBlockAccess, int par1, int par2, int par3, Material par4Material) { + Vec3 var5 = null; + + if (par4Material == Material.water) { + var5 = Block.waterMoving.getFlowVector(par0IBlockAccess, par1, par2, par3); + } + + if (par4Material == Material.lava) { + var5 = Block.lavaMoving.getFlowVector(par0IBlockAccess, par1, par2, par3); + } + + return var5.xCoord == 0.0D && var5.zCoord == 0.0D ? -1000.0D : Math.atan2(var5.zCoord, var5.xCoord) - (Math.PI / 2D); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + this.checkForHarden(par1World, par2, par3, par4); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + this.checkForHarden(par1World, par2, par3, par4); + } + + /** + * Forces lava to check to see if it is colliding with water, and then decide + * what it should harden to. + */ + private void checkForHarden(World par1World, int par2, int par3, int par4) { + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + if (this.blockMaterial == Material.lava) { + boolean var5 = false; + + if (var5 || par1World.getBlockMaterial(par2, par3, par4 - 1) == Material.water) { + var5 = true; + } + + if (var5 || par1World.getBlockMaterial(par2, par3, par4 + 1) == Material.water) { + var5 = true; + } + + if (var5 || par1World.getBlockMaterial(par2 - 1, par3, par4) == Material.water) { + var5 = true; + } + + if (var5 || par1World.getBlockMaterial(par2 + 1, par3, par4) == Material.water) { + var5 = true; + } + + if (var5 || par1World.getBlockMaterial(par2, par3 + 1, par4) == Material.water) { + var5 = true; + } + + if (var5) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (var6 == 0) { + par1World.setBlock(par2, par3, par4, Block.obsidian.blockID); + } else if (var6 <= 4) { + par1World.setBlock(par2, par3, par4, Block.cobblestone.blockID); + } + + this.triggerLavaMixEffects(par1World, par2, par3, par4); + } + } + } + } + + /** + * Creates fizzing sound and smoke. Used when lava flows over block or mixes + * with water. + */ + protected void triggerLavaMixEffects(World par1World, int par2, int par3, int par4) { + par1World.playSoundEffect((double) ((float) par2 + 0.5F), (double) ((float) par3 + 0.5F), (double) ((float) par4 + 0.5F), "random.fizz", 0.5F, 2.6F + (par1World.rand.nextFloat() - par1World.rand.nextFloat()) * 0.8F); + + for (int var5 = 0; var5 < 8; ++var5) { + par1World.spawnParticle("largesmoke", (double) par2 + Math.random(), (double) par3 + 1.2D, (double) par4 + Math.random(), 0.0D, 0.0D, 0.0D); + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + if (this.blockMaterial == Material.lava) { + this.theIcon = new Icon[] { par1IconRegister.registerIcon("lava"), par1IconRegister.registerIcon("lava_flow") }; + } else { + this.theIcon = new Icon[] { par1IconRegister.registerIcon("water"), par1IconRegister.registerIcon("water_flow") }; + } + } + + public static Icon func_94424_b(String par0Str) { + return par0Str == "water" ? Block.waterMoving.theIcon[0] : (par0Str == "water_flow" ? Block.waterMoving.theIcon[1] : (par0Str == "lava" ? Block.lavaMoving.theIcon[0] : (par0Str == "lava_flow" ? Block.lavaMoving.theIcon[1] : null))); + } +} diff --git a/src/main/java/net/minecraft/src/BlockFurnace.java b/src/main/java/net/minecraft/src/BlockFurnace.java new file mode 100644 index 0000000..2186687 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockFurnace.java @@ -0,0 +1,271 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockFurnace extends BlockContainer { + /** + * Is the random generator used by furnace to drop the inventory contents in + * random directions. + */ + private final Random furnaceRand = new Random(); + + /** True if this is an active furnace, false if idle */ + private final boolean isActive; + + /** + * This flag is used to prevent the furnace inventory to be dropped upon block + * removal, is used internally when the furnace block changes from idle to + * active and vice-versa. + */ + private static boolean keepFurnaceInventory = false; + private Icon furnaceIconTop; + private Icon furnaceIconFront; + + protected BlockFurnace(int par1, boolean par2) { + super(par1, Material.rock); + this.isActive = par2; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.furnaceIdle.blockID; + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + this.setDefaultDirection(par1World, par2, par3, par4); + } + + /** + * set a blocks direction + */ + private void setDefaultDirection(World par1World, int par2, int par3, int par4) { + if (!par1World.isRemote) { + int var5 = par1World.getBlockId(par2, par3, par4 - 1); + int var6 = par1World.getBlockId(par2, par3, par4 + 1); + int var7 = par1World.getBlockId(par2 - 1, par3, par4); + int var8 = par1World.getBlockId(par2 + 1, par3, par4); + byte var9 = 3; + + if (Block.opaqueCubeLookup[var5] && !Block.opaqueCubeLookup[var6]) { + var9 = 3; + } + + if (Block.opaqueCubeLookup[var6] && !Block.opaqueCubeLookup[var5]) { + var9 = 2; + } + + if (Block.opaqueCubeLookup[var7] && !Block.opaqueCubeLookup[var8]) { + var9 = 5; + } + + if (Block.opaqueCubeLookup[var8] && !Block.opaqueCubeLookup[var7]) { + var9 = 4; + } + + par1World.setBlockMetadataWithNotify(par2, par3, par4, var9, 2); + } + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 1 ? this.furnaceIconTop : (par1 == 0 ? this.furnaceIconTop : (par1 != par2 ? this.blockIcon : this.furnaceIconFront)); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("furnace_side"); + this.furnaceIconFront = par1IconRegister.registerIcon(this.isActive ? "furnace_front_lit" : "furnace_front"); + this.furnaceIconTop = par1IconRegister.registerIcon("furnace_top"); + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (this.isActive) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + float var7 = (float) par2 + 0.5F; + float var8 = (float) par3 + 0.0F + par5Random.nextFloat() * 6.0F / 16.0F; + float var9 = (float) par4 + 0.5F; + float var10 = 0.52F; + float var11 = par5Random.nextFloat() * 0.6F - 0.3F; + + if (var6 == 4) { + par1World.spawnParticle("smoke", (double) (var7 - var10), (double) var8, (double) (var9 + var11), 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("flame", (double) (var7 - var10), (double) var8, (double) (var9 + var11), 0.0D, 0.0D, 0.0D); + } else if (var6 == 5) { + par1World.spawnParticle("smoke", (double) (var7 + var10), (double) var8, (double) (var9 + var11), 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("flame", (double) (var7 + var10), (double) var8, (double) (var9 + var11), 0.0D, 0.0D, 0.0D); + } else if (var6 == 2) { + par1World.spawnParticle("smoke", (double) (var7 + var11), (double) var8, (double) (var9 - var10), 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("flame", (double) (var7 + var11), (double) var8, (double) (var9 - var10), 0.0D, 0.0D, 0.0D); + } else if (var6 == 3) { + par1World.spawnParticle("smoke", (double) (var7 + var11), (double) var8, (double) (var9 + var10), 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("flame", (double) (var7 + var11), (double) var8, (double) (var9 + var10), 0.0D, 0.0D, 0.0D); + } + } + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + TileEntityFurnace var10 = (TileEntityFurnace) par1World.getBlockTileEntity(par2, par3, par4); + + if (var10 != null) { + par5EntityPlayer.displayGUIFurnace(var10); + } + + return true; + } + } + + /** + * Update which block ID the furnace is using depending on whether or not it is + * burning + */ + public static void updateFurnaceBlockState(boolean par0, World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + TileEntity var6 = par1World.getBlockTileEntity(par2, par3, par4); + keepFurnaceInventory = true; + + if (par0) { + par1World.setBlock(par2, par3, par4, Block.furnaceBurning.blockID); + } else { + par1World.setBlock(par2, par3, par4, Block.furnaceIdle.blockID); + } + + keepFurnaceInventory = false; + par1World.setBlockMetadataWithNotify(par2, par3, par4, var5, 2); + + if (var6 != null) { + var6.validate(); + par1World.setBlockTileEntity(par2, par3, par4, var6); + } + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityFurnace(); + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + int var7 = MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + + if (var7 == 0) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 2, 2); + } + + if (var7 == 1) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 5, 2); + } + + if (var7 == 2) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 3, 2); + } + + if (var7 == 3) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 4, 2); + } + + if (par6ItemStack.hasDisplayName()) { + ((TileEntityFurnace) par1World.getBlockTileEntity(par2, par3, par4)).func_94129_a(par6ItemStack.getDisplayName()); + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + if (!keepFurnaceInventory) { + TileEntityFurnace var7 = (TileEntityFurnace) par1World.getBlockTileEntity(par2, par3, par4); + + if (var7 != null) { + for (int var8 = 0; var8 < var7.getSizeInventory(); ++var8) { + ItemStack var9 = var7.getStackInSlot(var8); + + if (var9 != null) { + float var10 = this.furnaceRand.nextFloat() * 0.8F + 0.1F; + float var11 = this.furnaceRand.nextFloat() * 0.8F + 0.1F; + float var12 = this.furnaceRand.nextFloat() * 0.8F + 0.1F; + + while (var9.stackSize > 0) { + int var13 = this.furnaceRand.nextInt(21) + 10; + + if (var13 > var9.stackSize) { + var13 = var9.stackSize; + } + + var9.stackSize -= var13; + EntityItem var14 = new EntityItem(par1World, (double) ((float) par2 + var10), (double) ((float) par3 + var11), (double) ((float) par4 + var12), new ItemStack(var9.itemID, var13, var9.getItemDamage())); + + if (var9.hasTagCompound()) { + var14.getEntityItem().setTagCompound((NBTTagCompound) var9.getTagCompound().copy()); + } + + float var15 = 0.05F; + var14.motionX = (double) ((float) this.furnaceRand.nextGaussian() * var15); + var14.motionY = (double) ((float) this.furnaceRand.nextGaussian() * var15 + 0.2F); + var14.motionZ = (double) ((float) this.furnaceRand.nextGaussian() * var15); + par1World.spawnEntityInWorld(var14); + } + } + } + + par1World.func_96440_m(par2, par3, par4, par5); + } + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + return Container.calcRedstoneFromInventory((IInventory) par1World.getBlockTileEntity(par2, par3, par4)); + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Block.furnaceIdle.blockID; + } +} diff --git a/src/main/java/net/minecraft/src/BlockGlass.java b/src/main/java/net/minecraft/src/BlockGlass.java new file mode 100644 index 0000000..3262c85 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockGlass.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockGlass extends BlockBreakable { + public BlockGlass(int par1, Material par2Material, boolean par3) { + super(par1, "glass", par2Material, par3); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Returns which pass should this block be rendered on. 0 for solids and 1 for + * alpha + */ + public int getRenderBlockPass() { + return 0; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Return true if a player with Silk Touch can harvest this block directly, and + * not its normal drops. + */ + protected boolean canSilkHarvest() { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/BlockGlowStone.java b/src/main/java/net/minecraft/src/BlockGlowStone.java new file mode 100644 index 0000000..a57eaa6 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockGlowStone.java @@ -0,0 +1,32 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockGlowStone extends Block { + public BlockGlowStone(int par1, Material par2Material) { + super(par1, par2Material); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the usual quantity dropped by the block plus a bonus of 1 to 'i' + * (inclusive). + */ + public int quantityDroppedWithBonus(int par1, Random par2Random) { + return MathHelper.clamp_int(this.quantityDropped(par2Random) + par2Random.nextInt(par1 + 1), 1, 4); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 2 + par1Random.nextInt(3); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.lightStoneDust.itemID; + } +} diff --git a/src/main/java/net/minecraft/src/BlockGrass.java b/src/main/java/net/minecraft/src/BlockGrass.java new file mode 100644 index 0000000..84aecc3 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockGrass.java @@ -0,0 +1,125 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockGrass extends Block { + private Icon iconGrassTop; + private Icon iconSnowSide; + private Icon iconGrassSideOverlay; + + protected BlockGrass(int par1) { + super(par1, Material.grass); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 1 ? this.iconGrassTop : (par1 == 0 ? Block.dirt.getBlockTextureFromSide(par1) : this.blockIcon); + } + + /** + * Retrieves the block texture to use based on the display side. Args: + * iBlockAccess, x, y, z, side + */ + public Icon getBlockTexture(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + if (par5 == 1) { + return this.iconGrassTop; + } else if (par5 == 0) { + return Block.dirt.getBlockTextureFromSide(par5); + } else { + Material var6 = par1IBlockAccess.getBlockMaterial(par2, par3 + 1, par4); + return var6 != Material.snow && var6 != Material.craftedSnow ? this.blockIcon : this.iconSnowSide; + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("grass_side"); + this.iconGrassTop = par1IconRegister.registerIcon("grass_top"); + this.iconSnowSide = par1IconRegister.registerIcon("snow_side"); + this.iconGrassSideOverlay = par1IconRegister.registerIcon("grass_side_overlay"); + } + + public int getBlockColor() { + double var1 = 0.5D; + double var3 = 1.0D; + return ColorizerGrass.getGrassColor(var1, var3); + } + + /** + * Returns the color this block should be rendered. Used by leaves. + */ + public int getRenderColor(int par1) { + return this.getBlockColor(); + } + + /** + * Returns a integer with hex for 0xrrggbb with this color multiplied against + * the blocks color. Note only called when first determining what to render. + */ + public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = 0; + int var6 = 0; + int var7 = 0; + + for (int var8 = -1; var8 <= 1; ++var8) { + for (int var9 = -1; var9 <= 1; ++var9) { + int var10 = par1IBlockAccess.getBiomeGenForCoords(par2 + var9, par4 + var8).getBiomeGrassColor(); + var5 += (var10 & 16711680) >> 16; + var6 += (var10 & 65280) >> 8; + var7 += var10 & 255; + } + } + + initNoiseField(par2 >> 4, par4 >> 4); + float noise = (float)(grassNoiseArray[(par4 & 15) + (par2 & 15) * 16]) * 0.15F + 1.0F; + + var6 = (int)((var6 / 9) * noise); + + if(var6 > 255) var6 = 255; + if(var6 < 0) var6 = 0; + + return ((var5 / 9) & 255) << 16 | (var6 & 255) << 8 | (var7 / 9) & 255; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + if (par1World.getBlockLightValue(par2, par3 + 1, par4) < 4 && Block.lightOpacity[par1World.getBlockId(par2, par3 + 1, par4)] > 2) { + par1World.setBlock(par2, par3, par4, Block.dirt.blockID); + } else if (par1World.getBlockLightValue(par2, par3 + 1, par4) >= 9) { + for (int var6 = 0; var6 < 4; ++var6) { + int var7 = par2 + par5Random.nextInt(3) - 1; + int var8 = par3 + par5Random.nextInt(5) - 3; + int var9 = par4 + par5Random.nextInt(3) - 1; + int var10 = par1World.getBlockId(var7, var8 + 1, var9); + + if (par1World.getBlockId(var7, var8, var9) == Block.dirt.blockID && par1World.getBlockLightValue(var7, var8 + 1, var9) >= 4 && Block.lightOpacity[var10] <= 2) { + par1World.setBlock(var7, var8, var9, Block.grass.blockID); + } + } + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.dirt.idDropped(0, par2Random, par3); + } + + public static Icon getIconSideOverlay() { + return Block.grass.iconGrassSideOverlay; + } +} diff --git a/src/main/java/net/minecraft/src/BlockGravel.java b/src/main/java/net/minecraft/src/BlockGravel.java new file mode 100644 index 0000000..bb817ed --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockGravel.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockGravel extends BlockSand { + public BlockGravel(int par1) { + super(par1); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + if (par3 > 3) { + par3 = 3; + } + + return par2Random.nextInt(10 - par3 * 3) == 0 ? Item.flint.itemID : this.blockID; + } +} diff --git a/src/main/java/net/minecraft/src/BlockHalfSlab.java b/src/main/java/net/minecraft/src/BlockHalfSlab.java new file mode 100644 index 0000000..303bdbb --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockHalfSlab.java @@ -0,0 +1,151 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public abstract class BlockHalfSlab extends Block { + protected final boolean isDoubleSlab; + + public BlockHalfSlab(int par1, boolean par2, Material par3Material) { + super(par1, par3Material); + this.isDoubleSlab = par2; + + if (par2) { + opaqueCubeLookup[par1] = true; + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); + } + + this.setLightOpacity(255); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + if (this.isDoubleSlab) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } else { + boolean var5 = (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) != 0; + + if (var5) { + this.setBlockBounds(0.0F, 0.5F, 0.0F, 1.0F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); + } + } + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + if (this.isDoubleSlab) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); + } + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return this.isDoubleSlab; + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9) { + return this.isDoubleSlab ? par9 : (par5 != 0 && (par5 == 1 || (double) par7 <= 0.5D) ? par9 : par9 | 8); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return this.isDoubleSlab ? 2 : 1; + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1 & 7; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return this.isDoubleSlab; + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + if (this.isDoubleSlab) { + return super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5); + } else if (par5 != 1 && par5 != 0 && !super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5)) { + return false; + } else { + int var6 = par2 + Facing.offsetsXForSide[Facing.oppositeSide[par5]]; + int var7 = par3 + Facing.offsetsYForSide[Facing.oppositeSide[par5]]; + int var8 = par4 + Facing.offsetsZForSide[Facing.oppositeSide[par5]]; + boolean var9 = (par1IBlockAccess.getBlockMetadata(var6, var7, var8) & 8) != 0; + return var9 + ? (par5 == 0 ? true + : (par5 == 1 && super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5) ? true + : !isBlockSingleSlab(par1IBlockAccess.getBlockId(par2, par3, par4)) || (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) == 0)) + : (par5 == 1 ? true + : (par5 == 0 && super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5) ? true + : !isBlockSingleSlab(par1IBlockAccess.getBlockId(par2, par3, par4)) || (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) != 0)); + } + } + + /** + * Takes a block ID, returns true if it's the same as the ID for a stone or + * wooden single slab. + */ + private static boolean isBlockSingleSlab(int par0) { + return par0 == Block.stoneSingleSlab.blockID || par0 == Block.woodSingleSlab.blockID; + } + + /** + * Returns the slab block name with step type. + */ + public abstract String getFullSlabName(int var1); + + /** + * Get the block's damage value (for use with pick block). + */ + public int getDamageValue(World par1World, int par2, int par3, int par4) { + return super.getDamageValue(par1World, par2, par3, par4) & 7; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return isBlockSingleSlab(this.blockID) ? this.blockID + : (this.blockID == Block.stoneDoubleSlab.blockID ? Block.stoneSingleSlab.blockID : (this.blockID == Block.woodDoubleSlab.blockID ? Block.woodSingleSlab.blockID : Block.stoneSingleSlab.blockID)); + } +} diff --git a/src/main/java/net/minecraft/src/BlockHopper.java b/src/main/java/net/minecraft/src/BlockHopper.java new file mode 100644 index 0000000..7456e6a --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockHopper.java @@ -0,0 +1,264 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockHopper extends BlockContainer { + private final Random field_94457_a = new Random(); + private Icon hopperIcon; + private Icon hopperTopIcon; + private Icon hopperInsideIcon; + + public BlockHopper(int par1) { + super(par1, Material.iron); + this.setCreativeTab(CreativeTabs.tabRedstone); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.625F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + float var8 = 0.125F; + this.setBlockBounds(0.0F, 0.0F, 0.0F, var8, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var8); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(1.0F - var8, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.0F, 0.0F, 1.0F - var8, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9) { + int var10 = Facing.oppositeSide[par5]; + + if (var10 == 1) { + var10 = 0; + } + + return var10; + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityHopper(); + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + super.onBlockPlacedBy(par1World, par2, par3, par4, par5EntityLiving, par6ItemStack); + + if (par6ItemStack.hasDisplayName()) { + TileEntityHopper var7 = getHopperTile(par1World, par2, par3, par4); + var7.setInventoryName(par6ItemStack.getDisplayName()); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + this.updateMetadata(par1World, par2, par3, par4); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + TileEntityHopper var10 = getHopperTile(par1World, par2, par3, par4); + + if (var10 != null) { + par5EntityPlayer.displayGUIHopper(var10); + } + + return true; + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + this.updateMetadata(par1World, par2, par3, par4); + } + + /** + * Updates the Metadata to include if the Hopper gets powered by Redstone or not + */ + private void updateMetadata(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + int var6 = getDirectionFromMetadata(var5); + boolean var7 = !par1World.isBlockIndirectlyGettingPowered(par2, par3, par4); + boolean var8 = getIsBlockNotPoweredFromMetadata(var5); + + if (var7 != var8) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 | (var7 ? 0 : 8), 4); + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + TileEntityHopper var7 = (TileEntityHopper) par1World.getBlockTileEntity(par2, par3, par4); + + if (var7 != null) { + for (int var8 = 0; var8 < var7.getSizeInventory(); ++var8) { + ItemStack var9 = var7.getStackInSlot(var8); + + if (var9 != null) { + float var10 = this.field_94457_a.nextFloat() * 0.8F + 0.1F; + float var11 = this.field_94457_a.nextFloat() * 0.8F + 0.1F; + float var12 = this.field_94457_a.nextFloat() * 0.8F + 0.1F; + + while (var9.stackSize > 0) { + int var13 = this.field_94457_a.nextInt(21) + 10; + + if (var13 > var9.stackSize) { + var13 = var9.stackSize; + } + + var9.stackSize -= var13; + EntityItem var14 = new EntityItem(par1World, (double) ((float) par2 + var10), (double) ((float) par3 + var11), (double) ((float) par4 + var12), new ItemStack(var9.itemID, var13, var9.getItemDamage())); + + if (var9.hasTagCompound()) { + var14.getEntityItem().setTagCompound((NBTTagCompound) var9.getTagCompound().copy()); + } + + float var15 = 0.05F; + var14.motionX = (double) ((float) this.field_94457_a.nextGaussian() * var15); + var14.motionY = (double) ((float) this.field_94457_a.nextGaussian() * var15 + 0.2F); + var14.motionZ = (double) ((float) this.field_94457_a.nextGaussian() * var15); + par1World.spawnEntityInWorld(var14); + } + } + } + + par1World.func_96440_m(par2, par3, par4, par5); + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 38; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return true; + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 1 ? this.hopperTopIcon : this.hopperIcon; + } + + public static int getDirectionFromMetadata(int par0) { + return par0 & 7; + } + + public static boolean getIsBlockNotPoweredFromMetadata(int par0) { + return (par0 & 8) != 8; + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + return Container.calcRedstoneFromInventory(getHopperTile(par1World, par2, par3, par4)); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.hopperIcon = par1IconRegister.registerIcon("hopper"); + this.hopperTopIcon = par1IconRegister.registerIcon("hopper_top"); + this.hopperInsideIcon = par1IconRegister.registerIcon("hopper_inside"); + } + + public static Icon getHopperIcon(String par0Str) { + return par0Str == "hopper" ? Block.hopperBlock.hopperIcon : (par0Str == "hopper_inside" ? Block.hopperBlock.hopperInsideIcon : null); + } + + /** + * Gets the icon name of the ItemBlock corresponding to this block. Used by + * hoppers. + */ + public String getItemIconName() { + return "hopper"; + } + + public static TileEntityHopper getHopperTile(IBlockAccess par0IBlockAccess, int par1, int par2, int par3) { + return (TileEntityHopper) par0IBlockAccess.getBlockTileEntity(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/BlockIce.java b/src/main/java/net/minecraft/src/BlockIce.java new file mode 100644 index 0000000..48e6992 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockIce.java @@ -0,0 +1,87 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockIce extends BlockBreakable { + public BlockIce(int par1) { + super(par1, "ice", Material.ice, false); + this.slipperiness = 0.98F; + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns which pass should this block be rendered on. 0 for solids and 1 for + * alpha + */ + public int getRenderBlockPass() { + return 1; + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, 1 - par5); + } + + /** + * Called when the player destroys a block with an item that can harvest it. (i, + * j, k) are the coordinates of the block and l is the block's subtype/damage. + */ + public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) { + par2EntityPlayer.addExhaustion(0.025F); + + if (this.canSilkHarvest() && EnchantmentHelper.getSilkTouchModifier(par2EntityPlayer)) { + ItemStack var9 = this.createStackedBlock(par6); + + if (var9 != null) { + this.dropBlockAsItem_do(par1World, par3, par4, par5, var9); + } + } else { + if (par1World.provider.isHellWorld) { + par1World.setBlockToAir(par3, par4, par5); + return; + } + + int var7 = EnchantmentHelper.getFortuneModifier(par2EntityPlayer); + this.dropBlockAsItem(par1World, par3, par4, par5, par6, var7); + Material var8 = par1World.getBlockMaterial(par3, par4 - 1, par5); + + if (var8.blocksMovement() || var8.isLiquid()) { + par1World.setBlock(par3, par4, par5, Block.waterMoving.blockID); + } + } + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par1World.getSavedLightValue(EnumSkyBlock.Block, par2, par3, par4) > 11 - Block.lightOpacity[this.blockID]) { + if (par1World.provider.isHellWorld) { + par1World.setBlockToAir(par2, par3, par4); + return; + } + + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlock(par2, par3, par4, Block.waterStill.blockID); + } + } + + /** + * Returns the mobility information of the block, 0 = free, 1 = can't push but + * can move over, 2 = total immobility and stop pistons + */ + public int getMobilityFlag() { + return 0; + } +} diff --git a/src/main/java/net/minecraft/src/BlockJukeBox.java b/src/main/java/net/minecraft/src/BlockJukeBox.java new file mode 100644 index 0000000..10a54fb --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockJukeBox.java @@ -0,0 +1,127 @@ +package net.minecraft.src; + +public class BlockJukeBox extends BlockContainer { + private Icon theIcon; + + protected BlockJukeBox(int par1) { + super(par1, Material.wood); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 1 ? this.theIcon : this.blockIcon; + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (par1World.getBlockMetadata(par2, par3, par4) == 0) { + return false; + } else { + this.ejectRecord(par1World, par2, par3, par4); + return true; + } + } + + /** + * Insert the specified music disc in the jukebox at the given coordinates + */ + public void insertRecord(World par1World, int par2, int par3, int par4, ItemStack par5ItemStack) { + if (!par1World.isRemote) { + TileEntityRecordPlayer var6 = (TileEntityRecordPlayer) par1World.getBlockTileEntity(par2, par3, par4); + + if (var6 != null) { + var6.func_96098_a(par5ItemStack.copy()); + par1World.setBlockMetadataWithNotify(par2, par3, par4, 1, 2); + } + } + } + + /** + * Ejects the current record inside of the jukebox. + */ + public void ejectRecord(World par1World, int par2, int par3, int par4) { + if (!par1World.isRemote) { + TileEntityRecordPlayer var5 = (TileEntityRecordPlayer) par1World.getBlockTileEntity(par2, par3, par4); + + if (var5 != null) { + ItemStack var6 = var5.func_96097_a(); + + if (var6 != null) { + par1World.playAuxSFX(1005, par2, par3, par4, 0); + par1World.playRecord((String) null, par2, par3, par4); + var5.func_96098_a((ItemStack) null); + par1World.setBlockMetadataWithNotify(par2, par3, par4, 0, 2); + float var7 = 0.7F; + double var8 = (double) (par1World.rand.nextFloat() * var7) + (double) (1.0F - var7) * 0.5D; + double var10 = (double) (par1World.rand.nextFloat() * var7) + (double) (1.0F - var7) * 0.2D + 0.6D; + double var12 = (double) (par1World.rand.nextFloat() * var7) + (double) (1.0F - var7) * 0.5D; + ItemStack var14 = var6.copy(); + EntityItem var15 = new EntityItem(par1World, (double) par2 + var8, (double) par3 + var10, (double) par4 + var12, var14); + var15.delayBeforeCanPickup = 10; + par1World.spawnEntityInWorld(var15); + } + } + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + this.ejectRecord(par1World, par2, par3, par4); + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + if (!par1World.isRemote) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0); + } + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityRecordPlayer(); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("musicBlock"); + this.theIcon = par1IconRegister.registerIcon("jukebox_top"); + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + ItemStack var6 = ((TileEntityRecordPlayer) par1World.getBlockTileEntity(par2, par3, par4)).func_96097_a(); + return var6 == null ? 0 : var6.itemID + 1 - Item.record13.itemID; + } +} diff --git a/src/main/java/net/minecraft/src/BlockLadder.java b/src/main/java/net/minecraft/src/BlockLadder.java new file mode 100644 index 0000000..2c62a99 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockLadder.java @@ -0,0 +1,156 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockLadder extends Block { + protected BlockLadder(int par1) { + super(par1, Material.circuits); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Returns the bounding box of the wired rectangular prism to render. + */ + public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getSelectedBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.updateLadderBounds(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + /** + * Update the ladder block bounds based on the given metadata value. + */ + public void updateLadderBounds(int par1) { + float var3 = 0.125F; + + if (par1 == 2) { + this.setBlockBounds(0.0F, 0.0F, 1.0F - var3, 1.0F, 1.0F, 1.0F); + } + + if (par1 == 3) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var3); + } + + if (par1 == 4) { + this.setBlockBounds(1.0F - var3, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + if (par1 == 5) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, var3, 1.0F, 1.0F); + } + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 8; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.isBlockNormalCube(par2 - 1, par3, par4) ? true + : (par1World.isBlockNormalCube(par2 + 1, par3, par4) ? true : (par1World.isBlockNormalCube(par2, par3, par4 - 1) ? true : par1World.isBlockNormalCube(par2, par3, par4 + 1))); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9) { + int var10 = par9; + + if ((par9 == 0 || par5 == 2) && par1World.isBlockNormalCube(par2, par3, par4 + 1)) { + var10 = 2; + } + + if ((var10 == 0 || par5 == 3) && par1World.isBlockNormalCube(par2, par3, par4 - 1)) { + var10 = 3; + } + + if ((var10 == 0 || par5 == 4) && par1World.isBlockNormalCube(par2 + 1, par3, par4)) { + var10 = 4; + } + + if ((var10 == 0 || par5 == 5) && par1World.isBlockNormalCube(par2 - 1, par3, par4)) { + var10 = 5; + } + + return var10; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + boolean var7 = false; + + if (var6 == 2 && par1World.isBlockNormalCube(par2, par3, par4 + 1)) { + var7 = true; + } + + if (var6 == 3 && par1World.isBlockNormalCube(par2, par3, par4 - 1)) { + var7 = true; + } + + if (var6 == 4 && par1World.isBlockNormalCube(par2 + 1, par3, par4)) { + var7 = true; + } + + if (var6 == 5 && par1World.isBlockNormalCube(par2 - 1, par3, par4)) { + var7 = true; + } + + if (!var7) { + this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0); + par1World.setBlockToAir(par2, par3, par4); + } + + super.onNeighborBlockChange(par1World, par2, par3, par4, par5); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } +} diff --git a/src/main/java/net/minecraft/src/BlockLeaves.java b/src/main/java/net/minecraft/src/BlockLeaves.java new file mode 100644 index 0000000..bf78d5d --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockLeaves.java @@ -0,0 +1,331 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockLeaves extends BlockLeavesBase { + public static final String[] LEAF_TYPES = new String[] { "oak", "spruce", "birch", "jungle" }; + public static final String[][] field_94396_b = new String[][] { { "leaves", "leaves_spruce", "leaves", "leaves_jungle" }, { "leaves_opaque", "leaves_spruce_opaque", "leaves_opaque", "leaves_jungle_opaque" } }; + private int field_94394_cP; + private Icon[][] iconArray = new Icon[2][]; + int[] adjacentTreeBlocks; + + protected BlockLeaves(int par1) { + super(par1, Material.leaves, false); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + public int getBlockColor() { + double var1 = 0.5D; + double var3 = 1.0D; + return ColorizerFoliage.getFoliageColor(var1, var3); + } + + /** + * Returns the color this block should be rendered. Used by leaves. + */ + public int getRenderColor(int par1) { + return (par1 & 3) == 1 ? ColorizerFoliage.getFoliageColorPine() : ((par1 & 3) == 2 ? ColorizerFoliage.getFoliageColorBirch() : ColorizerFoliage.getFoliageColorBasic()); + } + + /** + * Returns a integer with hex for 0xrrggbb with this color multiplied against + * the blocks color. Note only called when first determining what to render. + */ + public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if ((var5 & 3) == 1) { + return ColorizerFoliage.getFoliageColorPine(); + } else if ((var5 & 3) == 2) { + return ColorizerFoliage.getFoliageColorBirch(); + } else { + int var6 = 0; + int var7 = 0; + int var8 = 0; + + for (int var9 = -1; var9 <= 1; ++var9) { + for (int var10 = -1; var10 <= 1; ++var10) { + int var11 = par1IBlockAccess.getBiomeGenForCoords(par2 + var10, par4 + var9).getBiomeFoliageColor(); + var6 += (var11 & 16711680) >> 16; + var7 += (var11 & 65280) >> 8; + var8 += var11 & 255; + } + } + + initNoiseField(par2 >> 4, par4 >> 4); + float noise = (float)(grassNoiseArray[(par4 & 15) + (par2 & 15) * 16]) * 0.3F + 1.0F; + + var7 = (int)((var7 / 9) * noise); + + if(var7 > 255) var7 = 255; + if(var7 < 0) var7 = 0; + + return (var6 / 9 & 255) << 16 | (var7 & 255) << 8 | var8 / 9 & 255; + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + byte var7 = 1; + int var8 = var7 + 1; + + if (par1World.checkChunksExist(par2 - var8, par3 - var8, par4 - var8, par2 + var8, par3 + var8, par4 + var8)) { + for (int var9 = -var7; var9 <= var7; ++var9) { + for (int var10 = -var7; var10 <= var7; ++var10) { + for (int var11 = -var7; var11 <= var7; ++var11) { + int var12 = par1World.getBlockId(par2 + var9, par3 + var10, par4 + var11); + + if (var12 == Block.leaves.blockID) { + int var13 = par1World.getBlockMetadata(par2 + var9, par3 + var10, par4 + var11); + par1World.setBlockMetadataWithNotify(par2 + var9, par3 + var10, par4 + var11, var13 | 8, 4); + } + } + } + } + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) != 0 && (var6 & 4) == 0) { + byte var7 = 4; + int var8 = var7 + 1; + byte var9 = 32; + int var10 = var9 * var9; + int var11 = var9 / 2; + + if (this.adjacentTreeBlocks == null) { + this.adjacentTreeBlocks = new int[var9 * var9 * var9]; + } + + int var12; + + if (par1World.checkChunksExist(par2 - var8, par3 - var8, par4 - var8, par2 + var8, par3 + var8, par4 + var8)) { + int var13; + int var14; + int var15; + + for (var12 = -var7; var12 <= var7; ++var12) { + for (var13 = -var7; var13 <= var7; ++var13) { + for (var14 = -var7; var14 <= var7; ++var14) { + var15 = par1World.getBlockId(par2 + var12, par3 + var13, par4 + var14); + + if (var15 == Block.wood.blockID) { + this.adjacentTreeBlocks[(var12 + var11) * var10 + (var13 + var11) * var9 + var14 + var11] = 0; + } else if (var15 == Block.leaves.blockID) { + this.adjacentTreeBlocks[(var12 + var11) * var10 + (var13 + var11) * var9 + var14 + var11] = -2; + } else { + this.adjacentTreeBlocks[(var12 + var11) * var10 + (var13 + var11) * var9 + var14 + var11] = -1; + } + } + } + } + + for (var12 = 1; var12 <= 4; ++var12) { + for (var13 = -var7; var13 <= var7; ++var13) { + for (var14 = -var7; var14 <= var7; ++var14) { + for (var15 = -var7; var15 <= var7; ++var15) { + if (this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11) * var9 + var15 + var11] == var12 - 1) { + if (this.adjacentTreeBlocks[(var13 + var11 - 1) * var10 + (var14 + var11) * var9 + var15 + var11] == -2) { + this.adjacentTreeBlocks[(var13 + var11 - 1) * var10 + (var14 + var11) * var9 + var15 + var11] = var12; + } + + if (this.adjacentTreeBlocks[(var13 + var11 + 1) * var10 + (var14 + var11) * var9 + var15 + var11] == -2) { + this.adjacentTreeBlocks[(var13 + var11 + 1) * var10 + (var14 + var11) * var9 + var15 + var11] = var12; + } + + if (this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11 - 1) * var9 + var15 + var11] == -2) { + this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11 - 1) * var9 + var15 + var11] = var12; + } + + if (this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11 + 1) * var9 + var15 + var11] == -2) { + this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11 + 1) * var9 + var15 + var11] = var12; + } + + if (this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11) * var9 + (var15 + var11 - 1)] == -2) { + this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11) * var9 + (var15 + var11 - 1)] = var12; + } + + if (this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11) * var9 + var15 + var11 + 1] == -2) { + this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11) * var9 + var15 + var11 + 1] = var12; + } + } + } + } + } + } + } + + var12 = this.adjacentTreeBlocks[var11 * var10 + var11 * var9 + var11]; + + if (var12 >= 0) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 & -9, 4); + } else { + this.removeLeaves(par1World, par2, par3, par4); + } + } + } + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par1World.canLightningStrikeAt(par2, par3 + 1, par4) && !par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) && par5Random.nextInt(15) == 1) { + double var6 = (double) ((float) par2 + par5Random.nextFloat()); + double var8 = (double) par3 - 0.05D; + double var10 = (double) ((float) par4 + par5Random.nextFloat()); + par1World.spawnParticle("dripWater", var6, var8, var10, 0.0D, 0.0D, 0.0D); + } + } + + private void removeLeaves(World par1World, int par2, int par3, int par4) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return par1Random.nextInt(20) == 0 ? 1 : 0; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.sapling.blockID; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + if (!par1World.isRemote) { + int var8 = 20; + + if ((par5 & 3) == 3) { + var8 = 40; + } + + if (par7 > 0) { + var8 -= 2 << par7; + + if (var8 < 10) { + var8 = 10; + } + } + + if (par1World.rand.nextInt(var8) == 0) { + int var9 = this.idDropped(par5, par1World.rand, par7); + this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(var9, 1, this.damageDropped(par5))); + } + + var8 = 200; + + if (par7 > 0) { + var8 -= 10 << par7; + + if (var8 < 40) { + var8 = 40; + } + } + + if ((par5 & 3) == 0 && par1World.rand.nextInt(var8) == 0) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(Item.appleRed, 1, 0)); + } + } + } + + /** + * Called when the player destroys a block with an item that can harvest it. (i, + * j, k) are the coordinates of the block and l is the block's subtype/damage. + */ + public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) { + if (!par1World.isRemote && par2EntityPlayer.getCurrentEquippedItem() != null && par2EntityPlayer.getCurrentEquippedItem().itemID == Item.shears.itemID) { + this.dropBlockAsItem_do(par1World, par3, par4, par5, new ItemStack(Block.leaves.blockID, 1, par6 & 3)); + } else { + super.harvestBlock(par1World, par2EntityPlayer, par3, par4, par5, par6); + } + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1 & 3; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return !this.graphicsLevel; + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return (par2 & 3) == 1 ? this.iconArray[this.field_94394_cP][1] : ((par2 & 3) == 3 ? this.iconArray[this.field_94394_cP][3] : this.iconArray[this.field_94394_cP][0]); + } + + /** + * Pass true to draw this block using fancy graphics, or false for fast + * graphics. + */ + public void setGraphicsLevel(boolean par1) { + this.graphicsLevel = par1; + this.field_94394_cP = par1 ? 0 : 1; + } + + /** + * returns a list of blocks with the same ID, but different meta (eg: wood + * returns 4 blocks) + */ + public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + par3List.add(new ItemStack(par1, 1, 0)); + par3List.add(new ItemStack(par1, 1, 1)); + par3List.add(new ItemStack(par1, 1, 2)); + par3List.add(new ItemStack(par1, 1, 3)); + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + return new ItemStack(this.blockID, 1, par1 & 3); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + for (int var2 = 0; var2 < field_94396_b.length; ++var2) { + this.iconArray[var2] = new Icon[field_94396_b[var2].length]; + + for (int var3 = 0; var3 < field_94396_b[var2].length; ++var3) { + this.iconArray[var2][var3] = par1IconRegister.registerIcon(field_94396_b[var2][var3]); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockLeavesBase.java b/src/main/java/net/minecraft/src/BlockLeavesBase.java new file mode 100644 index 0000000..5fdaf06 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockLeavesBase.java @@ -0,0 +1,32 @@ +package net.minecraft.src; + +public class BlockLeavesBase extends Block { + /** + * Used to determine how to display leaves based on the graphics level. May also + * be used in rendering for transparency, not sure. + */ + protected boolean graphicsLevel; + + protected BlockLeavesBase(int par1, Material par2Material, boolean par3) { + super(par1, par2Material); + this.graphicsLevel = par3; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = par1IBlockAccess.getBlockId(par2, par3, par4); + return !this.graphicsLevel && var6 == this.blockID ? false : super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5); + } +} diff --git a/src/main/java/net/minecraft/src/BlockLever.java b/src/main/java/net/minecraft/src/BlockLever.java new file mode 100644 index 0000000..8ee423e --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockLever.java @@ -0,0 +1,339 @@ +package net.minecraft.src; + +public class BlockLever extends Block { + protected BlockLever(int par1) { + super(par1, Material.circuits); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 12; + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + return par5 == 0 && par1World.isBlockNormalCube(par2, par3 + 1, par4) ? true + : (par5 == 1 && par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) ? true + : (par5 == 2 && par1World.isBlockNormalCube(par2, par3, par4 + 1) ? true + : (par5 == 3 && par1World.isBlockNormalCube(par2, par3, par4 - 1) ? true + : (par5 == 4 && par1World.isBlockNormalCube(par2 + 1, par3, par4) ? true : par5 == 5 && par1World.isBlockNormalCube(par2 - 1, par3, par4))))); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.isBlockNormalCube(par2 - 1, par3, par4) ? true + : (par1World.isBlockNormalCube(par2 + 1, par3, par4) ? true + : (par1World.isBlockNormalCube(par2, par3, par4 - 1) ? true + : (par1World.isBlockNormalCube(par2, par3, par4 + 1) ? true : (par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) ? true : par1World.isBlockNormalCube(par2, par3 + 1, par4))))); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9) { + int var11 = par9 & 8; + int var10 = par9 & 7; + byte var12 = -1; + + if (par5 == 0 && par1World.isBlockNormalCube(par2, par3 + 1, par4)) { + var12 = 0; + } + + if (par5 == 1 && par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4)) { + var12 = 5; + } + + if (par5 == 2 && par1World.isBlockNormalCube(par2, par3, par4 + 1)) { + var12 = 4; + } + + if (par5 == 3 && par1World.isBlockNormalCube(par2, par3, par4 - 1)) { + var12 = 3; + } + + if (par5 == 4 && par1World.isBlockNormalCube(par2 + 1, par3, par4)) { + var12 = 2; + } + + if (par5 == 5 && par1World.isBlockNormalCube(par2 - 1, par3, par4)) { + var12 = 1; + } + + return var12 + var11; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + int var7 = par1World.getBlockMetadata(par2, par3, par4); + int var8 = var7 & 7; + int var9 = var7 & 8; + + if (var8 == invertMetadata(1)) { + if ((MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 1) == 0) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 5 | var9, 2); + } else { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 6 | var9, 2); + } + } else if (var8 == invertMetadata(0)) { + if ((MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 1) == 0) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 7 | var9, 2); + } else { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 0 | var9, 2); + } + } + } + + /** + * only used in ComponentScatteredFeatureJunglePyramid.addComponentParts" + */ + public static int invertMetadata(int par0) { + switch (par0) { + case 0: + return 0; + + case 1: + return 5; + + case 2: + return 4; + + case 3: + return 3; + + case 4: + return 2; + + case 5: + return 1; + + default: + return -1; + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (this.checkIfAttachedToBlock(par1World, par2, par3, par4)) { + int var6 = par1World.getBlockMetadata(par2, par3, par4) & 7; + boolean var7 = false; + + if (!par1World.isBlockNormalCube(par2 - 1, par3, par4) && var6 == 1) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2 + 1, par3, par4) && var6 == 2) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3, par4 - 1) && var6 == 3) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3, par4 + 1) && var6 == 4) { + var7 = true; + } + + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) && var6 == 5) { + var7 = true; + } + + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) && var6 == 6) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3 + 1, par4) && var6 == 0) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3 + 1, par4) && var6 == 7) { + var7 = true; + } + + if (var7) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + } + + /** + * Checks if the block is attached to another block. If it is not, it returns + * false and drops the block as an item. If it is it returns true. + */ + private boolean checkIfAttachedToBlock(World par1World, int par2, int par3, int par4) { + if (!this.canPlaceBlockAt(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + return false; + } else { + return true; + } + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 7; + float var6 = 0.1875F; + + if (var5 == 1) { + this.setBlockBounds(0.0F, 0.2F, 0.5F - var6, var6 * 2.0F, 0.8F, 0.5F + var6); + } else if (var5 == 2) { + this.setBlockBounds(1.0F - var6 * 2.0F, 0.2F, 0.5F - var6, 1.0F, 0.8F, 0.5F + var6); + } else if (var5 == 3) { + this.setBlockBounds(0.5F - var6, 0.2F, 0.0F, 0.5F + var6, 0.8F, var6 * 2.0F); + } else if (var5 == 4) { + this.setBlockBounds(0.5F - var6, 0.2F, 1.0F - var6 * 2.0F, 0.5F + var6, 0.8F, 1.0F); + } else if (var5 != 5 && var5 != 6) { + if (var5 == 0 || var5 == 7) { + var6 = 0.25F; + this.setBlockBounds(0.5F - var6, 0.4F, 0.5F - var6, 0.5F + var6, 1.0F, 0.5F + var6); + } + } else { + var6 = 0.25F; + this.setBlockBounds(0.5F - var6, 0.0F, 0.5F - var6, 0.5F + var6, 0.6F, 0.5F + var6); + } + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + int var11 = var10 & 7; + int var12 = 8 - (var10 & 8); + par1World.setBlockMetadataWithNotify(par2, par3, par4, var11 + var12, 3); + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "random.click", 0.3F, var12 > 0 ? 0.6F : 0.5F); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + + if (var11 == 1) { + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + } else if (var11 == 2) { + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + } else if (var11 == 3) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + } else if (var11 == 4) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + } else if (var11 != 5 && var11 != 6) { + if (var11 == 0 || var11 == 7) { + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + } + } else { + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + } + + return true; + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + if ((par6 & 8) > 0) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + int var7 = par6 & 7; + + if (var7 == 1) { + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + } else if (var7 == 2) { + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + } else if (var7 == 3) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + } else if (var7 == 4) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + } else if (var7 != 5 && var7 != 6) { + if (var7 == 0 || var7 == 7) { + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + } + } else { + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + } + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) > 0 ? 15 : 0; + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) == 0) { + return 0; + } else { + int var7 = var6 & 7; + return var7 == 0 && par5 == 0 ? 15 + : (var7 == 7 && par5 == 0 ? 15 + : (var7 == 6 && par5 == 1 ? 15 : (var7 == 5 && par5 == 1 ? 15 : (var7 == 4 && par5 == 2 ? 15 : (var7 == 3 && par5 == 3 ? 15 : (var7 == 2 && par5 == 4 ? 15 : (var7 == 1 && par5 == 5 ? 15 : 0))))))); + } + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/BlockLilyPad.java b/src/main/java/net/minecraft/src/BlockLilyPad.java new file mode 100644 index 0000000..dbf2241 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockLilyPad.java @@ -0,0 +1,74 @@ +package net.minecraft.src; + +import java.util.List; + +public class BlockLilyPad extends BlockFlower { + protected BlockLilyPad(int par1) { + super(par1); + float var2 = 0.5F; + float var3 = 0.015625F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, var3, 0.5F + var2); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 23; + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity) { + if (par7Entity == null || !(par7Entity instanceof EntityBoat)) { + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return AxisAlignedBB.getAABBPool().getAABB((double) par2 + this.minX, (double) par3 + this.minY, (double) par4 + this.minZ, (double) par2 + this.maxX, (double) par3 + this.maxY, (double) par4 + this.maxZ); + } + + public int getBlockColor() { + return 2129968; + } + + /** + * Returns the color this block should be rendered. Used by leaves. + */ + public int getRenderColor(int par1) { + return 2129968; + } + + /** + * Returns a integer with hex for 0xrrggbb with this color multiplied against + * the blocks color. Note only called when first determining what to render. + */ + public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return 2129968; + } + + /** + * Gets passed in the blockID of the block below and supposed to return true if + * its allowed to grow on the type of blockID passed in. Args: blockID + */ + protected boolean canThisPlantGrowOnThisBlockID(int par1) { + return par1 == Block.waterStill.blockID; + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + return par3 >= 0 && par3 < 256 ? par1World.getBlockMaterial(par2, par3 - 1, par4) == Material.water && par1World.getBlockMetadata(par2, par3 - 1, par4) == 0 : false; + } +} diff --git a/src/main/java/net/minecraft/src/BlockLockedChest.java b/src/main/java/net/minecraft/src/BlockLockedChest.java new file mode 100644 index 0000000..dc0eb37 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockLockedChest.java @@ -0,0 +1,32 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockLockedChest extends Block { + protected BlockLockedChest(int par1) { + super(par1, Material.wood); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return true; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + par1World.setBlockToAir(par2, par3, par4); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + } +} diff --git a/src/main/java/net/minecraft/src/BlockLog.java b/src/main/java/net/minecraft/src/BlockLog.java new file mode 100644 index 0000000..6dcbdf1 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockLog.java @@ -0,0 +1,150 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockLog extends Block { + /** The type of tree this log came from. */ + public static final String[] woodType = new String[] { "oak", "spruce", "birch", "jungle" }; + public static final String[] treeTextureTypes = new String[] { "tree_side", "tree_spruce", "tree_birch", "tree_jungle" }; + private Icon[] iconArray; + private Icon tree_top; + + protected BlockLog(int par1) { + super(par1, Material.wood); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 31; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.wood.blockID; + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + byte var7 = 4; + int var8 = var7 + 1; + + if (par1World.checkChunksExist(par2 - var8, par3 - var8, par4 - var8, par2 + var8, par3 + var8, par4 + var8)) { + for (int var9 = -var7; var9 <= var7; ++var9) { + for (int var10 = -var7; var10 <= var7; ++var10) { + for (int var11 = -var7; var11 <= var7; ++var11) { + int var12 = par1World.getBlockId(par2 + var9, par3 + var10, par4 + var11); + + if (var12 == Block.leaves.blockID) { + int var13 = par1World.getBlockMetadata(par2 + var9, par3 + var10, par4 + var11); + + if ((var13 & 8) == 0) { + par1World.setBlockMetadataWithNotify(par2 + var9, par3 + var10, par4 + var11, var13 | 8, 4); + } + } + } + } + } + } + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9) { + int var10 = par9 & 3; + byte var11 = 0; + + switch (par5) { + case 0: + case 1: + var11 = 0; + break; + + case 2: + case 3: + var11 = 8; + break; + + case 4: + case 5: + var11 = 4; + } + + return var10 | var11; + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + int var3 = par2 & 12; + int var4 = par2 & 3; + return var3 == 0 && (par1 == 1 || par1 == 0) ? this.tree_top : (var3 == 4 && (par1 == 5 || par1 == 4) ? this.tree_top : (var3 == 8 && (par1 == 2 || par1 == 3) ? this.tree_top : this.iconArray[var4])); + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1 & 3; + } + + /** + * returns a number between 0 and 3 + */ + public static int limitToValidMetadata(int par0) { + return par0 & 3; + } + + /** + * returns a list of blocks with the same ID, but different meta (eg: wood + * returns 4 blocks) + */ + public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + par3List.add(new ItemStack(par1, 1, 0)); + par3List.add(new ItemStack(par1, 1, 1)); + par3List.add(new ItemStack(par1, 1, 2)); + par3List.add(new ItemStack(par1, 1, 3)); + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + return new ItemStack(this.blockID, 1, limitToValidMetadata(par1)); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.tree_top = par1IconRegister.registerIcon("tree_top"); + this.iconArray = new Icon[treeTextureTypes.length]; + + for (int var2 = 0; var2 < this.iconArray.length; ++var2) { + this.iconArray[var2] = par1IconRegister.registerIcon(treeTextureTypes[var2]); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockMelon.java b/src/main/java/net/minecraft/src/BlockMelon.java new file mode 100644 index 0000000..db4209d --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockMelon.java @@ -0,0 +1,58 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockMelon extends Block { + private Icon theIcon; + + protected BlockMelon(int par1) { + super(par1, Material.pumpkin); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 != 1 && par1 != 0 ? this.blockIcon : this.theIcon; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.melon.itemID; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 3 + par1Random.nextInt(5); + } + + /** + * Returns the usual quantity dropped by the block plus a bonus of 1 to 'i' + * (inclusive). + */ + public int quantityDroppedWithBonus(int par1, Random par2Random) { + int var3 = this.quantityDropped(par2Random) + par2Random.nextInt(1 + par1); + + if (var3 > 9) { + var3 = 9; + } + + return var3; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("melon_side"); + this.theIcon = par1IconRegister.registerIcon("melon_top"); + } +} diff --git a/src/main/java/net/minecraft/src/BlockMobSpawner.java b/src/main/java/net/minecraft/src/BlockMobSpawner.java new file mode 100644 index 0000000..7b1ad36 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockMobSpawner.java @@ -0,0 +1,57 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockMobSpawner extends BlockContainer { + protected BlockMobSpawner(int par1) { + super(par1, Material.rock); + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityMobSpawner(); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return 0; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7); + int var8 = 15 + par1World.rand.nextInt(15) + par1World.rand.nextInt(15); + this.dropXpOnBlockBreak(par1World, par2, par3, par4, var8); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return 0; + } +} diff --git a/src/main/java/net/minecraft/src/BlockMushroom.java b/src/main/java/net/minecraft/src/BlockMushroom.java new file mode 100644 index 0000000..fd7f261 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockMushroom.java @@ -0,0 +1,100 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockMushroom extends BlockFlower { + private final String field_94374_a; + + protected BlockMushroom(int par1, String par2Str) { + super(par1); + this.field_94374_a = par2Str; + float var3 = 0.2F; + this.setBlockBounds(0.5F - var3, 0.0F, 0.5F - var3, 0.5F + var3, var3 * 2.0F, 0.5F + var3); + this.setTickRandomly(true); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par5Random.nextInt(25) == 0) { + byte var6 = 4; + int var7 = 5; + int var8; + int var9; + int var10; + + for (var8 = par2 - var6; var8 <= par2 + var6; ++var8) { + for (var9 = par4 - var6; var9 <= par4 + var6; ++var9) { + for (var10 = par3 - 1; var10 <= par3 + 1; ++var10) { + if (par1World.getBlockId(var8, var10, var9) == this.blockID) { + --var7; + + if (var7 <= 0) { + return; + } + } + } + } + } + + var8 = par2 + par5Random.nextInt(3) - 1; + var9 = par3 + par5Random.nextInt(2) - par5Random.nextInt(2); + var10 = par4 + par5Random.nextInt(3) - 1; + + for (int var11 = 0; var11 < 4; ++var11) { + if (par1World.isAirBlock(var8, var9, var10) && this.canBlockStay(par1World, var8, var9, var10)) { + par2 = var8; + par3 = var9; + par4 = var10; + } + + var8 = par2 + par5Random.nextInt(3) - 1; + var9 = par3 + par5Random.nextInt(2) - par5Random.nextInt(2); + var10 = par4 + par5Random.nextInt(3) - 1; + } + + if (par1World.isAirBlock(var8, var9, var10) && this.canBlockStay(par1World, var8, var9, var10)) { + par1World.setBlock(var8, var9, var10, this.blockID); + } + } + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return super.canPlaceBlockAt(par1World, par2, par3, par4) && this.canBlockStay(par1World, par2, par3, par4); + } + + /** + * Gets passed in the blockID of the block below and supposed to return true if + * its allowed to grow on the type of blockID passed in. Args: blockID + */ + protected boolean canThisPlantGrowOnThisBlockID(int par1) { + return Block.opaqueCubeLookup[par1]; + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + if (par3 >= 0 && par3 < 256) { + int var5 = par1World.getBlockId(par2, par3 - 1, par4); + return var5 == Block.mycelium.blockID || par1World.getFullBlockLightValue(par2, par3, par4) < 13 && this.canThisPlantGrowOnThisBlockID(var5); + } else { + return false; + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon(this.field_94374_a); + } +} diff --git a/src/main/java/net/minecraft/src/BlockMushroomCap.java b/src/main/java/net/minecraft/src/BlockMushroomCap.java new file mode 100644 index 0000000..443cead --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockMushroomCap.java @@ -0,0 +1,76 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockMushroomCap extends Block { + private static final String[] field_94429_a = new String[] { "mushroom_skin_brown", "mushroom_skin_red" }; + + /** The mushroom type. 0 for brown, 1 for red. */ + private final int mushroomType; + private Icon[] iconArray; + private Icon field_94426_cO; + private Icon field_94427_cP; + + public BlockMushroomCap(int par1, Material par2Material, int par3) { + super(par1, par2Material); + this.mushroomType = par3; + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par2 == 10 && par1 > 1 ? this.field_94426_cO + : (par2 >= 1 && par2 <= 9 && par1 == 1 ? this.iconArray[this.mushroomType] + : (par2 >= 1 && par2 <= 3 && par1 == 2 ? this.iconArray[this.mushroomType] + : (par2 >= 7 && par2 <= 9 && par1 == 3 ? this.iconArray[this.mushroomType] + : ((par2 == 1 || par2 == 4 || par2 == 7) && par1 == 4 ? this.iconArray[this.mushroomType] + : ((par2 == 3 || par2 == 6 || par2 == 9) && par1 == 5 ? this.iconArray[this.mushroomType] + : (par2 == 14 ? this.iconArray[this.mushroomType] : (par2 == 15 ? this.field_94426_cO : this.field_94427_cP))))))); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + int var2 = par1Random.nextInt(10) - 7; + + if (var2 < 0) { + var2 = 0; + } + + return var2; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.mushroomBrown.blockID + this.mushroomType; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Block.mushroomBrown.blockID + this.mushroomType; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.iconArray = new Icon[field_94429_a.length]; + + for (int var2 = 0; var2 < this.iconArray.length; ++var2) { + this.iconArray[var2] = par1IconRegister.registerIcon(field_94429_a[var2]); + } + + this.field_94427_cP = par1IconRegister.registerIcon("mushroom_inside"); + this.field_94426_cO = par1IconRegister.registerIcon("mushroom_skin_stem"); + } +} diff --git a/src/main/java/net/minecraft/src/BlockMycelium.java b/src/main/java/net/minecraft/src/BlockMycelium.java new file mode 100644 index 0000000..1c22d59 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockMycelium.java @@ -0,0 +1,89 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockMycelium extends Block { + private Icon field_94422_a; + private Icon field_94421_b; + + protected BlockMycelium(int par1) { + super(par1, Material.grass); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 1 ? this.field_94422_a : (par1 == 0 ? Block.dirt.getBlockTextureFromSide(par1) : this.blockIcon); + } + + /** + * Retrieves the block texture to use based on the display side. Args: + * iBlockAccess, x, y, z, side + */ + public Icon getBlockTexture(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + if (par5 == 1) { + return this.field_94422_a; + } else if (par5 == 0) { + return Block.dirt.getBlockTextureFromSide(par5); + } else { + Material var6 = par1IBlockAccess.getBlockMaterial(par2, par3 + 1, par4); + return var6 != Material.snow && var6 != Material.craftedSnow ? this.blockIcon : this.field_94421_b; + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("mycel_side"); + this.field_94422_a = par1IconRegister.registerIcon("mycel_top"); + this.field_94421_b = par1IconRegister.registerIcon("snow_side"); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + if (par1World.getBlockLightValue(par2, par3 + 1, par4) < 4 && Block.lightOpacity[par1World.getBlockId(par2, par3 + 1, par4)] > 2) { + par1World.setBlock(par2, par3, par4, Block.dirt.blockID); + } else if (par1World.getBlockLightValue(par2, par3 + 1, par4) >= 9) { + for (int var6 = 0; var6 < 4; ++var6) { + int var7 = par2 + par5Random.nextInt(3) - 1; + int var8 = par3 + par5Random.nextInt(5) - 3; + int var9 = par4 + par5Random.nextInt(3) - 1; + int var10 = par1World.getBlockId(var7, var8 + 1, var9); + + if (par1World.getBlockId(var7, var8, var9) == Block.dirt.blockID && par1World.getBlockLightValue(var7, var8 + 1, var9) >= 4 && Block.lightOpacity[var10] <= 2) { + par1World.setBlock(var7, var8, var9, this.blockID); + } + } + } + } + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + super.randomDisplayTick(par1World, par2, par3, par4, par5Random); + + if (par5Random.nextInt(10) == 0) { + par1World.spawnParticle("townaura", (double) ((float) par2 + par5Random.nextFloat()), (double) ((float) par3 + 1.1F), (double) ((float) par4 + par5Random.nextFloat()), 0.0D, 0.0D, 0.0D); + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.dirt.idDropped(0, par2Random, par3); + } +} diff --git a/src/main/java/net/minecraft/src/BlockNetherStalk.java b/src/main/java/net/minecraft/src/BlockNetherStalk.java new file mode 100644 index 0000000..6a487e0 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockNetherStalk.java @@ -0,0 +1,117 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockNetherStalk extends BlockFlower { + private static final String[] field_94373_a = new String[] { "netherStalk_0", "netherStalk_1", "netherStalk_2" }; + private Icon[] iconArray; + + protected BlockNetherStalk(int par1) { + super(par1); + this.setTickRandomly(true); + float var2 = 0.5F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, 0.25F, 0.5F + var2); + this.setCreativeTab((CreativeTabs) null); + } + + /** + * Gets passed in the blockID of the block below and supposed to return true if + * its allowed to grow on the type of blockID passed in. Args: blockID + */ + protected boolean canThisPlantGrowOnThisBlockID(int par1) { + return par1 == Block.slowSand.blockID; + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + return this.canThisPlantGrowOnThisBlockID(par1World.getBlockId(par2, par3 - 1, par4)); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (var6 < 3 && par5Random.nextInt(10) == 0) { + ++var6; + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6, 2); + } + + super.updateTick(par1World, par2, par3, par4, par5Random); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par2 >= 3 ? this.iconArray[2] : (par2 > 0 ? this.iconArray[1] : this.iconArray[0]); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 6; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + if (!par1World.isRemote) { + int var8 = 1; + + if (par5 >= 3) { + var8 = 2 + par1World.rand.nextInt(3); + + if (par7 > 0) { + var8 += par1World.rand.nextInt(par7 + 1); + } + } + + for (int var9 = 0; var9 < var8; ++var9) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(Item.netherStalkSeeds)); + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return 0; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Item.netherStalkSeeds.itemID; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.iconArray = new Icon[field_94373_a.length]; + + for (int var2 = 0; var2 < this.iconArray.length; ++var2) { + this.iconArray[var2] = par1IconRegister.registerIcon(field_94373_a[var2]); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockNetherrack.java b/src/main/java/net/minecraft/src/BlockNetherrack.java new file mode 100644 index 0000000..4d71fc5 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockNetherrack.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public class BlockNetherrack extends Block { + public BlockNetherrack(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabBlock); + } +} diff --git a/src/main/java/net/minecraft/src/BlockNote.java b/src/main/java/net/minecraft/src/BlockNote.java new file mode 100644 index 0000000..d7156b9 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockNote.java @@ -0,0 +1,97 @@ +package net.minecraft.src; + + + +public class BlockNote extends BlockContainer { + public BlockNote(int par1) { + super(par1, Material.wood); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + boolean var6 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4); + TileEntityNote var7 = (TileEntityNote) par1World.getBlockTileEntity(par2, par3, par4); + + if (var7 != null && var7.previousRedstoneState != var6) { + if (var6) { + var7.triggerNote(par1World, par2, par3, par4); + } + + var7.previousRedstoneState = var6; + } + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + TileEntityNote var10 = (TileEntityNote) par1World.getBlockTileEntity(par2, par3, par4); + + if (var10 != null) { + var10.changePitch(); + var10.triggerNote(par1World, par2, par3, par4); + } + + return true; + } + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + if (!par1World.isRemote) { + TileEntityNote var6 = (TileEntityNote) par1World.getBlockTileEntity(par2, par3, par4); + + if (var6 != null) { + var6.triggerNote(par1World, par2, par3, par4); + } + } + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityNote(); + } + + /** + * Called when the block receives a BlockEvent - see World.addBlockEvent. By + * default, passes it on to the tile entity at this location. Args: world, x, y, + * z, blockID, EventID, event parameter + */ + public boolean onBlockEventReceived(World par1World, int par2, int par3, int par4, int par5, int par6) { + float var7 = (float) Math.pow(2.0D, (double) (par6 - 12) / 12.0D); + String var8 = "harp"; + + if (par5 == 1) { + var8 = "bd"; + } + + if (par5 == 2) { + var8 = "snare"; + } + + if (par5 == 3) { + var8 = "hat"; + } + + if (par5 == 4) { + var8 = "bassattack"; + } + + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "note." + var8, 3.0F, var7); + par1World.spawnParticle("note", (double) par2 + 0.5D, (double) par3 + 1.2D, (double) par4 + 0.5D, (double) par6 / 24.0D, 0.0D, 0.0D); + return true; + } +} diff --git a/src/main/java/net/minecraft/src/BlockObsidian.java b/src/main/java/net/minecraft/src/BlockObsidian.java new file mode 100644 index 0000000..57dc43e --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockObsidian.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockObsidian extends BlockStone { + public BlockObsidian(int par1) { + super(par1); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.obsidian.blockID; + } +} diff --git a/src/main/java/net/minecraft/src/BlockOre.java b/src/main/java/net/minecraft/src/BlockOre.java new file mode 100644 index 0000000..000b267 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockOre.java @@ -0,0 +1,77 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockOre extends Block { + public BlockOre(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return this.blockID == Block.oreCoal.blockID ? Item.coal.itemID + : (this.blockID == Block.oreDiamond.blockID ? Item.diamond.itemID + : (this.blockID == Block.oreLapis.blockID ? Item.dyePowder.itemID + : (this.blockID == Block.oreEmerald.blockID ? Item.emerald.itemID : (this.blockID == Block.oreNetherQuartz.blockID ? Item.netherQuartz.itemID : this.blockID)))); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return this.blockID == Block.oreLapis.blockID ? 4 + par1Random.nextInt(5) : 1; + } + + /** + * Returns the usual quantity dropped by the block plus a bonus of 1 to 'i' + * (inclusive). + */ + public int quantityDroppedWithBonus(int par1, Random par2Random) { + if (par1 > 0 && this.blockID != this.idDropped(0, par2Random, par1)) { + int var3 = par2Random.nextInt(par1 + 2) - 1; + + if (var3 < 0) { + var3 = 0; + } + + return this.quantityDropped(par2Random) * (var3 + 1); + } else { + return this.quantityDropped(par2Random); + } + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7); + + if (this.idDropped(par5, par1World.rand, par7) != this.blockID) { + int var8 = 0; + + if (this.blockID == Block.oreCoal.blockID) { + var8 = MathHelper.getRandomIntegerInRange(par1World.rand, 0, 2); + } else if (this.blockID == Block.oreDiamond.blockID) { + var8 = MathHelper.getRandomIntegerInRange(par1World.rand, 3, 7); + } else if (this.blockID == Block.oreEmerald.blockID) { + var8 = MathHelper.getRandomIntegerInRange(par1World.rand, 3, 7); + } else if (this.blockID == Block.oreLapis.blockID) { + var8 = MathHelper.getRandomIntegerInRange(par1World.rand, 2, 5); + } else if (this.blockID == Block.oreNetherQuartz.blockID) { + var8 = MathHelper.getRandomIntegerInRange(par1World.rand, 2, 5); + } + + this.dropXpOnBlockBreak(par1World, par2, par3, par4, var8); + } + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return this.blockID == Block.oreLapis.blockID ? 4 : 0; + } +} diff --git a/src/main/java/net/minecraft/src/BlockOreStorage.java b/src/main/java/net/minecraft/src/BlockOreStorage.java new file mode 100644 index 0000000..6162cd9 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockOreStorage.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public class BlockOreStorage extends Block { + public BlockOreStorage(int par1) { + super(par1, Material.iron); + this.setCreativeTab(CreativeTabs.tabBlock); + } +} diff --git a/src/main/java/net/minecraft/src/BlockPane.java b/src/main/java/net/minecraft/src/BlockPane.java new file mode 100644 index 0000000..4d68762 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockPane.java @@ -0,0 +1,192 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockPane extends Block { + /** + * Holds the texture index of the side of the pane (the thin lateral side) + */ + private final String sideTextureIndex; + + /** + * If this field is true, the pane block drops itself when destroyed (like the + * iron fences), otherwise, it's just destroyed (like glass panes) + */ + private final boolean canDropItself; + private final String field_94402_c; + private Icon theIcon; + + protected BlockPane(int par1, String par2Str, String par3Str, Material par4Material, boolean par5) { + super(par1, par4Material); + this.sideTextureIndex = par3Str; + this.canDropItself = par5; + this.field_94402_c = par2Str; + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return !this.canDropItself ? 0 : super.idDropped(par1, par2Random, par3); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 18; + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = par1IBlockAccess.getBlockId(par2, par3, par4); + return var6 == this.blockID ? false : super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5); + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity) { + boolean var8 = this.canThisPaneConnectToThisBlockID(par1World.getBlockId(par2, par3, par4 - 1)); + boolean var9 = this.canThisPaneConnectToThisBlockID(par1World.getBlockId(par2, par3, par4 + 1)); + boolean var10 = this.canThisPaneConnectToThisBlockID(par1World.getBlockId(par2 - 1, par3, par4)); + boolean var11 = this.canThisPaneConnectToThisBlockID(par1World.getBlockId(par2 + 1, par3, par4)); + + if ((!var10 || !var11) && (var10 || var11 || var8 || var9)) { + if (var10 && !var11) { + this.setBlockBounds(0.0F, 0.0F, 0.4375F, 0.5F, 1.0F, 0.5625F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } else if (!var10 && var11) { + this.setBlockBounds(0.5F, 0.0F, 0.4375F, 1.0F, 1.0F, 0.5625F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + } else { + this.setBlockBounds(0.0F, 0.0F, 0.4375F, 1.0F, 1.0F, 0.5625F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + if ((!var8 || !var9) && (var10 || var11 || var8 || var9)) { + if (var8 && !var9) { + this.setBlockBounds(0.4375F, 0.0F, 0.0F, 0.5625F, 1.0F, 0.5F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } else if (!var8 && var9) { + this.setBlockBounds(0.4375F, 0.0F, 0.5F, 0.5625F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + } else { + this.setBlockBounds(0.4375F, 0.0F, 0.0F, 0.5625F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + float var5 = 0.4375F; + float var6 = 0.5625F; + float var7 = 0.4375F; + float var8 = 0.5625F; + boolean var9 = this.canThisPaneConnectToThisBlockID(par1IBlockAccess.getBlockId(par2, par3, par4 - 1)); + boolean var10 = this.canThisPaneConnectToThisBlockID(par1IBlockAccess.getBlockId(par2, par3, par4 + 1)); + boolean var11 = this.canThisPaneConnectToThisBlockID(par1IBlockAccess.getBlockId(par2 - 1, par3, par4)); + boolean var12 = this.canThisPaneConnectToThisBlockID(par1IBlockAccess.getBlockId(par2 + 1, par3, par4)); + + if ((!var11 || !var12) && (var11 || var12 || var9 || var10)) { + if (var11 && !var12) { + var5 = 0.0F; + } else if (!var11 && var12) { + var6 = 1.0F; + } + } else { + var5 = 0.0F; + var6 = 1.0F; + } + + if ((!var9 || !var10) && (var11 || var12 || var9 || var10)) { + if (var9 && !var10) { + var7 = 0.0F; + } else if (!var9 && var10) { + var8 = 1.0F; + } + } else { + var7 = 0.0F; + var8 = 1.0F; + } + + this.setBlockBounds(var5, 0.0F, var7, var6, 1.0F, var8); + } + + /** + * Returns the texture index of the thin side of the pane. + */ + public Icon getSideTextureIndex() { + return this.theIcon; + } + + /** + * Gets passed in the blockID of the block adjacent and supposed to return true + * if its allowed to connect to the type of blockID passed in. Args: blockID + */ + public final boolean canThisPaneConnectToThisBlockID(int par1) { + return Block.opaqueCubeLookup[par1] || par1 == this.blockID || par1 == Block.glass.blockID; + } + + /** + * Return true if a player with Silk Touch can harvest this block directly, and + * not its normal drops. + */ + protected boolean canSilkHarvest() { + return true; + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + return new ItemStack(this.blockID, 1, par1); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon(this.field_94402_c); + this.theIcon = par1IconRegister.registerIcon(this.sideTextureIndex); + } +} diff --git a/src/main/java/net/minecraft/src/BlockPistonBase.java b/src/main/java/net/minecraft/src/BlockPistonBase.java new file mode 100644 index 0000000..b305e4a --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockPistonBase.java @@ -0,0 +1,501 @@ +package net.minecraft.src; + +import java.util.List; + +public class BlockPistonBase extends Block { + /** This pistons is the sticky one? */ + private final boolean isSticky; + + /** Only visible when piston is extended */ + private Icon innerTopIcon; + + /** Bottom side texture */ + private Icon bottomIcon; + + /** Top icon of piston depends on (either sticky or normal) */ + private Icon topIcon; + + public BlockPistonBase(int par1, boolean par2) { + super(par1, Material.piston); + this.isSticky = par2; + this.setStepSound(soundStoneFootstep); + this.setHardness(0.5F); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Return the either 106 or 107 as the texture index depending on the isSticky + * flag. This will actually never get called by + * TileEntityRendererPiston.renderPiston() because + * TileEntityPiston.shouldRenderHead() will always return false. + */ + public Icon getPistonExtensionTexture() { + return this.topIcon; + } + + public void func_96479_b(float par1, float par2, float par3, float par4, float par5, float par6) { + this.setBlockBounds(par1, par2, par3, par4, par5, par6); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + int var3 = getOrientation(par2); + return var3 > 5 ? this.topIcon + : (par1 == var3 ? (!isExtended(par2) && this.minX <= 0.0D && this.minY <= 0.0D && this.minZ <= 0.0D && this.maxX >= 1.0D && this.maxY >= 1.0D && this.maxZ >= 1.0D ? this.topIcon : this.innerTopIcon) + : (par1 == Facing.oppositeSide[var3] ? this.bottomIcon : this.blockIcon)); + } + + public static Icon func_94496_b(String par0Str) { + return par0Str == "piston_side" ? Block.pistonBase.blockIcon + : (par0Str == "piston_top" ? Block.pistonBase.topIcon : (par0Str == "piston_top_sticky" ? Block.pistonStickyBase.topIcon : (par0Str == "piston_inner_top" ? Block.pistonBase.innerTopIcon : null))); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("piston_side"); + this.topIcon = par1IconRegister.registerIcon(this.isSticky ? "piston_top_sticky" : "piston_top"); + this.innerTopIcon = par1IconRegister.registerIcon("piston_inner_top"); + this.bottomIcon = par1IconRegister.registerIcon("piston_bottom"); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 16; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + return false; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + int var7 = determineOrientation(par1World, par2, par3, par4, par5EntityLiving); + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7, 2); + + if (!par1World.isRemote) { + this.updatePistonState(par1World, par2, par3, par4); + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + this.updatePistonState(par1World, par2, par3, par4); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + if (!par1World.isRemote && par1World.getBlockTileEntity(par2, par3, par4) == null) { + this.updatePistonState(par1World, par2, par3, par4); + } + } + + /** + * handles attempts to extend or retract the piston. + */ + private void updatePistonState(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + int var6 = getOrientation(var5); + + if (var6 != 7) { + boolean var7 = this.isIndirectlyPowered(par1World, par2, par3, par4, var6); + + if (var7 && !isExtended(var5)) { + if (canExtend(par1World, par2, par3, par4, var6)) { + par1World.addBlockEvent(par2, par3, par4, this.blockID, 0, var6); + } + } else if (!var7 && isExtended(var5)) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6, 2); + par1World.addBlockEvent(par2, par3, par4, this.blockID, 1, var6); + } + } + } + + /** + * checks the block to that side to see if it is indirectly powered. + */ + private boolean isIndirectlyPowered(World par1World, int par2, int par3, int par4, int par5) { + return par5 != 0 && par1World.getIndirectPowerOutput(par2, par3 - 1, par4, 0) ? true + : (par5 != 1 && par1World.getIndirectPowerOutput(par2, par3 + 1, par4, 1) ? true + : (par5 != 2 && par1World.getIndirectPowerOutput(par2, par3, par4 - 1, 2) ? true + : (par5 != 3 && par1World.getIndirectPowerOutput(par2, par3, par4 + 1, 3) ? true + : (par5 != 5 && par1World.getIndirectPowerOutput(par2 + 1, par3, par4, 5) ? true + : (par5 != 4 && par1World.getIndirectPowerOutput(par2 - 1, par3, par4, 4) ? true + : (par1World.getIndirectPowerOutput(par2, par3, par4, 0) ? true + : (par1World.getIndirectPowerOutput(par2, par3 + 2, par4, 1) ? true + : (par1World.getIndirectPowerOutput(par2, par3 + 1, par4 - 1, 2) ? true + : (par1World.getIndirectPowerOutput(par2, par3 + 1, par4 + 1, 3) ? true + : (par1World.getIndirectPowerOutput(par2 - 1, par3 + 1, par4, 4) ? true : par1World.getIndirectPowerOutput(par2 + 1, par3 + 1, par4, 5))))))))))); + } + + /** + * Called when the block receives a BlockEvent - see World.addBlockEvent. By + * default, passes it on to the tile entity at this location. Args: world, x, y, + * z, blockID, EventID, event parameter + */ + public boolean onBlockEventReceived(World par1World, int par2, int par3, int par4, int par5, int par6) { + if (!par1World.isRemote) { + boolean var7 = this.isIndirectlyPowered(par1World, par2, par3, par4, par6); + + if (var7 && par5 == 1) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, par6 | 8, 2); + return false; + } + + if (!var7 && par5 == 0) { + return false; + } + } + + if (par5 == 0) { + if (!this.tryExtend(par1World, par2, par3, par4, par6)) { + return false; + } + + par1World.setBlockMetadataWithNotify(par2, par3, par4, par6 | 8, 2); + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "tile.piston.out", 0.5F, par1World.rand.nextFloat() * 0.25F + 0.6F); + } else if (par5 == 1) { + TileEntity var16 = par1World.getBlockTileEntity(par2 + Facing.offsetsXForSide[par6], par3 + Facing.offsetsYForSide[par6], par4 + Facing.offsetsZForSide[par6]); + + if (var16 instanceof TileEntityPiston) { + ((TileEntityPiston) var16).clearPistonTileEntity(); + } + + par1World.setBlock(par2, par3, par4, Block.pistonMoving.blockID, par6, 3); + par1World.setBlockTileEntity(par2, par3, par4, BlockPistonMoving.getTileEntity(this.blockID, par6, par6, false, true)); + + if (this.isSticky) { + int var8 = par2 + Facing.offsetsXForSide[par6] * 2; + int var9 = par3 + Facing.offsetsYForSide[par6] * 2; + int var10 = par4 + Facing.offsetsZForSide[par6] * 2; + int var11 = par1World.getBlockId(var8, var9, var10); + int var12 = par1World.getBlockMetadata(var8, var9, var10); + boolean var13 = false; + + if (var11 == Block.pistonMoving.blockID) { + TileEntity var14 = par1World.getBlockTileEntity(var8, var9, var10); + + if (var14 instanceof TileEntityPiston) { + TileEntityPiston var15 = (TileEntityPiston) var14; + + if (var15.getPistonOrientation() == par6 && var15.isExtending()) { + var15.clearPistonTileEntity(); + var11 = var15.getStoredBlockID(); + var12 = var15.getBlockMetadata(); + var13 = true; + } + } + } + + if (!var13 && var11 > 0 && canPushBlock(var11, par1World, var8, var9, var10, false) && (Block.blocksList[var11].getMobilityFlag() == 0 || var11 == Block.pistonBase.blockID || var11 == Block.pistonStickyBase.blockID)) { + par2 += Facing.offsetsXForSide[par6]; + par3 += Facing.offsetsYForSide[par6]; + par4 += Facing.offsetsZForSide[par6]; + par1World.setBlock(par2, par3, par4, Block.pistonMoving.blockID, var12, 3); + par1World.setBlockTileEntity(par2, par3, par4, BlockPistonMoving.getTileEntity(var11, var12, par6, false, false)); + par1World.setBlockToAir(var8, var9, var10); + } else if (!var13) { + par1World.setBlockToAir(par2 + Facing.offsetsXForSide[par6], par3 + Facing.offsetsYForSide[par6], par4 + Facing.offsetsZForSide[par6]); + } + } else { + par1World.setBlockToAir(par2 + Facing.offsetsXForSide[par6], par3 + Facing.offsetsYForSide[par6], par4 + Facing.offsetsZForSide[par6]); + } + + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "tile.piston.in", 0.5F, par1World.rand.nextFloat() * 0.15F + 0.6F); + } + + return true; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if (isExtended(var5)) { + switch (getOrientation(var5)) { + case 0: + this.setBlockBounds(0.0F, 0.25F, 0.0F, 1.0F, 1.0F, 1.0F); + break; + + case 1: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F); + break; + + case 2: + this.setBlockBounds(0.0F, 0.0F, 0.25F, 1.0F, 1.0F, 1.0F); + break; + + case 3: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.75F); + break; + + case 4: + this.setBlockBounds(0.25F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + break; + + case 5: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 0.75F, 1.0F, 1.0F); + } + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * returns an int which describes the direction the piston faces + */ + public static int getOrientation(int par0) { + return par0 & 7; + } + + /** + * Determine if the metadata is related to something powered. + */ + public static boolean isExtended(int par0) { + return (par0 & 8) != 0; + } + + /** + * gets the way this piston should face for that entity that placed it. + */ + public static int determineOrientation(World par0World, int par1, int par2, int par3, EntityLiving par4EntityLiving) { + if (MathHelper.abs((float) par4EntityLiving.posX - (float) par1) < 2.0F && MathHelper.abs((float) par4EntityLiving.posZ - (float) par3) < 2.0F) { + double var5 = par4EntityLiving.posY + 1.82D - (double) par4EntityLiving.yOffset; + + if (var5 - (double) par2 > 2.0D) { + return 1; + } + + if ((double) par2 - var5 > 0.0D) { + return 0; + } + } + + int var7 = MathHelper.floor_double((double) (par4EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + return var7 == 0 ? 2 : (var7 == 1 ? 5 : (var7 == 2 ? 3 : (var7 == 3 ? 4 : 0))); + } + + /** + * returns true if the piston can push the specified block + */ + private static boolean canPushBlock(int par0, World par1World, int par2, int par3, int par4, boolean par5) { + if (par0 == Block.obsidian.blockID) { + return false; + } else { + if (par0 != Block.pistonBase.blockID && par0 != Block.pistonStickyBase.blockID) { + if (Block.blocksList[par0].getBlockHardness(par1World, par2, par3, par4) == -1.0F) { + return false; + } + + if (Block.blocksList[par0].getMobilityFlag() == 2) { + return false; + } + + if (Block.blocksList[par0].getMobilityFlag() == 1) { + if (!par5) { + return false; + } + + return true; + } + } else if (isExtended(par1World.getBlockMetadata(par2, par3, par4))) { + return false; + } + + return !(Block.blocksList[par0] instanceof ITileEntityProvider); + } + } + + /** + * checks to see if this piston could push the blocks in front of it. + */ + private static boolean canExtend(World par0World, int par1, int par2, int par3, int par4) { + int var5 = par1 + Facing.offsetsXForSide[par4]; + int var6 = par2 + Facing.offsetsYForSide[par4]; + int var7 = par3 + Facing.offsetsZForSide[par4]; + int var8 = 0; + + while (true) { + if (var8 < 13) { + if (var6 <= 0 || var6 >= 255) { + return false; + } + + int var9 = par0World.getBlockId(var5, var6, var7); + + if (var9 != 0) { + if (!canPushBlock(var9, par0World, var5, var6, var7, true)) { + return false; + } + + if (Block.blocksList[var9].getMobilityFlag() != 1) { + if (var8 == 12) { + return false; + } + + var5 += Facing.offsetsXForSide[par4]; + var6 += Facing.offsetsYForSide[par4]; + var7 += Facing.offsetsZForSide[par4]; + ++var8; + continue; + } + } + } + + return true; + } + } + + /** + * attempts to extend the piston. returns false if impossible. + */ + private boolean tryExtend(World par1World, int par2, int par3, int par4, int par5) { + int var6 = par2 + Facing.offsetsXForSide[par5]; + int var7 = par3 + Facing.offsetsYForSide[par5]; + int var8 = par4 + Facing.offsetsZForSide[par5]; + int var9 = 0; + + while (true) { + int var10; + + if (var9 < 13) { + if (var7 <= 0 || var7 >= 255) { + return false; + } + + var10 = par1World.getBlockId(var6, var7, var8); + + if (var10 != 0) { + if (!canPushBlock(var10, par1World, var6, var7, var8, true)) { + return false; + } + + if (Block.blocksList[var10].getMobilityFlag() != 1) { + if (var9 == 12) { + return false; + } + + var6 += Facing.offsetsXForSide[par5]; + var7 += Facing.offsetsYForSide[par5]; + var8 += Facing.offsetsZForSide[par5]; + ++var9; + continue; + } + + Block.blocksList[var10].dropBlockAsItem(par1World, var6, var7, var8, par1World.getBlockMetadata(var6, var7, var8), 0); + par1World.setBlockToAir(var6, var7, var8); + } + } + + var9 = var6; + var10 = var7; + int var11 = var8; + int var12 = 0; + int[] var13; + int var14; + int var15; + int var16; + + for (var13 = new int[13]; var6 != par2 || var7 != par3 || var8 != par4; var8 = var16) { + var14 = var6 - Facing.offsetsXForSide[par5]; + var15 = var7 - Facing.offsetsYForSide[par5]; + var16 = var8 - Facing.offsetsZForSide[par5]; + int var17 = par1World.getBlockId(var14, var15, var16); + int var18 = par1World.getBlockMetadata(var14, var15, var16); + + if (var17 == this.blockID && var14 == par2 && var15 == par3 && var16 == par4) { + par1World.setBlock(var6, var7, var8, Block.pistonMoving.blockID, par5 | (this.isSticky ? 8 : 0), 4); + par1World.setBlockTileEntity(var6, var7, var8, BlockPistonMoving.getTileEntity(Block.pistonExtension.blockID, par5 | (this.isSticky ? 8 : 0), par5, true, false)); + } else { + par1World.setBlock(var6, var7, var8, Block.pistonMoving.blockID, var18, 4); + par1World.setBlockTileEntity(var6, var7, var8, BlockPistonMoving.getTileEntity(var17, var18, par5, true, false)); + } + + var13[var12++] = var17; + var6 = var14; + var7 = var15; + } + + var6 = var9; + var7 = var10; + var8 = var11; + + for (var12 = 0; var6 != par2 || var7 != par3 || var8 != par4; var8 = var16) { + var14 = var6 - Facing.offsetsXForSide[par5]; + var15 = var7 - Facing.offsetsYForSide[par5]; + var16 = var8 - Facing.offsetsZForSide[par5]; + par1World.notifyBlocksOfNeighborChange(var14, var15, var16, var13[var12++]); + var6 = var14; + var7 = var15; + } + + return true; + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockPistonExtension.java b/src/main/java/net/minecraft/src/BlockPistonExtension.java new file mode 100644 index 0000000..bf514b0 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockPistonExtension.java @@ -0,0 +1,224 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockPistonExtension extends Block { + /** The texture for the 'head' of the piston. Sticky or normal. */ + private Icon headTexture = null; + + public BlockPistonExtension(int par1) { + super(par1, Material.piston); + this.setStepSound(soundStoneFootstep); + this.setHardness(0.5F); + } + + public void setHeadTexture(Icon par1Icon) { + this.headTexture = par1Icon; + } + + public void clearHeadTexture() { + this.headTexture = null; + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + super.breakBlock(par1World, par2, par3, par4, par5, par6); + int var7 = Facing.oppositeSide[getDirectionMeta(par6)]; + par2 += Facing.offsetsXForSide[var7]; + par3 += Facing.offsetsYForSide[var7]; + par4 += Facing.offsetsZForSide[var7]; + int var8 = par1World.getBlockId(par2, par3, par4); + + if (var8 == Block.pistonBase.blockID || var8 == Block.pistonStickyBase.blockID) { + par6 = par1World.getBlockMetadata(par2, par3, par4); + + if (BlockPistonBase.isExtended(par6)) { + Block.blocksList[var8].dropBlockAsItem(par1World, par2, par3, par4, par6, 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + int var3 = getDirectionMeta(par2); + return par1 == var3 ? (this.headTexture != null ? this.headTexture : ((par2 & 8) != 0 ? BlockPistonBase.func_94496_b("piston_top_sticky") : BlockPistonBase.func_94496_b("piston_top"))) + : (var3 < 6 && par1 == Facing.oppositeSide[var3] ? BlockPistonBase.func_94496_b("piston_top") : BlockPistonBase.func_94496_b("piston_side")); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 17; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return false; + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + return false; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity) { + int var8 = par1World.getBlockMetadata(par2, par3, par4); + + switch (getDirectionMeta(var8)) { + case 0: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.25F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.375F, 0.25F, 0.375F, 0.625F, 1.0F, 0.625F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + break; + + case 1: + this.setBlockBounds(0.0F, 0.75F, 0.0F, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.375F, 0.0F, 0.375F, 0.625F, 0.75F, 0.625F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + break; + + case 2: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.25F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.25F, 0.375F, 0.25F, 0.75F, 0.625F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + break; + + case 3: + this.setBlockBounds(0.0F, 0.0F, 0.75F, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.25F, 0.375F, 0.0F, 0.75F, 0.625F, 0.75F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + break; + + case 4: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 0.25F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.375F, 0.25F, 0.25F, 0.625F, 0.75F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + break; + + case 5: + this.setBlockBounds(0.75F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.0F, 0.375F, 0.25F, 0.75F, 0.625F, 0.75F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + switch (getDirectionMeta(var5)) { + case 0: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.25F, 1.0F); + break; + + case 1: + this.setBlockBounds(0.0F, 0.75F, 0.0F, 1.0F, 1.0F, 1.0F); + break; + + case 2: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.25F); + break; + + case 3: + this.setBlockBounds(0.0F, 0.0F, 0.75F, 1.0F, 1.0F, 1.0F); + break; + + case 4: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 0.25F, 1.0F, 1.0F); + break; + + case 5: + this.setBlockBounds(0.75F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + int var6 = getDirectionMeta(par1World.getBlockMetadata(par2, par3, par4)); + int var7 = par1World.getBlockId(par2 - Facing.offsetsXForSide[var6], par3 - Facing.offsetsYForSide[var6], par4 - Facing.offsetsZForSide[var6]); + + if (var7 != Block.pistonBase.blockID && var7 != Block.pistonStickyBase.blockID) { + par1World.setBlockToAir(par2, par3, par4); + } else { + Block.blocksList[var7].onNeighborBlockChange(par1World, par2 - Facing.offsetsXForSide[var6], par3 - Facing.offsetsYForSide[var6], par4 - Facing.offsetsZForSide[var6], par5); + } + } + + public static int getDirectionMeta(int par0) { + return par0 & 7; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return 0; + } +} diff --git a/src/main/java/net/minecraft/src/BlockPistonMoving.java b/src/main/java/net/minecraft/src/BlockPistonMoving.java new file mode 100644 index 0000000..9e6adaa --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockPistonMoving.java @@ -0,0 +1,235 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockPistonMoving extends BlockContainer { + public BlockPistonMoving(int par1) { + super(par1, Material.piston); + this.setHardness(-1.0F); + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return null; + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + TileEntity var7 = par1World.getBlockTileEntity(par2, par3, par4); + + if (var7 instanceof TileEntityPiston) { + ((TileEntityPiston) var7).clearPistonTileEntity(); + } else { + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return false; + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return -1; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (!par1World.isRemote && par1World.getBlockTileEntity(par2, par3, par4) == null) { + par1World.setBlockToAir(par2, par3, par4); + return true; + } else { + return false; + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return 0; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + if (!par1World.isRemote) { + TileEntityPiston var8 = this.getTileEntityAtLocation(par1World, par2, par3, par4); + + if (var8 != null) { + Block.blocksList[var8.getStoredBlockID()].dropBlockAsItem(par1World, par2, par3, par4, var8.getBlockMetadata(), 0); + } + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote && par1World.getBlockTileEntity(par2, par3, par4) == null) { + ; + } + } + + /** + * gets a new TileEntityPiston created with the arguments provided. + */ + public static TileEntity getTileEntity(int par0, int par1, int par2, boolean par3, boolean par4) { + return new TileEntityPiston(par0, par1, par2, par3, par4); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + TileEntityPiston var5 = this.getTileEntityAtLocation(par1World, par2, par3, par4); + + if (var5 == null) { + return null; + } else { + float var6 = var5.getProgress(0.0F); + + if (var5.isExtending()) { + var6 = 1.0F - var6; + } + + return this.getAxisAlignedBB(par1World, par2, par3, par4, var5.getStoredBlockID(), var6, var5.getPistonOrientation()); + } + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + TileEntityPiston var5 = this.getTileEntityAtLocation(par1IBlockAccess, par2, par3, par4); + + if (var5 != null) { + Block var6 = Block.blocksList[var5.getStoredBlockID()]; + + if (var6 == null || var6 == this) { + return; + } + + var6.setBlockBoundsBasedOnState(par1IBlockAccess, par2, par3, par4); + float var7 = var5.getProgress(0.0F); + + if (var5.isExtending()) { + var7 = 1.0F - var7; + } + + int var8 = var5.getPistonOrientation(); + this.minX = var6.getBlockBoundsMinX() - (double) ((float) Facing.offsetsXForSide[var8] * var7); + this.minY = var6.getBlockBoundsMinY() - (double) ((float) Facing.offsetsYForSide[var8] * var7); + this.minZ = var6.getBlockBoundsMinZ() - (double) ((float) Facing.offsetsZForSide[var8] * var7); + this.maxX = var6.getBlockBoundsMaxX() - (double) ((float) Facing.offsetsXForSide[var8] * var7); + this.maxY = var6.getBlockBoundsMaxY() - (double) ((float) Facing.offsetsYForSide[var8] * var7); + this.maxZ = var6.getBlockBoundsMaxZ() - (double) ((float) Facing.offsetsZForSide[var8] * var7); + } + } + + public AxisAlignedBB getAxisAlignedBB(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + if (par5 != 0 && par5 != this.blockID) { + AxisAlignedBB var8 = Block.blocksList[par5].getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + + if (var8 == null) { + return null; + } else { + if (Facing.offsetsXForSide[par7] < 0) { + var8.minX -= (double) ((float) Facing.offsetsXForSide[par7] * par6); + } else { + var8.maxX -= (double) ((float) Facing.offsetsXForSide[par7] * par6); + } + + if (Facing.offsetsYForSide[par7] < 0) { + var8.minY -= (double) ((float) Facing.offsetsYForSide[par7] * par6); + } else { + var8.maxY -= (double) ((float) Facing.offsetsYForSide[par7] * par6); + } + + if (Facing.offsetsZForSide[par7] < 0) { + var8.minZ -= (double) ((float) Facing.offsetsZForSide[par7] * par6); + } else { + var8.maxZ -= (double) ((float) Facing.offsetsZForSide[par7] * par6); + } + + return var8; + } + } else { + return null; + } + } + + /** + * gets the piston tile entity at the specified location + */ + private TileEntityPiston getTileEntityAtLocation(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + TileEntity var5 = par1IBlockAccess.getBlockTileEntity(par2, par3, par4); + return var5 instanceof TileEntityPiston ? (TileEntityPiston) var5 : null; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return 0; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("piston_top"); + } +} diff --git a/src/main/java/net/minecraft/src/BlockPortal.java b/src/main/java/net/minecraft/src/BlockPortal.java new file mode 100644 index 0000000..6986722 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockPortal.java @@ -0,0 +1,262 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockPortal extends BlockBreakable { + public BlockPortal(int par1) { + super(par1, "portal", Material.portal, false); + this.setTickRandomly(true); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + super.updateTick(par1World, par2, par3, par4, par5Random); + + if (par1World.provider.isSurfaceWorld() && par5Random.nextInt(2000) < par1World.difficultySetting) { + int var6; + + for (var6 = par3; !par1World.doesBlockHaveSolidTopSurface(par2, var6, par4) && var6 > 0; --var6) { + ; + } + + if (var6 > 0 && !par1World.isBlockNormalCube(par2, var6 + 1, par4)) { + Entity var7 = ItemMonsterPlacer.spawnCreature(par1World, 57, (double) par2 + 0.5D, (double) var6 + 1.1D, (double) par4 + 0.5D); + + if (var7 != null) { + var7.timeUntilPortal = var7.getPortalCooldown(); + } + } + } + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + float var5; + float var6; + + if (par1IBlockAccess.getBlockId(par2 - 1, par3, par4) != this.blockID && par1IBlockAccess.getBlockId(par2 + 1, par3, par4) != this.blockID) { + var5 = 0.125F; + var6 = 0.5F; + this.setBlockBounds(0.5F - var5, 0.0F, 0.5F - var6, 0.5F + var5, 1.0F, 0.5F + var6); + } else { + var5 = 0.5F; + var6 = 0.125F; + this.setBlockBounds(0.5F - var5, 0.0F, 0.5F - var6, 0.5F + var5, 1.0F, 0.5F + var6); + } + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Checks to see if this location is valid to create a portal and will return + * True if it does. Args: world, x, y, z + */ + public boolean tryToCreatePortal(World par1World, int par2, int par3, int par4) { + byte var5 = 0; + byte var6 = 0; + + if (par1World.getBlockId(par2 - 1, par3, par4) == Block.obsidian.blockID || par1World.getBlockId(par2 + 1, par3, par4) == Block.obsidian.blockID) { + var5 = 1; + } + + if (par1World.getBlockId(par2, par3, par4 - 1) == Block.obsidian.blockID || par1World.getBlockId(par2, par3, par4 + 1) == Block.obsidian.blockID) { + var6 = 1; + } + + if (var5 == var6) { + return false; + } else { + if (par1World.getBlockId(par2 - var5, par3, par4 - var6) == 0) { + par2 -= var5; + par4 -= var6; + } + + int var7; + int var8; + + for (var7 = -1; var7 <= 2; ++var7) { + for (var8 = -1; var8 <= 3; ++var8) { + boolean var9 = var7 == -1 || var7 == 2 || var8 == -1 || var8 == 3; + + if (var7 != -1 && var7 != 2 || var8 != -1 && var8 != 3) { + int var10 = par1World.getBlockId(par2 + var5 * var7, par3 + var8, par4 + var6 * var7); + + if (var9) { + if (var10 != Block.obsidian.blockID) { + return false; + } + } else if (var10 != 0 && var10 != Block.fire.blockID) { + return false; + } + } + } + } + + for (var7 = 0; var7 < 2; ++var7) { + for (var8 = 0; var8 < 3; ++var8) { + par1World.setBlock(par2 + var5 * var7, par3 + var8, par4 + var6 * var7, Block.portal.blockID, 0, 2); + } + } + + return true; + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + byte var6 = 0; + byte var7 = 1; + + if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID || par1World.getBlockId(par2 + 1, par3, par4) == this.blockID) { + var6 = 1; + var7 = 0; + } + + int var8; + + for (var8 = par3; par1World.getBlockId(par2, var8 - 1, par4) == this.blockID; --var8) { + ; + } + + if (par1World.getBlockId(par2, var8 - 1, par4) != Block.obsidian.blockID) { + par1World.setBlockToAir(par2, par3, par4); + } else { + int var9; + + for (var9 = 1; var9 < 4 && par1World.getBlockId(par2, var8 + var9, par4) == this.blockID; ++var9) { + ; + } + + if (var9 == 3 && par1World.getBlockId(par2, var8 + var9, par4) == Block.obsidian.blockID) { + boolean var10 = par1World.getBlockId(par2 - 1, par3, par4) == this.blockID || par1World.getBlockId(par2 + 1, par3, par4) == this.blockID; + boolean var11 = par1World.getBlockId(par2, par3, par4 - 1) == this.blockID || par1World.getBlockId(par2, par3, par4 + 1) == this.blockID; + + if (var10 && var11) { + par1World.setBlockToAir(par2, par3, par4); + } else { + if ((par1World.getBlockId(par2 + var6, par3, par4 + var7) != Block.obsidian.blockID || par1World.getBlockId(par2 - var6, par3, par4 - var7) != this.blockID) + && (par1World.getBlockId(par2 - var6, par3, par4 - var7) != Block.obsidian.blockID || par1World.getBlockId(par2 + var6, par3, par4 + var7) != this.blockID)) { + par1World.setBlockToAir(par2, par3, par4); + } + } + } else { + par1World.setBlockToAir(par2, par3, par4); + } + } + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + if (par1IBlockAccess.getBlockId(par2, par3, par4) == this.blockID) { + return false; + } else { + boolean var6 = par1IBlockAccess.getBlockId(par2 - 1, par3, par4) == this.blockID && par1IBlockAccess.getBlockId(par2 - 2, par3, par4) != this.blockID; + boolean var7 = par1IBlockAccess.getBlockId(par2 + 1, par3, par4) == this.blockID && par1IBlockAccess.getBlockId(par2 + 2, par3, par4) != this.blockID; + boolean var8 = par1IBlockAccess.getBlockId(par2, par3, par4 - 1) == this.blockID && par1IBlockAccess.getBlockId(par2, par3, par4 - 2) != this.blockID; + boolean var9 = par1IBlockAccess.getBlockId(par2, par3, par4 + 1) == this.blockID && par1IBlockAccess.getBlockId(par2, par3, par4 + 2) != this.blockID; + boolean var10 = var6 || var7; + boolean var11 = var8 || var9; + return var10 && par5 == 4 ? true : (var10 && par5 == 5 ? true : (var11 && par5 == 2 ? true : var11 && par5 == 3)); + } + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Returns which pass should this block be rendered on. 0 for solids and 1 for + * alpha + */ + public int getRenderBlockPass() { + return 1; + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + if (par5Entity.ridingEntity == null && par5Entity.riddenByEntity == null) { + par5Entity.setInPortal(); + } + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par5Random.nextInt(100) == 0) { + par1World.playSound((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "portal.portal", 0.5F, par5Random.nextFloat() * 0.4F + 0.8F, false); + } + + for (int var6 = 0; var6 < 4; ++var6) { + double var7 = (double) ((float) par2 + par5Random.nextFloat()); + double var9 = (double) ((float) par3 + par5Random.nextFloat()); + double var11 = (double) ((float) par4 + par5Random.nextFloat()); + double var13 = 0.0D; + double var15 = 0.0D; + double var17 = 0.0D; + int var19 = par5Random.nextInt(2) * 2 - 1; + var13 = ((double) par5Random.nextFloat() - 0.5D) * 0.5D; + var15 = ((double) par5Random.nextFloat() - 0.5D) * 0.5D; + var17 = ((double) par5Random.nextFloat() - 0.5D) * 0.5D; + + if (par1World.getBlockId(par2 - 1, par3, par4) != this.blockID && par1World.getBlockId(par2 + 1, par3, par4) != this.blockID) { + var7 = (double) par2 + 0.5D + 0.25D * (double) var19; + var13 = (double) (par5Random.nextFloat() * 2.0F * (float) var19); + } else { + var11 = (double) par4 + 0.5D + 0.25D * (double) var19; + var17 = (double) (par5Random.nextFloat() * 2.0F * (float) var19); + } + + par1World.spawnParticle("portal", var7, var9, var11, var13, var15, var17); + } + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return 0; + } +} diff --git a/src/main/java/net/minecraft/src/BlockPotato.java b/src/main/java/net/minecraft/src/BlockPotato.java new file mode 100644 index 0000000..2d85627 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockPotato.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +public class BlockPotato extends BlockCrops { + private Icon[] iconArray; + + public BlockPotato(int par1) { + super(par1); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + if (par2 < 7) { + if (par2 == 6) { + par2 = 5; + } + + return this.iconArray[par2 >> 1]; + } else { + return this.iconArray[3]; + } + } + + /** + * Generate a seed ItemStack for this crop. + */ + protected int getSeedItem() { + return Item.potato.itemID; + } + + /** + * Generate a crop produce ItemStack for this crop. + */ + protected int getCropItem() { + return Item.potato.itemID; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7); + + if (!par1World.isRemote) { + if (par5 >= 7 && par1World.rand.nextInt(50) == 0) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(Item.poisonousPotato)); + } + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.iconArray = new Icon[4]; + + for (int var2 = 0; var2 < this.iconArray.length; ++var2) { + this.iconArray[var2] = par1IconRegister.registerIcon("potatoes_" + var2); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockPoweredOre.java b/src/main/java/net/minecraft/src/BlockPoweredOre.java new file mode 100644 index 0000000..c84d008 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockPoweredOre.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class BlockPoweredOre extends BlockOreStorage { + public BlockPoweredOre(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return 15; + } +} diff --git a/src/main/java/net/minecraft/src/BlockPressurePlate.java b/src/main/java/net/minecraft/src/BlockPressurePlate.java new file mode 100644 index 0000000..e2198cb --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockPressurePlate.java @@ -0,0 +1,62 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class BlockPressurePlate extends BlockBasePressurePlate { + /** The mob type that can trigger this pressure plate. */ + private EnumMobType triggerMobType; + + protected BlockPressurePlate(int par1, String par2Str, Material par3Material, EnumMobType par4EnumMobType) { + super(par1, par2Str, par3Material); + this.triggerMobType = par4EnumMobType; + } + + /** + * Argument is weight (0-15). Return the metadata to be set because of it. + */ + protected int getMetaFromWeight(int par1) { + return par1 > 0 ? 1 : 0; + } + + /** + * Argument is metadata. Returns power level (0-15) + */ + protected int getPowerSupply(int par1) { + return par1 == 1 ? 15 : 0; + } + + /** + * Returns the current state of the pressure plate. Returns a value between 0 + * and 15 based on the number of items on it. + */ + protected int getPlateState(World par1World, int par2, int par3, int par4) { + List var5 = null; + + if (this.triggerMobType == EnumMobType.everything) { + var5 = par1World.getEntitiesWithinAABBExcludingEntity((Entity) null, this.getSensitiveAABB(par2, par3, par4)); + } + + if (this.triggerMobType == EnumMobType.mobs) { + var5 = par1World.getEntitiesWithinAABB(EntityLiving.class, this.getSensitiveAABB(par2, par3, par4)); + } + + if (this.triggerMobType == EnumMobType.players) { + var5 = par1World.getEntitiesWithinAABB(EntityPlayer.class, this.getSensitiveAABB(par2, par3, par4)); + } + + if (!var5.isEmpty()) { + Iterator var6 = var5.iterator(); + + while (var6.hasNext()) { + Entity var7 = (Entity) var6.next(); + + if (!var7.doesEntityNotTriggerPressurePlate()) { + return 15; + } + } + } + + return 0; + } +} diff --git a/src/main/java/net/minecraft/src/BlockPressurePlateWeighted.java b/src/main/java/net/minecraft/src/BlockPressurePlateWeighted.java new file mode 100644 index 0000000..6f0952a --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockPressurePlateWeighted.java @@ -0,0 +1,61 @@ +package net.minecraft.src; + +import java.util.Iterator; + + + +public class BlockPressurePlateWeighted extends BlockBasePressurePlate { + /** The maximum number of items the plate weights. */ + private final int maxItemsWeighted; + + protected BlockPressurePlateWeighted(int par1, String par2Str, Material par3Material, int par4) { + super(par1, par2Str, par3Material); + this.maxItemsWeighted = par4; + } + + /** + * Returns the current state of the pressure plate. Returns a value between 0 + * and 15 based on the number of items on it. + */ + protected int getPlateState(World par1World, int par2, int par3, int par4) { + int var5 = 0; + Iterator var6 = par1World.getEntitiesWithinAABB(EntityItem.class, this.getSensitiveAABB(par2, par3, par4)).iterator(); + + while (var6.hasNext()) { + EntityItem var7 = (EntityItem) var6.next(); + var5 += var7.getEntityItem().stackSize; + + if (var5 >= this.maxItemsWeighted) { + break; + } + } + + if (var5 <= 0) { + return 0; + } else { + float var8 = (float) Math.min(this.maxItemsWeighted, var5) / (float) this.maxItemsWeighted; + return MathHelper.ceiling_float_int(var8 * 15.0F); + } + } + + /** + * Argument is metadata. Returns power level (0-15) + */ + protected int getPowerSupply(int par1) { + return par1; + } + + /** + * Argument is weight (0-15). Return the metadata to be set because of it. + */ + protected int getMetaFromWeight(int par1) { + return par1; + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 10; + } +} diff --git a/src/main/java/net/minecraft/src/BlockPumpkin.java b/src/main/java/net/minecraft/src/BlockPumpkin.java new file mode 100644 index 0000000..2edb20f --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockPumpkin.java @@ -0,0 +1,118 @@ +package net.minecraft.src; + +public class BlockPumpkin extends BlockDirectional { + /** Boolean used to seperate different states of blocks */ + private boolean blockType; + private Icon field_94474_b; + private Icon field_94475_c; + + protected BlockPumpkin(int par1, boolean par2) { + super(par1, Material.pumpkin); + this.setTickRandomly(true); + this.blockType = par2; + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 1 ? this.field_94474_b + : (par1 == 0 ? this.field_94474_b + : (par2 == 2 && par1 == 2 ? this.field_94475_c : (par2 == 3 && par1 == 5 ? this.field_94475_c : (par2 == 0 && par1 == 3 ? this.field_94475_c : (par2 == 1 && par1 == 4 ? this.field_94475_c : this.blockIcon))))); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + + if (par1World.getBlockId(par2, par3 - 1, par4) == Block.blockSnow.blockID && par1World.getBlockId(par2, par3 - 2, par4) == Block.blockSnow.blockID) { + if (!par1World.isRemote) { + par1World.setBlock(par2, par3, par4, 0, 0, 2); + par1World.setBlock(par2, par3 - 1, par4, 0, 0, 2); + par1World.setBlock(par2, par3 - 2, par4, 0, 0, 2); + EntitySnowman var9 = new EntitySnowman(); + var9.setWorld(par1World); + var9.setLocationAndAngles((double) par2 + 0.5D, (double) par3 - 1.95D, (double) par4 + 0.5D, 0.0F, 0.0F); + par1World.spawnEntityInWorld(var9); + par1World.notifyBlockChange(par2, par3, par4, 0); + par1World.notifyBlockChange(par2, par3 - 1, par4, 0); + par1World.notifyBlockChange(par2, par3 - 2, par4, 0); + } + + for (int var10 = 0; var10 < 120; ++var10) { + par1World.spawnParticle("snowshovel", (double) par2 + par1World.rand.nextDouble(), (double) (par3 - 2) + par1World.rand.nextDouble() * 2.5D, (double) par4 + par1World.rand.nextDouble(), 0.0D, 0.0D, 0.0D); + } + } else if (par1World.getBlockId(par2, par3 - 1, par4) == Block.blockIron.blockID && par1World.getBlockId(par2, par3 - 2, par4) == Block.blockIron.blockID) { + boolean var5 = par1World.getBlockId(par2 - 1, par3 - 1, par4) == Block.blockIron.blockID && par1World.getBlockId(par2 + 1, par3 - 1, par4) == Block.blockIron.blockID; + boolean var6 = par1World.getBlockId(par2, par3 - 1, par4 - 1) == Block.blockIron.blockID && par1World.getBlockId(par2, par3 - 1, par4 + 1) == Block.blockIron.blockID; + + if (var5 || var6) { + par1World.setBlock(par2, par3, par4, 0, 0, 2); + par1World.setBlock(par2, par3 - 1, par4, 0, 0, 2); + par1World.setBlock(par2, par3 - 2, par4, 0, 0, 2); + + if (var5) { + par1World.setBlock(par2 - 1, par3 - 1, par4, 0, 0, 2); + par1World.setBlock(par2 + 1, par3 - 1, par4, 0, 0, 2); + } else { + par1World.setBlock(par2, par3 - 1, par4 - 1, 0, 0, 2); + par1World.setBlock(par2, par3 - 1, par4 + 1, 0, 0, 2); + } + + EntityIronGolem var7 = new EntityIronGolem(); + var7.setWorld(par1World); + var7.setPlayerCreated(true); + var7.setLocationAndAngles((double) par2 + 0.5D, (double) par3 - 1.95D, (double) par4 + 0.5D, 0.0F, 0.0F); + par1World.spawnEntityInWorld(var7); + + for (int var8 = 0; var8 < 120; ++var8) { + par1World.spawnParticle("snowballpoof", (double) par2 + par1World.rand.nextDouble(), (double) (par3 - 2) + par1World.rand.nextDouble() * 3.9D, (double) par4 + par1World.rand.nextDouble(), 0.0D, 0.0D, 0.0D); + } + + par1World.notifyBlockChange(par2, par3, par4, 0); + par1World.notifyBlockChange(par2, par3 - 1, par4, 0); + par1World.notifyBlockChange(par2, par3 - 2, par4, 0); + + if (var5) { + par1World.notifyBlockChange(par2 - 1, par3 - 1, par4, 0); + par1World.notifyBlockChange(par2 + 1, par3 - 1, par4, 0); + } else { + par1World.notifyBlockChange(par2, par3 - 1, par4 - 1, 0); + par1World.notifyBlockChange(par2, par3 - 1, par4 + 1, 0); + } + } + } + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockId(par2, par3, par4); + return (var5 == 0 || Block.blocksList[var5].blockMaterial.isReplaceable()) && par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4); + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + int var7 = MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 2.5D) & 3; + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7, 2); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.field_94475_c = par1IconRegister.registerIcon(this.blockType ? "pumpkin_jack" : "pumpkin_face"); + this.field_94474_b = par1IconRegister.registerIcon("pumpkin_top"); + this.blockIcon = par1IconRegister.registerIcon("pumpkin_side"); + } +} diff --git a/src/main/java/net/minecraft/src/BlockQuartz.java b/src/main/java/net/minecraft/src/BlockQuartz.java new file mode 100644 index 0000000..167b6d3 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockQuartz.java @@ -0,0 +1,124 @@ +package net.minecraft.src; + +import java.util.List; + +public class BlockQuartz extends Block { + public static final String[] quartzBlockTypes = new String[] { "default", "chiseled", "lines" }; + private static final String[] quartzBlockTextureTypes = new String[] { "quartzblock_side", "quartzblock_chiseled", "quartzblock_lines", null, null }; + private Icon[] quartzblockIcons; + private Icon quartzblock_chiseled_top; + private Icon quartzblock_lines_top; + private Icon quartzblock_top; + private Icon quartzblock_bottom; + + public BlockQuartz(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + if (par2 != 2 && par2 != 3 && par2 != 4) { + if (par1 != 1 && (par1 != 0 || par2 != 1)) { + if (par1 == 0) { + return this.quartzblock_bottom; + } else { + if (par2 < 0 || par2 >= this.quartzblockIcons.length) { + par2 = 0; + } + + return this.quartzblockIcons[par2]; + } + } else { + return par2 == 1 ? this.quartzblock_chiseled_top : this.quartzblock_top; + } + } else { + return par2 == 2 && (par1 == 1 || par1 == 0) ? this.quartzblock_lines_top + : (par2 == 3 && (par1 == 5 || par1 == 4) ? this.quartzblock_lines_top : (par2 == 4 && (par1 == 2 || par1 == 3) ? this.quartzblock_lines_top : this.quartzblockIcons[par2])); + } + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9) { + if (par9 == 2) { + switch (par5) { + case 0: + case 1: + par9 = 2; + break; + + case 2: + case 3: + par9 = 4; + break; + + case 4: + case 5: + par9 = 3; + } + } + + return par9; + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1 != 3 && par1 != 4 ? par1 : 2; + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + return par1 != 3 && par1 != 4 ? super.createStackedBlock(par1) : new ItemStack(this.blockID, 1, 2); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 39; + } + + /** + * returns a list of blocks with the same ID, but different meta (eg: wood + * returns 4 blocks) + */ + public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + par3List.add(new ItemStack(par1, 1, 0)); + par3List.add(new ItemStack(par1, 1, 1)); + par3List.add(new ItemStack(par1, 1, 2)); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.quartzblockIcons = new Icon[quartzBlockTextureTypes.length]; + + for (int var2 = 0; var2 < this.quartzblockIcons.length; ++var2) { + if (quartzBlockTextureTypes[var2] == null) { + this.quartzblockIcons[var2] = this.quartzblockIcons[var2 - 1]; + } else { + this.quartzblockIcons[var2] = par1IconRegister.registerIcon(quartzBlockTextureTypes[var2]); + } + } + + this.quartzblock_top = par1IconRegister.registerIcon("quartzblock_top"); + this.quartzblock_chiseled_top = par1IconRegister.registerIcon("quartzblock_chiseled_top"); + this.quartzblock_lines_top = par1IconRegister.registerIcon("quartzblock_lines_top"); + this.quartzblock_bottom = par1IconRegister.registerIcon("quartzblock_bottom"); + } +} diff --git a/src/main/java/net/minecraft/src/BlockRail.java b/src/main/java/net/minecraft/src/BlockRail.java new file mode 100644 index 0000000..d265870 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockRail.java @@ -0,0 +1,33 @@ +package net.minecraft.src; + +public class BlockRail extends BlockRailBase { + private Icon theIcon; + + protected BlockRail(int par1) { + super(par1, false); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par2 >= 6 ? this.theIcon : this.blockIcon; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + super.registerIcons(par1IconRegister); + this.theIcon = par1IconRegister.registerIcon("rail_turn"); + } + + protected void func_94358_a(World par1World, int par2, int par3, int par4, int par5, int par6, int par7) { + if (par7 > 0 && Block.blocksList[par7].canProvidePower() && (new BlockBaseRailLogic(this, par1World, par2, par3, par4)).getNumberOfAdjacentTracks() == 3) { + this.refreshTrackShape(par1World, par2, par3, par4, false); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockRailBase.java b/src/main/java/net/minecraft/src/BlockRailBase.java new file mode 100644 index 0000000..d1210cd --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockRailBase.java @@ -0,0 +1,208 @@ +package net.minecraft.src; + +import java.util.Random; + +public abstract class BlockRailBase extends Block { + /** Power related rails have this field at true. */ + protected final boolean isPowered; + + /** + * Returns true if the block at the coordinates of world passed is a valid rail + * block (current is rail, powered or detector). + */ + public static final boolean isRailBlockAt(World par0World, int par1, int par2, int par3) { + return isRailBlock(par0World.getBlockId(par1, par2, par3)); + } + + /** + * Return true if the parameter is a blockID for a valid rail block (current is + * rail, powered or detector). + */ + public static final boolean isRailBlock(int par0) { + return par0 == Block.rail.blockID || par0 == Block.railPowered.blockID || par0 == Block.railDetector.blockID || par0 == Block.railActivator.blockID; + } + + protected BlockRailBase(int par1, boolean par2) { + super(par1, Material.circuits); + this.isPowered = par2; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + this.setCreativeTab(CreativeTabs.tabTransport); + } + + /** + * Returns true if the block is power related rail. + */ + public boolean isPowered() { + return this.isPowered; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Ray traces through the blocks collision from start vector to end vector + * returning a ray trace hit. Args: world, x, y, z, startVec, endVec + */ + public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, Vec3 par6Vec3) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if (var5 >= 2 && var5 <= 5) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.625F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + } + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 9; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + if (!par1World.isRemote) { + this.refreshTrackShape(par1World, par2, par3, par4, true); + + if (this.isPowered) { + this.onNeighborBlockChange(par1World, par2, par3, par4, this.blockID); + } + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + int var7 = var6; + + if (this.isPowered) { + var7 = var6 & 7; + } + + boolean var8 = false; + + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4)) { + var8 = true; + } + + if (var7 == 2 && !par1World.doesBlockHaveSolidTopSurface(par2 + 1, par3, par4)) { + var8 = true; + } + + if (var7 == 3 && !par1World.doesBlockHaveSolidTopSurface(par2 - 1, par3, par4)) { + var8 = true; + } + + if (var7 == 4 && !par1World.doesBlockHaveSolidTopSurface(par2, par3, par4 - 1)) { + var8 = true; + } + + if (var7 == 5 && !par1World.doesBlockHaveSolidTopSurface(par2, par3, par4 + 1)) { + var8 = true; + } + + if (var8) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } else { + this.func_94358_a(par1World, par2, par3, par4, var6, var7, par5); + } + } + } + + protected void func_94358_a(World par1World, int par2, int par3, int par4, int par5, int par6, int par7) { + } + + /** + * Completely recalculates the track shape based on neighboring tracks + */ + protected void refreshTrackShape(World par1World, int par2, int par3, int par4, boolean par5) { + if (!par1World.isRemote) { + (new BlockBaseRailLogic(this, par1World, par2, par3, par4)).func_94511_a(par1World.isBlockIndirectlyGettingPowered(par2, par3, par4), par5); + } + } + + /** + * Returns the mobility information of the block, 0 = free, 1 = can't push but + * can move over, 2 = total immobility and stop pistons + */ + public int getMobilityFlag() { + return 0; + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + int var7 = par6; + + if (this.isPowered) { + var7 = par6 & 7; + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + + if (var7 == 2 || var7 == 3 || var7 == 4 || var7 == 5) { + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, par5); + } + + if (this.isPowered) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, par5); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, par5); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockRailPowered.java b/src/main/java/net/minecraft/src/BlockRailPowered.java new file mode 100644 index 0000000..fd12275 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockRailPowered.java @@ -0,0 +1,154 @@ +package net.minecraft.src; + +public class BlockRailPowered extends BlockRailBase { + protected Icon theIcon; + + protected BlockRailPowered(int par1) { + super(par1, true); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return (par2 & 8) == 0 ? this.blockIcon : this.theIcon; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + super.registerIcons(par1IconRegister); + this.theIcon = par1IconRegister.registerIcon(this.getUnlocalizedName2() + "_powered"); + } + + protected boolean func_94360_a(World par1World, int par2, int par3, int par4, int par5, boolean par6, int par7) { + if (par7 >= 8) { + return false; + } else { + int var8 = par5 & 7; + boolean var9 = true; + + switch (var8) { + case 0: + if (par6) { + ++par4; + } else { + --par4; + } + + break; + + case 1: + if (par6) { + --par2; + } else { + ++par2; + } + + break; + + case 2: + if (par6) { + --par2; + } else { + ++par2; + ++par3; + var9 = false; + } + + var8 = 1; + break; + + case 3: + if (par6) { + --par2; + ++par3; + var9 = false; + } else { + ++par2; + } + + var8 = 1; + break; + + case 4: + if (par6) { + ++par4; + } else { + --par4; + ++par3; + var9 = false; + } + + var8 = 0; + break; + + case 5: + if (par6) { + ++par4; + ++par3; + var9 = false; + } else { + --par4; + } + + var8 = 0; + } + + return this.func_94361_a(par1World, par2, par3, par4, par6, par7, var8) ? true : var9 && this.func_94361_a(par1World, par2, par3 - 1, par4, par6, par7, var8); + } + } + + protected boolean func_94361_a(World par1World, int par2, int par3, int par4, boolean par5, int par6, int par7) { + int var8 = par1World.getBlockId(par2, par3, par4); + + if (var8 == this.blockID) { + int var9 = par1World.getBlockMetadata(par2, par3, par4); + int var10 = var9 & 7; + + if (par7 == 1 && (var10 == 0 || var10 == 4 || var10 == 5)) { + return false; + } + + if (par7 == 0 && (var10 == 1 || var10 == 2 || var10 == 3)) { + return false; + } + + if ((var9 & 8) != 0) { + if (par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + return true; + } + + return this.func_94360_a(par1World, par2, par3, par4, var9, par5, par6 + 1); + } + } + + return false; + } + + protected void func_94358_a(World par1World, int par2, int par3, int par4, int par5, int par6, int par7) { + boolean var8 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4); + var8 = var8 || this.func_94360_a(par1World, par2, par3, par4, par5, true, 0) || this.func_94360_a(par1World, par2, par3, par4, par5, false, 0); + boolean var9 = false; + + if (var8 && (par5 & 8) == 0) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, par6 | 8, 3); + var9 = true; + } else if (!var8 && (par5 & 8) != 0) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, par6, 3); + var9 = true; + } + + if (var9) { + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + + if (par6 == 2 || par6 == 3 || par6 == 4 || par6 == 5) { + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockRedstoneLight.java b/src/main/java/net/minecraft/src/BlockRedstoneLight.java new file mode 100644 index 0000000..d10a699 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockRedstoneLight.java @@ -0,0 +1,82 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockRedstoneLight extends Block { + /** Whether this lamp block is the powered version. */ + private final boolean powered; + + public BlockRedstoneLight(int par1, boolean par2) { + super(par1, Material.redstoneLight); + this.powered = par2; + + if (par2) { + this.setLightValue(1.0F); + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + if (this.powered) { + this.blockIcon = par1IconRegister.registerIcon("redstoneLight_lit"); + } else { + this.blockIcon = par1IconRegister.registerIcon("redstoneLight"); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + if (!par1World.isRemote) { + if (this.powered && !par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, 4); + } else if (!this.powered && par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + par1World.setBlock(par2, par3, par4, Block.redstoneLampActive.blockID, 0, 2); + } + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + if (this.powered && !par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, 4); + } else if (!this.powered && par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + par1World.setBlock(par2, par3, par4, Block.redstoneLampActive.blockID, 0, 2); + } + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote && this.powered && !par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + par1World.setBlock(par2, par3, par4, Block.redstoneLampIdle.blockID, 0, 2); + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.redstoneLampIdle.blockID; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Block.redstoneLampIdle.blockID; + } +} diff --git a/src/main/java/net/minecraft/src/BlockRedstoneLogic.java b/src/main/java/net/minecraft/src/BlockRedstoneLogic.java new file mode 100644 index 0000000..9a6411a --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockRedstoneLogic.java @@ -0,0 +1,335 @@ +package net.minecraft.src; + +import java.util.Random; + + + +public abstract class BlockRedstoneLogic extends BlockDirectional { + /** Tells whether the repeater is powered or not */ + protected final boolean isRepeaterPowered; + + protected BlockRedstoneLogic(int par1, boolean par2) { + super(par1, Material.circuits); + this.isRepeaterPowered = par2; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return !par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) ? false : super.canPlaceBlockAt(par1World, par2, par3, par4); + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + return !par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) ? false : super.canBlockStay(par1World, par2, par3, par4); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (!this.func_94476_e(par1World, par2, par3, par4, var6)) { + boolean var7 = this.func_94478_d(par1World, par2, par3, par4, var6); + + if (this.isRepeaterPowered && !var7) { + par1World.setBlock(par2, par3, par4, this.func_94484_i().blockID, var6, 2); + } else if (!this.isRepeaterPowered) { + par1World.setBlock(par2, par3, par4, this.func_94485_e().blockID, var6, 2); + + if (!var7) { + par1World.func_82740_a(par2, par3, par4, this.func_94485_e().blockID, this.func_94486_g(var6), -1); + } + } + } + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 0 ? (this.isRepeaterPowered ? Block.torchRedstoneActive.getBlockTextureFromSide(par1) : Block.torchRedstoneIdle.getBlockTextureFromSide(par1)) + : (par1 == 1 ? this.blockIcon : Block.stoneDoubleSlab.getBlockTextureFromSide(1)); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon(this.isRepeaterPowered ? "repeater_lit" : "repeater"); + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return par5 != 0 && par5 != 1; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 36; + } + + protected boolean func_96470_c(int par1) { + return this.isRepeaterPowered; + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return this.isProvidingWeakPower(par1IBlockAccess, par2, par3, par4, par5); + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if (!this.func_96470_c(var6)) { + return 0; + } else { + int var7 = getDirection(var6); + return var7 == 0 && par5 == 3 ? this.func_94480_d(par1IBlockAccess, par2, par3, par4, var6) + : (var7 == 1 && par5 == 4 ? this.func_94480_d(par1IBlockAccess, par2, par3, par4, var6) + : (var7 == 2 && par5 == 2 ? this.func_94480_d(par1IBlockAccess, par2, par3, par4, var6) : (var7 == 3 && par5 == 5 ? this.func_94480_d(par1IBlockAccess, par2, par3, par4, var6) : 0))); + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!this.canBlockStay(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + } else { + this.func_94479_f(par1World, par2, par3, par4, par5); + } + } + + protected void func_94479_f(World par1World, int par2, int par3, int par4, int par5) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (!this.func_94476_e(par1World, par2, par3, par4, var6)) { + boolean var7 = this.func_94478_d(par1World, par2, par3, par4, var6); + + if ((this.isRepeaterPowered && !var7 || !this.isRepeaterPowered && var7) && !par1World.isBlockTickScheduled(par2, par3, par4, this.blockID)) { + byte var8 = -1; + + if (this.func_83011_d(par1World, par2, par3, par4, var6)) { + var8 = -3; + } else if (this.isRepeaterPowered) { + var8 = -2; + } + + par1World.func_82740_a(par2, par3, par4, this.blockID, this.func_94481_j_(var6), var8); + } + } + } + + public boolean func_94476_e(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return false; + } + + protected boolean func_94478_d(World par1World, int par2, int par3, int par4, int par5) { + return this.getInputStrength(par1World, par2, par3, par4, par5) > 0; + } + + /** + * Returns the signal strength at one input of the block. Args: world, X, Y, Z, + * side + */ + protected int getInputStrength(World par1World, int par2, int par3, int par4, int par5) { + int var6 = getDirection(par5); + int var7 = par2 + Direction.offsetX[var6]; + int var8 = par4 + Direction.offsetZ[var6]; + int var9 = par1World.getIndirectPowerLevelTo(var7, par3, var8, Direction.directionToFacing[var6]); + return var9 >= 15 ? var9 : Math.max(var9, par1World.getBlockId(var7, par3, var8) == Block.redstoneWire.blockID ? par1World.getBlockMetadata(var7, par3, var8) : 0); + } + + protected int func_94482_f(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = getDirection(par5); + + switch (var6) { + case 0: + case 2: + return Math.max(this.func_94488_g(par1IBlockAccess, par2 - 1, par3, par4, 4), this.func_94488_g(par1IBlockAccess, par2 + 1, par3, par4, 5)); + + case 1: + case 3: + return Math.max(this.func_94488_g(par1IBlockAccess, par2, par3, par4 + 1, 3), this.func_94488_g(par1IBlockAccess, par2, par3, par4 - 1, 2)); + + default: + return 0; + } + } + + protected int func_94488_g(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = par1IBlockAccess.getBlockId(par2, par3, par4); + return this.func_94477_d(var6) ? (var6 == Block.redstoneWire.blockID ? par1IBlockAccess.getBlockMetadata(par2, par3, par4) : par1IBlockAccess.isBlockProvidingPowerTo(par2, par3, par4, par5)) : 0; + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + int var7 = ((MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) + 2) % 4; + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7, 3); + boolean var8 = this.func_94478_d(par1World, par2, par3, par4, var7); + + if (var8) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, 1); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + this.func_94483_i_(par1World, par2, par3, par4); + } + + protected void func_94483_i_(World par1World, int par2, int par3, int par4) { + int var5 = getDirection(par1World.getBlockMetadata(par2, par3, par4)); + + if (var5 == 1) { + par1World.notifyBlockOfNeighborChange(par2 + 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID, 4); + } + + if (var5 == 3) { + par1World.notifyBlockOfNeighborChange(par2 - 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID, 5); + } + + if (var5 == 2) { + par1World.notifyBlockOfNeighborChange(par2, par3, par4 + 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID, 2); + } + + if (var5 == 0) { + par1World.notifyBlockOfNeighborChange(par2, par3, par4 - 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID, 3); + } + } + + /** + * Called right before the block is destroyed by a player. Args: world, x, y, z, + * metaData + */ + public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) { + if (this.isRepeaterPowered) { + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + } + + super.onBlockDestroyedByPlayer(par1World, par2, par3, par4, par5); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + protected boolean func_94477_d(int par1) { + Block var2 = Block.blocksList[par1]; + return var2 != null && var2.canProvidePower(); + } + + protected int func_94480_d(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return 15; + } + + public static boolean isRedstoneRepeaterBlockID(int par0) { + return Block.redstoneRepeaterIdle.func_94487_f(par0) || Block.redstoneComparatorIdle.func_94487_f(par0); + } + + public boolean func_94487_f(int par1) { + return par1 == this.func_94485_e().blockID || par1 == this.func_94484_i().blockID; + } + + public boolean func_83011_d(World par1World, int par2, int par3, int par4, int par5) { + int var6 = getDirection(par5); + + if (isRedstoneRepeaterBlockID(par1World.getBlockId(par2 - Direction.offsetX[var6], par3, par4 - Direction.offsetZ[var6]))) { + int var7 = par1World.getBlockMetadata(par2 - Direction.offsetX[var6], par3, par4 - Direction.offsetZ[var6]); + int var8 = getDirection(var7); + return var8 != var6; + } else { + return false; + } + } + + protected int func_94486_g(int par1) { + return this.func_94481_j_(par1); + } + + protected abstract int func_94481_j_(int var1); + + protected abstract BlockRedstoneLogic func_94485_e(); + + protected abstract BlockRedstoneLogic func_94484_i(); + + /** + * Returns true if the given block ID is equivalent to this one. Example: + * redstoneTorchOn matches itself and redstoneTorchOff, and vice versa. Most + * blocks only match themselves. + */ + public boolean isAssociatedBlockID(int par1) { + return this.func_94487_f(par1); + } +} diff --git a/src/main/java/net/minecraft/src/BlockRedstoneOre.java b/src/main/java/net/minecraft/src/BlockRedstoneOre.java new file mode 100644 index 0000000..3f83a25 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockRedstoneOre.java @@ -0,0 +1,164 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockRedstoneOre extends Block { + private boolean glowing; + + public BlockRedstoneOre(int par1, boolean par2) { + super(par1, Material.rock); + + if (par2) { + this.setTickRandomly(true); + } + + this.glowing = par2; + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 30; + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + this.glow(par1World, par2, par3, par4); + super.onBlockClicked(par1World, par2, par3, par4, par5EntityPlayer); + } + + /** + * Called whenever an entity is walking on top of this block. Args: world, x, y, + * z, entity + */ + public void onEntityWalking(World par1World, int par2, int par3, int par4, Entity par5Entity) { + this.glow(par1World, par2, par3, par4); + super.onEntityWalking(par1World, par2, par3, par4, par5Entity); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + this.glow(par1World, par2, par3, par4); + return super.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, par6, par7, par8, par9); + } + + /** + * The redstone ore glows. + */ + private void glow(World par1World, int par2, int par3, int par4) { + this.sparkle(par1World, par2, par3, par4); + + if (this.blockID == Block.oreRedstone.blockID) { + par1World.setBlock(par2, par3, par4, Block.oreRedstoneGlowing.blockID); + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (this.blockID == Block.oreRedstoneGlowing.blockID) { + par1World.setBlock(par2, par3, par4, Block.oreRedstone.blockID); + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.redstone.itemID; + } + + /** + * Returns the usual quantity dropped by the block plus a bonus of 1 to 'i' + * (inclusive). + */ + public int quantityDroppedWithBonus(int par1, Random par2Random) { + return this.quantityDropped(par2Random) + par2Random.nextInt(par1 + 1); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 4 + par1Random.nextInt(2); + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7); + + if (this.idDropped(par5, par1World.rand, par7) != this.blockID) { + int var8 = 1 + par1World.rand.nextInt(5); + this.dropXpOnBlockBreak(par1World, par2, par3, par4, var8); + } + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (this.glowing) { + this.sparkle(par1World, par2, par3, par4); + } + } + + /** + * The redstone ore sparkles. + */ + private void sparkle(World par1World, int par2, int par3, int par4) { + Random var5 = par1World.rand; + double var6 = 0.0625D; + + for (int var8 = 0; var8 < 6; ++var8) { + double var9 = (double) ((float) par2 + var5.nextFloat()); + double var11 = (double) ((float) par3 + var5.nextFloat()); + double var13 = (double) ((float) par4 + var5.nextFloat()); + + if (var8 == 0 && !par1World.isBlockOpaqueCube(par2, par3 + 1, par4)) { + var11 = (double) (par3 + 1) + var6; + } + + if (var8 == 1 && !par1World.isBlockOpaqueCube(par2, par3 - 1, par4)) { + var11 = (double) (par3 + 0) - var6; + } + + if (var8 == 2 && !par1World.isBlockOpaqueCube(par2, par3, par4 + 1)) { + var13 = (double) (par4 + 1) + var6; + } + + if (var8 == 3 && !par1World.isBlockOpaqueCube(par2, par3, par4 - 1)) { + var13 = (double) (par4 + 0) - var6; + } + + if (var8 == 4 && !par1World.isBlockOpaqueCube(par2 + 1, par3, par4)) { + var9 = (double) (par2 + 1) + var6; + } + + if (var8 == 5 && !par1World.isBlockOpaqueCube(par2 - 1, par3, par4)) { + var9 = (double) (par2 + 0) - var6; + } + + if (var9 < (double) par2 || var9 > (double) (par2 + 1) || var11 < 0.0D || var11 > (double) (par3 + 1) || var13 < (double) par4 || var13 > (double) (par4 + 1)) { + par1World.spawnParticle("reddust", var9, var11, var13, 0.0D, 0.0D, 0.0D); + } + } + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + return new ItemStack(Block.oreRedstone); + } +} diff --git a/src/main/java/net/minecraft/src/BlockRedstoneRepeater.java b/src/main/java/net/minecraft/src/BlockRedstoneRepeater.java new file mode 100644 index 0000000..e17d992 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockRedstoneRepeater.java @@ -0,0 +1,133 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockRedstoneRepeater extends BlockRedstoneLogic { + /** The offsets for the two torches in redstone repeater blocks. */ + public static final double[] repeaterTorchOffset = new double[] { -0.0625D, 0.0625D, 0.1875D, 0.3125D }; + + /** The states in which the redstone repeater blocks can be. */ + private static final int[] repeaterState = new int[] { 1, 2, 3, 4 }; + + protected BlockRedstoneRepeater(int par1, boolean par2) { + super(par1, par2); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + int var11 = (var10 & 12) >> 2; + var11 = var11 + 1 << 2 & 12; + par1World.setBlockMetadataWithNotify(par2, par3, par4, var11 | var10 & 3, 3); + return true; + } + + protected int func_94481_j_(int par1) { + return repeaterState[(par1 & 12) >> 2] * 2; + } + + protected BlockRedstoneLogic func_94485_e() { + return Block.redstoneRepeaterActive; + } + + protected BlockRedstoneLogic func_94484_i() { + return Block.redstoneRepeaterIdle; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.redstoneRepeater.itemID; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Item.redstoneRepeater.itemID; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 15; + } + + public boolean func_94476_e(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return this.func_94482_f(par1IBlockAccess, par2, par3, par4, par5) > 0; + } + + protected boolean func_94477_d(int par1) { + return isRedstoneRepeaterBlockID(par1); + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (this.isRepeaterPowered) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + int var7 = getDirection(var6); + double var8 = (double) ((float) par2 + 0.5F) + (double) (par5Random.nextFloat() - 0.5F) * 0.2D; + double var10 = (double) ((float) par3 + 0.4F) + (double) (par5Random.nextFloat() - 0.5F) * 0.2D; + double var12 = (double) ((float) par4 + 0.5F) + (double) (par5Random.nextFloat() - 0.5F) * 0.2D; + double var14 = 0.0D; + double var16 = 0.0D; + + if (par5Random.nextInt(2) == 0) { + switch (var7) { + case 0: + var16 = -0.3125D; + break; + + case 1: + var14 = 0.3125D; + break; + + case 2: + var16 = 0.3125D; + break; + + case 3: + var14 = -0.3125D; + } + } else { + int var18 = (var6 & 12) >> 2; + + switch (var7) { + case 0: + var16 = repeaterTorchOffset[var18]; + break; + + case 1: + var14 = -repeaterTorchOffset[var18]; + break; + + case 2: + var16 = -repeaterTorchOffset[var18]; + break; + + case 3: + var14 = repeaterTorchOffset[var18]; + } + } + + par1World.spawnParticle("reddust", var8 + var14, var10, var12 + var16, 0.0D, 0.0D, 0.0D); + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + super.breakBlock(par1World, par2, par3, par4, par5, par6); + this.func_94483_i_(par1World, par2, par3, par4); + } +} diff --git a/src/main/java/net/minecraft/src/BlockRedstoneTorch.java b/src/main/java/net/minecraft/src/BlockRedstoneTorch.java new file mode 100644 index 0000000..c625067 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockRedstoneTorch.java @@ -0,0 +1,245 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +public class BlockRedstoneTorch extends BlockTorch { + /** Whether the redstone torch is currently active or not. */ + private boolean torchActive = false; + + /** Map of ArrayLists of RedstoneUpdateInfo. Key of map is World. */ + private static Map redstoneUpdateInfoCache = new HashMap(); + + private boolean checkForBurnout(World par1World, int par2, int par3, int par4, boolean par5) { + if (!redstoneUpdateInfoCache.containsKey(par1World)) { + redstoneUpdateInfoCache.put(par1World, new ArrayList()); + } + + List var6 = (List) redstoneUpdateInfoCache.get(par1World); + + if (par5) { + var6.add(new RedstoneUpdateInfo(par2, par3, par4, par1World.getTotalWorldTime())); + } + + int var7 = 0; + + for (int var8 = 0; var8 < var6.size(); ++var8) { + RedstoneUpdateInfo var9 = (RedstoneUpdateInfo) var6.get(var8); + + if (var9.x == par2 && var9.y == par3 && var9.z == par4) { + ++var7; + + if (var7 >= 8) { + return true; + } + } + } + + return false; + } + + protected BlockRedstoneTorch(int par1, boolean par2) { + super(par1); + this.torchActive = par2; + this.setTickRandomly(true); + this.setCreativeTab((CreativeTabs) null); + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 2; + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + if (par1World.getBlockMetadata(par2, par3, par4) == 0) { + super.onBlockAdded(par1World, par2, par3, par4); + } + + if (this.torchActive) { + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + if (this.torchActive) { + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + } + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + if (!this.torchActive) { + return 0; + } else { + int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + return var6 == 5 && par5 == 1 ? 0 : (var6 == 3 && par5 == 3 ? 0 : (var6 == 4 && par5 == 2 ? 0 : (var6 == 1 && par5 == 5 ? 0 : (var6 == 2 && par5 == 4 ? 0 : 15)))); + } + } + + /** + * Returns true or false based on whether the block the torch is attached to is + * providing indirect power. + */ + private boolean isIndirectlyPowered(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + return var5 == 5 && par1World.getIndirectPowerOutput(par2, par3 - 1, par4, 0) ? true + : (var5 == 3 && par1World.getIndirectPowerOutput(par2, par3, par4 - 1, 2) ? true + : (var5 == 4 && par1World.getIndirectPowerOutput(par2, par3, par4 + 1, 3) ? true + : (var5 == 1 && par1World.getIndirectPowerOutput(par2 - 1, par3, par4, 4) ? true : var5 == 2 && par1World.getIndirectPowerOutput(par2 + 1, par3, par4, 5)))); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + boolean var6 = this.isIndirectlyPowered(par1World, par2, par3, par4); + List var7 = (List) redstoneUpdateInfoCache.get(par1World); + + while (var7 != null && !var7.isEmpty() && par1World.getTotalWorldTime() - ((RedstoneUpdateInfo) var7.get(0)).updateTime > 60L) { + var7.remove(0); + } + + if (this.torchActive) { + if (var6) { + par1World.setBlock(par2, par3, par4, Block.torchRedstoneIdle.blockID, par1World.getBlockMetadata(par2, par3, par4), 3); + + if (this.checkForBurnout(par1World, par2, par3, par4, true)) { + par1World.playSoundEffect((double) ((float) par2 + 0.5F), (double) ((float) par3 + 0.5F), (double) ((float) par4 + 0.5F), "random.fizz", 0.5F, 2.6F + (par1World.rand.nextFloat() - par1World.rand.nextFloat()) * 0.8F); + + for (int var8 = 0; var8 < 5; ++var8) { + double var9 = (double) par2 + par5Random.nextDouble() * 0.6D + 0.2D; + double var11 = (double) par3 + par5Random.nextDouble() * 0.6D + 0.2D; + double var13 = (double) par4 + par5Random.nextDouble() * 0.6D + 0.2D; + par1World.spawnParticle("smoke", var9, var11, var13, 0.0D, 0.0D, 0.0D); + } + } + } + } else if (!var6 && !this.checkForBurnout(par1World, par2, par3, par4, false)) { + par1World.setBlock(par2, par3, par4, Block.torchRedstoneActive.blockID, par1World.getBlockMetadata(par2, par3, par4), 3); + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!this.func_94397_d(par1World, par2, par3, par4, par5)) { + boolean var6 = this.isIndirectlyPowered(par1World, par2, par3, par4); + + if (this.torchActive && var6 || !this.torchActive && !var6) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + } + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return par5 == 0 ? this.isProvidingWeakPower(par1IBlockAccess, par2, par3, par4, par5) : 0; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.torchRedstoneActive.blockID; + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (this.torchActive) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + double var7 = (double) ((float) par2 + 0.5F) + (double) (par5Random.nextFloat() - 0.5F) * 0.2D; + double var9 = (double) ((float) par3 + 0.7F) + (double) (par5Random.nextFloat() - 0.5F) * 0.2D; + double var11 = (double) ((float) par4 + 0.5F) + (double) (par5Random.nextFloat() - 0.5F) * 0.2D; + double var13 = 0.2199999988079071D; + double var15 = 0.27000001072883606D; + + if (var6 == 1) { + par1World.spawnParticle("reddust", var7 - var15, var9 + var13, var11, 0.0D, 0.0D, 0.0D); + } else if (var6 == 2) { + par1World.spawnParticle("reddust", var7 + var15, var9 + var13, var11, 0.0D, 0.0D, 0.0D); + } else if (var6 == 3) { + par1World.spawnParticle("reddust", var7, var9 + var13, var11 - var15, 0.0D, 0.0D, 0.0D); + } else if (var6 == 4) { + par1World.spawnParticle("reddust", var7, var9 + var13, var11 + var15, 0.0D, 0.0D, 0.0D); + } else { + par1World.spawnParticle("reddust", var7, var9, var11, 0.0D, 0.0D, 0.0D); + } + } + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Block.torchRedstoneActive.blockID; + } + + /** + * Returns true if the given block ID is equivalent to this one. Example: + * redstoneTorchOn matches itself and redstoneTorchOff, and vice versa. Most + * blocks only match themselves. + */ + public boolean isAssociatedBlockID(int par1) { + return par1 == Block.torchRedstoneIdle.blockID || par1 == Block.torchRedstoneActive.blockID; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + if (this.torchActive) { + this.blockIcon = par1IconRegister.registerIcon("redtorch_lit"); + } else { + this.blockIcon = par1IconRegister.registerIcon("redtorch"); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockRedstoneWire.java b/src/main/java/net/minecraft/src/BlockRedstoneWire.java new file mode 100644 index 0000000..09d24dd --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockRedstoneWire.java @@ -0,0 +1,464 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +public class BlockRedstoneWire extends Block { + /** + * When false, power transmission methods do not look at other redstone wires. + * Used internally during updateCurrentStrength. + */ + private boolean wiresProvidePower = true; + private Set blocksNeedingUpdate = new HashSet(); + private Icon field_94413_c; + private Icon field_94410_cO; + private Icon field_94411_cP; + private Icon field_94412_cQ; + + public BlockRedstoneWire(int par1) { + super(par1, Material.circuits); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.0625F, 1.0F); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 5; + } + + /** + * Returns a integer with hex for 0xrrggbb with this color multiplied against + * the blocks color. Note only called when first determining what to render. + */ + public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return 8388608; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) || par1World.getBlockId(par2, par3 - 1, par4) == Block.glowStone.blockID; + } + + /** + * Sets the strength of the wire current (0-15) for this block based on + * neighboring blocks and propagates to neighboring redstone wires + */ + private void updateAndPropagateCurrentStrength(World par1World, int par2, int par3, int par4) { + this.calculateCurrentChanges(par1World, par2, par3, par4, par2, par3, par4); + ArrayList var5 = new ArrayList(this.blocksNeedingUpdate); + this.blocksNeedingUpdate.clear(); + + for (int var6 = 0; var6 < var5.size(); ++var6) { + ChunkPosition var7 = (ChunkPosition) var5.get(var6); + par1World.notifyBlocksOfNeighborChange(var7.x, var7.y, var7.z, this.blockID); + } + } + + private void calculateCurrentChanges(World par1World, int par2, int par3, int par4, int par5, int par6, int par7) { + int var8 = par1World.getBlockMetadata(par2, par3, par4); + byte var9 = 0; + int var15 = this.getMaxCurrentStrength(par1World, par5, par6, par7, var9); + this.wiresProvidePower = false; + int var10 = par1World.getStrongestIndirectPower(par2, par3, par4); + this.wiresProvidePower = true; + + if (var10 > 0 && var10 > var15 - 1) { + var15 = var10; + } + + int var11 = 0; + + for (int var12 = 0; var12 < 4; ++var12) { + int var13 = par2; + int var14 = par4; + + if (var12 == 0) { + var13 = par2 - 1; + } + + if (var12 == 1) { + ++var13; + } + + if (var12 == 2) { + var14 = par4 - 1; + } + + if (var12 == 3) { + ++var14; + } + + if (var13 != par5 || var14 != par7) { + var11 = this.getMaxCurrentStrength(par1World, var13, par3, var14, var11); + } + + if (par1World.isBlockNormalCube(var13, par3, var14) && !par1World.isBlockNormalCube(par2, par3 + 1, par4)) { + if ((var13 != par5 || var14 != par7) && par3 >= par6) { + var11 = this.getMaxCurrentStrength(par1World, var13, par3 + 1, var14, var11); + } + } else if (!par1World.isBlockNormalCube(var13, par3, var14) && (var13 != par5 || var14 != par7) && par3 <= par6) { + var11 = this.getMaxCurrentStrength(par1World, var13, par3 - 1, var14, var11); + } + } + + if (var11 > var15) { + var15 = var11 - 1; + } else if (var15 > 0) { + --var15; + } else { + var15 = 0; + } + + if (var10 > var15 - 1) { + var15 = var10; + } + + if (var8 != var15) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var15, 2); + this.blocksNeedingUpdate.add(new ChunkPosition(par2, par3, par4)); + this.blocksNeedingUpdate.add(new ChunkPosition(par2 - 1, par3, par4)); + this.blocksNeedingUpdate.add(new ChunkPosition(par2 + 1, par3, par4)); + this.blocksNeedingUpdate.add(new ChunkPosition(par2, par3 - 1, par4)); + this.blocksNeedingUpdate.add(new ChunkPosition(par2, par3 + 1, par4)); + this.blocksNeedingUpdate.add(new ChunkPosition(par2, par3, par4 - 1)); + this.blocksNeedingUpdate.add(new ChunkPosition(par2, par3, par4 + 1)); + } + } + + /** + * Calls World.notifyBlocksOfNeighborChange() for all neighboring blocks, but + * only if the given block is a redstone wire. + */ + private void notifyWireNeighborsOfNeighborChange(World par1World, int par2, int par3, int par4) { + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + + if (!par1World.isRemote) { + this.updateAndPropagateCurrentStrength(par1World, par2, par3, par4); + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + this.notifyWireNeighborsOfNeighborChange(par1World, par2 - 1, par3, par4); + this.notifyWireNeighborsOfNeighborChange(par1World, par2 + 1, par3, par4); + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3, par4 - 1); + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3, par4 + 1); + + if (par1World.isBlockNormalCube(par2 - 1, par3, par4)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 - 1, par3 + 1, par4); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 - 1, par3 - 1, par4); + } + + if (par1World.isBlockNormalCube(par2 + 1, par3, par4)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 + 1, par3 + 1, par4); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 + 1, par3 - 1, par4); + } + + if (par1World.isBlockNormalCube(par2, par3, par4 - 1)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 + 1, par4 - 1); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 - 1, par4 - 1); + } + + if (par1World.isBlockNormalCube(par2, par3, par4 + 1)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 + 1, par4 + 1); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 - 1, par4 + 1); + } + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + super.breakBlock(par1World, par2, par3, par4, par5, par6); + + if (!par1World.isRemote) { + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + this.updateAndPropagateCurrentStrength(par1World, par2, par3, par4); + this.notifyWireNeighborsOfNeighborChange(par1World, par2 - 1, par3, par4); + this.notifyWireNeighborsOfNeighborChange(par1World, par2 + 1, par3, par4); + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3, par4 - 1); + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3, par4 + 1); + + if (par1World.isBlockNormalCube(par2 - 1, par3, par4)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 - 1, par3 + 1, par4); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 - 1, par3 - 1, par4); + } + + if (par1World.isBlockNormalCube(par2 + 1, par3, par4)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 + 1, par3 + 1, par4); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 + 1, par3 - 1, par4); + } + + if (par1World.isBlockNormalCube(par2, par3, par4 - 1)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 + 1, par4 - 1); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 - 1, par4 - 1); + } + + if (par1World.isBlockNormalCube(par2, par3, par4 + 1)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 + 1, par4 + 1); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 - 1, par4 + 1); + } + } + } + + /** + * Returns the current strength at the specified block if it is greater than the + * passed value, or the passed value otherwise. Signature: (world, x, y, z, + * strength) + */ + private int getMaxCurrentStrength(World par1World, int par2, int par3, int par4, int par5) { + if (par1World.getBlockId(par2, par3, par4) != this.blockID) { + return par5; + } else { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + return var6 > par5 ? var6 : par5; + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + boolean var6 = this.canPlaceBlockAt(par1World, par2, par3, par4); + + if (var6) { + this.updateAndPropagateCurrentStrength(par1World, par2, par3, par4); + } else { + this.dropBlockAsItem(par1World, par2, par3, par4, 0, 0); + par1World.setBlockToAir(par2, par3, par4); + } + + super.onNeighborBlockChange(par1World, par2, par3, par4, par5); + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.redstone.itemID; + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return !this.wiresProvidePower ? 0 : this.isProvidingWeakPower(par1IBlockAccess, par2, par3, par4, par5); + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + if (!this.wiresProvidePower) { + return 0; + } else { + int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if (var6 == 0) { + return 0; + } else if (par5 == 1) { + return var6; + } else { + boolean var7 = isPoweredOrRepeater(par1IBlockAccess, par2 - 1, par3, par4, 1) || !par1IBlockAccess.isBlockNormalCube(par2 - 1, par3, par4) && isPoweredOrRepeater(par1IBlockAccess, par2 - 1, par3 - 1, par4, -1); + boolean var8 = isPoweredOrRepeater(par1IBlockAccess, par2 + 1, par3, par4, 3) || !par1IBlockAccess.isBlockNormalCube(par2 + 1, par3, par4) && isPoweredOrRepeater(par1IBlockAccess, par2 + 1, par3 - 1, par4, -1); + boolean var9 = isPoweredOrRepeater(par1IBlockAccess, par2, par3, par4 - 1, 2) || !par1IBlockAccess.isBlockNormalCube(par2, par3, par4 - 1) && isPoweredOrRepeater(par1IBlockAccess, par2, par3 - 1, par4 - 1, -1); + boolean var10 = isPoweredOrRepeater(par1IBlockAccess, par2, par3, par4 + 1, 0) || !par1IBlockAccess.isBlockNormalCube(par2, par3, par4 + 1) && isPoweredOrRepeater(par1IBlockAccess, par2, par3 - 1, par4 + 1, -1); + + if (!par1IBlockAccess.isBlockNormalCube(par2, par3 + 1, par4)) { + if (par1IBlockAccess.isBlockNormalCube(par2 - 1, par3, par4) && isPoweredOrRepeater(par1IBlockAccess, par2 - 1, par3 + 1, par4, -1)) { + var7 = true; + } + + if (par1IBlockAccess.isBlockNormalCube(par2 + 1, par3, par4) && isPoweredOrRepeater(par1IBlockAccess, par2 + 1, par3 + 1, par4, -1)) { + var8 = true; + } + + if (par1IBlockAccess.isBlockNormalCube(par2, par3, par4 - 1) && isPoweredOrRepeater(par1IBlockAccess, par2, par3 + 1, par4 - 1, -1)) { + var9 = true; + } + + if (par1IBlockAccess.isBlockNormalCube(par2, par3, par4 + 1) && isPoweredOrRepeater(par1IBlockAccess, par2, par3 + 1, par4 + 1, -1)) { + var10 = true; + } + } + + return !var9 && !var8 && !var7 && !var10 && par5 >= 2 && par5 <= 5 ? var6 + : (par5 == 2 && var9 && !var7 && !var8 ? var6 : (par5 == 3 && var10 && !var7 && !var8 ? var6 : (par5 == 4 && var7 && !var9 && !var10 ? var6 : (par5 == 5 && var8 && !var9 && !var10 ? var6 : 0)))); + } + } + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return this.wiresProvidePower; + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (var6 > 0) { + double var7 = (double) par2 + 0.5D + ((double) par5Random.nextFloat() - 0.5D) * 0.2D; + double var9 = (double) ((float) par3 + 0.0625F); + double var11 = (double) par4 + 0.5D + ((double) par5Random.nextFloat() - 0.5D) * 0.2D; + float var13 = (float) var6 / 15.0F; + float var14 = var13 * 0.6F + 0.4F; + + if (var6 == 0) { + var14 = 0.0F; + } + + float var15 = var13 * var13 * 0.7F - 0.5F; + float var16 = var13 * var13 * 0.6F - 0.7F; + + if (var15 < 0.0F) { + var15 = 0.0F; + } + + if (var16 < 0.0F) { + var16 = 0.0F; + } + + par1World.spawnParticle("reddust", var7, var9, var11, (double) var14, (double) var15, (double) var16); + } + } + + /** + * Returns true if redstone wire can connect to the specified block. Params: + * World, X, Y, Z, side (not a normal notch-side, this can be 0, 1, 2, 3 or -1) + */ + public static boolean isPowerProviderOrWire(IBlockAccess par0IBlockAccess, int par1, int par2, int par3, int par4) { + int var5 = par0IBlockAccess.getBlockId(par1, par2, par3); + + if (var5 == Block.redstoneWire.blockID) { + return true; + } else if (var5 == 0) { + return false; + } else if (!Block.redstoneRepeaterIdle.func_94487_f(var5)) { + return Block.blocksList[var5].canProvidePower() && par4 != -1; + } else { + int var6 = par0IBlockAccess.getBlockMetadata(par1, par2, par3); + return par4 == (var6 & 3) || par4 == Direction.rotateOpposite[var6 & 3]; + } + } + + /** + * Returns true if the block coordinate passed can provide power, or is a + * redstone wire, or if its a repeater that is powered. + */ + public static boolean isPoweredOrRepeater(IBlockAccess par0IBlockAccess, int par1, int par2, int par3, int par4) { + if (isPowerProviderOrWire(par0IBlockAccess, par1, par2, par3, par4)) { + return true; + } else { + int var5 = par0IBlockAccess.getBlockId(par1, par2, par3); + + if (var5 == Block.redstoneRepeaterActive.blockID) { + int var6 = par0IBlockAccess.getBlockMetadata(par1, par2, par3); + return par4 == (var6 & 3); + } else { + return false; + } + } + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Item.redstone.itemID; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.field_94413_c = par1IconRegister.registerIcon("redstoneDust_cross"); + this.field_94410_cO = par1IconRegister.registerIcon("redstoneDust_line"); + this.field_94411_cP = par1IconRegister.registerIcon("redstoneDust_cross_overlay"); + this.field_94412_cQ = par1IconRegister.registerIcon("redstoneDust_line_overlay"); + this.blockIcon = this.field_94413_c; + } + + public static Icon func_94409_b(String par0Str) { + return par0Str == "redstoneDust_cross" ? Block.redstoneWire.field_94413_c + : (par0Str == "redstoneDust_line" ? Block.redstoneWire.field_94410_cO + : (par0Str == "redstoneDust_cross_overlay" ? Block.redstoneWire.field_94411_cP : (par0Str == "redstoneDust_line_overlay" ? Block.redstoneWire.field_94412_cQ : null))); + } +} diff --git a/src/main/java/net/minecraft/src/BlockReed.java b/src/main/java/net/minecraft/src/BlockReed.java new file mode 100644 index 0000000..ac75350 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockReed.java @@ -0,0 +1,124 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockReed extends Block { + protected BlockReed(int par1) { + super(par1, Material.plants); + float var2 = 0.375F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, 1.0F, 0.5F + var2); + this.setTickRandomly(true); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par1World.isAirBlock(par2, par3 + 1, par4)) { + int var6; + + for (var6 = 1; par1World.getBlockId(par2, par3 - var6, par4) == this.blockID; ++var6) { + ; + } + + if (var6 < 3) { + int var7 = par1World.getBlockMetadata(par2, par3, par4); + + if (var7 == 15) { + par1World.setBlock(par2, par3 + 1, par4, this.blockID); + par1World.setBlockMetadataWithNotify(par2, par3, par4, 0, 4); + } else { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7 + 1, 4); + } + } + } + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockId(par2, par3 - 1, par4); + return var5 == this.blockID ? true + : (var5 != Block.grass.blockID && var5 != Block.dirt.blockID && var5 != Block.sand.blockID ? false + : (par1World.getBlockMaterial(par2 - 1, par3 - 1, par4) == Material.water ? true + : (par1World.getBlockMaterial(par2 + 1, par3 - 1, par4) == Material.water ? true + : (par1World.getBlockMaterial(par2, par3 - 1, par4 - 1) == Material.water ? true : par1World.getBlockMaterial(par2, par3 - 1, par4 + 1) == Material.water)))); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + this.checkBlockCoordValid(par1World, par2, par3, par4); + } + + /** + * Checks if current block pos is valid, if not, breaks the block as dropable + * item. Used for reed and cactus. + */ + protected final void checkBlockCoordValid(World par1World, int par2, int par3, int par4) { + if (!this.canBlockStay(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + return this.canPlaceBlockAt(par1World, par2, par3, par4); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.reed.itemID; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 1; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Item.reed.itemID; + } +} diff --git a/src/main/java/net/minecraft/src/BlockSand.java b/src/main/java/net/minecraft/src/BlockSand.java new file mode 100644 index 0000000..6f85b3a --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSand.java @@ -0,0 +1,105 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockSand extends Block { + /** Do blocks fall instantly to where they stop or do they fall over time */ + public static boolean fallInstantly = false; + + public BlockSand(int par1) { + super(par1, Material.sand); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + public BlockSand(int par1, Material par2Material) { + super(par1, par2Material); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + this.tryToFall(par1World, par2, par3, par4); + } + } + + /** + * If there is space to fall below will start this block falling + */ + private void tryToFall(World par1World, int par2, int par3, int par4) { + if (canFallBelow(par1World, par2, par3 - 1, par4) && par3 >= 0) { + byte var8 = 32; + + if (!fallInstantly && par1World.checkChunksExist(par2 - var8, par3 - var8, par4 - var8, par2 + var8, par3 + var8, par4 + var8)) { + if (!par1World.isRemote) { + EntityFallingSand var9 = new EntityFallingSand(par1World, (double) ((float) par2 + 0.5F), (double) ((float) par3 + 0.5F), (double) ((float) par4 + 0.5F), this.blockID, par1World.getBlockMetadata(par2, par3, par4)); + this.onStartFalling(var9); + par1World.spawnEntityInWorld(var9); + } + } else { + par1World.setBlockToAir(par2, par3, par4); + + while (canFallBelow(par1World, par2, par3 - 1, par4) && par3 > 0) { + --par3; + } + + if (par3 > 0) { + par1World.setBlock(par2, par3, par4, this.blockID); + } + } + } + } + + /** + * Called when the falling block entity for this block is created + */ + protected void onStartFalling(EntityFallingSand par1EntityFallingSand) { + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 2; + } + + /** + * Checks to see if the sand can fall into the block below it + */ + public static boolean canFallBelow(World par0World, int par1, int par2, int par3) { + int var4 = par0World.getBlockId(par1, par2, par3); + + if (var4 == 0) { + return true; + } else if (var4 == Block.fire.blockID) { + return true; + } else { + Material var5 = Block.blocksList[var4].blockMaterial; + return var5 == Material.water ? true : var5 == Material.lava; + } + } + + /** + * Called when the falling block entity for this block hits the ground and turns + * back into a block + */ + public void onFinishFalling(World par1World, int par2, int par3, int par4, int par5) { + } +} diff --git a/src/main/java/net/minecraft/src/BlockSandStone.java b/src/main/java/net/minecraft/src/BlockSandStone.java new file mode 100644 index 0000000..dce6f3f --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSandStone.java @@ -0,0 +1,69 @@ +package net.minecraft.src; + +import java.util.List; + +public class BlockSandStone extends Block { + public static final String[] SAND_STONE_TYPES = new String[] { "default", "chiseled", "smooth" }; + private static final String[] field_94405_b = new String[] { "sandstone_side", "sandstone_carved", "sandstone_smooth" }; + private Icon[] field_94406_c; + private Icon field_94403_cO; + private Icon field_94404_cP; + + public BlockSandStone(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + if (par1 != 1 && (par1 != 0 || par2 != 1 && par2 != 2)) { + if (par1 == 0) { + return this.field_94404_cP; + } else { + if (par2 < 0 || par2 >= this.field_94406_c.length) { + par2 = 0; + } + + return this.field_94406_c[par2]; + } + } else { + return this.field_94403_cO; + } + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1; + } + + /** + * returns a list of blocks with the same ID, but different meta (eg: wood + * returns 4 blocks) + */ + public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + par3List.add(new ItemStack(par1, 1, 0)); + par3List.add(new ItemStack(par1, 1, 1)); + par3List.add(new ItemStack(par1, 1, 2)); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.field_94406_c = new Icon[field_94405_b.length]; + + for (int var2 = 0; var2 < this.field_94406_c.length; ++var2) { + this.field_94406_c[var2] = par1IconRegister.registerIcon(field_94405_b[var2]); + } + + this.field_94403_cO = par1IconRegister.registerIcon("sandstone_top"); + this.field_94404_cP = par1IconRegister.registerIcon("sandstone_bottom"); + } +} diff --git a/src/main/java/net/minecraft/src/BlockSapling.java b/src/main/java/net/minecraft/src/BlockSapling.java new file mode 100644 index 0000000..0bb17a2 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSapling.java @@ -0,0 +1,64 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockSapling extends BlockFlower { + public static final String[] WOOD_TYPES = new String[] { "oak", "spruce", "birch", "jungle" }; + private static final String[] field_94370_b = new String[] { "sapling", "sapling_spruce", "sapling_birch", "sapling_jungle" }; + private Icon[] saplingIcon; + + protected BlockSapling(int par1) { + super(par1); + float var2 = 0.4F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, var2 * 2.0F, 0.5F + var2); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + par2 &= 3; + return this.saplingIcon[par2]; + } + + /** + * Determines if the same sapling is present at the given location. + */ + public boolean isSameSapling(World par1World, int par2, int par3, int par4, int par5) { + return par1World.getBlockId(par2, par3, par4) == this.blockID && (par1World.getBlockMetadata(par2, par3, par4) & 3) == par5; + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1 & 3; + } + + /** + * returns a list of blocks with the same ID, but different meta (eg: wood + * returns 4 blocks) + */ + public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + par3List.add(new ItemStack(par1, 1, 0)); + par3List.add(new ItemStack(par1, 1, 1)); + par3List.add(new ItemStack(par1, 1, 2)); + par3List.add(new ItemStack(par1, 1, 3)); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.saplingIcon = new Icon[field_94370_b.length]; + + for (int var2 = 0; var2 < this.saplingIcon.length; ++var2) { + this.saplingIcon[var2] = par1IconRegister.registerIcon(field_94370_b[var2]); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockSign.java b/src/main/java/net/minecraft/src/BlockSign.java new file mode 100644 index 0000000..458f6d5 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSign.java @@ -0,0 +1,178 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockSign extends BlockContainer { + private Class signEntityClass; + + /** Whether this is a freestanding sign or a wall-mounted sign */ + private boolean isFreestanding; + + protected BlockSign(int par1, Class par2Class, boolean par3) { + super(par1, Material.wood); + this.isFreestanding = par3; + this.signEntityClass = par2Class; + float var4 = 0.25F; + float var5 = 1.0F; + this.setBlockBounds(0.5F - var4, 0.0F, 0.5F - var4, 0.5F + var4, var5, 0.5F + var4); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return Block.planks.getBlockTextureFromSide(par1); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Returns the bounding box of the wired rectangular prism to render. + */ + public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getSelectedBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + if (!this.isFreestanding) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + float var6 = 0.28125F; + float var7 = 0.78125F; + float var8 = 0.0F; + float var9 = 1.0F; + float var10 = 0.125F; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + + if (var5 == 2) { + this.setBlockBounds(var8, var6, 1.0F - var10, var9, var7, 1.0F); + } + + if (var5 == 3) { + this.setBlockBounds(var8, var6, 0.0F, var9, var7, var10); + } + + if (var5 == 4) { + this.setBlockBounds(1.0F - var10, var6, var8, 1.0F, var7, var9); + } + + if (var5 == 5) { + this.setBlockBounds(0.0F, var6, var8, var10, var7, var9); + } + } + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return -1; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return true; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + try { + return (TileEntity) this.signEntityClass.newInstance(); + } catch (Exception var3) { + throw new RuntimeException(var3); + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.sign.itemID; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + boolean var6 = false; + + if (this.isFreestanding) { + if (!par1World.getBlockMaterial(par2, par3 - 1, par4).isSolid()) { + var6 = true; + } + } else { + int var7 = par1World.getBlockMetadata(par2, par3, par4); + var6 = true; + + if (var7 == 2 && par1World.getBlockMaterial(par2, par3, par4 + 1).isSolid()) { + var6 = false; + } + + if (var7 == 3 && par1World.getBlockMaterial(par2, par3, par4 - 1).isSolid()) { + var6 = false; + } + + if (var7 == 4 && par1World.getBlockMaterial(par2 + 1, par3, par4).isSolid()) { + var6 = false; + } + + if (var7 == 5 && par1World.getBlockMaterial(par2 - 1, par3, par4).isSolid()) { + var6 = false; + } + } + + if (var6) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + + super.onNeighborBlockChange(par1World, par2, par3, par4, par5); + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Item.sign.itemID; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + } +} diff --git a/src/main/java/net/minecraft/src/BlockSilverfish.java b/src/main/java/net/minecraft/src/BlockSilverfish.java new file mode 100644 index 0000000..3109da3 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSilverfish.java @@ -0,0 +1,107 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockSilverfish extends Block { + /** Block names that can be a silverfish stone. */ + public static final String[] silverfishStoneTypes = new String[] { "stone", "cobble", "brick" }; + + public BlockSilverfish(int par1) { + super(par1, Material.clay); + this.setHardness(0.0F); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par2 == 1 ? Block.cobblestone.getBlockTextureFromSide(par1) : (par2 == 2 ? Block.stoneBrick.getBlockTextureFromSide(par1) : Block.stone.getBlockTextureFromSide(par1)); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + } + + /** + * Called right before the block is destroyed by a player. Args: world, x, y, z, + * metaData + */ + public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + EntitySilverfish var6 = new EntitySilverfish(); + var6.setWorld(par1World); + var6.setLocationAndAngles((double) par2 + 0.5D, (double) par3, (double) par4 + 0.5D, 0.0F, 0.0F); + par1World.spawnEntityInWorld(var6); + var6.spawnExplosionParticle(); + } + + super.onBlockDestroyedByPlayer(par1World, par2, par3, par4, par5); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Gets the blockID of the block this block is pretending to be according to + * this block's metadata. + */ + public static boolean getPosingIdByMetadata(int par0) { + return par0 == Block.stone.blockID || par0 == Block.cobblestone.blockID || par0 == Block.stoneBrick.blockID; + } + + /** + * Returns the metadata to use when a Silverfish hides in the block. Sets the + * block to BlockSilverfish with this metadata. It changes the displayed texture + * client side to look like a normal block. + */ + public static int getMetadataForBlockType(int par0) { + return par0 == Block.cobblestone.blockID ? 1 : (par0 == Block.stoneBrick.blockID ? 2 : 0); + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + Block var2 = Block.stone; + + if (par1 == 1) { + var2 = Block.cobblestone; + } + + if (par1 == 2) { + var2 = Block.stoneBrick; + } + + return new ItemStack(var2); + } + + /** + * Get the block's damage value (for use with pick block). + */ + public int getDamageValue(World par1World, int par2, int par3, int par4) { + return par1World.getBlockMetadata(par2, par3, par4); + } + + /** + * returns a list of blocks with the same ID, but different meta (eg: wood + * returns 4 blocks) + */ + public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + for (int var4 = 0; var4 < 3; ++var4) { + par3List.add(new ItemStack(par1, 1, var4)); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockSkull.java b/src/main/java/net/minecraft/src/BlockSkull.java new file mode 100644 index 0000000..71a5ac4 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSkull.java @@ -0,0 +1,282 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockSkull extends BlockContainer { + protected BlockSkull(int par1) { + super(par1, Material.circuits); + this.setBlockBounds(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return -1; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 7; + + switch (var5) { + case 1: + default: + this.setBlockBounds(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F); + break; + + case 2: + this.setBlockBounds(0.25F, 0.25F, 0.5F, 0.75F, 0.75F, 1.0F); + break; + + case 3: + this.setBlockBounds(0.25F, 0.25F, 0.0F, 0.75F, 0.75F, 0.5F); + break; + + case 4: + this.setBlockBounds(0.5F, 0.25F, 0.25F, 1.0F, 0.75F, 0.75F); + break; + + case 5: + this.setBlockBounds(0.0F, 0.25F, 0.25F, 0.5F, 0.75F, 0.75F); + } + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + int var7 = MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 2.5D) & 3; + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7, 2); + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntitySkull(); + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Item.skull.itemID; + } + + /** + * Get the block's damage value (for use with pick block). + */ + public int getDamageValue(World par1World, int par2, int par3, int par4) { + TileEntity var5 = par1World.getBlockTileEntity(par2, par3, par4); + return var5 != null && var5 instanceof TileEntitySkull ? ((TileEntitySkull) var5).getSkullType() : super.getDamageValue(par1World, par2, par3, par4); + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + } + + /** + * Called when the block is attempted to be harvested + */ + public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer) { + if (par6EntityPlayer.capabilities.isCreativeMode) { + par5 |= 8; + par1World.setBlockMetadataWithNotify(par2, par3, par4, par5, 4); + } + + super.onBlockHarvested(par1World, par2, par3, par4, par5, par6EntityPlayer); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + if (!par1World.isRemote) { + if ((par6 & 8) == 0) { + ItemStack var7 = new ItemStack(Item.skull.itemID, 1, this.getDamageValue(par1World, par2, par3, par4)); + TileEntitySkull var8 = (TileEntitySkull) par1World.getBlockTileEntity(par2, par3, par4); + + if (var8.getSkullType() == 3 && var8.getExtraType() != null && var8.getExtraType().length() > 0) { + var7.setTagCompound(new NBTTagCompound()); + var7.getTagCompound().setString("SkullOwner", var8.getExtraType()); + } + + this.dropBlockAsItem_do(par1World, par2, par3, par4, var7); + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.skull.itemID; + } + + /** + * This method attempts to create a wither at the given location and skull + */ + public void makeWither(World par1World, int par2, int par3, int par4, TileEntitySkull par5TileEntitySkull) { + if (par5TileEntitySkull.getSkullType() == 1 && par3 >= 2 && par1World.difficultySetting > 0 && !par1World.isRemote) { + int var6 = Block.slowSand.blockID; + int var7; + EntityWither var8; + int var9; + + for (var7 = -2; var7 <= 0; ++var7) { + if (par1World.getBlockId(par2, par3 - 1, par4 + var7) == var6 && par1World.getBlockId(par2, par3 - 1, par4 + var7 + 1) == var6 && par1World.getBlockId(par2, par3 - 2, par4 + var7 + 1) == var6 + && par1World.getBlockId(par2, par3 - 1, par4 + var7 + 2) == var6 && this.func_82528_d(par1World, par2, par3, par4 + var7, 1) && this.func_82528_d(par1World, par2, par3, par4 + var7 + 1, 1) + && this.func_82528_d(par1World, par2, par3, par4 + var7 + 2, 1)) { + par1World.setBlockMetadataWithNotify(par2, par3, par4 + var7, 8, 2); + par1World.setBlockMetadataWithNotify(par2, par3, par4 + var7 + 1, 8, 2); + par1World.setBlockMetadataWithNotify(par2, par3, par4 + var7 + 2, 8, 2); + par1World.setBlock(par2, par3, par4 + var7, 0, 0, 2); + par1World.setBlock(par2, par3, par4 + var7 + 1, 0, 0, 2); + par1World.setBlock(par2, par3, par4 + var7 + 2, 0, 0, 2); + par1World.setBlock(par2, par3 - 1, par4 + var7, 0, 0, 2); + par1World.setBlock(par2, par3 - 1, par4 + var7 + 1, 0, 0, 2); + par1World.setBlock(par2, par3 - 1, par4 + var7 + 2, 0, 0, 2); + par1World.setBlock(par2, par3 - 2, par4 + var7 + 1, 0, 0, 2); + + if (!par1World.isRemote) { + var8 = new EntityWither(); + var8.setWorld(par1World); + var8.setLocationAndAngles((double) par2 + 0.5D, (double) par3 - 1.45D, (double) (par4 + var7) + 1.5D, 90.0F, 0.0F); + var8.renderYawOffset = 90.0F; + var8.func_82206_m(); + par1World.spawnEntityInWorld(var8); + } + + for (var9 = 0; var9 < 120; ++var9) { + par1World.spawnParticle("snowballpoof", (double) par2 + par1World.rand.nextDouble(), (double) (par3 - 2) + par1World.rand.nextDouble() * 3.9D, (double) (par4 + var7 + 1) + par1World.rand.nextDouble(), 0.0D, 0.0D, + 0.0D); + } + + par1World.notifyBlockChange(par2, par3, par4 + var7, 0); + par1World.notifyBlockChange(par2, par3, par4 + var7 + 1, 0); + par1World.notifyBlockChange(par2, par3, par4 + var7 + 2, 0); + par1World.notifyBlockChange(par2, par3 - 1, par4 + var7, 0); + par1World.notifyBlockChange(par2, par3 - 1, par4 + var7 + 1, 0); + par1World.notifyBlockChange(par2, par3 - 1, par4 + var7 + 2, 0); + par1World.notifyBlockChange(par2, par3 - 2, par4 + var7 + 1, 0); + return; + } + } + + for (var7 = -2; var7 <= 0; ++var7) { + if (par1World.getBlockId(par2 + var7, par3 - 1, par4) == var6 && par1World.getBlockId(par2 + var7 + 1, par3 - 1, par4) == var6 && par1World.getBlockId(par2 + var7 + 1, par3 - 2, par4) == var6 + && par1World.getBlockId(par2 + var7 + 2, par3 - 1, par4) == var6 && this.func_82528_d(par1World, par2 + var7, par3, par4, 1) && this.func_82528_d(par1World, par2 + var7 + 1, par3, par4, 1) + && this.func_82528_d(par1World, par2 + var7 + 2, par3, par4, 1)) { + par1World.setBlockMetadataWithNotify(par2 + var7, par3, par4, 8, 2); + par1World.setBlockMetadataWithNotify(par2 + var7 + 1, par3, par4, 8, 2); + par1World.setBlockMetadataWithNotify(par2 + var7 + 2, par3, par4, 8, 2); + par1World.setBlock(par2 + var7, par3, par4, 0, 0, 2); + par1World.setBlock(par2 + var7 + 1, par3, par4, 0, 0, 2); + par1World.setBlock(par2 + var7 + 2, par3, par4, 0, 0, 2); + par1World.setBlock(par2 + var7, par3 - 1, par4, 0, 0, 2); + par1World.setBlock(par2 + var7 + 1, par3 - 1, par4, 0, 0, 2); + par1World.setBlock(par2 + var7 + 2, par3 - 1, par4, 0, 0, 2); + par1World.setBlock(par2 + var7 + 1, par3 - 2, par4, 0, 0, 2); + + if (!par1World.isRemote) { + var8 = new EntityWither(); + var8.setWorld(par1World); + var8.setLocationAndAngles((double) (par2 + var7) + 1.5D, (double) par3 - 1.45D, (double) par4 + 0.5D, 0.0F, 0.0F); + var8.func_82206_m(); + par1World.spawnEntityInWorld(var8); + } + + for (var9 = 0; var9 < 120; ++var9) { + par1World.spawnParticle("snowballpoof", (double) (par2 + var7 + 1) + par1World.rand.nextDouble(), (double) (par3 - 2) + par1World.rand.nextDouble() * 3.9D, (double) par4 + par1World.rand.nextDouble(), 0.0D, 0.0D, + 0.0D); + } + + par1World.notifyBlockChange(par2 + var7, par3, par4, 0); + par1World.notifyBlockChange(par2 + var7 + 1, par3, par4, 0); + par1World.notifyBlockChange(par2 + var7 + 2, par3, par4, 0); + par1World.notifyBlockChange(par2 + var7, par3 - 1, par4, 0); + par1World.notifyBlockChange(par2 + var7 + 1, par3 - 1, par4, 0); + par1World.notifyBlockChange(par2 + var7 + 2, par3 - 1, par4, 0); + par1World.notifyBlockChange(par2 + var7 + 1, par3 - 2, par4, 0); + return; + } + } + } + } + + private boolean func_82528_d(World par1World, int par2, int par3, int par4, int par5) { + if (par1World.getBlockId(par2, par3, par4) != this.blockID) { + return false; + } else { + TileEntity var6 = par1World.getBlockTileEntity(par2, par3, par4); + return var6 != null && var6 instanceof TileEntitySkull ? ((TileEntitySkull) var6).getSkullType() == par5 : false; + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return Block.slowSand.getBlockTextureFromSide(par1); + } + + /** + * Gets the icon name of the ItemBlock corresponding to this block. Used by + * hoppers. + */ + public String getItemIconName() { + return ItemSkull.field_94587_a[0]; + } +} diff --git a/src/main/java/net/minecraft/src/BlockSnow.java b/src/main/java/net/minecraft/src/BlockSnow.java new file mode 100644 index 0000000..a8843bf --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSnow.java @@ -0,0 +1,149 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockSnow extends Block { + protected BlockSnow(int par1) { + super(par1, Material.snow); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabDecorations); + this.setBlockBoundsForSnowDepth(0); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("snow"); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4) & 7; + float var6 = 0.125F; + return AxisAlignedBB.getAABBPool().getAABB((double) par2 + this.minX, (double) par3 + this.minY, (double) par4 + this.minZ, (double) par2 + this.maxX, (double) ((float) par3 + (float) var5 * var6), (double) par4 + this.maxZ); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + this.setBlockBoundsForSnowDepth(0); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.setBlockBoundsForSnowDepth(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + /** + * calls setBlockBounds based on the depth of the snow. Int is any values + * 0x0-0x7, usually this blocks metadata. + */ + protected void setBlockBoundsForSnowDepth(int par1) { + int var2 = par1 & 7; + float var3 = (float) (2 * (1 + var2)) / 16.0F; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, var3, 1.0F); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockId(par2, par3 - 1, par4); + return var5 == 0 ? false + : (var5 == this.blockID && (par1World.getBlockMetadata(par2, par3 - 1, par4) & 7) == 7 ? true + : (var5 != Block.leaves.blockID && !Block.blocksList[var5].isOpaqueCube() ? false : par1World.getBlockMaterial(par2, par3 - 1, par4).blocksMovement())); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + this.canSnowStay(par1World, par2, par3, par4); + } + + /** + * Checks if this snow block can stay at this location. + */ + private boolean canSnowStay(World par1World, int par2, int par3, int par4) { + if (!this.canPlaceBlockAt(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + return false; + } else { + return true; + } + } + + /** + * Called when the player destroys a block with an item that can harvest it. (i, + * j, k) are the coordinates of the block and l is the block's subtype/damage. + */ + public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) { + int var7 = Item.snowball.itemID; + int var8 = par6 & 7; + this.dropBlockAsItem_do(par1World, par3, par4, par5, new ItemStack(var7, var8 + 1, 0)); + par1World.setBlockToAir(par3, par4, par5); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.snowball.itemID; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par1World.getSavedLightValue(EnumSkyBlock.Block, par2, par3, par4) > 11) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return par5 == 1 ? true : super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5); + } +} diff --git a/src/main/java/net/minecraft/src/BlockSnowBlock.java b/src/main/java/net/minecraft/src/BlockSnowBlock.java new file mode 100644 index 0000000..223abcb --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSnowBlock.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockSnowBlock extends Block { + protected BlockSnowBlock(int par1) { + super(par1, Material.craftedSnow); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.snowball.itemID; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 4; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par1World.getSavedLightValue(EnumSkyBlock.Block, par2, par3, par4) > 11) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockSoulSand.java b/src/main/java/net/minecraft/src/BlockSoulSand.java new file mode 100644 index 0000000..fd5e103 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSoulSand.java @@ -0,0 +1,26 @@ +package net.minecraft.src; + +public class BlockSoulSand extends Block { + public BlockSoulSand(int par1) { + super(par1, Material.sand); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + float var5 = 0.125F; + return AxisAlignedBB.getAABBPool().getAABB((double) par2, (double) par3, (double) par4, (double) (par2 + 1), (double) ((float) (par3 + 1) - var5), (double) (par4 + 1)); + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + par5Entity.motionX *= 0.4D; + par5Entity.motionZ *= 0.4D; + } +} diff --git a/src/main/java/net/minecraft/src/BlockSourceImpl.java b/src/main/java/net/minecraft/src/BlockSourceImpl.java new file mode 100644 index 0000000..ddf8289 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSourceImpl.java @@ -0,0 +1,51 @@ +package net.minecraft.src; + +public class BlockSourceImpl implements IBlockSource { + private final World worldObj; + private final int xPos; + private final int yPos; + private final int zPos; + + public BlockSourceImpl(World par1World, int par2, int par3, int par4) { + this.worldObj = par1World; + this.xPos = par2; + this.yPos = par3; + this.zPos = par4; + } + + public World getWorld() { + return this.worldObj; + } + + public double getX() { + return (double) this.xPos + 0.5D; + } + + public double getY() { + return (double) this.yPos + 0.5D; + } + + public double getZ() { + return (double) this.zPos + 0.5D; + } + + public int getXInt() { + return this.xPos; + } + + public int getYInt() { + return this.yPos; + } + + public int getZInt() { + return this.zPos; + } + + public int getBlockMetadata() { + return this.worldObj.getBlockMetadata(this.xPos, this.yPos, this.zPos); + } + + public TileEntity getBlockTileEntity() { + return this.worldObj.getBlockTileEntity(this.xPos, this.yPos, this.zPos); + } +} diff --git a/src/main/java/net/minecraft/src/BlockSponge.java b/src/main/java/net/minecraft/src/BlockSponge.java new file mode 100644 index 0000000..8fd03ed --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSponge.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public class BlockSponge extends Block { + protected BlockSponge(int par1) { + super(par1, Material.sponge); + this.setCreativeTab(CreativeTabs.tabBlock); + } +} diff --git a/src/main/java/net/minecraft/src/BlockStairs.java b/src/main/java/net/minecraft/src/BlockStairs.java new file mode 100644 index 0000000..6a76755 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockStairs.java @@ -0,0 +1,542 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockStairs extends Block { + private static final int[][] field_72159_a = new int[][] { { 2, 6 }, { 3, 7 }, { 2, 3 }, { 6, 7 }, { 0, 4 }, { 1, 5 }, { 0, 1 }, { 4, 5 } }; + + /** The block that is used as model for the stair. */ + private final Block modelBlock; + private final int modelBlockMetadata; + private boolean field_72156_cr = false; + private int field_72160_cs = 0; + + protected BlockStairs(int par1, Block par2Block, int par3) { + super(par1, par2Block.blockMaterial); + this.modelBlock = par2Block; + this.modelBlockMetadata = par3; + this.setHardness(par2Block.blockHardness); + this.setResistance(par2Block.blockResistance / 3.0F); + this.setStepSound(par2Block.stepSound); + this.setLightOpacity(255); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + if (this.field_72156_cr) { + this.setBlockBounds(0.5F * (float) (this.field_72160_cs % 2), 0.5F * (float) (this.field_72160_cs / 2 % 2), 0.5F * (float) (this.field_72160_cs / 4 % 2), 0.5F + 0.5F * (float) (this.field_72160_cs % 2), + 0.5F + 0.5F * (float) (this.field_72160_cs / 2 % 2), 0.5F + 0.5F * (float) (this.field_72160_cs / 4 % 2)); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 10; + } + + public void func_82541_d(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if ((var5 & 4) != 0) { + this.setBlockBounds(0.0F, 0.5F, 0.0F, 1.0F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); + } + } + + /** + * Checks if supplied ID is one of a BlockStairs + */ + public static boolean isBlockStairsID(int par0) { + return par0 > 0 && Block.blocksList[par0] instanceof BlockStairs; + } + + private boolean func_82540_f(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = par1IBlockAccess.getBlockId(par2, par3, par4); + return isBlockStairsID(var6) && par1IBlockAccess.getBlockMetadata(par2, par3, par4) == par5; + } + + public boolean func_82542_g(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + int var6 = var5 & 3; + float var7 = 0.5F; + float var8 = 1.0F; + + if ((var5 & 4) != 0) { + var7 = 0.0F; + var8 = 0.5F; + } + + float var9 = 0.0F; + float var10 = 1.0F; + float var11 = 0.0F; + float var12 = 0.5F; + boolean var13 = true; + int var14; + int var15; + int var16; + + if (var6 == 0) { + var9 = 0.5F; + var12 = 1.0F; + var14 = par1IBlockAccess.getBlockId(par2 + 1, par3, par4); + var15 = par1IBlockAccess.getBlockMetadata(par2 + 1, par3, par4); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var16 = var15 & 3; + + if (var16 == 3 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 + 1, var5)) { + var12 = 0.5F; + var13 = false; + } else if (var16 == 2 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 - 1, var5)) { + var11 = 0.5F; + var13 = false; + } + } + } else if (var6 == 1) { + var10 = 0.5F; + var12 = 1.0F; + var14 = par1IBlockAccess.getBlockId(par2 - 1, par3, par4); + var15 = par1IBlockAccess.getBlockMetadata(par2 - 1, par3, par4); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var16 = var15 & 3; + + if (var16 == 3 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 + 1, var5)) { + var12 = 0.5F; + var13 = false; + } else if (var16 == 2 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 - 1, var5)) { + var11 = 0.5F; + var13 = false; + } + } + } else if (var6 == 2) { + var11 = 0.5F; + var12 = 1.0F; + var14 = par1IBlockAccess.getBlockId(par2, par3, par4 + 1); + var15 = par1IBlockAccess.getBlockMetadata(par2, par3, par4 + 1); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var16 = var15 & 3; + + if (var16 == 1 && !this.func_82540_f(par1IBlockAccess, par2 + 1, par3, par4, var5)) { + var10 = 0.5F; + var13 = false; + } else if (var16 == 0 && !this.func_82540_f(par1IBlockAccess, par2 - 1, par3, par4, var5)) { + var9 = 0.5F; + var13 = false; + } + } + } else if (var6 == 3) { + var14 = par1IBlockAccess.getBlockId(par2, par3, par4 - 1); + var15 = par1IBlockAccess.getBlockMetadata(par2, par3, par4 - 1); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var16 = var15 & 3; + + if (var16 == 1 && !this.func_82540_f(par1IBlockAccess, par2 + 1, par3, par4, var5)) { + var10 = 0.5F; + var13 = false; + } else if (var16 == 0 && !this.func_82540_f(par1IBlockAccess, par2 - 1, par3, par4, var5)) { + var9 = 0.5F; + var13 = false; + } + } + } + + this.setBlockBounds(var9, var7, var11, var10, var8, var12); + return var13; + } + + public boolean func_82544_h(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + int var6 = var5 & 3; + float var7 = 0.5F; + float var8 = 1.0F; + + if ((var5 & 4) != 0) { + var7 = 0.0F; + var8 = 0.5F; + } + + float var9 = 0.0F; + float var10 = 0.5F; + float var11 = 0.5F; + float var12 = 1.0F; + boolean var13 = false; + int var14; + int var15; + int var16; + + if (var6 == 0) { + var14 = par1IBlockAccess.getBlockId(par2 - 1, par3, par4); + var15 = par1IBlockAccess.getBlockMetadata(par2 - 1, par3, par4); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var16 = var15 & 3; + + if (var16 == 3 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 - 1, var5)) { + var11 = 0.0F; + var12 = 0.5F; + var13 = true; + } else if (var16 == 2 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 + 1, var5)) { + var11 = 0.5F; + var12 = 1.0F; + var13 = true; + } + } + } else if (var6 == 1) { + var14 = par1IBlockAccess.getBlockId(par2 + 1, par3, par4); + var15 = par1IBlockAccess.getBlockMetadata(par2 + 1, par3, par4); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var9 = 0.5F; + var10 = 1.0F; + var16 = var15 & 3; + + if (var16 == 3 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 - 1, var5)) { + var11 = 0.0F; + var12 = 0.5F; + var13 = true; + } else if (var16 == 2 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 + 1, var5)) { + var11 = 0.5F; + var12 = 1.0F; + var13 = true; + } + } + } else if (var6 == 2) { + var14 = par1IBlockAccess.getBlockId(par2, par3, par4 - 1); + var15 = par1IBlockAccess.getBlockMetadata(par2, par3, par4 - 1); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var11 = 0.0F; + var12 = 0.5F; + var16 = var15 & 3; + + if (var16 == 1 && !this.func_82540_f(par1IBlockAccess, par2 - 1, par3, par4, var5)) { + var13 = true; + } else if (var16 == 0 && !this.func_82540_f(par1IBlockAccess, par2 + 1, par3, par4, var5)) { + var9 = 0.5F; + var10 = 1.0F; + var13 = true; + } + } + } else if (var6 == 3) { + var14 = par1IBlockAccess.getBlockId(par2, par3, par4 + 1); + var15 = par1IBlockAccess.getBlockMetadata(par2, par3, par4 + 1); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var16 = var15 & 3; + + if (var16 == 1 && !this.func_82540_f(par1IBlockAccess, par2 - 1, par3, par4, var5)) { + var13 = true; + } else if (var16 == 0 && !this.func_82540_f(par1IBlockAccess, par2 + 1, par3, par4, var5)) { + var9 = 0.5F; + var10 = 1.0F; + var13 = true; + } + } + } + + if (var13) { + this.setBlockBounds(var9, var7, var11, var10, var8, var12); + } + + return var13; + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity) { + this.func_82541_d(par1World, par2, par3, par4); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + boolean var8 = this.func_82542_g(par1World, par2, par3, par4); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + + if (var8 && this.func_82544_h(par1World, par2, par3, par4)) { + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + this.modelBlock.randomDisplayTick(par1World, par2, par3, par4, par5Random); + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + this.modelBlock.onBlockClicked(par1World, par2, par3, par4, par5EntityPlayer); + } + + /** + * Called right before the block is destroyed by a player. Args: world, x, y, z, + * metaData + */ + public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) { + this.modelBlock.onBlockDestroyedByPlayer(par1World, par2, par3, par4, par5); + } + + /** + * Goes straight to getLightBrightnessForSkyBlocks for Blocks, does some fancy + * computing for Fluids + */ + public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return this.modelBlock.getMixedBrightnessForBlock(par1IBlockAccess, par2, par3, par4); + } + + /** + * How bright to render this block based on the light its receiving. Args: + * iBlockAccess, x, y, z + */ + public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return this.modelBlock.getBlockBrightness(par1IBlockAccess, par2, par3, par4); + } + + /** + * Returns how much this block can resist explosions from the passed in entity. + */ + public float getExplosionResistance(Entity par1Entity) { + return this.modelBlock.getExplosionResistance(par1Entity); + } + + /** + * Returns which pass should this block be rendered on. 0 for solids and 1 for + * alpha + */ + public int getRenderBlockPass() { + return this.modelBlock.getRenderBlockPass(); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return this.modelBlock.getIcon(par1, this.modelBlockMetadata); + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return this.modelBlock.tickRate(par1World); + } + + /** + * Returns the bounding box of the wired rectangular prism to render. + */ + public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return this.modelBlock.getSelectedBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Can add to the passed in vector for a movement vector to be applied to the + * entity. Args: x, y, z, entity, vec3d + */ + public void velocityToAddToEntity(World par1World, int par2, int par3, int par4, Entity par5Entity, Vec3 par6Vec3) { + this.modelBlock.velocityToAddToEntity(par1World, par2, par3, par4, par5Entity, par6Vec3); + } + + /** + * Returns if this block is collidable (only used by Fire). Args: x, y, z + */ + public boolean isCollidable() { + return this.modelBlock.isCollidable(); + } + + /** + * Returns whether this block is collideable based on the arguments passed in + * Args: blockMetaData, unknownFlag + */ + public boolean canCollideCheck(int par1, boolean par2) { + return this.modelBlock.canCollideCheck(par1, par2); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return this.modelBlock.canPlaceBlockAt(par1World, par2, par3, par4); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + this.onNeighborBlockChange(par1World, par2, par3, par4, 0); + this.modelBlock.onBlockAdded(par1World, par2, par3, par4); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + this.modelBlock.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * Called whenever an entity is walking on top of this block. Args: world, x, y, + * z, entity + */ + public void onEntityWalking(World par1World, int par2, int par3, int par4, Entity par5Entity) { + this.modelBlock.onEntityWalking(par1World, par2, par3, par4, par5Entity); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + this.modelBlock.updateTick(par1World, par2, par3, par4, par5Random); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + return this.modelBlock.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, 0, 0.0F, 0.0F, 0.0F); + } + + /** + * Called upon the block being destroyed by an explosion + */ + public void onBlockDestroyedByExplosion(World par1World, int par2, int par3, int par4, Explosion par5Explosion) { + this.modelBlock.onBlockDestroyedByExplosion(par1World, par2, par3, par4, par5Explosion); + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, ItemStack par6ItemStack) { + int var7 = MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + int var8 = par1World.getBlockMetadata(par2, par3, par4) & 4; + + if (var7 == 0) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 2 | var8, 2); + } + + if (var7 == 1) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 1 | var8, 2); + } + + if (var7 == 2) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 3 | var8, 2); + } + + if (var7 == 3) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 0 | var8, 2); + } + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9) { + return par5 != 0 && (par5 == 1 || (double) par7 <= 0.5D) ? par9 : par9 | 4; + } + + /** + * Ray traces through the blocks collision from start vector to end vector + * returning a ray trace hit. Args: world, x, y, z, startVec, endVec + */ + public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, Vec3 par6Vec3) { + MovingObjectPosition[] var7 = new MovingObjectPosition[8]; + int var8 = par1World.getBlockMetadata(par2, par3, par4); + int var9 = var8 & 3; + boolean var10 = (var8 & 4) == 4; + int[] var11 = field_72159_a[var9 + (var10 ? 4 : 0)]; + this.field_72156_cr = true; + int var14; + int var15; + int var16; + + for (int var12 = 0; var12 < 8; ++var12) { + this.field_72160_cs = var12; + int[] var13 = var11; + var14 = var11.length; + + for (var15 = 0; var15 < var14; ++var15) { + var16 = var13[var15]; + + if (var16 == var12) { + ; + } + } + + var7[var12] = super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3); + } + + int[] var21 = var11; + int var23 = var11.length; + + for (var14 = 0; var14 < var23; ++var14) { + var15 = var21[var14]; + var7[var15] = null; + } + + MovingObjectPosition var22 = null; + double var24 = 0.0D; + MovingObjectPosition[] var25 = var7; + var16 = var7.length; + + for (int var17 = 0; var17 < var16; ++var17) { + MovingObjectPosition var18 = var25[var17]; + + if (var18 != null) { + double var19 = var18.hitVec.squareDistanceTo(par6Vec3); + + if (var19 > var24) { + var22 = var18; + var24 = var19; + } + } + } + + return var22; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + } +} diff --git a/src/main/java/net/minecraft/src/BlockStationary.java b/src/main/java/net/minecraft/src/BlockStationary.java new file mode 100644 index 0000000..1a73d56 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockStationary.java @@ -0,0 +1,89 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockStationary extends BlockFluid { + protected BlockStationary(int par1, Material par2Material) { + super(par1, par2Material); + this.setTickRandomly(false); + + if (par2Material == Material.lava) { + this.setTickRandomly(true); + } + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return this.blockMaterial != Material.lava; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + super.onNeighborBlockChange(par1World, par2, par3, par4, par5); + + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + this.setNotStationary(par1World, par2, par3, par4); + } + } + + /** + * Changes the block ID to that of an updating fluid. + */ + private void setNotStationary(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + par1World.setBlock(par2, par3, par4, this.blockID - 1, var5, 2); + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID - 1, this.tickRate(par1World)); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (this.blockMaterial == Material.lava) { + int var6 = par5Random.nextInt(3); + int var7; + int var8; + + for (var7 = 0; var7 < var6; ++var7) { + par2 += par5Random.nextInt(3) - 1; + ++par3; + par4 += par5Random.nextInt(3) - 1; + var8 = par1World.getBlockId(par2, par3, par4); + + if (var8 == 0) { + if (this.isFlammable(par1World, par2 - 1, par3, par4) || this.isFlammable(par1World, par2 + 1, par3, par4) || this.isFlammable(par1World, par2, par3, par4 - 1) || this.isFlammable(par1World, par2, par3, par4 + 1) + || this.isFlammable(par1World, par2, par3 - 1, par4) || this.isFlammable(par1World, par2, par3 + 1, par4)) { + par1World.setBlock(par2, par3, par4, Block.fire.blockID); + return; + } + } else if (Block.blocksList[var8].blockMaterial.blocksMovement()) { + return; + } + } + + if (var6 == 0) { + var7 = par2; + var8 = par4; + + for (int var9 = 0; var9 < 3; ++var9) { + par2 = var7 + par5Random.nextInt(3) - 1; + par4 = var8 + par5Random.nextInt(3) - 1; + + if (par1World.isAirBlock(par2, par3 + 1, par4) && this.isFlammable(par1World, par2, par3, par4)) { + par1World.setBlock(par2, par3 + 1, par4, Block.fire.blockID); + } + } + } + } + } + + /** + * Checks to see if the block is flammable. + */ + private boolean isFlammable(World par1World, int par2, int par3, int par4) { + return par1World.getBlockMaterial(par2, par3, par4).getCanBurn(); + } +} diff --git a/src/main/java/net/minecraft/src/BlockStem.java b/src/main/java/net/minecraft/src/BlockStem.java new file mode 100644 index 0000000..0ee4f12 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockStem.java @@ -0,0 +1,255 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockStem extends BlockFlower { + /** Defines if it is a Melon or a Pumpkin that the stem is producing. */ + private final Block fruitType; + private Icon theIcon; + + protected BlockStem(int par1, Block par2Block) { + super(par1); + this.fruitType = par2Block; + this.setTickRandomly(true); + float var3 = 0.125F; + this.setBlockBounds(0.5F - var3, 0.0F, 0.5F - var3, 0.5F + var3, 0.25F, 0.5F + var3); + this.setCreativeTab((CreativeTabs) null); + } + + /** + * Gets passed in the blockID of the block below and supposed to return true if + * its allowed to grow on the type of blockID passed in. Args: blockID + */ + protected boolean canThisPlantGrowOnThisBlockID(int par1) { + return par1 == Block.tilledField.blockID; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + super.updateTick(par1World, par2, par3, par4, par5Random); + + if (par1World.getBlockLightValue(par2, par3 + 1, par4) >= 9) { + float var6 = this.getGrowthModifier(par1World, par2, par3, par4); + + if (par5Random.nextInt((int) (25.0F / var6) + 1) == 0) { + int var7 = par1World.getBlockMetadata(par2, par3, par4); + + if (var7 < 7) { + ++var7; + par1World.setBlockMetadataWithNotify(par2, par3, par4, var7, 2); + } else { + if (par1World.getBlockId(par2 - 1, par3, par4) == this.fruitType.blockID) { + return; + } + + if (par1World.getBlockId(par2 + 1, par3, par4) == this.fruitType.blockID) { + return; + } + + if (par1World.getBlockId(par2, par3, par4 - 1) == this.fruitType.blockID) { + return; + } + + if (par1World.getBlockId(par2, par3, par4 + 1) == this.fruitType.blockID) { + return; + } + + int var8 = par5Random.nextInt(4); + int var9 = par2; + int var10 = par4; + + if (var8 == 0) { + var9 = par2 - 1; + } + + if (var8 == 1) { + ++var9; + } + + if (var8 == 2) { + var10 = par4 - 1; + } + + if (var8 == 3) { + ++var10; + } + + int var11 = par1World.getBlockId(var9, par3 - 1, var10); + + if (par1World.getBlockId(var9, par3, var10) == 0 && (var11 == Block.tilledField.blockID || var11 == Block.dirt.blockID || var11 == Block.grass.blockID)) { + par1World.setBlock(var9, par3, var10, this.fruitType.blockID); + } + } + } + } + } + + public void fertilizeStem(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4) + MathHelper.getRandomIntegerInRange(par1World.rand, 2, 5); + + if (var5 > 7) { + var5 = 7; + } + + par1World.setBlockMetadataWithNotify(par2, par3, par4, var5, 2); + } + + private float getGrowthModifier(World par1World, int par2, int par3, int par4) { + float var5 = 1.0F; + int var6 = par1World.getBlockId(par2, par3, par4 - 1); + int var7 = par1World.getBlockId(par2, par3, par4 + 1); + int var8 = par1World.getBlockId(par2 - 1, par3, par4); + int var9 = par1World.getBlockId(par2 + 1, par3, par4); + int var10 = par1World.getBlockId(par2 - 1, par3, par4 - 1); + int var11 = par1World.getBlockId(par2 + 1, par3, par4 - 1); + int var12 = par1World.getBlockId(par2 + 1, par3, par4 + 1); + int var13 = par1World.getBlockId(par2 - 1, par3, par4 + 1); + boolean var14 = var8 == this.blockID || var9 == this.blockID; + boolean var15 = var6 == this.blockID || var7 == this.blockID; + boolean var16 = var10 == this.blockID || var11 == this.blockID || var12 == this.blockID || var13 == this.blockID; + + for (int var17 = par2 - 1; var17 <= par2 + 1; ++var17) { + for (int var18 = par4 - 1; var18 <= par4 + 1; ++var18) { + int var19 = par1World.getBlockId(var17, par3 - 1, var18); + float var20 = 0.0F; + + if (var19 == Block.tilledField.blockID) { + var20 = 1.0F; + + if (par1World.getBlockMetadata(var17, par3 - 1, var18) > 0) { + var20 = 3.0F; + } + } + + if (var17 != par2 || var18 != par4) { + var20 /= 4.0F; + } + + var5 += var20; + } + } + + if (var16 || var14 && var15) { + var5 /= 2.0F; + } + + return var5; + } + + /** + * Returns the color this block should be rendered. Used by leaves. + */ + public int getRenderColor(int par1) { + int var2 = par1 * 32; + int var3 = 255 - par1 * 8; + int var4 = par1 * 4; + return var2 << 16 | var3 << 8 | var4; + } + + /** + * Returns a integer with hex for 0xrrggbb with this color multiplied against + * the blocks color. Note only called when first determining what to render. + */ + public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return this.getRenderColor(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + float var1 = 0.125F; + this.setBlockBounds(0.5F - var1, 0.0F, 0.5F - var1, 0.5F + var1, 0.25F, 0.5F + var1); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.maxY = (double) ((float) (par1IBlockAccess.getBlockMetadata(par2, par3, par4) * 2 + 2) / 16.0F); + float var5 = 0.125F; + this.setBlockBounds(0.5F - var5, 0.0F, 0.5F - var5, 0.5F + var5, (float) this.maxY, 0.5F + var5); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 19; + } + + /** + * Returns the current state of the stem. Returns -1 if the stem is not fully + * grown, or a value between 0 and 3 based on the direction the stem is facing. + */ + public int getState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + return var5 < 7 ? -1 + : (par1IBlockAccess.getBlockId(par2 - 1, par3, par4) == this.fruitType.blockID ? 0 + : (par1IBlockAccess.getBlockId(par2 + 1, par3, par4) == this.fruitType.blockID ? 1 + : (par1IBlockAccess.getBlockId(par2, par3, par4 - 1) == this.fruitType.blockID ? 2 : (par1IBlockAccess.getBlockId(par2, par3, par4 + 1) == this.fruitType.blockID ? 3 : -1)))); + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7); + + if (!par1World.isRemote) { + Item var8 = null; + + if (this.fruitType == Block.pumpkin) { + var8 = Item.pumpkinSeeds; + } + + if (this.fruitType == Block.melon) { + var8 = Item.melonSeeds; + } + + for (int var9 = 0; var9 < 3; ++var9) { + if (par1World.rand.nextInt(15) <= par5) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(var8)); + } + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return -1; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return this.fruitType == Block.pumpkin ? Item.pumpkinSeeds.itemID : (this.fruitType == Block.melon ? Item.melonSeeds.itemID : 0); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("stem_straight"); + this.theIcon = par1IconRegister.registerIcon("stem_bent"); + } + + public Icon func_94368_p() { + return this.theIcon; + } +} diff --git a/src/main/java/net/minecraft/src/BlockStep.java b/src/main/java/net/minecraft/src/BlockStep.java new file mode 100644 index 0000000..d3ab3ec --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockStep.java @@ -0,0 +1,86 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockStep extends BlockHalfSlab { + /** The list of the types of step blocks. */ + public static final String[] blockStepTypes = new String[] { "stone", "sand", "wood", "cobble", "brick", "smoothStoneBrick", "netherBrick", "quartz" }; + private Icon theIcon; + + public BlockStep(int par1, boolean par2) { + super(par1, par2, Material.rock); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + int var3 = par2 & 7; + + if (this.isDoubleSlab && (par2 & 8) != 0) { + par1 = 1; + } + + return var3 == 0 ? (par1 != 1 && par1 != 0 ? this.theIcon : this.blockIcon) + : (var3 == 1 ? Block.sandStone.getBlockTextureFromSide(par1) + : (var3 == 2 ? Block.planks.getBlockTextureFromSide(par1) + : (var3 == 3 ? Block.cobblestone.getBlockTextureFromSide(par1) + : (var3 == 4 ? Block.brick.getBlockTextureFromSide(par1) + : (var3 == 5 ? Block.stoneBrick.getIcon(par1, 0) + : (var3 == 6 ? Block.netherBrick.getBlockTextureFromSide(1) : (var3 == 7 ? Block.blockNetherQuartz.getBlockTextureFromSide(par1) : this.blockIcon))))))); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("stoneslab_top"); + this.theIcon = par1IconRegister.registerIcon("stoneslab_side"); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.stoneSingleSlab.blockID; + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + return new ItemStack(Block.stoneSingleSlab.blockID, 2, par1 & 7); + } + + /** + * Returns the slab block name with step type. + */ + public String getFullSlabName(int par1) { + if (par1 < 0 || par1 >= blockStepTypes.length) { + par1 = 0; + } + + return super.getUnlocalizedName() + "." + blockStepTypes[par1]; + } + + /** + * returns a list of blocks with the same ID, but different meta (eg: wood + * returns 4 blocks) + */ + public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + if (par1 != Block.stoneDoubleSlab.blockID) { + for (int var4 = 0; var4 <= 7; ++var4) { + if (var4 != 2) { + par3List.add(new ItemStack(par1, 1, var4)); + } + } + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockStone.java b/src/main/java/net/minecraft/src/BlockStone.java new file mode 100644 index 0000000..29b7ebb --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockStone.java @@ -0,0 +1,17 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockStone extends Block { + public BlockStone(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.cobblestone.blockID; + } +} diff --git a/src/main/java/net/minecraft/src/BlockStoneBrick.java b/src/main/java/net/minecraft/src/BlockStoneBrick.java new file mode 100644 index 0000000..1917c64 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockStoneBrick.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +import java.util.List; + +public class BlockStoneBrick extends Block { + public static final String[] STONE_BRICK_TYPES = new String[] { "default", "mossy", "cracked", "chiseled" }; + public static final String[] field_94407_b = new String[] { "stonebricksmooth", "stonebricksmooth_mossy", "stonebricksmooth_cracked", "stonebricksmooth_carved" }; + private Icon[] field_94408_c; + + public BlockStoneBrick(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + if (par2 < 0 || par2 >= field_94407_b.length) { + par2 = 0; + } + + return this.field_94408_c[par2]; + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1; + } + + /** + * returns a list of blocks with the same ID, but different meta (eg: wood + * returns 4 blocks) + */ + public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + for (int var4 = 0; var4 < 4; ++var4) { + par3List.add(new ItemStack(par1, 1, var4)); + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.field_94408_c = new Icon[field_94407_b.length]; + + for (int var2 = 0; var2 < this.field_94408_c.length; ++var2) { + this.field_94408_c[var2] = par1IconRegister.registerIcon(field_94407_b[var2]); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockTNT.java b/src/main/java/net/minecraft/src/BlockTNT.java new file mode 100644 index 0000000..113d79f --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockTNT.java @@ -0,0 +1,127 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockTNT extends Block { + private Icon field_94393_a; + private Icon field_94392_b; + + public BlockTNT(int par1) { + super(par1, Material.tnt); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 0 ? this.field_94392_b : (par1 == 1 ? this.field_94393_a : this.blockIcon); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + + if (par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + this.onBlockDestroyedByPlayer(par1World, par2, par3, par4, 1); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + this.onBlockDestroyedByPlayer(par1World, par2, par3, par4, 1); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } + + /** + * Called upon the block being destroyed by an explosion + */ + public void onBlockDestroyedByExplosion(World par1World, int par2, int par3, int par4, Explosion par5Explosion) { + if (!par1World.isRemote) { + EntityTNTPrimed var6 = new EntityTNTPrimed(par1World, (double) ((float) par2 + 0.5F), (double) ((float) par3 + 0.5F), (double) ((float) par4 + 0.5F), par5Explosion.func_94613_c()); + var6.fuse = par1World.rand.nextInt(var6.fuse / 4) + var6.fuse / 8; + par1World.spawnEntityInWorld(var6); + } + } + + /** + * Called right before the block is destroyed by a player. Args: world, x, y, z, + * metaData + */ + public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) { + this.func_94391_a(par1World, par2, par3, par4, par5, (EntityLiving) null); + } + + public void func_94391_a(World par1World, int par2, int par3, int par4, int par5, EntityLiving par6EntityLiving) { + if (!par1World.isRemote) { + if ((par5 & 1) == 1) { + EntityTNTPrimed var7 = new EntityTNTPrimed(par1World, (double) ((float) par2 + 0.5F), (double) ((float) par3 + 0.5F), (double) ((float) par4 + 0.5F), par6EntityLiving); + par1World.spawnEntityInWorld(var7); + par1World.playSoundAtEntity(var7, "random.fuse", 1.0F, 1.0F); + } + } + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (par5EntityPlayer.getCurrentEquippedItem() != null && par5EntityPlayer.getCurrentEquippedItem().itemID == Item.flintAndSteel.itemID) { + this.func_94391_a(par1World, par2, par3, par4, 1, par5EntityPlayer); + par1World.setBlockToAir(par2, par3, par4); + return true; + } else { + return super.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, par6, par7, par8, par9); + } + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + if (par5Entity instanceof EntityArrow && !par1World.isRemote) { + EntityArrow var6 = (EntityArrow) par5Entity; + + if (var6.isBurning()) { + this.func_94391_a(par1World, par2, par3, par4, 1, var6.shootingEntity instanceof EntityLiving ? (EntityLiving) var6.shootingEntity : null); + par1World.setBlockToAir(par2, par3, par4); + } + } + } + + /** + * Return whether this block can drop from an explosion. + */ + public boolean canDropFromExplosion(Explosion par1Explosion) { + return false; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("tnt_side"); + this.field_94393_a = par1IconRegister.registerIcon("tnt_top"); + this.field_94392_b = par1IconRegister.registerIcon("tnt_bottom"); + } +} diff --git a/src/main/java/net/minecraft/src/BlockTallGrass.java b/src/main/java/net/minecraft/src/BlockTallGrass.java new file mode 100644 index 0000000..9e28510 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockTallGrass.java @@ -0,0 +1,115 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockTallGrass extends BlockFlower { + private static final String[] grassTypes = new String[] { "deadbush", "tallgrass", "fern" }; + private Icon[] iconArray; + + protected BlockTallGrass(int par1) { + super(par1, Material.vine); + float var2 = 0.4F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, 0.8F, 0.5F + var2); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + if (par2 >= this.iconArray.length) { + par2 = 0; + } + + return this.iconArray[par2]; + } + + public int getBlockColor() { + double var1 = 0.5D; + double var3 = 1.0D; + return ColorizerGrass.getGrassColor(var1, var3); + } + + /** + * Returns the color this block should be rendered. Used by leaves. + */ + public int getRenderColor(int par1) { + return par1 == 0 ? 16777215 : ColorizerFoliage.getFoliageColorBasic(); + } + + /** + * Returns a integer with hex for 0xrrggbb with this color multiplied against + * the blocks color. Note only called when first determining what to render. + */ + public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + if(var5 == 0) return 16777215; + var5 = par1IBlockAccess.getBiomeGenForCoords(par2, par4).getBiomeGrassColor(); + + initNoiseField(par2 >> 4, par4 >> 4); + float noise = (float)(grassNoiseArray[(par4 & 15) + (par2 & 15) * 16]) * 0.25F + 1.0F; + int var6 = (int)(((var5 >> 8) & 255) * noise); + if(var6 > 255) var6 = 255; + if(var6 < 0) var6 = 0; + + return (var5 & 0xff00ff) | (var6 << 8); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return par2Random.nextInt(8) == 0 ? Item.seeds.itemID : -1; + } + + /** + * Returns the usual quantity dropped by the block plus a bonus of 1 to 'i' + * (inclusive). + */ + public int quantityDroppedWithBonus(int par1, Random par2Random) { + return 1 + par2Random.nextInt(par1 * 2 + 1); + } + + /** + * Called when the player destroys a block with an item that can harvest it. (i, + * j, k) are the coordinates of the block and l is the block's subtype/damage. + */ + public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) { + if (!par1World.isRemote && par2EntityPlayer.getCurrentEquippedItem() != null && par2EntityPlayer.getCurrentEquippedItem().itemID == Item.shears.itemID) { + this.dropBlockAsItem_do(par1World, par3, par4, par5, new ItemStack(Block.tallGrass, 1, par6)); + } else { + super.harvestBlock(par1World, par2EntityPlayer, par3, par4, par5, par6); + } + } + + /** + * Get the block's damage value (for use with pick block). + */ + public int getDamageValue(World par1World, int par2, int par3, int par4) { + return par1World.getBlockMetadata(par2, par3, par4); + } + + /** + * returns a list of blocks with the same ID, but different meta (eg: wood + * returns 4 blocks) + */ + public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + for (int var4 = 1; var4 < 3; ++var4) { + par3List.add(new ItemStack(par1, 1, var4)); + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.iconArray = new Icon[grassTypes.length]; + + for (int var2 = 0; var2 < this.iconArray.length; ++var2) { + this.iconArray[var2] = par1IconRegister.registerIcon(grassTypes[var2]); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockTorch.java b/src/main/java/net/minecraft/src/BlockTorch.java new file mode 100644 index 0000000..288a315 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockTorch.java @@ -0,0 +1,245 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockTorch extends Block { + protected BlockTorch(int par1) { + super(par1, Material.circuits); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 2; + } + + /** + * Gets if we can place a torch on a block. + */ + private boolean canPlaceTorchOn(World par1World, int par2, int par3, int par4) { + if (par1World.doesBlockHaveSolidTopSurface(par2, par3, par4)) { + return true; + } else { + int var5 = par1World.getBlockId(par2, par3, par4); + return var5 == Block.fence.blockID || var5 == Block.netherFence.blockID || var5 == Block.glass.blockID || var5 == Block.cobblestoneWall.blockID; + } + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.isBlockNormalCubeDefault(par2 - 1, par3, par4, true) ? true + : (par1World.isBlockNormalCubeDefault(par2 + 1, par3, par4, true) ? true + : (par1World.isBlockNormalCubeDefault(par2, par3, par4 - 1, true) ? true : (par1World.isBlockNormalCubeDefault(par2, par3, par4 + 1, true) ? true : this.canPlaceTorchOn(par1World, par2, par3 - 1, par4)))); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9) { + int var10 = par9; + + if (par5 == 1 && this.canPlaceTorchOn(par1World, par2, par3 - 1, par4)) { + var10 = 5; + } + + if (par5 == 2 && par1World.isBlockNormalCubeDefault(par2, par3, par4 + 1, true)) { + var10 = 4; + } + + if (par5 == 3 && par1World.isBlockNormalCubeDefault(par2, par3, par4 - 1, true)) { + var10 = 3; + } + + if (par5 == 4 && par1World.isBlockNormalCubeDefault(par2 + 1, par3, par4, true)) { + var10 = 2; + } + + if (par5 == 5 && par1World.isBlockNormalCubeDefault(par2 - 1, par3, par4, true)) { + var10 = 1; + } + + return var10; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + super.updateTick(par1World, par2, par3, par4, par5Random); + + if (par1World.getBlockMetadata(par2, par3, par4) == 0) { + this.onBlockAdded(par1World, par2, par3, par4); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + if (par1World.getBlockMetadata(par2, par3, par4) == 0) { + if (par1World.isBlockNormalCubeDefault(par2 - 1, par3, par4, true)) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 1, 2); + } else if (par1World.isBlockNormalCubeDefault(par2 + 1, par3, par4, true)) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 2, 2); + } else if (par1World.isBlockNormalCubeDefault(par2, par3, par4 - 1, true)) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 3, 2); + } else if (par1World.isBlockNormalCubeDefault(par2, par3, par4 + 1, true)) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 4, 2); + } else if (this.canPlaceTorchOn(par1World, par2, par3 - 1, par4)) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, 5, 2); + } + } + + this.dropTorchIfCantStay(par1World, par2, par3, par4); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + this.func_94397_d(par1World, par2, par3, par4, par5); + } + + protected boolean func_94397_d(World par1World, int par2, int par3, int par4, int par5) { + if (this.dropTorchIfCantStay(par1World, par2, par3, par4)) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + boolean var7 = false; + + if (!par1World.isBlockNormalCubeDefault(par2 - 1, par3, par4, true) && var6 == 1) { + var7 = true; + } + + if (!par1World.isBlockNormalCubeDefault(par2 + 1, par3, par4, true) && var6 == 2) { + var7 = true; + } + + if (!par1World.isBlockNormalCubeDefault(par2, par3, par4 - 1, true) && var6 == 3) { + var7 = true; + } + + if (!par1World.isBlockNormalCubeDefault(par2, par3, par4 + 1, true) && var6 == 4) { + var7 = true; + } + + if (!this.canPlaceTorchOn(par1World, par2, par3 - 1, par4) && var6 == 5) { + var7 = true; + } + + if (var7) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + return true; + } else { + return false; + } + } else { + return true; + } + } + + /** + * Tests if the block can remain at its current location and will drop as an + * item if it is unable to stay. Returns True if it can stay and False if it + * drops. Args: world, x, y, z + */ + protected boolean dropTorchIfCantStay(World par1World, int par2, int par3, int par4) { + if (!this.canPlaceBlockAt(par1World, par2, par3, par4)) { + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + + return false; + } else { + return true; + } + } + + /** + * Ray traces through the blocks collision from start vector to end vector + * returning a ray trace hit. Args: world, x, y, z, startVec, endVec + */ + public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, Vec3 par6Vec3) { + int var7 = par1World.getBlockMetadata(par2, par3, par4) & 7; + float var8 = 0.15F; + + if (var7 == 1) { + this.setBlockBounds(0.0F, 0.2F, 0.5F - var8, var8 * 2.0F, 0.8F, 0.5F + var8); + } else if (var7 == 2) { + this.setBlockBounds(1.0F - var8 * 2.0F, 0.2F, 0.5F - var8, 1.0F, 0.8F, 0.5F + var8); + } else if (var7 == 3) { + this.setBlockBounds(0.5F - var8, 0.2F, 0.0F, 0.5F + var8, 0.8F, var8 * 2.0F); + } else if (var7 == 4) { + this.setBlockBounds(0.5F - var8, 0.2F, 1.0F - var8 * 2.0F, 0.5F + var8, 0.8F, 1.0F); + } else { + var8 = 0.1F; + this.setBlockBounds(0.5F - var8, 0.0F, 0.5F - var8, 0.5F + var8, 0.6F, 0.5F + var8); + } + + return super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3); + } + + /** + * A randomly called display update to be able to add particles or other items + * for display + */ + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + double var7 = (double) ((float) par2 + 0.5F); + double var9 = (double) ((float) par3 + 0.7F); + double var11 = (double) ((float) par4 + 0.5F); + double var13 = 0.2199999988079071D; + double var15 = 0.27000001072883606D; + + if (var6 == 1) { + par1World.spawnParticle("smoke", var7 - var15, var9 + var13, var11, 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("flame", var7 - var15, var9 + var13, var11, 0.0D, 0.0D, 0.0D); + } else if (var6 == 2) { + par1World.spawnParticle("smoke", var7 + var15, var9 + var13, var11, 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("flame", var7 + var15, var9 + var13, var11, 0.0D, 0.0D, 0.0D); + } else if (var6 == 3) { + par1World.spawnParticle("smoke", var7, var9 + var13, var11 - var15, 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("flame", var7, var9 + var13, var11 - var15, 0.0D, 0.0D, 0.0D); + } else if (var6 == 4) { + par1World.spawnParticle("smoke", var7, var9 + var13, var11 + var15, 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("flame", var7, var9 + var13, var11 + var15, 0.0D, 0.0D, 0.0D); + } else { + par1World.spawnParticle("smoke", var7, var9, var11, 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("flame", var7, var9, var11, 0.0D, 0.0D, 0.0D); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockTrapDoor.java b/src/main/java/net/minecraft/src/BlockTrapDoor.java new file mode 100644 index 0000000..4c3770c --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockTrapDoor.java @@ -0,0 +1,255 @@ +package net.minecraft.src; + +public class BlockTrapDoor extends Block { + protected BlockTrapDoor(int par1, Material par2Material) { + super(par1, par2Material); + float var3 = 0.5F; + float var4 = 1.0F; + this.setBlockBounds(0.5F - var3, 0.0F, 0.5F - var3, 0.5F + var3, var4, 0.5F + var3); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return !isTrapdoorOpen(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 0; + } + + /** + * Returns the bounding box of the wired rectangular prism to render. + */ + public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getSelectedBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.setBlockBoundsForBlockRender(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + float var1 = 0.1875F; + this.setBlockBounds(0.0F, 0.5F - var1 / 2.0F, 0.0F, 1.0F, 0.5F + var1 / 2.0F, 1.0F); + } + + public void setBlockBoundsForBlockRender(int par1) { + float var2 = 0.1875F; + + if ((par1 & 8) != 0) { + this.setBlockBounds(0.0F, 1.0F - var2, 0.0F, 1.0F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, var2, 1.0F); + } + + if (isTrapdoorOpen(par1)) { + if ((par1 & 3) == 0) { + this.setBlockBounds(0.0F, 0.0F, 1.0F - var2, 1.0F, 1.0F, 1.0F); + } + + if ((par1 & 3) == 1) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var2); + } + + if ((par1 & 3) == 2) { + this.setBlockBounds(1.0F - var2, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + if ((par1 & 3) == 3) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, var2, 1.0F, 1.0F); + } + } + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (this.blockMaterial == Material.iron) { + return true; + } else { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + par1World.setBlockMetadataWithNotify(par2, par3, par4, var10 ^ 4, 2); + par1World.playAuxSFXAtEntity(par5EntityPlayer, 1003, par2, par3, par4, 0); + return true; + } + } + + public void onPoweredBlockChange(World par1World, int par2, int par3, int par4, boolean par5) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + boolean var7 = (var6 & 4) > 0; + + if (var7 != par5) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 ^ 4, 2); + par1World.playAuxSFXAtEntity((EntityPlayer) null, 1003, par2, par3, par4, 0); + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + int var7 = par2; + int var8 = par4; + + if ((var6 & 3) == 0) { + var8 = par4 + 1; + } + + if ((var6 & 3) == 1) { + --var8; + } + + if ((var6 & 3) == 2) { + var7 = par2 + 1; + } + + if ((var6 & 3) == 3) { + --var7; + } + + if (!isValidSupportBlock(par1World.getBlockId(var7, par3, var8))) { + par1World.setBlockToAir(par2, par3, par4); + this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0); + } + + boolean var9 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4); + + if (var9 || par5 > 0 && Block.blocksList[par5].canProvidePower()) { + this.onPoweredBlockChange(par1World, par2, par3, par4, var9); + } + } + } + + /** + * Ray traces through the blocks collision from start vector to end vector + * returning a ray trace hit. Args: world, x, y, z, startVec, endVec + */ + public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, Vec3 par6Vec3) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9) { + int var10 = 0; + + if (par5 == 2) { + var10 = 0; + } + + if (par5 == 3) { + var10 = 1; + } + + if (par5 == 4) { + var10 = 2; + } + + if (par5 == 5) { + var10 = 3; + } + + if (par5 != 1 && par5 != 0 && par7 > 0.5F) { + var10 |= 8; + } + + return var10; + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + if (par5 == 0) { + return false; + } else if (par5 == 1) { + return false; + } else { + if (par5 == 2) { + ++par4; + } + + if (par5 == 3) { + --par4; + } + + if (par5 == 4) { + ++par2; + } + + if (par5 == 5) { + --par2; + } + + return isValidSupportBlock(par1World.getBlockId(par2, par3, par4)); + } + } + + public static boolean isTrapdoorOpen(int par0) { + return (par0 & 4) != 0; + } + + /** + * Checks if the block ID is a valid support block for the trap door to connect + * with. If it is not the trapdoor is dropped into the world. + */ + private static boolean isValidSupportBlock(int par0) { + if (par0 <= 0) { + return false; + } else { + Block var1 = Block.blocksList[par0]; + return var1 != null && var1.blockMaterial.isOpaque() && var1.renderAsNormalBlock() || var1 == Block.glowStone || var1 instanceof BlockHalfSlab || var1 instanceof BlockStairs; + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockTripWire.java b/src/main/java/net/minecraft/src/BlockTripWire.java new file mode 100644 index 0000000..8f77e4e --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockTripWire.java @@ -0,0 +1,247 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class BlockTripWire extends Block { + public BlockTripWire(int par1) { + super(par1, Material.circuits); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.15625F, 1.0F); + this.setTickRandomly(true); + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 10; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Returns which pass should this block be rendered on. 0 for solids and 1 for + * alpha + */ + public int getRenderBlockPass() { + return 1; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 30; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.silk.itemID; + } + + /** + * only called by clickMiddleMouseButton , and passed to + * inventory.setCurrentItem (along with isCreative) + */ + public int idPicked(World par1World, int par2, int par3, int par4) { + return Item.silk.itemID; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + boolean var7 = (var6 & 2) == 2; + boolean var8 = !par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4); + + if (var7 != var8) { + this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + boolean var6 = (var5 & 4) == 4; + boolean var7 = (var5 & 2) == 2; + + if (!var7) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.09375F, 1.0F); + } else if (!var6) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0625F, 0.0F, 1.0F, 0.15625F, 1.0F); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + int var5 = par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) ? 0 : 2; + par1World.setBlockMetadataWithNotify(par2, par3, par4, var5, 3); + this.func_72149_e(par1World, par2, par3, par4, var5); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + this.func_72149_e(par1World, par2, par3, par4, par6 | 1); + } + + /** + * Called when the block is attempted to be harvested + */ + public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer) { + if (!par1World.isRemote) { + if (par6EntityPlayer.getCurrentEquippedItem() != null && par6EntityPlayer.getCurrentEquippedItem().itemID == Item.shears.itemID) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, par5 | 8, 4); + } + } + } + + private void func_72149_e(World par1World, int par2, int par3, int par4, int par5) { + int var6 = 0; + + while (var6 < 2) { + int var7 = 1; + + while (true) { + if (var7 < 42) { + int var8 = par2 + Direction.offsetX[var6] * var7; + int var9 = par4 + Direction.offsetZ[var6] * var7; + int var10 = par1World.getBlockId(var8, par3, var9); + + if (var10 == Block.tripWireSource.blockID) { + int var11 = par1World.getBlockMetadata(var8, par3, var9) & 3; + + if (var11 == Direction.rotateOpposite[var6]) { + Block.tripWireSource.func_72143_a(par1World, var8, par3, var9, var10, par1World.getBlockMetadata(var8, par3, var9), true, var7, par5); + } + } else if (var10 == Block.tripWire.blockID) { + ++var7; + continue; + } + } + + ++var6; + break; + } + } + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + if (!par1World.isRemote) { + if ((par1World.getBlockMetadata(par2, par3, par4) & 1) != 1) { + this.updateTripWireState(par1World, par2, par3, par4); + } + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + if ((par1World.getBlockMetadata(par2, par3, par4) & 1) == 1) { + this.updateTripWireState(par1World, par2, par3, par4); + } + } + } + + private void updateTripWireState(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + boolean var6 = (var5 & 1) == 1; + boolean var7 = false; + List var8 = par1World.getEntitiesWithinAABBExcludingEntity((Entity) null, + AxisAlignedBB.getAABBPool().getAABB((double) par2 + this.minX, (double) par3 + this.minY, (double) par4 + this.minZ, (double) par2 + this.maxX, (double) par3 + this.maxY, (double) par4 + this.maxZ)); + + if (!var8.isEmpty()) { + Iterator var9 = var8.iterator(); + + while (var9.hasNext()) { + Entity var10 = (Entity) var9.next(); + + if (!var10.doesEntityNotTriggerPressurePlate()) { + var7 = true; + break; + } + } + } + + if (var7 && !var6) { + var5 |= 1; + } + + if (!var7 && var6) { + var5 &= -2; + } + + if (var7 != var6) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var5, 3); + this.func_72149_e(par1World, par2, par3, par4, var5); + } + + if (var7) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + } + + public static boolean func_72148_a(IBlockAccess par0IBlockAccess, int par1, int par2, int par3, int par4, int par5) { + int var6 = par1 + Direction.offsetX[par5]; + int var8 = par3 + Direction.offsetZ[par5]; + int var9 = par0IBlockAccess.getBlockId(var6, par2, var8); + boolean var10 = (par4 & 2) == 2; + int var11; + + if (var9 == Block.tripWireSource.blockID) { + var11 = par0IBlockAccess.getBlockMetadata(var6, par2, var8); + int var13 = var11 & 3; + return var13 == Direction.rotateOpposite[par5]; + } else if (var9 == Block.tripWire.blockID) { + var11 = par0IBlockAccess.getBlockMetadata(var6, par2, var8); + boolean var12 = (var11 & 2) == 2; + return var10 == var12; + } else { + return false; + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockTripWireSource.java b/src/main/java/net/minecraft/src/BlockTripWireSource.java new file mode 100644 index 0000000..d66d257 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockTripWireSource.java @@ -0,0 +1,360 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockTripWireSource extends Block { + public BlockTripWireSource(int par1) { + super(par1, Material.circuits); + this.setCreativeTab(CreativeTabs.tabRedstone); + this.setTickRandomly(true); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 29; + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 10; + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + return par5 == 2 && par1World.isBlockNormalCube(par2, par3, par4 + 1) ? true + : (par5 == 3 && par1World.isBlockNormalCube(par2, par3, par4 - 1) ? true : (par5 == 4 && par1World.isBlockNormalCube(par2 + 1, par3, par4) ? true : par5 == 5 && par1World.isBlockNormalCube(par2 - 1, par3, par4))); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.isBlockNormalCube(par2 - 1, par3, par4) ? true + : (par1World.isBlockNormalCube(par2 + 1, par3, par4) ? true : (par1World.isBlockNormalCube(par2, par3, par4 - 1) ? true : par1World.isBlockNormalCube(par2, par3, par4 + 1))); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9) { + byte var10 = 0; + + if (par5 == 2 && par1World.isBlockNormalCubeDefault(par2, par3, par4 + 1, true)) { + var10 = 2; + } + + if (par5 == 3 && par1World.isBlockNormalCubeDefault(par2, par3, par4 - 1, true)) { + var10 = 0; + } + + if (par5 == 4 && par1World.isBlockNormalCubeDefault(par2 + 1, par3, par4, true)) { + var10 = 1; + } + + if (par5 == 5 && par1World.isBlockNormalCubeDefault(par2 - 1, par3, par4, true)) { + var10 = 3; + } + + return var10; + } + + /** + * Called after a block is placed + */ + public void onPostBlockPlaced(World par1World, int par2, int par3, int par4, int par5) { + this.func_72143_a(par1World, par2, par3, par4, this.blockID, par5, false, -1, 0); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (par5 != this.blockID) { + if (this.func_72144_l(par1World, par2, par3, par4)) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + int var7 = var6 & 3; + boolean var8 = false; + + if (!par1World.isBlockNormalCube(par2 - 1, par3, par4) && var7 == 3) { + var8 = true; + } + + if (!par1World.isBlockNormalCube(par2 + 1, par3, par4) && var7 == 1) { + var8 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3, par4 - 1) && var7 == 0) { + var8 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3, par4 + 1) && var7 == 2) { + var8 = true; + } + + if (var8) { + this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + } + } + + public void func_72143_a(World par1World, int par2, int par3, int par4, int par5, int par6, boolean par7, int par8, int par9) { + int var10 = par6 & 3; + boolean var11 = (par6 & 4) == 4; + boolean var12 = (par6 & 8) == 8; + boolean var13 = par5 == Block.tripWireSource.blockID; + boolean var14 = false; + boolean var15 = !par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4); + int var16 = Direction.offsetX[var10]; + int var17 = Direction.offsetZ[var10]; + int var18 = 0; + int[] var19 = new int[42]; + int var20; + int var21; + int var22; + int var23; + int var24; + + for (var20 = 1; var20 < 42; ++var20) { + var21 = par2 + var16 * var20; + var22 = par4 + var17 * var20; + var23 = par1World.getBlockId(var21, par3, var22); + + if (var23 == Block.tripWireSource.blockID) { + var24 = par1World.getBlockMetadata(var21, par3, var22); + + if ((var24 & 3) == Direction.rotateOpposite[var10]) { + var18 = var20; + } + + break; + } + + if (var23 != Block.tripWire.blockID && var20 != par8) { + var19[var20] = -1; + var13 = false; + } else { + var24 = var20 == par8 ? par9 : par1World.getBlockMetadata(var21, par3, var22); + boolean var25 = (var24 & 8) != 8; + boolean var26 = (var24 & 1) == 1; + boolean var27 = (var24 & 2) == 2; + var13 &= var27 == var15; + var14 |= var25 && var26; + var19[var20] = var24; + + if (var20 == par8) { + par1World.scheduleBlockUpdate(par2, par3, par4, par5, this.tickRate(par1World)); + var13 &= var25; + } + } + } + + var13 &= var18 > 1; + var14 &= var13; + var20 = (var13 ? 4 : 0) | (var14 ? 8 : 0); + par6 = var10 | var20; + + if (var18 > 0) { + var21 = par2 + var16 * var18; + var22 = par4 + var17 * var18; + var23 = Direction.rotateOpposite[var10]; + par1World.setBlockMetadataWithNotify(var21, par3, var22, var23 | var20, 3); + this.notifyNeighborOfChange(par1World, var21, par3, var22, var23); + this.playSoundEffect(par1World, var21, par3, var22, var13, var14, var11, var12); + } + + this.playSoundEffect(par1World, par2, par3, par4, var13, var14, var11, var12); + + if (par5 > 0) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, par6, 3); + + if (par7) { + this.notifyNeighborOfChange(par1World, par2, par3, par4, var10); + } + } + + if (var11 != var13) { + for (var21 = 1; var21 < var18; ++var21) { + var22 = par2 + var16 * var21; + var23 = par4 + var17 * var21; + var24 = var19[var21]; + + if (var24 >= 0) { + if (var13) { + var24 |= 4; + } else { + var24 &= -5; + } + + par1World.setBlockMetadataWithNotify(var22, par3, var23, var24, 3); + } + } + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + this.func_72143_a(par1World, par2, par3, par4, this.blockID, par1World.getBlockMetadata(par2, par3, par4), true, -1, 0); + } + + /** + * only of the conditions are right + */ + private void playSoundEffect(World par1World, int par2, int par3, int par4, boolean par5, boolean par6, boolean par7, boolean par8) { + if (par6 && !par8) { + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.1D, (double) par4 + 0.5D, "random.click", 0.4F, 0.6F); + } else if (!par6 && par8) { + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.1D, (double) par4 + 0.5D, "random.click", 0.4F, 0.5F); + } else if (par5 && !par7) { + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.1D, (double) par4 + 0.5D, "random.click", 0.4F, 0.7F); + } else if (!par5 && par7) { + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.1D, (double) par4 + 0.5D, "random.bowhit", 0.4F, 1.2F / (par1World.rand.nextFloat() * 0.2F + 0.9F)); + } + } + + private void notifyNeighborOfChange(World par1World, int par2, int par3, int par4, int par5) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + + if (par5 == 3) { + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + } else if (par5 == 1) { + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + } else if (par5 == 0) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + } else if (par5 == 2) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + } + } + + private boolean func_72144_l(World par1World, int par2, int par3, int par4) { + if (!this.canPlaceBlockAt(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + return false; + } else { + return true; + } + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 3; + float var6 = 0.1875F; + + if (var5 == 3) { + this.setBlockBounds(0.0F, 0.2F, 0.5F - var6, var6 * 2.0F, 0.8F, 0.5F + var6); + } else if (var5 == 1) { + this.setBlockBounds(1.0F - var6 * 2.0F, 0.2F, 0.5F - var6, 1.0F, 0.8F, 0.5F + var6); + } else if (var5 == 0) { + this.setBlockBounds(0.5F - var6, 0.2F, 0.0F, 0.5F + var6, 0.8F, var6 * 2.0F); + } else if (var5 == 2) { + this.setBlockBounds(0.5F - var6, 0.2F, 1.0F - var6 * 2.0F, 0.5F + var6, 0.8F, 1.0F); + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + boolean var7 = (par6 & 4) == 4; + boolean var8 = (par6 & 8) == 8; + + if (var7 || var8) { + this.func_72143_a(par1World, par2, par3, par4, 0, par6, false, -1, 0); + } + + if (var8) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + int var9 = par6 & 3; + + if (var9 == 3) { + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + } else if (var9 == 1) { + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + } else if (var9 == 0) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + } else if (var9 == 2) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + } + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) == 8 ? 15 : 0; + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) != 8) { + return 0; + } else { + int var7 = var6 & 3; + return var7 == 2 && par5 == 2 ? 15 : (var7 == 0 && par5 == 3 ? 15 : (var7 == 1 && par5 == 4 ? 15 : (var7 == 3 && par5 == 5 ? 15 : 0))); + } + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/BlockVine.java b/src/main/java/net/minecraft/src/BlockVine.java new file mode 100644 index 0000000..0020b0a --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockVine.java @@ -0,0 +1,384 @@ +package net.minecraft.src; + +import java.util.Random; + + + +public class BlockVine extends Block { + public BlockVine(int par1) { + super(par1, Material.vine); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 20; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + float var7 = 1.0F; + float var8 = 1.0F; + float var9 = 1.0F; + float var10 = 0.0F; + float var11 = 0.0F; + float var12 = 0.0F; + boolean var13 = var6 > 0; + + if ((var6 & 2) != 0) { + var10 = Math.max(var10, 0.0625F); + var7 = 0.0F; + var8 = 0.0F; + var11 = 1.0F; + var9 = 0.0F; + var12 = 1.0F; + var13 = true; + } + + if ((var6 & 8) != 0) { + var7 = Math.min(var7, 0.9375F); + var10 = 1.0F; + var8 = 0.0F; + var11 = 1.0F; + var9 = 0.0F; + var12 = 1.0F; + var13 = true; + } + + if ((var6 & 4) != 0) { + var12 = Math.max(var12, 0.0625F); + var9 = 0.0F; + var7 = 0.0F; + var10 = 1.0F; + var8 = 0.0F; + var11 = 1.0F; + var13 = true; + } + + if ((var6 & 1) != 0) { + var9 = Math.min(var9, 0.9375F); + var12 = 1.0F; + var7 = 0.0F; + var10 = 1.0F; + var8 = 0.0F; + var11 = 1.0F; + var13 = true; + } + + if (!var13 && this.canBePlacedOn(par1IBlockAccess.getBlockId(par2, par3 + 1, par4))) { + var8 = Math.min(var8, 0.9375F); + var11 = 1.0F; + var7 = 0.0F; + var10 = 1.0F; + var9 = 0.0F; + var12 = 1.0F; + } + + this.setBlockBounds(var7, var8, var9, var10, var11, var12); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + switch (par5) { + case 1: + return this.canBePlacedOn(par1World.getBlockId(par2, par3 + 1, par4)); + + case 2: + return this.canBePlacedOn(par1World.getBlockId(par2, par3, par4 + 1)); + + case 3: + return this.canBePlacedOn(par1World.getBlockId(par2, par3, par4 - 1)); + + case 4: + return this.canBePlacedOn(par1World.getBlockId(par2 + 1, par3, par4)); + + case 5: + return this.canBePlacedOn(par1World.getBlockId(par2 - 1, par3, par4)); + + default: + return false; + } + } + + /** + * returns true if a vine can be placed on that block (checks for render as + * normal block and if it is solid) + */ + private boolean canBePlacedOn(int par1) { + if (par1 == 0) { + return false; + } else { + Block var2 = Block.blocksList[par1]; + return var2.renderAsNormalBlock() && var2.blockMaterial.blocksMovement(); + } + } + + /** + * Returns if the vine can stay in the world. It also changes the metadata + * according to neighboring blocks. + */ + private boolean canVineStay(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + int var6 = var5; + + if (var5 > 0) { + for (int var7 = 0; var7 <= 3; ++var7) { + int var8 = 1 << var7; + + if ((var5 & var8) != 0 && !this.canBePlacedOn(par1World.getBlockId(par2 + Direction.offsetX[var7], par3, par4 + Direction.offsetZ[var7])) + && (par1World.getBlockId(par2, par3 + 1, par4) != this.blockID || (par1World.getBlockMetadata(par2, par3 + 1, par4) & var8) == 0)) { + var6 &= ~var8; + } + } + } + + if (var6 == 0 && !this.canBePlacedOn(par1World.getBlockId(par2, par3 + 1, par4))) { + return false; + } else { + if (var6 != var5) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var6, 2); + } + + return true; + } + } + + public int getBlockColor() { + return ColorizerFoliage.getFoliageColorBasic(); + } + + /** + * Returns the color this block should be rendered. Used by leaves. + */ + public int getRenderColor(int par1) { + return ColorizerFoliage.getFoliageColorBasic(); + } + + /** + * Returns a integer with hex for 0xrrggbb with this color multiplied against + * the blocks color. Note only called when first determining what to render. + */ + public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBiomeGenForCoords(par2, par4).getBiomeFoliageColor(); + + initNoiseField(par2 >> 4, par4 >> 4); + float noise = (float)(grassNoiseArray[(par4 & 15) + (par2 & 15) * 16]) * 0.25F + 1.0F; + int var6 = (int)(((var5 >> 8) & 255) * noise); + if(var6 > 255) var6 = 255; + if(var6 < 0) var6 = 0; + + return (var5 & 0xff00ff) | (var6 << 8); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote && !this.canVineStay(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote && par1World.rand.nextInt(4) == 0) { + byte var6 = 4; + int var7 = 5; + boolean var8 = false; + int var9; + int var10; + int var11; + label138: + + for (var9 = par2 - var6; var9 <= par2 + var6; ++var9) { + for (var10 = par4 - var6; var10 <= par4 + var6; ++var10) { + for (var11 = par3 - 1; var11 <= par3 + 1; ++var11) { + if (par1World.getBlockId(var9, var11, var10) == this.blockID) { + --var7; + + if (var7 <= 0) { + var8 = true; + break label138; + } + } + } + } + } + + var9 = par1World.getBlockMetadata(par2, par3, par4); + var10 = par1World.rand.nextInt(6); + var11 = Direction.facingToDirection[var10]; + int var12; + int var13; + + if (var10 == 1 && par3 < 255 && par1World.isAirBlock(par2, par3 + 1, par4)) { + if (var8) { + return; + } + + var12 = par1World.rand.nextInt(16) & var9; + + if (var12 > 0) { + for (var13 = 0; var13 <= 3; ++var13) { + if (!this.canBePlacedOn(par1World.getBlockId(par2 + Direction.offsetX[var13], par3 + 1, par4 + Direction.offsetZ[var13]))) { + var12 &= ~(1 << var13); + } + } + + if (var12 > 0) { + par1World.setBlock(par2, par3 + 1, par4, this.blockID, var12, 2); + } + } + } else { + int var14; + + if (var10 >= 2 && var10 <= 5 && (var9 & 1 << var11) == 0) { + if (var8) { + return; + } + + var12 = par1World.getBlockId(par2 + Direction.offsetX[var11], par3, par4 + Direction.offsetZ[var11]); + + if (var12 != 0 && Block.blocksList[var12] != null) { + if (Block.blocksList[var12].blockMaterial.isOpaque() && Block.blocksList[var12].renderAsNormalBlock()) { + par1World.setBlockMetadataWithNotify(par2, par3, par4, var9 | 1 << var11, 2); + } + } else { + var13 = var11 + 1 & 3; + var14 = var11 + 3 & 3; + + if ((var9 & 1 << var13) != 0 && this.canBePlacedOn(par1World.getBlockId(par2 + Direction.offsetX[var11] + Direction.offsetX[var13], par3, par4 + Direction.offsetZ[var11] + Direction.offsetZ[var13]))) { + par1World.setBlock(par2 + Direction.offsetX[var11], par3, par4 + Direction.offsetZ[var11], this.blockID, 1 << var13, 2); + } else if ((var9 & 1 << var14) != 0 && this.canBePlacedOn(par1World.getBlockId(par2 + Direction.offsetX[var11] + Direction.offsetX[var14], par3, par4 + Direction.offsetZ[var11] + Direction.offsetZ[var14]))) { + par1World.setBlock(par2 + Direction.offsetX[var11], par3, par4 + Direction.offsetZ[var11], this.blockID, 1 << var14, 2); + } else if ((var9 & 1 << var13) != 0 && par1World.isAirBlock(par2 + Direction.offsetX[var11] + Direction.offsetX[var13], par3, par4 + Direction.offsetZ[var11] + Direction.offsetZ[var13]) + && this.canBePlacedOn(par1World.getBlockId(par2 + Direction.offsetX[var13], par3, par4 + Direction.offsetZ[var13]))) { + par1World.setBlock(par2 + Direction.offsetX[var11] + Direction.offsetX[var13], par3, par4 + Direction.offsetZ[var11] + Direction.offsetZ[var13], this.blockID, 1 << (var11 + 2 & 3), 2); + } else if ((var9 & 1 << var14) != 0 && par1World.isAirBlock(par2 + Direction.offsetX[var11] + Direction.offsetX[var14], par3, par4 + Direction.offsetZ[var11] + Direction.offsetZ[var14]) + && this.canBePlacedOn(par1World.getBlockId(par2 + Direction.offsetX[var14], par3, par4 + Direction.offsetZ[var14]))) { + par1World.setBlock(par2 + Direction.offsetX[var11] + Direction.offsetX[var14], par3, par4 + Direction.offsetZ[var11] + Direction.offsetZ[var14], this.blockID, 1 << (var11 + 2 & 3), 2); + } else if (this.canBePlacedOn(par1World.getBlockId(par2 + Direction.offsetX[var11], par3 + 1, par4 + Direction.offsetZ[var11]))) { + par1World.setBlock(par2 + Direction.offsetX[var11], par3, par4 + Direction.offsetZ[var11], this.blockID, 0, 2); + } + } + } else if (par3 > 1) { + var12 = par1World.getBlockId(par2, par3 - 1, par4); + + if (var12 == 0) { + var13 = par1World.rand.nextInt(16) & var9; + + if (var13 > 0) { + par1World.setBlock(par2, par3 - 1, par4, this.blockID, var13, 2); + } + } else if (var12 == this.blockID) { + var13 = par1World.rand.nextInt(16) & var9; + var14 = par1World.getBlockMetadata(par2, par3 - 1, par4); + + if (var14 != (var14 | var13)) { + par1World.setBlockMetadataWithNotify(par2, par3 - 1, par4, var14 | var13, 2); + } + } + } + } + } + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9) { + byte var10 = 0; + + switch (par5) { + case 2: + var10 = 1; + break; + + case 3: + var10 = 4; + break; + + case 4: + var10 = 8; + break; + + case 5: + var10 = 2; + } + + return var10 != 0 ? var10 : par9; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return 0; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Called when the player destroys a block with an item that can harvest it. (i, + * j, k) are the coordinates of the block and l is the block's subtype/damage. + */ + public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) { + if (!par1World.isRemote && par2EntityPlayer.getCurrentEquippedItem() != null && par2EntityPlayer.getCurrentEquippedItem().itemID == Item.shears.itemID) { + this.dropBlockAsItem_do(par1World, par3, par4, par5, new ItemStack(Block.vine, 1, 0)); + } else { + super.harvestBlock(par1World, par2EntityPlayer, par3, par4, par5, par6); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockWall.java b/src/main/java/net/minecraft/src/BlockWall.java new file mode 100644 index 0000000..8391d00 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockWall.java @@ -0,0 +1,151 @@ +package net.minecraft.src; + +import java.util.List; + +public class BlockWall extends Block { + /** The types of the wall. */ + public static final String[] types = new String[] { "normal", "mossy" }; + + public BlockWall(int par1, Block par2Block) { + super(par1, par2Block.blockMaterial); + this.setHardness(par2Block.blockHardness); + this.setResistance(par2Block.blockResistance / 3.0F); + this.setStepSound(par2Block.stepSound); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par2 == 1 ? Block.cobblestoneMossy.getBlockTextureFromSide(par1) : Block.cobblestone.getBlockTextureFromSide(par1); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 32; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + boolean var5 = this.canConnectWallTo(par1IBlockAccess, par2, par3, par4 - 1); + boolean var6 = this.canConnectWallTo(par1IBlockAccess, par2, par3, par4 + 1); + boolean var7 = this.canConnectWallTo(par1IBlockAccess, par2 - 1, par3, par4); + boolean var8 = this.canConnectWallTo(par1IBlockAccess, par2 + 1, par3, par4); + float var9 = 0.25F; + float var10 = 0.75F; + float var11 = 0.25F; + float var12 = 0.75F; + float var13 = 1.0F; + + if (var5) { + var11 = 0.0F; + } + + if (var6) { + var12 = 1.0F; + } + + if (var7) { + var9 = 0.0F; + } + + if (var8) { + var10 = 1.0F; + } + + if (var5 && var6 && !var7 && !var8) { + var13 = 0.8125F; + var9 = 0.3125F; + var10 = 0.6875F; + } else if (!var5 && !var6 && var7 && var8) { + var13 = 0.8125F; + var11 = 0.3125F; + var12 = 0.6875F; + } + + this.setBlockBounds(var9, 0.0F, var11, var10, var13, var12); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + this.maxY = 1.5D; + return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Return whether an adjacent block can connect to a wall. + */ + public boolean canConnectWallTo(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockId(par2, par3, par4); + + if (var5 != this.blockID && var5 != Block.fenceGate.blockID) { + Block var6 = Block.blocksList[var5]; + return var6 != null && var6.blockMaterial.isOpaque() && var6.renderAsNormalBlock() ? var6.blockMaterial != Material.pumpkin : false; + } else { + return true; + } + } + + /** + * returns a list of blocks with the same ID, but different meta (eg: wood + * returns 4 blocks) + */ + public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + par3List.add(new ItemStack(par1, 1, 0)); + par3List.add(new ItemStack(par1, 1, 1)); + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1; + } + + /** + * Returns true if the given side of this block type should be rendered, if the + * adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side + */ + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return par5 == 0 ? super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5) : true; + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + } +} diff --git a/src/main/java/net/minecraft/src/BlockWeb.java b/src/main/java/net/minecraft/src/BlockWeb.java new file mode 100644 index 0000000..1844507 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockWeb.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockWeb extends Block { + public BlockWeb(int par1) { + super(par1, Material.web); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + par5Entity.setInWeb(); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 1; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.silk.itemID; + } + + /** + * Return true if a player with Silk Touch can harvest this block directly, and + * not its normal drops. + */ + protected boolean canSilkHarvest() { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/BlockWood.java b/src/main/java/net/minecraft/src/BlockWood.java new file mode 100644 index 0000000..1ecdaa1 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockWood.java @@ -0,0 +1,58 @@ +package net.minecraft.src; + +import java.util.List; + +public class BlockWood extends Block { + /** The type of tree this block came from. */ + public static final String[] woodType = new String[] { "oak", "spruce", "birch", "jungle" }; + public static final String[] woodTextureTypes = new String[] { "wood", "wood_spruce", "wood_birch", "wood_jungle" }; + private Icon[] iconArray; + + public BlockWood(int par1) { + super(par1, Material.wood); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + if (par2 < 0 || par2 >= this.iconArray.length) { + par2 = 0; + } + + return this.iconArray[par2]; + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1; + } + + /** + * returns a list of blocks with the same ID, but different meta (eg: wood + * returns 4 blocks) + */ + public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + par3List.add(new ItemStack(par1, 1, 0)); + par3List.add(new ItemStack(par1, 1, 1)); + par3List.add(new ItemStack(par1, 1, 2)); + par3List.add(new ItemStack(par1, 1, 3)); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.iconArray = new Icon[woodTextureTypes.length]; + + for (int var2 = 0; var2 < this.iconArray.length; ++var2) { + this.iconArray[var2] = par1IconRegister.registerIcon(woodTextureTypes[var2]); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockWoodSlab.java b/src/main/java/net/minecraft/src/BlockWoodSlab.java new file mode 100644 index 0000000..e42cf18 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockWoodSlab.java @@ -0,0 +1,69 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockWoodSlab extends BlockHalfSlab { + /** The type of tree this slab came from. */ + public static final String[] woodType = new String[] { "oak", "spruce", "birch", "jungle" }; + + public BlockWoodSlab(int par1, boolean par2) { + super(par1, par2, Material.wood); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return Block.planks.getIcon(par1, par2 & 7); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.woodSingleSlab.blockID; + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + return new ItemStack(Block.woodSingleSlab.blockID, 2, par1 & 7); + } + + /** + * Returns the slab block name with step type. + */ + public String getFullSlabName(int par1) { + if (par1 < 0 || par1 >= woodType.length) { + par1 = 0; + } + + return super.getUnlocalizedName() + "." + woodType[par1]; + } + + /** + * returns a list of blocks with the same ID, but different meta (eg: wood + * returns 4 blocks) + */ + public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + if (par1 != Block.woodDoubleSlab.blockID) { + for (int var4 = 0; var4 < 4; ++var4) { + par3List.add(new ItemStack(par1, 1, var4)); + } + } + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + } +} diff --git a/src/main/java/net/minecraft/src/BlockWorkbench.java b/src/main/java/net/minecraft/src/BlockWorkbench.java new file mode 100644 index 0000000..11cc82d --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockWorkbench.java @@ -0,0 +1,42 @@ +package net.minecraft.src; + +public class BlockWorkbench extends Block { + private Icon workbenchIconTop; + private Icon workbenchIconFront; + + protected BlockWorkbench(int par1) { + super(par1, Material.wood); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * From the specified side and block metadata retrieves the blocks texture. + * Args: side, metadata + */ + public Icon getIcon(int par1, int par2) { + return par1 == 1 ? this.workbenchIconTop : (par1 == 0 ? Block.planks.getBlockTextureFromSide(par1) : (par1 != 2 && par1 != 4 ? this.blockIcon : this.workbenchIconFront)); + } + + /** + * When this method is called, your block should register all the icons it needs + * with the given IconRegister. This is the only chance you get to register + * icons. + */ + public void registerIcons(IconRegister par1IconRegister) { + this.blockIcon = par1IconRegister.registerIcon("workbench_side"); + this.workbenchIconTop = par1IconRegister.registerIcon("workbench_top"); + this.workbenchIconFront = par1IconRegister.registerIcon("workbench_front"); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + par5EntityPlayer.displayGUIWorkbench(par2, par3, par4); + return true; + } + } +} diff --git a/src/main/java/net/minecraft/src/BossStatus.java b/src/main/java/net/minecraft/src/BossStatus.java new file mode 100644 index 0000000..61055aa --- /dev/null +++ b/src/main/java/net/minecraft/src/BossStatus.java @@ -0,0 +1,15 @@ +package net.minecraft.src; + +public final class BossStatus { + public static float healthScale; + public static int statusBarLength; + public static String bossName; + public static boolean field_82825_d; + + public static void func_82824_a(IBossDisplayData par0IBossDisplayData, boolean par1) { + healthScale = (float) par0IBossDisplayData.getBossHealth() / (float) par0IBossDisplayData.getMaxHealth(); + statusBarLength = 100; + bossName = par0IBossDisplayData.getEntityName(); + field_82825_d = par1; + } +} diff --git a/src/main/java/net/minecraft/src/ChatAllowedCharacters.java b/src/main/java/net/minecraft/src/ChatAllowedCharacters.java new file mode 100644 index 0000000..ed5def5 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChatAllowedCharacters.java @@ -0,0 +1,68 @@ +package net.minecraft.src; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +public class ChatAllowedCharacters { + /** + * This String have the characters allowed in any text drawing of minecraft. + */ + public static String allowedCharacters = null; + + /** + * Array of the special characters that are allowed in any text drawing of + * Minecraft. + */ + public static final char[] allowedCharactersArray = new char[] { '/', '\n', '\r', '\t', '\u0000', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':' }; + + /** + * Load the font.txt resource file, that is on UTF-8 format. This file contains + * the characters that minecraft can render Strings on screen. + */ + public static void getAllowedCharacters() { + String var0 = ""; + + try { + BufferedReader var1 = new BufferedReader(new InputStreamReader(EaglerAdapter.loadResource("/font.txt"), "UTF-8")); + String var2 = ""; + + while ((var2 = var1.readLine()) != null) { + if (!var2.startsWith("#")) { + var0 = var0 + var2; + } + } + + var1.close(); + } catch (Exception var3) { + ; + } + + allowedCharacters = var0; + } + + public static final boolean isAllowedCharacter(char par0) { + return par0 != 167 && (allowedCharacters.indexOf(par0) >= 0 || par0 > 32); + } + + /** + * Filter string by only keeping those characters for which isAllowedCharacter() + * returns true. + */ + public static String filerAllowedCharacters(String par0Str) { + StringBuilder var1 = new StringBuilder(); + char[] var2 = par0Str.toCharArray(); + int var3 = var2.length; + + for (int var4 = 0; var4 < var3; ++var4) { + char var5 = var2[var4]; + + if (isAllowedCharacter(var5)) { + var1.append(var5); + } + } + + return var1.toString(); + } +} diff --git a/src/main/java/net/minecraft/src/ChatClickData.java b/src/main/java/net/minecraft/src/ChatClickData.java new file mode 100644 index 0000000..f7cb920 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChatClickData.java @@ -0,0 +1,76 @@ +package net.minecraft.src; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ChatClickData { + public static final Pattern pattern = Pattern.compile("^(?:(https?)://)?([-\\w_\\.]{2,}\\.[a-z]{2,4})(/\\S*)?$"); + private final FontRenderer fontR; + private final ChatLine line; + private final String field_78310_f; + + /** The URL which was clicked on. */ + private final String clickedUrl; + + public ChatClickData(FontRenderer par1FontRenderer, ChatLine par2ChatLine, int par3, int par4) { + this.fontR = par1FontRenderer; + this.line = par2ChatLine; + this.field_78310_f = par1FontRenderer.trimStringToWidth(par2ChatLine.getChatLineString(), par3); + this.clickedUrl = this.findClickedUrl(); + } + + /** + * Gets the URL which was clicked on. + */ + public String getClickedUrl() { + return this.clickedUrl; + } + + /** + * computes the URI from the clicked chat data object + */ + /* + public URI getURI() { + String var1 = this.getClickedUrl(); + + if (var1 == null) { + return null; + } else { + Matcher var2 = pattern.matcher(var1); + + if (var2.matches()) { + try { + String var3 = var2.group(0); + + if (var2.group(1) == null) { + var3 = "http://" + var3; + } + + return new URI(var3); + } catch (URISyntaxException var4) { + System.err.println("Couldn\'t create URI from chat"); + var4.printStackTrace(); + } + } + + return null; + } + } + */ + + private String findClickedUrl() { + int var1 = this.field_78310_f.lastIndexOf(" ", this.field_78310_f.length()) + 1; + + if (var1 < 0) { + var1 = 0; + } + + int var2 = this.line.getChatLineString().indexOf(" ", var1); + + if (var2 < 0) { + var2 = this.line.getChatLineString().length(); + } + + return StringUtils.stripControlCodes(this.line.getChatLineString().substring(var1, var2)); + } +} diff --git a/src/main/java/net/minecraft/src/ChatLine.java b/src/main/java/net/minecraft/src/ChatLine.java new file mode 100644 index 0000000..063af39 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChatLine.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +public class ChatLine { + /** GUI Update Counter value this Line was created at */ + private final int updateCounterCreated; + private final String lineString; + + /** + * int value to refer to existing Chat Lines, can be 0 which means unreferrable + */ + private final int chatLineID; + + public ChatLine(int par1, String par2Str, int par3) { + this.lineString = par2Str; + this.updateCounterCreated = par1; + this.chatLineID = par3; + } + + public String getChatLineString() { + return this.lineString; + } + + public int getUpdatedCounter() { + return this.updateCounterCreated; + } + + public int getChatLineID() { + return this.chatLineID; + } +} diff --git a/src/main/java/net/minecraft/src/ChestItemRenderHelper.java b/src/main/java/net/minecraft/src/ChestItemRenderHelper.java new file mode 100644 index 0000000..6287280 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChestItemRenderHelper.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +public class ChestItemRenderHelper { + /** The static instance of ChestItemRenderHelper. */ + public static ChestItemRenderHelper instance = new ChestItemRenderHelper(); + + /** Instance of Chest's Tile Entity. */ + private TileEntityChest theChest = new TileEntityChest(); + + /** Instance of Ender Chest's Tile Entity. */ + private TileEntityEnderChest theEnderChest = new TileEntityEnderChest(); + + /** + * Renders a chest at 0,0,0 - used for item rendering + */ + public void renderChest(Block par1Block, int par2, float par3) { + if (par1Block.blockID == Block.enderChest.blockID) { + TileEntityRenderer.instance.renderTileEntityAt(this.theEnderChest, 0.0D, 0.0D, 0.0D, 0.0F); + } else { + TileEntityRenderer.instance.renderTileEntityAt(this.theChest, 0.0D, 0.0D, 0.0D, 0.0F); + } + } +} diff --git a/src/main/java/net/minecraft/src/Chunk.java b/src/main/java/net/minecraft/src/Chunk.java new file mode 100644 index 0000000..1a67d39 --- /dev/null +++ b/src/main/java/net/minecraft/src/Chunk.java @@ -0,0 +1,1220 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; + + + +public class Chunk { + /** + * Determines if the chunk is lit or not at a light value greater than 0. + */ + public static boolean isLit; + + /** + * Used to store block IDs, block MSBs, Sky-light maps, Block-light maps, and + * metadata. Each entry corresponds to a logical segment of 16x16x16 blocks, + * stacked vertically. + */ + private ExtendedBlockStorage[] storageArrays; + + /** + * Contains a 16x16 mapping on the X/Z plane of the biome ID to which each colum + * belongs. + */ + private byte[] blockBiomeArray; + + /** + * A map, similar to heightMap, that tracks how far down precipitation can fall. + */ + public int[] precipitationHeightMap; + + /** Which columns need their skylightMaps updated. */ + public boolean[] updateSkylightColumns; + + /** Whether or not this Chunk is currently loaded into the World */ + public boolean isChunkLoaded; + + /** Reference to the World object. */ + public World worldObj; + public int[] heightMap; + + /** The x coordinate of the chunk. */ + public final int xPosition; + + /** The z coordinate of the chunk. */ + public final int zPosition; + private boolean isGapLightingUpdated; + + /** A Map of ChunkPositions to TileEntities in this chunk */ + public Map chunkTileEntityMap; + + /** + * Array of Lists containing the entities in this Chunk. Each List represents a + * 16 block subchunk. + */ + public List[] entityLists; + + /** Boolean value indicating if the terrain is populated. */ + public boolean isTerrainPopulated; + + /** + * Set to true if the chunk has been modified and needs to be updated + * internally. + */ + public boolean isModified; + + /** + * Whether this Chunk has any Entities and thus requires saving on every tick + */ + public boolean hasEntities; + + /** The time according to World.worldTime when this chunk was last saved */ + public long lastSaveTime; + + /** + * Updates to this chunk will not be sent to clients if this is false. This + * field is set to true the first time the chunk is sent to a client, and never + * set to false. + */ + public boolean sendUpdates; + + /** Lowest value in the heightmap. */ + public int heightMapMinimum; + + /** + * Contains the current round-robin relight check index, and is implied as the + * relight check location as well. + */ + private int queuedLightChecks; + boolean field_76653_p; + + public Chunk(World par1World, int par2, int par3) { + this.storageArrays = new ExtendedBlockStorage[16]; + this.blockBiomeArray = new byte[256]; + this.precipitationHeightMap = new int[256]; + this.updateSkylightColumns = new boolean[256]; + this.isGapLightingUpdated = false; + this.chunkTileEntityMap = new HashMap(); + this.isTerrainPopulated = false; + this.isModified = false; + this.hasEntities = false; + this.lastSaveTime = 0L; + this.sendUpdates = false; + this.heightMapMinimum = 0; + this.queuedLightChecks = 4096; + this.field_76653_p = false; + this.entityLists = new List[16]; + this.worldObj = par1World; + this.xPosition = par2; + this.zPosition = par3; + this.heightMap = new int[256]; + + for (int var4 = 0; var4 < this.entityLists.length; ++var4) { + this.entityLists[var4] = new ArrayList(); + } + + Arrays.fill(this.precipitationHeightMap, -999); + Arrays.fill(this.blockBiomeArray, (byte) -1); + } + + public Chunk(World par1World, byte[] par2ArrayOfByte, int par3, int par4) { + this(par1World, par3, par4); + int var5 = par2ArrayOfByte.length / 256; + + for (int var6 = 0; var6 < 16; ++var6) { + for (int var7 = 0; var7 < 16; ++var7) { + for (int var8 = 0; var8 < var5; ++var8) { + byte var9 = par2ArrayOfByte[var6 << 11 | var7 << 7 | var8]; + + if (var9 != 0) { + int var10 = var8 >> 4; + + if (this.storageArrays[var10] == null) { + this.storageArrays[var10] = new ExtendedBlockStorage(var10 << 4, !par1World.provider.hasNoSky); + } + + this.storageArrays[var10].setExtBlockID(var6, var8 & 15, var7, var9); + } + } + } + } + } + + /** + * Checks whether the chunk is at the X/Z location specified + */ + public boolean isAtLocation(int par1, int par2) { + return par1 == this.xPosition && par2 == this.zPosition; + } + + /** + * Returns the value in the height map at this x, z coordinate in the chunk + */ + public int getHeightValue(int par1, int par2) { + return this.heightMap[par2 << 4 | par1]; + } + + /** + * Returns the topmost ExtendedBlockStorage instance for this Chunk that + * actually contains a block. + */ + public int getTopFilledSegment() { + for (int var1 = this.storageArrays.length - 1; var1 >= 0; --var1) { + if (this.storageArrays[var1] != null) { + return this.storageArrays[var1].getYLocation(); + } + } + + return 0; + } + + /** + * Returns the ExtendedBlockStorage array for this Chunk. + */ + public ExtendedBlockStorage[] getBlockStorageArray() { + return this.storageArrays; + } + + /** + * Generates the height map for a chunk from scratch + */ + public void generateHeightMap() { + int var1 = this.getTopFilledSegment(); + + for (int var2 = 0; var2 < 16; ++var2) { + int var3 = 0; + + while (var3 < 16) { + this.precipitationHeightMap[var2 + (var3 << 4)] = -999; + int var4 = var1 + 16 - 1; + + while (true) { + if (var4 > 0) { + int var5 = this.getBlockID(var2, var4 - 1, var3); + + if (Block.lightOpacity[var5] == 0) { + --var4; + continue; + } + + this.heightMap[var3 << 4 | var2] = var4; + } + + ++var3; + break; + } + } + } + + this.isModified = true; + } + + /** + * Generates the initial skylight map for the chunk upon generation or load. + */ + public void generateSkylightMap() { + int var1 = this.getTopFilledSegment(); + this.heightMapMinimum = Integer.MAX_VALUE; + int var2; + int var3; + + for (var2 = 0; var2 < 16; ++var2) { + var3 = 0; + + while (var3 < 16) { + this.precipitationHeightMap[var2 + (var3 << 4)] = -999; + int var4 = var1 + 16 - 1; + + while (true) { + if (var4 > 0) { + if (this.getBlockLightOpacity(var2, var4 - 1, var3) == 0) { + --var4; + continue; + } + + this.heightMap[var3 << 4 | var2] = var4; + + if (var4 < this.heightMapMinimum) { + this.heightMapMinimum = var4; + } + } + + if (!this.worldObj.provider.hasNoSky) { + var4 = 15; + int var5 = var1 + 16 - 1; + + do { + var4 -= this.getBlockLightOpacity(var2, var5, var3); + + if (var4 > 0) { + ExtendedBlockStorage var6 = this.storageArrays[var5 >> 4]; + + if (var6 != null) { + var6.setExtSkylightValue(var2, var5 & 15, var3, var4); + this.worldObj.markBlockForRenderUpdate((this.xPosition << 4) + var2, var5, (this.zPosition << 4) + var3); + } + } + + --var5; + } while (var5 > 0 && var4 > 0); + } + + ++var3; + break; + } + } + } + + this.isModified = true; + + for (var2 = 0; var2 < 16; ++var2) { + for (var3 = 0; var3 < 16; ++var3) { + this.propagateSkylightOcclusion(var2, var3); + } + } + } + + /** + * Propagates a given sky-visible block's light value downward and upward to + * neighboring blocks as necessary. + */ + private void propagateSkylightOcclusion(int par1, int par2) { + this.updateSkylightColumns[par1 + par2 * 16] = true; + this.isGapLightingUpdated = true; + } + + /** + * Runs delayed skylight updates. + */ + private void updateSkylight_do() { + this.worldObj.theProfiler.startSection("recheckGaps"); + + if (this.worldObj.doChunksNearChunkExist(this.xPosition * 16 + 8, 0, this.zPosition * 16 + 8, 16)) { + for (int var1 = 0; var1 < 16; ++var1) { + for (int var2 = 0; var2 < 16; ++var2) { + if (this.updateSkylightColumns[var1 + var2 * 16]) { + this.updateSkylightColumns[var1 + var2 * 16] = false; + int var3 = this.getHeightValue(var1, var2); + int var4 = this.xPosition * 16 + var1; + int var5 = this.zPosition * 16 + var2; + int var6 = this.worldObj.getChunkHeightMapMinimum(var4 - 1, var5); + int var7 = this.worldObj.getChunkHeightMapMinimum(var4 + 1, var5); + int var8 = this.worldObj.getChunkHeightMapMinimum(var4, var5 - 1); + int var9 = this.worldObj.getChunkHeightMapMinimum(var4, var5 + 1); + + if (var7 < var6) { + var6 = var7; + } + + if (var8 < var6) { + var6 = var8; + } + + if (var9 < var6) { + var6 = var9; + } + + this.checkSkylightNeighborHeight(var4, var5, var6); + this.checkSkylightNeighborHeight(var4 - 1, var5, var3); + this.checkSkylightNeighborHeight(var4 + 1, var5, var3); + this.checkSkylightNeighborHeight(var4, var5 - 1, var3); + this.checkSkylightNeighborHeight(var4, var5 + 1, var3); + } + } + } + + this.isGapLightingUpdated = false; + } + + this.worldObj.theProfiler.endSection(); + } + + /** + * Checks the height of a block next to a sky-visible block and schedules a + * lighting update as necessary. + */ + private void checkSkylightNeighborHeight(int par1, int par2, int par3) { + int var4 = this.worldObj.getHeightValue(par1, par2); + + if (var4 > par3) { + this.updateSkylightNeighborHeight(par1, par2, par3, var4 + 1); + } else if (var4 < par3) { + this.updateSkylightNeighborHeight(par1, par2, var4, par3 + 1); + } + } + + private void updateSkylightNeighborHeight(int par1, int par2, int par3, int par4) { + if (par4 > par3 && this.worldObj.doChunksNearChunkExist(par1, 0, par2, 16)) { + for (int var5 = par3; var5 < par4; ++var5) { + this.worldObj.updateLightByType(EnumSkyBlock.Sky, par1, var5, par2); + } + + this.isModified = true; + } + } + + /** + * Initiates the recalculation of both the block-light and sky-light for a given + * block inside a chunk. + */ + private void relightBlock(int par1, int par2, int par3) { + int var4 = this.heightMap[par3 << 4 | par1] & 255; + int var5 = var4; + + if (par2 > var4) { + var5 = par2; + } + + while (var5 > 0 && this.getBlockLightOpacity(par1, var5 - 1, par3) == 0) { + --var5; + } + + if (var5 != var4) { + this.worldObj.markBlocksDirtyVertical(par1 + this.xPosition * 16, par3 + this.zPosition * 16, var5, var4); + this.heightMap[par3 << 4 | par1] = var5; + int var6 = this.xPosition * 16 + par1; + int var7 = this.zPosition * 16 + par3; + int var8; + int var12; + + if (!this.worldObj.provider.hasNoSky) { + ExtendedBlockStorage var9; + + if (var5 < var4) { + for (var8 = var5; var8 < var4; ++var8) { + var9 = this.storageArrays[var8 >> 4]; + + if (var9 != null) { + var9.setExtSkylightValue(par1, var8 & 15, par3, 15); + this.worldObj.markBlockForRenderUpdate((this.xPosition << 4) + par1, var8, (this.zPosition << 4) + par3); + } + } + } else { + for (var8 = var4; var8 < var5; ++var8) { + var9 = this.storageArrays[var8 >> 4]; + + if (var9 != null) { + var9.setExtSkylightValue(par1, var8 & 15, par3, 0); + this.worldObj.markBlockForRenderUpdate((this.xPosition << 4) + par1, var8, (this.zPosition << 4) + par3); + } + } + } + + var8 = 15; + + while (var5 > 0 && var8 > 0) { + --var5; + var12 = this.getBlockLightOpacity(par1, var5, par3); + + if (var12 == 0) { + var12 = 1; + } + + var8 -= var12; + + if (var8 < 0) { + var8 = 0; + } + + ExtendedBlockStorage var10 = this.storageArrays[var5 >> 4]; + + if (var10 != null) { + var10.setExtSkylightValue(par1, var5 & 15, par3, var8); + } + } + } + + var8 = this.heightMap[par3 << 4 | par1]; + var12 = var4; + int var13 = var8; + + if (var8 < var4) { + var12 = var8; + var13 = var4; + } + + if (var8 < this.heightMapMinimum) { + this.heightMapMinimum = var8; + } + + if (!this.worldObj.provider.hasNoSky) { + this.updateSkylightNeighborHeight(var6 - 1, var7, var12, var13); + this.updateSkylightNeighborHeight(var6 + 1, var7, var12, var13); + this.updateSkylightNeighborHeight(var6, var7 - 1, var12, var13); + this.updateSkylightNeighborHeight(var6, var7 + 1, var12, var13); + this.updateSkylightNeighborHeight(var6, var7, var12, var13); + } + + this.isModified = true; + } + } + + public int getBlockLightOpacity(int par1, int par2, int par3) { + return Block.lightOpacity[this.getBlockID(par1, par2, par3)]; + } + + /** + * Return the ID of a block in the chunk. + */ + public int getBlockID(int par1, int par2, int par3) { + if (par2 >> 4 >= this.storageArrays.length) { + return 0; + } else { + ExtendedBlockStorage var4 = this.storageArrays[par2 >> 4]; + return var4 != null ? var4.getExtBlockID(par1, par2 & 15, par3) : 0; + } + } + + /** + * Return the metadata corresponding to the given coordinates inside a chunk. + */ + public int getBlockMetadata(int par1, int par2, int par3) { + if (par2 >> 4 >= this.storageArrays.length) { + return 0; + } else { + ExtendedBlockStorage var4 = this.storageArrays[par2 >> 4]; + return var4 != null ? var4.getExtBlockMetadata(par1, par2 & 15, par3) : 0; + } + } + + /** + * Sets a blockID of a position within a chunk with metadata. Args: x, y, z, + * blockID, metadata + */ + public boolean setBlockIDWithMetadata(int par1, int par2, int par3, int par4, int par5) { + int var6 = par3 << 4 | par1; + + if (par2 >= this.precipitationHeightMap[var6] - 1) { + this.precipitationHeightMap[var6] = -999; + } + + int var7 = this.heightMap[var6]; + int var8 = this.getBlockID(par1, par2, par3); + int var9 = this.getBlockMetadata(par1, par2, par3); + + if (var8 == par4 && var9 == par5) { + return false; + } else { + ExtendedBlockStorage var10 = this.storageArrays[par2 >> 4]; + boolean var11 = false; + + if (var10 == null) { + if (par4 == 0) { + return false; + } + + var10 = this.storageArrays[par2 >> 4] = new ExtendedBlockStorage(par2 >> 4 << 4, !this.worldObj.provider.hasNoSky); + var11 = par2 >= var7; + } + + int var12 = this.xPosition * 16 + par1; + int var13 = this.zPosition * 16 + par3; + + if (var8 != 0 && !this.worldObj.isRemote) { + Block.blocksList[var8].onSetBlockIDWithMetaData(this.worldObj, var12, par2, var13, var9); + } + + var10.setExtBlockID(par1, par2 & 15, par3, par4); + + if (var8 != 0) { + if (!this.worldObj.isRemote) { + Block.blocksList[var8].breakBlock(this.worldObj, var12, par2, var13, var8, var9); + } else if (Block.blocksList[var8] instanceof ITileEntityProvider && var8 != par4) { + this.worldObj.removeBlockTileEntity(var12, par2, var13); + } + } + + if (var10.getExtBlockID(par1, par2 & 15, par3) != par4) { + return false; + } else { + var10.setExtBlockMetadata(par1, par2 & 15, par3, par5); + + if (var11) { + this.generateSkylightMap(); + } else { + if (Block.lightOpacity[par4 & 4095] > 0) { + if (par2 >= var7) { + this.relightBlock(par1, par2 + 1, par3); + } + } else if (par2 == var7 - 1) { + this.relightBlock(par1, par2, par3); + } + + this.propagateSkylightOcclusion(par1, par3); + } + + TileEntity var14; + + if (par4 != 0) { + if (!this.worldObj.isRemote) { + Block.blocksList[par4].onBlockAdded(this.worldObj, var12, par2, var13); + } + + if (Block.blocksList[par4] instanceof ITileEntityProvider) { + var14 = this.getChunkBlockTileEntity(par1, par2, par3); + + if (var14 == null) { + var14 = ((ITileEntityProvider) Block.blocksList[par4]).createNewTileEntity(this.worldObj); + this.worldObj.setBlockTileEntity(var12, par2, var13, var14); + } + + if (var14 != null) { + var14.updateContainingBlockInfo(); + } + } + } else if (var8 > 0 && Block.blocksList[var8] instanceof ITileEntityProvider) { + var14 = this.getChunkBlockTileEntity(par1, par2, par3); + + if (var14 != null) { + var14.updateContainingBlockInfo(); + } + } + + this.isModified = true; + return true; + } + } + } + + /** + * Set the metadata of a block in the chunk + */ + public boolean setBlockMetadata(int par1, int par2, int par3, int par4) { + ExtendedBlockStorage var5 = this.storageArrays[par2 >> 4]; + + if (var5 == null) { + return false; + } else { + int var6 = var5.getExtBlockMetadata(par1, par2 & 15, par3); + + if (var6 == par4) { + return false; + } else { + this.isModified = true; + var5.setExtBlockMetadata(par1, par2 & 15, par3, par4); + int var7 = var5.getExtBlockID(par1, par2 & 15, par3); + + if (var7 > 0 && Block.blocksList[var7] instanceof ITileEntityProvider) { + TileEntity var8 = this.getChunkBlockTileEntity(par1, par2, par3); + + if (var8 != null) { + var8.updateContainingBlockInfo(); + var8.blockMetadata = par4; + } + } + + return true; + } + } + } + + /** + * Gets the amount of light saved in this block (doesn't adjust for daylight) + */ + public int getSavedLightValue(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4) { + ExtendedBlockStorage var5 = this.storageArrays[par3 >> 4]; + return var5 == null ? (this.canBlockSeeTheSky(par2, par3, par4) ? par1EnumSkyBlock.defaultLightValue : 0) + : (par1EnumSkyBlock == EnumSkyBlock.Sky ? (this.worldObj.provider.hasNoSky ? 0 : var5.getExtSkylightValue(par2, par3 & 15, par4)) + : (par1EnumSkyBlock == EnumSkyBlock.Block ? var5.getExtBlocklightValue(par2, par3 & 15, par4) : par1EnumSkyBlock.defaultLightValue)); + } + + /** + * Sets the light value at the coordinate. If enumskyblock is set to sky it sets + * it in the skylightmap and if its a block then into the blocklightmap. Args + * enumSkyBlock, x, y, z, lightValue + */ + public void setLightValue(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4, int par5) { + ExtendedBlockStorage var6 = this.storageArrays[par3 >> 4]; + + if (var6 == null) { + var6 = this.storageArrays[par3 >> 4] = new ExtendedBlockStorage(par3 >> 4 << 4, !this.worldObj.provider.hasNoSky); + this.generateSkylightMap(); + } + + this.isModified = true; + + if (par1EnumSkyBlock == EnumSkyBlock.Sky) { + if (!this.worldObj.provider.hasNoSky) { + var6.setExtSkylightValue(par2, par3 & 15, par4, par5); + } + } else if (par1EnumSkyBlock == EnumSkyBlock.Block) { + var6.setExtBlocklightValue(par2, par3 & 15, par4, par5); + } + } + + /** + * Gets the amount of light on a block taking into account sunlight + */ + public int getBlockLightValue(int par1, int par2, int par3, int par4) { + ExtendedBlockStorage var5 = this.storageArrays[par2 >> 4]; + + if (var5 == null) { + return !this.worldObj.provider.hasNoSky && par4 < EnumSkyBlock.Sky.defaultLightValue ? EnumSkyBlock.Sky.defaultLightValue - par4 : 0; + } else { + int var6 = this.worldObj.provider.hasNoSky ? 0 : var5.getExtSkylightValue(par1, par2 & 15, par3); + + if (var6 > 0) { + isLit = true; + } + + var6 -= par4; + int var7 = var5.getExtBlocklightValue(par1, par2 & 15, par3); + + if (var7 > var6) { + var6 = var7; + } + + return var6; + } + } + + /** + * Adds an entity to the chunk. Args: entity + */ + public void addEntity(Entity par1Entity) { + this.hasEntities = true; + int var2 = MathHelper.floor_double(par1Entity.posX / 16.0D); + int var3 = MathHelper.floor_double(par1Entity.posZ / 16.0D); + + if (var2 != this.xPosition || var3 != this.zPosition) { + System.err.println("Wrong location! " + par1Entity); + } + + int var4 = MathHelper.floor_double(par1Entity.posY / 16.0D); + + if (var4 < 0) { + var4 = 0; + } + + if (var4 >= this.entityLists.length) { + var4 = this.entityLists.length - 1; + } + + par1Entity.addedToChunk = true; + par1Entity.chunkCoordX = this.xPosition; + par1Entity.chunkCoordY = var4; + par1Entity.chunkCoordZ = this.zPosition; + this.entityLists[var4].add(par1Entity); + } + + /** + * removes entity using its y chunk coordinate as its index + */ + public void removeEntity(Entity par1Entity) { + this.removeEntityAtIndex(par1Entity, par1Entity.chunkCoordY); + } + + /** + * Removes entity at the specified index from the entity array. + */ + public void removeEntityAtIndex(Entity par1Entity, int par2) { + if (par2 < 0) { + par2 = 0; + } + + if (par2 >= this.entityLists.length) { + par2 = this.entityLists.length - 1; + } + + this.entityLists[par2].remove(par1Entity); + } + + /** + * Returns whether is not a block above this one blocking sight to the sky (done + * via checking against the heightmap) + */ + public boolean canBlockSeeTheSky(int par1, int par2, int par3) { + return par2 >= this.heightMap[par3 << 4 | par1]; + } + + /** + * Gets the TileEntity for a given block in this chunk + */ + public TileEntity getChunkBlockTileEntity(int par1, int par2, int par3) { + ChunkPosition var4 = new ChunkPosition(par1, par2, par3); + TileEntity var5 = (TileEntity) this.chunkTileEntityMap.get(var4); + + if (var5 == null) { + int var6 = this.getBlockID(par1, par2, par3); + + if (var6 <= 0 || !Block.blocksList[var6].hasTileEntity()) { + return null; + } + + if (var5 == null) { + var5 = ((ITileEntityProvider) Block.blocksList[var6]).createNewTileEntity(this.worldObj); + this.worldObj.setBlockTileEntity(this.xPosition * 16 + par1, par2, this.zPosition * 16 + par3, var5); + } + + var5 = (TileEntity) this.chunkTileEntityMap.get(var4); + } + + if (var5 != null && var5.isInvalid()) { + this.chunkTileEntityMap.remove(var4); + return null; + } else { + return var5; + } + } + + /** + * Adds a TileEntity to a chunk + */ + public void addTileEntity(TileEntity par1TileEntity) { + int var2 = par1TileEntity.xCoord - this.xPosition * 16; + int var3 = par1TileEntity.yCoord; + int var4 = par1TileEntity.zCoord - this.zPosition * 16; + this.setChunkBlockTileEntity(var2, var3, var4, par1TileEntity); + + if (this.isChunkLoaded) { + this.worldObj.loadedTileEntityList.add(par1TileEntity); + } + } + + /** + * Sets the TileEntity for a given block in this chunk + */ + public void setChunkBlockTileEntity(int par1, int par2, int par3, TileEntity par4TileEntity) { + ChunkPosition var5 = new ChunkPosition(par1, par2, par3); + par4TileEntity.setWorldObj(this.worldObj); + par4TileEntity.xCoord = this.xPosition * 16 + par1; + par4TileEntity.yCoord = par2; + par4TileEntity.zCoord = this.zPosition * 16 + par3; + + if (this.getBlockID(par1, par2, par3) != 0 && Block.blocksList[this.getBlockID(par1, par2, par3)] instanceof ITileEntityProvider) { + if (this.chunkTileEntityMap.containsKey(var5)) { + ((TileEntity) this.chunkTileEntityMap.get(var5)).invalidate(); + } + + par4TileEntity.validate(); + this.chunkTileEntityMap.put(var5, par4TileEntity); + } + } + + /** + * Removes the TileEntity for a given block in this chunk + */ + public void removeChunkBlockTileEntity(int par1, int par2, int par3) { + ChunkPosition var4 = new ChunkPosition(par1, par2, par3); + + if (this.isChunkLoaded) { + TileEntity var5 = (TileEntity) this.chunkTileEntityMap.remove(var4); + + if (var5 != null) { + var5.invalidate(); + } + } + } + + /** + * Called when this Chunk is loaded by the ChunkProvider + */ + public void onChunkLoad() { + this.isChunkLoaded = true; + this.worldObj.addTileEntity(this.chunkTileEntityMap.values()); + + for (int var1 = 0; var1 < this.entityLists.length; ++var1) { + this.worldObj.addLoadedEntities(this.entityLists[var1]); + } + } + + /** + * Called when this Chunk is unloaded by the ChunkProvider + */ + public void onChunkUnload() { + this.isChunkLoaded = false; + Iterator var1 = this.chunkTileEntityMap.values().iterator(); + + while (var1.hasNext()) { + TileEntity var2 = (TileEntity) var1.next(); + this.worldObj.markTileEntityForDespawn(var2); + } + + for (int var3 = 0; var3 < this.entityLists.length; ++var3) { + this.worldObj.unloadEntities(this.entityLists[var3]); + } + } + + /** + * Sets the isModified flag for this Chunk + */ + public void setChunkModified() { + this.isModified = true; + } + + /** + * Fills the given list of all entities that intersect within the given bounding + * box that aren't the passed entity Args: entity, aabb, listToFill + */ + public void getEntitiesWithinAABBForEntity(Entity par1Entity, AxisAlignedBB par2AxisAlignedBB, List par3List, IEntitySelector par4IEntitySelector) { + int var5 = MathHelper.floor_double((par2AxisAlignedBB.minY - 2.0D) / 16.0D); + int var6 = MathHelper.floor_double((par2AxisAlignedBB.maxY + 2.0D) / 16.0D); + + if (var5 < 0) { + var5 = 0; + var6 = Math.max(var5, var6); + } + + if (var6 >= this.entityLists.length) { + var6 = this.entityLists.length - 1; + var5 = Math.min(var5, var6); + } + + for (int var7 = var5; var7 <= var6; ++var7) { + List var8 = this.entityLists[var7]; + + for (int var9 = 0; var9 < var8.size(); ++var9) { + Entity var10 = (Entity) var8.get(var9); + + if (var10 != par1Entity && var10.boundingBox.intersectsWith(par2AxisAlignedBB) && (par4IEntitySelector == null || par4IEntitySelector.isEntityApplicable(var10))) { + par3List.add(var10); + Entity[] var11 = var10.getParts(); + + if (var11 != null) { + for (int var12 = 0; var12 < var11.length; ++var12) { + var10 = var11[var12]; + + if (var10 != par1Entity && var10.boundingBox.intersectsWith(par2AxisAlignedBB) && (par4IEntitySelector == null || par4IEntitySelector.isEntityApplicable(var10))) { + par3List.add(var10); + } + } + } + } + } + } + } + + /** + * Gets all entities that can be assigned to the specified class. Args: + * entityClass, aabb, listToFill + */ + public void getEntitiesOfTypeWithinAAAB(Class par1Class, AxisAlignedBB par2AxisAlignedBB, List par3List, IEntitySelector par4IEntitySelector) { + int var5 = MathHelper.floor_double((par2AxisAlignedBB.minY - 2.0D) / 16.0D); + int var6 = MathHelper.floor_double((par2AxisAlignedBB.maxY + 2.0D) / 16.0D); + + if (var5 < 0) { + var5 = 0; + } else if (var5 >= this.entityLists.length) { + var5 = this.entityLists.length - 1; + } + + if (var6 >= this.entityLists.length) { + var6 = this.entityLists.length - 1; + } else if (var6 < 0) { + var6 = 0; + } + + for (int var7 = var5; var7 <= var6; ++var7) { + List var8 = this.entityLists[var7]; + + for (int var9 = 0; var9 < var8.size(); ++var9) { + Entity var10 = (Entity) var8.get(var9); + + if (par1Class.isAssignableFrom(var10.getClass()) && var10.boundingBox.intersectsWith(par2AxisAlignedBB) && (par4IEntitySelector == null || par4IEntitySelector.isEntityApplicable(var10))) { + par3List.add(var10); + } + } + } + } + + /** + * Returns true if this Chunk needs to be saved + */ + public boolean needsSaving(boolean par1) { + if (par1) { + if (this.hasEntities && this.worldObj.getTotalWorldTime() != this.lastSaveTime || this.isModified) { + return true; + } + } else if (this.hasEntities && this.worldObj.getTotalWorldTime() >= this.lastSaveTime + 600L) { + return true; + } + + return this.isModified; + } + + public Random getRandomWithSeed(long par1) { + return new Random(this.worldObj.getSeed() + (long) (this.xPosition * this.xPosition * 4987142) + (long) (this.xPosition * 5947611) + (long) (this.zPosition * this.zPosition) * 4392871L + (long) (this.zPosition * 389711) ^ par1); + } + + public boolean isEmpty() { + return false; + } + + public void populateChunk(IChunkProvider par1IChunkProvider, IChunkProvider par2IChunkProvider, int par3, int par4) { + if (!this.isTerrainPopulated && par1IChunkProvider.chunkExists(par3 + 1, par4 + 1) && par1IChunkProvider.chunkExists(par3, par4 + 1) && par1IChunkProvider.chunkExists(par3 + 1, par4)) { + par1IChunkProvider.populate(par2IChunkProvider, par3, par4); + } + + if (par1IChunkProvider.chunkExists(par3 - 1, par4) && !par1IChunkProvider.provideChunk(par3 - 1, par4).isTerrainPopulated && par1IChunkProvider.chunkExists(par3 - 1, par4 + 1) && par1IChunkProvider.chunkExists(par3, par4 + 1) + && par1IChunkProvider.chunkExists(par3 - 1, par4 + 1)) { + par1IChunkProvider.populate(par2IChunkProvider, par3 - 1, par4); + } + + if (par1IChunkProvider.chunkExists(par3, par4 - 1) && !par1IChunkProvider.provideChunk(par3, par4 - 1).isTerrainPopulated && par1IChunkProvider.chunkExists(par3 + 1, par4 - 1) && par1IChunkProvider.chunkExists(par3 + 1, par4 - 1) + && par1IChunkProvider.chunkExists(par3 + 1, par4)) { + par1IChunkProvider.populate(par2IChunkProvider, par3, par4 - 1); + } + + if (par1IChunkProvider.chunkExists(par3 - 1, par4 - 1) && !par1IChunkProvider.provideChunk(par3 - 1, par4 - 1).isTerrainPopulated && par1IChunkProvider.chunkExists(par3, par4 - 1) && par1IChunkProvider.chunkExists(par3 - 1, par4)) { + par1IChunkProvider.populate(par2IChunkProvider, par3 - 1, par4 - 1); + } + } + + /** + * Gets the height to which rain/snow will fall. Calculates it if not already + * stored. + */ + public int getPrecipitationHeight(int par1, int par2) { + int var3 = par1 | par2 << 4; + int var4 = this.precipitationHeightMap[var3]; + + if (var4 == -999) { + int var5 = this.getTopFilledSegment() + 15; + var4 = -1; + + while (var5 > 0 && var4 == -1) { + int var6 = this.getBlockID(par1, var5, par2); + Material var7 = var6 == 0 ? Material.air : Block.blocksList[var6].blockMaterial; + + if (!var7.blocksMovement() && !var7.isLiquid()) { + --var5; + } else { + var4 = var5 + 1; + } + } + + this.precipitationHeightMap[var3] = var4; + } + + return var4; + } + + /** + * Checks whether skylight needs updated; if it does, calls updateSkylight_do + */ + public void updateSkylight() { + if (this.isGapLightingUpdated && !this.worldObj.provider.hasNoSky) { + this.updateSkylight_do(); + } + } + + /** + * Gets a ChunkCoordIntPair representing the Chunk's position. + */ + public ChunkCoordIntPair getChunkCoordIntPair() { + return new ChunkCoordIntPair(this.xPosition, this.zPosition); + } + + /** + * Returns whether the ExtendedBlockStorages containing levels (in blocks) from + * arg 1 to arg 2 are fully empty (true) or not (false). + */ + public boolean getAreLevelsEmpty(int par1, int par2) { + if (par1 < 0) { + par1 = 0; + } + + if (par2 >= 256) { + par2 = 255; + } + + for (int var3 = par1; var3 <= par2; var3 += 16) { + ExtendedBlockStorage var4 = this.storageArrays[var3 >> 4]; + + if (var4 != null && !var4.isEmpty()) { + return false; + } + } + + return true; + } + + public void setStorageArrays(ExtendedBlockStorage[] par1ArrayOfExtendedBlockStorage) { + this.storageArrays = par1ArrayOfExtendedBlockStorage; + } + + /** + * Initialise this chunk with new binary data + */ + public void fillChunk(byte[] par1ArrayOfByte, int par2, int par3, boolean par4) { + int var5 = 0; + boolean var6 = !this.worldObj.provider.hasNoSky; + int var7; + + for (var7 = 0; var7 < this.storageArrays.length; ++var7) { + if ((par2 & 1 << var7) != 0) { + if (this.storageArrays[var7] == null) { + this.storageArrays[var7] = new ExtendedBlockStorage(var7 << 4, var6); + } + + byte[] var8 = this.storageArrays[var7].getBlockLSBArray(); + System.arraycopy(par1ArrayOfByte, var5, var8, 0, var8.length); + var5 += var8.length; + } else if (par4 && this.storageArrays[var7] != null) { + this.storageArrays[var7] = null; + } + } + + NibbleArray var9; + + for (var7 = 0; var7 < this.storageArrays.length; ++var7) { + if ((par2 & 1 << var7) != 0 && this.storageArrays[var7] != null) { + var9 = this.storageArrays[var7].getMetadataArray(); + System.arraycopy(par1ArrayOfByte, var5, var9.data, 0, var9.data.length); + var5 += var9.data.length; + } + } + + for (var7 = 0; var7 < this.storageArrays.length; ++var7) { + if ((par2 & 1 << var7) != 0 && this.storageArrays[var7] != null) { + var9 = this.storageArrays[var7].getBlocklightArray(); + System.arraycopy(par1ArrayOfByte, var5, var9.data, 0, var9.data.length); + var5 += var9.data.length; + } + } + + if (var6) { + for (var7 = 0; var7 < this.storageArrays.length; ++var7) { + if ((par2 & 1 << var7) != 0 && this.storageArrays[var7] != null) { + var9 = this.storageArrays[var7].getSkylightArray(); + System.arraycopy(par1ArrayOfByte, var5, var9.data, 0, var9.data.length); + var5 += var9.data.length; + } + } + } + + for (var7 = 0; var7 < this.storageArrays.length; ++var7) { + if ((par3 & 1 << var7) != 0) { + if (this.storageArrays[var7] == null) { + var5 += 2048; + } else { + var9 = this.storageArrays[var7].getBlockMSBArray(); + + if (var9 == null) { + var9 = this.storageArrays[var7].createBlockMSBArray(); + } + + System.arraycopy(par1ArrayOfByte, var5, var9.data, 0, var9.data.length); + var5 += var9.data.length; + } + } else if (par4 && this.storageArrays[var7] != null && this.storageArrays[var7].getBlockMSBArray() != null) { + this.storageArrays[var7].clearMSBArray(); + } + } + + if (par4) { + System.arraycopy(par1ArrayOfByte, var5, this.blockBiomeArray, 0, this.blockBiomeArray.length); + int var10000 = var5 + this.blockBiomeArray.length; + } + + for (var7 = 0; var7 < this.storageArrays.length; ++var7) { + if (this.storageArrays[var7] != null && (par2 & 1 << var7) != 0) { + this.storageArrays[var7].removeInvalidBlocks(); + } + } + + this.generateHeightMap(); + Iterator var11 = this.chunkTileEntityMap.values().iterator(); + + while (var11.hasNext()) { + TileEntity var10 = (TileEntity) var11.next(); + var10.updateContainingBlockInfo(); + } + } + + /** + * This method retrieves the biome at a set of coordinates + */ + public BiomeGenBase getBiomeGenForWorldCoords(int par1, int par2) { + int var4 = this.blockBiomeArray[par2 << 4 | par1] & 255; + + if (var4 == 255) { + var4 = 0; + } + + return BiomeGenBase.biomeList[var4] == null ? BiomeGenBase.plains : BiomeGenBase.biomeList[var4]; + } + + /** + * Returns an array containing a 16x16 mapping on the X/Z of block positions in + * this Chunk to biome IDs. + */ + public byte[] getBiomeArray() { + return this.blockBiomeArray; + } + + /** + * Accepts a 256-entry array that contains a 16x16 mapping on the X/Z plane of + * block positions in this Chunk to biome IDs. + */ + public void setBiomeArray(byte[] par1ArrayOfByte) { + this.blockBiomeArray = par1ArrayOfByte; + } + + /** + * Resets the relight check index to 0 for this Chunk. + */ + public void resetRelightChecks() { + this.queuedLightChecks = 0; + } + + /** + * Called once-per-chunk-per-tick, and advances the round-robin relight check + * index per-storage-block by up to 8 blocks at a time. In a worst-case + * scenario, can potentially take up to 1.6 seconds, calculated via + * (4096/(8*16))/20, to re-check all blocks in a chunk, which could explain both + * lagging light updates in certain cases as well as Nether relight + */ + public void enqueueRelightChecks() { + for (int var1 = 0; var1 < 8; ++var1) { + if (this.queuedLightChecks >= 4096) { + return; + } + + int var2 = this.queuedLightChecks % 16; + int var3 = this.queuedLightChecks / 16 % 16; + int var4 = this.queuedLightChecks / 256; + ++this.queuedLightChecks; + int var5 = (this.xPosition << 4) + var3; + int var6 = (this.zPosition << 4) + var4; + + for (int var7 = 0; var7 < 16; ++var7) { + int var8 = (var2 << 4) + var7; + + if (this.storageArrays[var2] == null && (var7 == 0 || var7 == 15 || var3 == 0 || var3 == 15 || var4 == 0 || var4 == 15) || this.storageArrays[var2] != null && this.storageArrays[var2].getExtBlockID(var3, var7, var4) == 0) { + if (Block.lightValue[this.worldObj.getBlockId(var5, var8 - 1, var6)] > 0) { + this.worldObj.updateAllLightTypes(var5, var8 - 1, var6); + } + + if (Block.lightValue[this.worldObj.getBlockId(var5, var8 + 1, var6)] > 0) { + this.worldObj.updateAllLightTypes(var5, var8 + 1, var6); + } + + if (Block.lightValue[this.worldObj.getBlockId(var5 - 1, var8, var6)] > 0) { + this.worldObj.updateAllLightTypes(var5 - 1, var8, var6); + } + + if (Block.lightValue[this.worldObj.getBlockId(var5 + 1, var8, var6)] > 0) { + this.worldObj.updateAllLightTypes(var5 + 1, var8, var6); + } + + if (Block.lightValue[this.worldObj.getBlockId(var5, var8, var6 - 1)] > 0) { + this.worldObj.updateAllLightTypes(var5, var8, var6 - 1); + } + + if (Block.lightValue[this.worldObj.getBlockId(var5, var8, var6 + 1)] > 0) { + this.worldObj.updateAllLightTypes(var5, var8, var6 + 1); + } + + this.worldObj.updateAllLightTypes(var5, var8, var6); + } + } + } + } +} diff --git a/src/main/java/net/minecraft/src/ChunkCache.java b/src/main/java/net/minecraft/src/ChunkCache.java new file mode 100644 index 0000000..bf0d64d --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkCache.java @@ -0,0 +1,345 @@ +package net.minecraft.src; + +public class ChunkCache implements IBlockAccess { + private int chunkX; + private int chunkZ; + private Chunk[][] chunkArray; + + /** set by !chunk.getAreLevelsEmpty */ + private boolean hasExtendedLevels; + + /** Reference to the World object. */ + private World worldObj; + + public ChunkCache(World par1World, int par2, int par3, int par4, int par5, int par6, int par7, int par8) { + this.worldObj = par1World; + this.chunkX = par2 - par8 >> 4; + this.chunkZ = par4 - par8 >> 4; + int var9 = par5 + par8 >> 4; + int var10 = par7 + par8 >> 4; + this.chunkArray = new Chunk[var9 - this.chunkX + 1][var10 - this.chunkZ + 1]; + this.hasExtendedLevels = true; + int var11; + int var12; + Chunk var13; + + for (var11 = this.chunkX; var11 <= var9; ++var11) { + for (var12 = this.chunkZ; var12 <= var10; ++var12) { + var13 = par1World.getChunkFromChunkCoords(var11, var12); + + if (var13 != null) { + this.chunkArray[var11 - this.chunkX][var12 - this.chunkZ] = var13; + } + } + } + + for (var11 = par2 >> 4; var11 <= par5 >> 4; ++var11) { + for (var12 = par4 >> 4; var12 <= par7 >> 4; ++var12) { + var13 = this.chunkArray[var11 - this.chunkX][var12 - this.chunkZ]; + + if (var13 != null && !var13.getAreLevelsEmpty(par3, par6)) { + this.hasExtendedLevels = false; + } + } + } + } + + /** + * set by !chunk.getAreLevelsEmpty + */ + public boolean extendedLevelsInChunkCache() { + return this.hasExtendedLevels; + } + + /** + * Returns the block ID at coords x,y,z + */ + public int getBlockId(int par1, int par2, int par3) { + if (par2 < 0) { + return 0; + } else if (par2 >= 256) { + return 0; + } else { + int var4 = (par1 >> 4) - this.chunkX; + int var5 = (par3 >> 4) - this.chunkZ; + + if (var4 >= 0 && var4 < this.chunkArray.length && var5 >= 0 && var5 < this.chunkArray[var4].length) { + Chunk var6 = this.chunkArray[var4][var5]; + return var6 == null ? 0 : var6.getBlockID(par1 & 15, par2, par3 & 15); + } else { + return 0; + } + } + } + + /** + * Returns the TileEntity associated with a given block in X,Y,Z coordinates, or + * null if no TileEntity exists + */ + public TileEntity getBlockTileEntity(int par1, int par2, int par3) { + int var4 = (par1 >> 4) - this.chunkX; + int var5 = (par3 >> 4) - this.chunkZ; + return this.chunkArray[var4][var5].getChunkBlockTileEntity(par1 & 15, par2, par3 & 15); + } + + public float getBrightness(int par1, int par2, int par3, int par4) { + int var5 = this.getLightValue(par1, par2, par3); + + if (var5 < par4) { + var5 = par4; + } + + return this.worldObj.provider.lightBrightnessTable[var5]; + } + + /** + * Any Light rendered on a 1.8 Block goes through here + */ + public int getLightBrightnessForSkyBlocks(int par1, int par2, int par3, int par4) { + int var5 = this.getSkyBlockTypeBrightness(EnumSkyBlock.Sky, par1, par2, par3); + int var6 = this.getSkyBlockTypeBrightness(EnumSkyBlock.Block, par1, par2, par3); + + if (var6 < par4) { + var6 = par4; + } + + return var5 << 20 | var6 << 4; + } + + /** + * Returns how bright the block is shown as which is the block's light value + * looked up in a lookup table (light values aren't linear for brightness). + * Args: x, y, z + */ + public float getLightBrightness(int par1, int par2, int par3) { + return this.worldObj.provider.lightBrightnessTable[this.getLightValue(par1, par2, par3)]; + } + + /** + * Gets the light value of the specified block coords. Args: x, y, z + */ + public int getLightValue(int par1, int par2, int par3) { + return this.getLightValueExt(par1, par2, par3, true); + } + + /** + * Get light value with flag + */ + public int getLightValueExt(int par1, int par2, int par3, boolean par4) { + if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 <= 30000000) { + int var5; + int var6; + + if (par4) { + var5 = this.getBlockId(par1, par2, par3); + + if (var5 == Block.stoneSingleSlab.blockID || var5 == Block.woodSingleSlab.blockID || var5 == Block.tilledField.blockID || var5 == Block.stairsWoodOak.blockID || var5 == Block.stairsCobblestone.blockID) { + var6 = this.getLightValueExt(par1, par2 + 1, par3, false); + int var7 = this.getLightValueExt(par1 + 1, par2, par3, false); + int var8 = this.getLightValueExt(par1 - 1, par2, par3, false); + int var9 = this.getLightValueExt(par1, par2, par3 + 1, false); + int var10 = this.getLightValueExt(par1, par2, par3 - 1, false); + + if (var7 > var6) { + var6 = var7; + } + + if (var8 > var6) { + var6 = var8; + } + + if (var9 > var6) { + var6 = var9; + } + + if (var10 > var6) { + var6 = var10; + } + + return var6; + } + } + + if (par2 < 0) { + return 0; + } else if (par2 >= 256) { + var5 = 15 - this.worldObj.skylightSubtracted; + + if (var5 < 0) { + var5 = 0; + } + + return var5; + } else { + var5 = (par1 >> 4) - this.chunkX; + var6 = (par3 >> 4) - this.chunkZ; + return this.chunkArray[var5][var6].getBlockLightValue(par1 & 15, par2, par3 & 15, this.worldObj.skylightSubtracted); + } + } else { + return 15; + } + } + + /** + * Returns the block metadata at coords x,y,z + */ + public int getBlockMetadata(int par1, int par2, int par3) { + if (par2 < 0) { + return 0; + } else if (par2 >= 256) { + return 0; + } else { + int var4 = (par1 >> 4) - this.chunkX; + int var5 = (par3 >> 4) - this.chunkZ; + return this.chunkArray[var4][var5].getBlockMetadata(par1 & 15, par2, par3 & 15); + } + } + + /** + * Returns the block's material. + */ + public Material getBlockMaterial(int par1, int par2, int par3) { + int var4 = this.getBlockId(par1, par2, par3); + return var4 == 0 ? Material.air : Block.blocksList[var4].blockMaterial; + } + + /** + * Gets the biome for a given set of x/z coordinates + */ + public BiomeGenBase getBiomeGenForCoords(int par1, int par2) { + return this.worldObj.getBiomeGenForCoords(par1, par2); + } + + /** + * Returns true if the block at the specified coordinates is an opaque cube. + * Args: x, y, z + */ + public boolean isBlockOpaqueCube(int par1, int par2, int par3) { + Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)]; + return var4 == null ? false : var4.isOpaqueCube(); + } + + /** + * Indicate if a material is a normal solid opaque cube. + */ + public boolean isBlockNormalCube(int par1, int par2, int par3) { + Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)]; + return var4 == null ? false : var4.blockMaterial.blocksMovement() && var4.renderAsNormalBlock(); + } + + /** + * Returns true if the block at the given coordinate has a solid (buildable) top + * surface. + */ + public boolean doesBlockHaveSolidTopSurface(int par1, int par2, int par3) { + Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)]; + return this.worldObj.isBlockTopFacingSurfaceSolid(var4, this.getBlockMetadata(par1, par2, par3)); + } + + /** + * Return the Vec3Pool object for this world. + */ + public Vec3Pool getWorldVec3Pool() { + return this.worldObj.getWorldVec3Pool(); + } + + /** + * Returns true if the block at the specified coordinates is empty + */ + public boolean isAirBlock(int par1, int par2, int par3) { + Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)]; + return var4 == null; + } + + /** + * Brightness for SkyBlock.Sky is clear white and (through color computing it is + * assumed) DEPENDENT ON DAYTIME. Brightness for SkyBlock.Block is yellowish and + * independent. + */ + public int getSkyBlockTypeBrightness(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4) { + if (par3 < 0) { + par3 = 0; + } + + if (par3 >= 256) { + par3 = 255; + } + + if (par3 >= 0 && par3 < 256 && par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 <= 30000000) { + if (par1EnumSkyBlock == EnumSkyBlock.Sky && this.worldObj.provider.hasNoSky) { + return 0; + } else { + int var5; + int var6; + + if (Block.useNeighborBrightness[this.getBlockId(par2, par3, par4)]) { + var5 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2, par3 + 1, par4); + var6 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2 + 1, par3, par4); + int var7 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2 - 1, par3, par4); + int var8 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2, par3, par4 + 1); + int var9 = this.getSpecialBlockBrightness(par1EnumSkyBlock, par2, par3, par4 - 1); + + if (var6 > var5) { + var5 = var6; + } + + if (var7 > var5) { + var5 = var7; + } + + if (var8 > var5) { + var5 = var8; + } + + if (var9 > var5) { + var5 = var9; + } + + return var5; + } else { + var5 = (par2 >> 4) - this.chunkX; + var6 = (par4 >> 4) - this.chunkZ; + return this.chunkArray[var5][var6].getSavedLightValue(par1EnumSkyBlock, par2 & 15, par3, par4 & 15); + } + } + } else { + return par1EnumSkyBlock.defaultLightValue; + } + } + + /** + * is only used on stairs and tilled fields + */ + public int getSpecialBlockBrightness(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4) { + if (par3 < 0) { + par3 = 0; + } + + if (par3 >= 256) { + par3 = 255; + } + + if (par3 >= 0 && par3 < 256 && par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 <= 30000000) { + int var5 = (par2 >> 4) - this.chunkX; + int var6 = (par4 >> 4) - this.chunkZ; + return this.chunkArray[var5][var6].getSavedLightValue(par1EnumSkyBlock, par2 & 15, par3, par4 & 15); + } else { + return par1EnumSkyBlock.defaultLightValue; + } + } + + /** + * Returns current world height. + */ + public int getHeight() { + return 256; + } + + /** + * Is this block powering in the specified direction Args: x, y, z, direction + */ + public int isBlockProvidingPowerTo(int par1, int par2, int par3, int par4) { + int var5 = this.getBlockId(par1, par2, par3); + return var5 == 0 ? 0 : Block.blocksList[var5].isProvidingStrongPower(this, par1, par2, par3, par4); + } +} diff --git a/src/main/java/net/minecraft/src/ChunkCoordIntPair.java b/src/main/java/net/minecraft/src/ChunkCoordIntPair.java new file mode 100644 index 0000000..c8c7f8b --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkCoordIntPair.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + +public class ChunkCoordIntPair { + /** The X position of this Chunk Coordinate Pair */ + public final int chunkXPos; + + /** The Z position of this Chunk Coordinate Pair */ + public final int chunkZPos; + + public ChunkCoordIntPair(int par1, int par2) { + this.chunkXPos = par1; + this.chunkZPos = par2; + } + + /** + * converts a chunk coordinate pair to an integer (suitable for hashing) + */ + public static long chunkXZ2Int(int par0, int par1) { + return (long) par0 & 4294967295L | ((long) par1 & 4294967295L) << 32; + } + + public int hashCode() { + long var1 = chunkXZ2Int(this.chunkXPos, this.chunkZPos); + int var3 = (int) var1; + int var4 = (int) (var1 >> 32); + return var3 ^ var4; + } + + public boolean equals(Object par1Obj) { + ChunkCoordIntPair var2 = (ChunkCoordIntPair) par1Obj; + return var2.chunkXPos == this.chunkXPos && var2.chunkZPos == this.chunkZPos; + } + + public int getCenterXPos() { + return (this.chunkXPos << 4) + 8; + } + + public int getCenterZPosition() { + return (this.chunkZPos << 4) + 8; + } + + public ChunkPosition getChunkPosition(int par1) { + return new ChunkPosition(this.getCenterXPos(), par1, this.getCenterZPosition()); + } + + public String toString() { + return "[" + this.chunkXPos + ", " + this.chunkZPos + "]"; + } +} diff --git a/src/main/java/net/minecraft/src/ChunkCoordinates.java b/src/main/java/net/minecraft/src/ChunkCoordinates.java new file mode 100644 index 0000000..afd2d69 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkCoordinates.java @@ -0,0 +1,75 @@ +package net.minecraft.src; + +public class ChunkCoordinates implements Comparable { + public int posX; + + /** the y coordinate */ + public int posY; + + /** the z coordinate */ + public int posZ; + + public ChunkCoordinates() { + } + + public ChunkCoordinates(int par1, int par2, int par3) { + this.posX = par1; + this.posY = par2; + this.posZ = par3; + } + + public ChunkCoordinates(ChunkCoordinates par1ChunkCoordinates) { + this.posX = par1ChunkCoordinates.posX; + this.posY = par1ChunkCoordinates.posY; + this.posZ = par1ChunkCoordinates.posZ; + } + + public boolean equals(Object par1Obj) { + if (!(par1Obj instanceof ChunkCoordinates)) { + return false; + } else { + ChunkCoordinates var2 = (ChunkCoordinates) par1Obj; + return this.posX == var2.posX && this.posY == var2.posY && this.posZ == var2.posZ; + } + } + + public int hashCode() { + return this.posX + this.posZ << 8 + this.posY << 16; + } + + /** + * Compare the coordinate with another coordinate + */ + public int compareChunkCoordinate(ChunkCoordinates par1ChunkCoordinates) { + return this.posY == par1ChunkCoordinates.posY ? (this.posZ == par1ChunkCoordinates.posZ ? this.posX - par1ChunkCoordinates.posX : this.posZ - par1ChunkCoordinates.posZ) : this.posY - par1ChunkCoordinates.posY; + } + + public void set(int par1, int par2, int par3) { + this.posX = par1; + this.posY = par2; + this.posZ = par3; + } + + /** + * Returns the squared distance between this coordinates and the coordinates + * given as argument. + */ + public float getDistanceSquared(int par1, int par2, int par3) { + int var4 = this.posX - par1; + int var5 = this.posY - par2; + int var6 = this.posZ - par3; + return (float) (var4 * var4 + var5 * var5 + var6 * var6); + } + + /** + * Return the squared distance between this coordinates and the ChunkCoordinates + * given as argument. + */ + public float getDistanceSquaredToChunkCoordinates(ChunkCoordinates par1ChunkCoordinates) { + return this.getDistanceSquared(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY, par1ChunkCoordinates.posZ); + } + + public int compareTo(Object par1Obj) { + return this.compareChunkCoordinate((ChunkCoordinates) par1Obj); + } +} diff --git a/src/main/java/net/minecraft/src/ChunkPosition.java b/src/main/java/net/minecraft/src/ChunkPosition.java new file mode 100644 index 0000000..4f6c1d3 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkPosition.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +public class ChunkPosition { + /** The x coordinate of this ChunkPosition */ + public final int x; + + /** The y coordinate of this ChunkPosition */ + public final int y; + + /** The z coordinate of this ChunkPosition */ + public final int z; + + public ChunkPosition(int par1, int par2, int par3) { + this.x = par1; + this.y = par2; + this.z = par3; + } + + public ChunkPosition(Vec3 par1Vec3) { + this(MathHelper.floor_double(par1Vec3.xCoord), MathHelper.floor_double(par1Vec3.yCoord), MathHelper.floor_double(par1Vec3.zCoord)); + } + + public boolean equals(Object par1Obj) { + if (!(par1Obj instanceof ChunkPosition)) { + return false; + } else { + ChunkPosition var2 = (ChunkPosition) par1Obj; + return var2.x == this.x && var2.y == this.y && var2.z == this.z; + } + } + + public int hashCode() { + return this.x * 8976890 + this.y * 981131 + this.z; + } +} diff --git a/src/main/java/net/minecraft/src/ChunkProviderClient.java b/src/main/java/net/minecraft/src/ChunkProviderClient.java new file mode 100644 index 0000000..2ebe01d --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkProviderClient.java @@ -0,0 +1,137 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +public class ChunkProviderClient implements IChunkProvider { + /** + * The completely empty chunk used by ChunkProviderClient when chunkMapping + * doesn't contain the requested coordinates. + */ + private Chunk blankChunk; + + /** + * The mapping between ChunkCoordinates and Chunks that ChunkProviderClient + * maintains. + */ + private LongHashMap chunkMapping = new LongHashMap(); + + /** + * This may have been intended to be an iterable version of all currently loaded + * chunks (MultiplayerChunkCache), with identical contents to chunkMapping's + * values. However it is never actually added to. + */ + private List chunkListing = new ArrayList(); + + /** Reference to the World object. */ + private World worldObj; + + public ChunkProviderClient(World par1World) { + this.blankChunk = new EmptyChunk(par1World, 0, 0); + this.worldObj = par1World; + } + + /** + * Checks to see if a chunk exists at x, y + */ + public boolean chunkExists(int par1, int par2) { + return true; + } + + /** + * Unload chunk from ChunkProviderClient's hashmap. Called in response to a + * Packet50PreChunk with its mode field set to false + */ + public void unloadChunk(int par1, int par2) { + Chunk var3 = this.provideChunk(par1, par2); + + if (!var3.isEmpty()) { + var3.onChunkUnload(); + } + + this.chunkMapping.remove(ChunkCoordIntPair.chunkXZ2Int(par1, par2)); + this.chunkListing.remove(var3); + } + + /** + * loads or generates the chunk at the chunk location specified + */ + public Chunk loadChunk(int par1, int par2) { + Chunk var3 = new Chunk(this.worldObj, par1, par2); + this.chunkMapping.add(ChunkCoordIntPair.chunkXZ2Int(par1, par2), var3); + var3.isChunkLoaded = true; + return var3; + } + + /** + * Will return back a chunk, if it doesn't exist and its not a MP client it will + * generates all the blocks for the specified chunk from the map seed and chunk + * seed + */ + public Chunk provideChunk(int par1, int par2) { + Chunk var3 = (Chunk) this.chunkMapping.getValueByKey(ChunkCoordIntPair.chunkXZ2Int(par1, par2)); + return var3 == null ? this.blankChunk : var3; + } + + /** + * Two modes of operation: if passed true, save all Chunks in one go. If passed + * false, save up to two chunks. Return true if all chunks have been saved. + */ + public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate) { + return true; + } + + public void func_104112_b() { + } + + /** + * Unloads chunks that are marked to be unloaded. This is not guaranteed to + * unload every such chunk. + */ + public boolean unloadQueuedChunks() { + return false; + } + + /** + * Returns if the IChunkProvider supports saving. + */ + public boolean canSave() { + return false; + } + + /** + * Populates chunk with ores etc etc + */ + public void populate(IChunkProvider par1IChunkProvider, int par2, int par3) { + } + + /** + * Converts the instance data to a readable string. + */ + public String makeString() { + return "MultiplayerChunkCache: " + this.chunkMapping.getNumHashElements(); + } + + /** + * Returns a list of creatures of the specified type that can spawn at the given + * location. + */ + public List getPossibleCreatures(EnumCreatureType par1EnumCreatureType, int par2, int par3, int par4) { + return null; + } + + /** + * Returns the location of the closest structure of the specified type. If not + * found returns null. + */ + public ChunkPosition findClosestStructure(World par1World, String par2Str, int par3, int par4, int par5) { + return null; + } + + public int getLoadedChunkCount() { + return this.chunkListing.size(); + } + + public void recreateStructures(int par1, int par2) { + } +} diff --git a/src/main/java/net/minecraft/src/ClippingHelper.java b/src/main/java/net/minecraft/src/ClippingHelper.java new file mode 100644 index 0000000..df45db1 --- /dev/null +++ b/src/main/java/net/minecraft/src/ClippingHelper.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +public class ClippingHelper { + public float[][] frustum = new float[16][16]; + public float[] projectionMatrix = new float[16]; + public float[] modelviewMatrix = new float[16]; + public float[] clippingMatrix = new float[16]; + + /** + * Returns true if the box is inside all 6 clipping planes, otherwise returns + * false. + */ + public boolean isBoxInFrustum(double par1, double par3, double par5, double par7, double par9, double par11) { + for (int var13 = 0; var13 < 6; ++var13) { + if ((double) this.frustum[var13][0] * par1 + (double) this.frustum[var13][1] * par3 + (double) this.frustum[var13][2] * par5 + (double) this.frustum[var13][3] <= 0.0D + && (double) this.frustum[var13][0] * par7 + (double) this.frustum[var13][1] * par3 + (double) this.frustum[var13][2] * par5 + (double) this.frustum[var13][3] <= 0.0D + && (double) this.frustum[var13][0] * par1 + (double) this.frustum[var13][1] * par9 + (double) this.frustum[var13][2] * par5 + (double) this.frustum[var13][3] <= 0.0D + && (double) this.frustum[var13][0] * par7 + (double) this.frustum[var13][1] * par9 + (double) this.frustum[var13][2] * par5 + (double) this.frustum[var13][3] <= 0.0D + && (double) this.frustum[var13][0] * par1 + (double) this.frustum[var13][1] * par3 + (double) this.frustum[var13][2] * par11 + (double) this.frustum[var13][3] <= 0.0D + && (double) this.frustum[var13][0] * par7 + (double) this.frustum[var13][1] * par3 + (double) this.frustum[var13][2] * par11 + (double) this.frustum[var13][3] <= 0.0D + && (double) this.frustum[var13][0] * par1 + (double) this.frustum[var13][1] * par9 + (double) this.frustum[var13][2] * par11 + (double) this.frustum[var13][3] <= 0.0D + && (double) this.frustum[var13][0] * par7 + (double) this.frustum[var13][1] * par9 + (double) this.frustum[var13][2] * par11 + (double) this.frustum[var13][3] <= 0.0D) { + return false; + } + } + + return true; + } +} diff --git a/src/main/java/net/minecraft/src/ClippingHelperImpl.java b/src/main/java/net/minecraft/src/ClippingHelperImpl.java new file mode 100644 index 0000000..0cf7396 --- /dev/null +++ b/src/main/java/net/minecraft/src/ClippingHelperImpl.java @@ -0,0 +1,105 @@ +package net.minecraft.src; + +import java.nio.FloatBuffer; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +public class ClippingHelperImpl extends ClippingHelper { + private static ClippingHelperImpl instance = new ClippingHelperImpl(); + private FloatBuffer projectionMatrixBuffer = GLAllocation.createDirectFloatBuffer(16); + private FloatBuffer modelviewMatrixBuffer = GLAllocation.createDirectFloatBuffer(16); + private FloatBuffer field_78564_h = GLAllocation.createDirectFloatBuffer(16); + + /** + * Initialises the ClippingHelper object then returns an instance of it. + */ + public static ClippingHelper getInstance() { + instance.init(); + return instance; + } + + /** + * Normalize the frustum. + */ + private void normalize(float[][] par1ArrayOfFloat, int par2) { + float var3 = MathHelper.sqrt_float(par1ArrayOfFloat[par2][0] * par1ArrayOfFloat[par2][0] + par1ArrayOfFloat[par2][1] * par1ArrayOfFloat[par2][1] + par1ArrayOfFloat[par2][2] * par1ArrayOfFloat[par2][2]); + par1ArrayOfFloat[par2][0] /= var3; + par1ArrayOfFloat[par2][1] /= var3; + par1ArrayOfFloat[par2][2] /= var3; + par1ArrayOfFloat[par2][3] /= var3; + } + + private void init() { + this.projectionMatrixBuffer.clear(); + this.modelviewMatrixBuffer.clear(); + this.field_78564_h.clear(); + EaglerAdapter.glGetFloat(EaglerAdapter.GL_PROJECTION_MATRIX, this.projectionMatrixBuffer); + EaglerAdapter.glGetFloat(EaglerAdapter.GL_MODELVIEW_MATRIX, this.modelviewMatrixBuffer); + this.projectionMatrixBuffer.flip().limit(16); + this.projectionMatrixBuffer.get(this.projectionMatrix); + this.modelviewMatrixBuffer.flip().limit(16); + this.modelviewMatrixBuffer.get(this.modelviewMatrix); + this.clippingMatrix[0] = this.modelviewMatrix[0] * this.projectionMatrix[0] + this.modelviewMatrix[1] * this.projectionMatrix[4] + this.modelviewMatrix[2] * this.projectionMatrix[8] + + this.modelviewMatrix[3] * this.projectionMatrix[12]; + this.clippingMatrix[1] = this.modelviewMatrix[0] * this.projectionMatrix[1] + this.modelviewMatrix[1] * this.projectionMatrix[5] + this.modelviewMatrix[2] * this.projectionMatrix[9] + + this.modelviewMatrix[3] * this.projectionMatrix[13]; + this.clippingMatrix[2] = this.modelviewMatrix[0] * this.projectionMatrix[2] + this.modelviewMatrix[1] * this.projectionMatrix[6] + this.modelviewMatrix[2] * this.projectionMatrix[10] + + this.modelviewMatrix[3] * this.projectionMatrix[14]; + this.clippingMatrix[3] = this.modelviewMatrix[0] * this.projectionMatrix[3] + this.modelviewMatrix[1] * this.projectionMatrix[7] + this.modelviewMatrix[2] * this.projectionMatrix[11] + + this.modelviewMatrix[3] * this.projectionMatrix[15]; + this.clippingMatrix[4] = this.modelviewMatrix[4] * this.projectionMatrix[0] + this.modelviewMatrix[5] * this.projectionMatrix[4] + this.modelviewMatrix[6] * this.projectionMatrix[8] + + this.modelviewMatrix[7] * this.projectionMatrix[12]; + this.clippingMatrix[5] = this.modelviewMatrix[4] * this.projectionMatrix[1] + this.modelviewMatrix[5] * this.projectionMatrix[5] + this.modelviewMatrix[6] * this.projectionMatrix[9] + + this.modelviewMatrix[7] * this.projectionMatrix[13]; + this.clippingMatrix[6] = this.modelviewMatrix[4] * this.projectionMatrix[2] + this.modelviewMatrix[5] * this.projectionMatrix[6] + this.modelviewMatrix[6] * this.projectionMatrix[10] + + this.modelviewMatrix[7] * this.projectionMatrix[14]; + this.clippingMatrix[7] = this.modelviewMatrix[4] * this.projectionMatrix[3] + this.modelviewMatrix[5] * this.projectionMatrix[7] + this.modelviewMatrix[6] * this.projectionMatrix[11] + + this.modelviewMatrix[7] * this.projectionMatrix[15]; + this.clippingMatrix[8] = this.modelviewMatrix[8] * this.projectionMatrix[0] + this.modelviewMatrix[9] * this.projectionMatrix[4] + this.modelviewMatrix[10] * this.projectionMatrix[8] + + this.modelviewMatrix[11] * this.projectionMatrix[12]; + this.clippingMatrix[9] = this.modelviewMatrix[8] * this.projectionMatrix[1] + this.modelviewMatrix[9] * this.projectionMatrix[5] + this.modelviewMatrix[10] * this.projectionMatrix[9] + + this.modelviewMatrix[11] * this.projectionMatrix[13]; + this.clippingMatrix[10] = this.modelviewMatrix[8] * this.projectionMatrix[2] + this.modelviewMatrix[9] * this.projectionMatrix[6] + this.modelviewMatrix[10] * this.projectionMatrix[10] + + this.modelviewMatrix[11] * this.projectionMatrix[14]; + this.clippingMatrix[11] = this.modelviewMatrix[8] * this.projectionMatrix[3] + this.modelviewMatrix[9] * this.projectionMatrix[7] + this.modelviewMatrix[10] * this.projectionMatrix[11] + + this.modelviewMatrix[11] * this.projectionMatrix[15]; + this.clippingMatrix[12] = this.modelviewMatrix[12] * this.projectionMatrix[0] + this.modelviewMatrix[13] * this.projectionMatrix[4] + this.modelviewMatrix[14] * this.projectionMatrix[8] + + this.modelviewMatrix[15] * this.projectionMatrix[12]; + this.clippingMatrix[13] = this.modelviewMatrix[12] * this.projectionMatrix[1] + this.modelviewMatrix[13] * this.projectionMatrix[5] + this.modelviewMatrix[14] * this.projectionMatrix[9] + + this.modelviewMatrix[15] * this.projectionMatrix[13]; + this.clippingMatrix[14] = this.modelviewMatrix[12] * this.projectionMatrix[2] + this.modelviewMatrix[13] * this.projectionMatrix[6] + this.modelviewMatrix[14] * this.projectionMatrix[10] + + this.modelviewMatrix[15] * this.projectionMatrix[14]; + this.clippingMatrix[15] = this.modelviewMatrix[12] * this.projectionMatrix[3] + this.modelviewMatrix[13] * this.projectionMatrix[7] + this.modelviewMatrix[14] * this.projectionMatrix[11] + + this.modelviewMatrix[15] * this.projectionMatrix[15]; + this.frustum[0][0] = this.clippingMatrix[3] - this.clippingMatrix[0]; + this.frustum[0][1] = this.clippingMatrix[7] - this.clippingMatrix[4]; + this.frustum[0][2] = this.clippingMatrix[11] - this.clippingMatrix[8]; + this.frustum[0][3] = this.clippingMatrix[15] - this.clippingMatrix[12]; + this.normalize(this.frustum, 0); + this.frustum[1][0] = this.clippingMatrix[3] + this.clippingMatrix[0]; + this.frustum[1][1] = this.clippingMatrix[7] + this.clippingMatrix[4]; + this.frustum[1][2] = this.clippingMatrix[11] + this.clippingMatrix[8]; + this.frustum[1][3] = this.clippingMatrix[15] + this.clippingMatrix[12]; + this.normalize(this.frustum, 1); + this.frustum[2][0] = this.clippingMatrix[3] + this.clippingMatrix[1]; + this.frustum[2][1] = this.clippingMatrix[7] + this.clippingMatrix[5]; + this.frustum[2][2] = this.clippingMatrix[11] + this.clippingMatrix[9]; + this.frustum[2][3] = this.clippingMatrix[15] + this.clippingMatrix[13]; + this.normalize(this.frustum, 2); + this.frustum[3][0] = this.clippingMatrix[3] - this.clippingMatrix[1]; + this.frustum[3][1] = this.clippingMatrix[7] - this.clippingMatrix[5]; + this.frustum[3][2] = this.clippingMatrix[11] - this.clippingMatrix[9]; + this.frustum[3][3] = this.clippingMatrix[15] - this.clippingMatrix[13]; + this.normalize(this.frustum, 3); + this.frustum[4][0] = this.clippingMatrix[3] - this.clippingMatrix[2]; + this.frustum[4][1] = this.clippingMatrix[7] - this.clippingMatrix[6]; + this.frustum[4][2] = this.clippingMatrix[11] - this.clippingMatrix[10]; + this.frustum[4][3] = this.clippingMatrix[15] - this.clippingMatrix[14]; + this.normalize(this.frustum, 4); + this.frustum[5][0] = this.clippingMatrix[3] + this.clippingMatrix[2]; + this.frustum[5][1] = this.clippingMatrix[7] + this.clippingMatrix[6]; + this.frustum[5][2] = this.clippingMatrix[11] + this.clippingMatrix[10]; + this.frustum[5][3] = this.clippingMatrix[15] + this.clippingMatrix[14]; + this.normalize(this.frustum, 5); + } +} diff --git a/src/main/java/net/minecraft/src/ColorizerFoliage.java b/src/main/java/net/minecraft/src/ColorizerFoliage.java new file mode 100644 index 0000000..ae45026 --- /dev/null +++ b/src/main/java/net/minecraft/src/ColorizerFoliage.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + +public class ColorizerFoliage { + /** Color buffer for foliage */ + private static int[] foliageBuffer = new int[65536]; + + public static void setFoliageBiomeColorizer(int[] par0ArrayOfInteger) { + foliageBuffer = par0ArrayOfInteger; + } + + /** + * Gets foliage color from temperature and humidity. Args: temperature, humidity + */ + public static int getFoliageColor(double par0, double par2) { + par2 *= par0; + int var4 = (int) ((1.0D - par0) * 255.0D); + int var5 = (int) ((1.0D - par2) * 255.0D); + return foliageBuffer[var5 << 8 | var4]; + } + + /** + * Gets the foliage color for pine type (metadata 1) trees + */ + public static int getFoliageColorPine() { + return 6396257; + } + + /** + * Gets the foliage color for birch type (metadata 2) trees + */ + public static int getFoliageColorBirch() { + return 8431445; + } + + public static int getFoliageColorBasic() { + return 4764952; + } +} diff --git a/src/main/java/net/minecraft/src/ColorizerGrass.java b/src/main/java/net/minecraft/src/ColorizerGrass.java new file mode 100644 index 0000000..100d7aa --- /dev/null +++ b/src/main/java/net/minecraft/src/ColorizerGrass.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +public class ColorizerGrass { + /** Color buffer for grass */ + private static int[] grassBuffer = new int[65536]; + + public static void setGrassBiomeColorizer(int[] par0ArrayOfInteger) { + grassBuffer = par0ArrayOfInteger; + } + + /** + * Gets grass color from temperature and humidity. Args: temperature, humidity + */ + public static int getGrassColor(double par0, double par2) { + par2 *= par0; + int var4 = (int) ((1.0D - par0) * 255.0D); + int var5 = (int) ((1.0D - par2) * 255.0D); + return grassBuffer[var5 << 8 | var4]; + } +} diff --git a/src/main/java/net/minecraft/src/CombatEntry.java b/src/main/java/net/minecraft/src/CombatEntry.java new file mode 100644 index 0000000..f1aa836 --- /dev/null +++ b/src/main/java/net/minecraft/src/CombatEntry.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +public class CombatEntry { + private final DamageSource field_94569_a; + private final int field_94567_b; + private final int field_94568_c; + private final int field_94565_d; + private final String field_94566_e; + private final float field_94564_f; + + public CombatEntry(DamageSource par1DamageSource, int par2, int par3, int par4, String par5Str, float par6) { + this.field_94569_a = par1DamageSource; + this.field_94567_b = par2; + this.field_94568_c = par4; + this.field_94565_d = par3; + this.field_94566_e = par5Str; + this.field_94564_f = par6; + } + + public DamageSource func_94560_a() { + return this.field_94569_a; + } + + public int func_94563_c() { + return this.field_94568_c; + } + + public boolean func_94559_f() { + return this.field_94569_a.getEntity() instanceof EntityLiving; + } + + public String func_94562_g() { + return this.field_94566_e; + } + + public String func_94558_h() { + return this.func_94560_a().getEntity() == null ? null : this.func_94560_a().getEntity().getTranslatedEntityName(); + } + + public float func_94561_i() { + return this.field_94569_a == DamageSource.outOfWorld ? Float.MAX_VALUE : this.field_94564_f; + } +} diff --git a/src/main/java/net/minecraft/src/CombatTracker.java b/src/main/java/net/minecraft/src/CombatTracker.java new file mode 100644 index 0000000..5800509 --- /dev/null +++ b/src/main/java/net/minecraft/src/CombatTracker.java @@ -0,0 +1,169 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class CombatTracker { + private final List field_94556_a = new ArrayList(); + private final EntityLiving field_94554_b; + private int field_94555_c = 0; + private boolean field_94552_d = false; + private boolean field_94553_e = false; + private String field_94551_f; + + public CombatTracker(EntityLiving par1EntityLiving) { + this.field_94554_b = par1EntityLiving; + } + + public void func_94545_a() { + this.func_94542_g(); + + if (this.field_94554_b.isOnLadder()) { + int var1 = this.field_94554_b.worldObj.getBlockId(MathHelper.floor_double(this.field_94554_b.posX), MathHelper.floor_double(this.field_94554_b.boundingBox.minY), MathHelper.floor_double(this.field_94554_b.posZ)); + + if (var1 == Block.ladder.blockID) { + this.field_94551_f = "ladder"; + } else if (var1 == Block.vine.blockID) { + this.field_94551_f = "vines"; + } + } else if (this.field_94554_b.isInWater()) { + this.field_94551_f = "water"; + } + } + + public void func_94547_a(DamageSource par1DamageSource, int par2, int par3) { + this.func_94549_h(); + this.func_94545_a(); + CombatEntry var4 = new CombatEntry(par1DamageSource, this.field_94554_b.ticksExisted, par2, par3, this.field_94551_f, this.field_94554_b.fallDistance); + this.field_94556_a.add(var4); + this.field_94555_c = this.field_94554_b.ticksExisted; + this.field_94553_e = true; + this.field_94552_d |= var4.func_94559_f(); + } + + public String func_94546_b() { + if (this.field_94556_a.size() == 0) { + return this.field_94554_b.getTranslatedEntityName() + " died"; + } else { + CombatEntry var1 = this.func_94544_f(); + CombatEntry var2 = (CombatEntry) this.field_94556_a.get(this.field_94556_a.size() - 1); + String var3 = ""; + String var4 = var2.func_94558_h(); + Entity var5 = var2.func_94560_a().getEntity(); + + if (var1 != null && var2.func_94560_a() == DamageSource.fall) { + String var6 = var1.func_94558_h(); + + if (var1.func_94560_a() != DamageSource.fall && var1.func_94560_a() != DamageSource.outOfWorld) { + if (var6 != null && (var4 == null || !var6.equals(var4))) { + Entity var9 = var1.func_94560_a().getEntity(); + ItemStack var8 = var9 instanceof EntityLiving ? ((EntityLiving) var9).getHeldItem() : null; + + if (var8 != null && var8.hasDisplayName()) { + var3 = StatCollector.translateToLocalFormatted("death.fell.assist.item", new Object[] { this.field_94554_b.getTranslatedEntityName(), var4, var8.getDisplayName() }); + } else { + var3 = StatCollector.translateToLocalFormatted("death.fell.assist", new Object[] { this.field_94554_b.getTranslatedEntityName(), var6 }); + } + } else if (var4 != null) { + ItemStack var7 = var5 instanceof EntityLiving ? ((EntityLiving) var5).getHeldItem() : null; + + if (var7 != null && var7.hasDisplayName()) { + var3 = StatCollector.translateToLocalFormatted("death.fell.finish.item", new Object[] { this.field_94554_b.getTranslatedEntityName(), var4, var7.getDisplayName() }); + } else { + var3 = StatCollector.translateToLocalFormatted("death.fell.finish", new Object[] { this.field_94554_b.getTranslatedEntityName(), var4 }); + } + } else { + var3 = StatCollector.translateToLocalFormatted("death.fell.killer", new Object[] { this.field_94554_b.getTranslatedEntityName() }); + } + } else { + var3 = StatCollector.translateToLocalFormatted("death.fell.accident." + this.func_94548_b(var1), new Object[] { this.field_94554_b.getTranslatedEntityName() }); + } + } else { + var3 = var2.func_94560_a().getDeathMessage(this.field_94554_b); + } + + return var3; + } + } + + public EntityLiving func_94550_c() { + EntityLiving var1 = null; + EntityPlayer var2 = null; + int var3 = 0; + int var4 = 0; + Iterator var5 = this.field_94556_a.iterator(); + + while (var5.hasNext()) { + CombatEntry var6 = (CombatEntry) var5.next(); + + if (var6.func_94560_a().getEntity() instanceof EntityPlayer && (var2 == null || var6.func_94563_c() > var4)) { + var4 = var6.func_94563_c(); + var2 = (EntityPlayer) var6.func_94560_a().getEntity(); + } + + if (var6.func_94560_a().getEntity() instanceof EntityLiving && (var1 == null || var6.func_94563_c() > var3)) { + var3 = var6.func_94563_c(); + var1 = (EntityLiving) var6.func_94560_a().getEntity(); + } + } + + if (var2 != null && var4 >= var3 / 3) { + return var2; + } else { + return var1; + } + } + + private CombatEntry func_94544_f() { + CombatEntry var1 = null; + CombatEntry var2 = null; + byte var3 = 0; + float var4 = 0.0F; + + for (int var5 = 0; var5 < this.field_94556_a.size(); ++var5) { + CombatEntry var6 = (CombatEntry) this.field_94556_a.get(var5); + CombatEntry var7 = var5 > 0 ? (CombatEntry) this.field_94556_a.get(var5 - 1) : null; + + if ((var6.func_94560_a() == DamageSource.fall || var6.func_94560_a() == DamageSource.outOfWorld) && var6.func_94561_i() > 0.0F && (var1 == null || var6.func_94561_i() > var4)) { + if (var5 > 0) { + var1 = var7; + } else { + var1 = var6; + } + + var4 = var6.func_94561_i(); + } + + if (var6.func_94562_g() != null && (var2 == null || var6.func_94563_c() > var3)) { + var2 = var6; + } + } + + if (var4 > 5.0F && var1 != null) { + return var1; + } else if (var3 > 5 && var2 != null) { + return var2; + } else { + return null; + } + } + + private String func_94548_b(CombatEntry par1CombatEntry) { + return par1CombatEntry.func_94562_g() == null ? "generic" : par1CombatEntry.func_94562_g(); + } + + private void func_94542_g() { + this.field_94551_f = null; + } + + private void func_94549_h() { + int var1 = this.field_94552_d ? 300 : 100; + + if (this.field_94553_e && this.field_94554_b.ticksExisted - this.field_94555_c > var1) { + this.field_94556_a.clear(); + this.field_94553_e = false; + this.field_94552_d = false; + } + } +} diff --git a/src/main/java/net/minecraft/src/CompressedStreamTools.java b/src/main/java/net/minecraft/src/CompressedStreamTools.java new file mode 100644 index 0000000..37256c4 --- /dev/null +++ b/src/main/java/net/minecraft/src/CompressedStreamTools.java @@ -0,0 +1,114 @@ +package net.minecraft.src; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import com.jcraft.jzlib.GZIPInputStream; +import com.jcraft.jzlib.GZIPOutputStream; + +public class CompressedStreamTools { + /** + * Load the gzipped compound from the inputstream. + */ + public static NBTTagCompound readCompressed(InputStream par0InputStream) throws IOException { + DataInputStream var1 = new DataInputStream(new BufferedInputStream(new GZIPInputStream(par0InputStream))); + NBTTagCompound var2; + + try { + var2 = read(var1); + } finally { + var1.close(); + } + + return var2; + } + + /** + * Write the compound, gzipped, to the outputstream. + */ + public static void writeCompressed(NBTTagCompound par0NBTTagCompound, OutputStream par1OutputStream) throws IOException { + DataOutputStream var2 = new DataOutputStream(new GZIPOutputStream(par1OutputStream)); + + try { + write(par0NBTTagCompound, var2); + } finally { + var2.close(); + } + } + + public static NBTTagCompound decompress(byte[] par0ArrayOfByte) throws IOException { + DataInputStream var1 = new DataInputStream(new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(par0ArrayOfByte)))); + NBTTagCompound var2; + + try { + var2 = read(var1); + } finally { + var1.close(); + } + + return var2; + } + + public static byte[] compress(NBTTagCompound par0NBTTagCompound) throws IOException { + ByteArrayOutputStream var1 = new ByteArrayOutputStream(); + DataOutputStream var2 = new DataOutputStream(new GZIPOutputStream(var1)); + + try { + write(par0NBTTagCompound, var2); + } finally { + var2.close(); + } + + return var1.toByteArray(); + } + + public static NBTTagCompound readUncompressed(byte[] par0ArrayOfByte) throws IOException { + DataInputStream var1 = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(par0ArrayOfByte))); + NBTTagCompound var2; + + try { + var2 = read(var1); + } finally { + var1.close(); + } + + return var2; + } + + public static byte[] writeUncompressed(NBTTagCompound par0NBTTagCompound) throws IOException { + ByteArrayOutputStream var1 = new ByteArrayOutputStream(); + DataOutputStream var2 = new DataOutputStream(var1); + + try { + write(par0NBTTagCompound, var2); + } finally { + var2.close(); + } + + return var1.toByteArray(); + } + /** + * Reads from a CompressedStream. + */ + public static NBTTagCompound read(DataInput par0DataInput) throws IOException { + NBTBase var1 = NBTBase.readNamedTag(par0DataInput); + + if (var1 instanceof NBTTagCompound) { + return (NBTTagCompound) var1; + } else { + throw new IOException("Root tag must be a named compound tag"); + } + } + + public static void write(NBTTagCompound par0NBTTagCompound, DataOutput par1DataOutput) throws IOException { + NBTBase.writeNamedTag(par0NBTTagCompound, par1DataOutput); + } +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/src/Container.java b/src/main/java/net/minecraft/src/Container.java new file mode 100644 index 0000000..594cbf5 --- /dev/null +++ b/src/main/java/net/minecraft/src/Container.java @@ -0,0 +1,616 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + + + +public abstract class Container { + /** the list of all items(stacks) for the corresponding slot */ + public List inventoryItemStacks = new ArrayList(); + + /** the list of all slots in the inventory */ + public List inventorySlots = new ArrayList(); + public int windowId = 0; + private short transactionID = 0; + private int field_94535_f = -1; + private int field_94536_g = 0; + private final Set field_94537_h = new HashSet(); + + /** + * list of all people that need to be notified when this craftinventory changes + */ + protected List crafters = new ArrayList(); + private Set playerList = new HashSet(); + + /** + * the slot is assumed empty + */ + protected Slot addSlotToContainer(Slot par1Slot) { + par1Slot.slotNumber = this.inventorySlots.size(); + this.inventorySlots.add(par1Slot); + this.inventoryItemStacks.add((Object) null); + return par1Slot; + } + + public void addCraftingToCrafters(ICrafting par1ICrafting) { + if (this.crafters.contains(par1ICrafting)) { + throw new IllegalArgumentException("Listener already listening"); + } else { + this.crafters.add(par1ICrafting); + par1ICrafting.sendContainerAndContentsToPlayer(this, this.getInventory()); + this.detectAndSendChanges(); + } + } + + /** + * Remove this crafting listener from the listener list. + */ + public void removeCraftingFromCrafters(ICrafting par1ICrafting) { + this.crafters.remove(par1ICrafting); + } + + /** + * returns a list if itemStacks, for each slot. + */ + public List getInventory() { + ArrayList var1 = new ArrayList(); + + for (int var2 = 0; var2 < this.inventorySlots.size(); ++var2) { + var1.add(((Slot) this.inventorySlots.get(var2)).getStack()); + } + + return var1; + } + + /** + * Looks for changes made in the container, sends them to every listener. + */ + public void detectAndSendChanges() { + for (int var1 = 0; var1 < this.inventorySlots.size(); ++var1) { + ItemStack var2 = ((Slot) this.inventorySlots.get(var1)).getStack(); + ItemStack var3 = (ItemStack) this.inventoryItemStacks.get(var1); + + if (!ItemStack.areItemStacksEqual(var3, var2)) { + var3 = var2 == null ? null : var2.copy(); + this.inventoryItemStacks.set(var1, var3); + + for (int var4 = 0; var4 < this.crafters.size(); ++var4) { + ((ICrafting) this.crafters.get(var4)).sendSlotContents(this, var1, var3); + } + } + } + } + + /** + * enchants the item on the table using the specified slot; also deducts XP from + * player + */ + public boolean enchantItem(EntityPlayer par1EntityPlayer, int par2) { + return false; + } + + public Slot getSlotFromInventory(IInventory par1IInventory, int par2) { + for (int var3 = 0; var3 < this.inventorySlots.size(); ++var3) { + Slot var4 = (Slot) this.inventorySlots.get(var3); + + if (var4.isSlotInInventory(par1IInventory, par2)) { + return var4; + } + } + + return null; + } + + public Slot getSlot(int par1) { + return (Slot) this.inventorySlots.get(par1); + } + + /** + * Called when a player shift-clicks on a slot. You must override this or you + * will crash when someone does that. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + Slot var3 = (Slot) this.inventorySlots.get(par2); + return var3 != null ? var3.getStack() : null; + } + + public ItemStack slotClick(int par1, int par2, int par3, EntityPlayer par4EntityPlayer) { + ItemStack var5 = null; + InventoryPlayer var6 = par4EntityPlayer.inventory; + int var9; + ItemStack var17; + + if (par3 == 5) { + int var7 = this.field_94536_g; + this.field_94536_g = func_94532_c(par2); + + if ((var7 != 1 || this.field_94536_g != 2) && var7 != this.field_94536_g) { + this.func_94533_d(); + } else if (var6.getItemStack() == null) { + this.func_94533_d(); + } else if (this.field_94536_g == 0) { + this.field_94535_f = func_94529_b(par2); + + if (func_94528_d(this.field_94535_f)) { + this.field_94536_g = 1; + this.field_94537_h.clear(); + } else { + this.func_94533_d(); + } + } else if (this.field_94536_g == 1) { + Slot var8 = (Slot) this.inventorySlots.get(par1); + + if (var8 != null && func_94527_a(var8, var6.getItemStack(), true) && var8.isItemValid(var6.getItemStack()) && var6.getItemStack().stackSize > this.field_94537_h.size() && this.func_94531_b(var8)) { + this.field_94537_h.add(var8); + } + } else if (this.field_94536_g == 2) { + if (!this.field_94537_h.isEmpty()) { + var17 = var6.getItemStack().copy(); + var9 = var6.getItemStack().stackSize; + Iterator var10 = this.field_94537_h.iterator(); + + while (var10.hasNext()) { + Slot var11 = (Slot) var10.next(); + + if (var11 != null && func_94527_a(var11, var6.getItemStack(), true) && var11.isItemValid(var6.getItemStack()) && var6.getItemStack().stackSize >= this.field_94537_h.size() && this.func_94531_b(var11)) { + ItemStack var12 = var17.copy(); + int var13 = var11.getHasStack() ? var11.getStack().stackSize : 0; + func_94525_a(this.field_94537_h, this.field_94535_f, var12, var13); + + if (var12.stackSize > var12.getMaxStackSize()) { + var12.stackSize = var12.getMaxStackSize(); + } + + if (var12.stackSize > var11.getSlotStackLimit()) { + var12.stackSize = var11.getSlotStackLimit(); + } + + var9 -= var12.stackSize - var13; + var11.putStack(var12); + } + } + + var17.stackSize = var9; + + if (var17.stackSize <= 0) { + var17 = null; + } + + var6.setItemStack(var17); + } + + this.func_94533_d(); + } else { + this.func_94533_d(); + } + } else if (this.field_94536_g != 0) { + this.func_94533_d(); + } else { + Slot var16; + int var19; + ItemStack var22; + + if ((par3 == 0 || par3 == 1) && (par2 == 0 || par2 == 1)) { + if (par1 == -999) { + if (var6.getItemStack() != null && par1 == -999) { + if (par2 == 0) { + par4EntityPlayer.dropPlayerItem(var6.getItemStack()); + var6.setItemStack((ItemStack) null); + } + + if (par2 == 1) { + par4EntityPlayer.dropPlayerItem(var6.getItemStack().splitStack(1)); + + if (var6.getItemStack().stackSize == 0) { + var6.setItemStack((ItemStack) null); + } + } + } + } else if (par3 == 1) { + if (par1 < 0) { + return null; + } + + var16 = (Slot) this.inventorySlots.get(par1); + + if (var16 != null && var16.canTakeStack(par4EntityPlayer)) { + var17 = this.transferStackInSlot(par4EntityPlayer, par1); + + if (var17 != null) { + var9 = var17.itemID; + var5 = var17.copy(); + + if (var16 != null && var16.getStack() != null && var16.getStack().itemID == var9) { + this.retrySlotClick(par1, par2, true, par4EntityPlayer); + } + } + } + } else { + if (par1 < 0) { + return null; + } + + var16 = (Slot) this.inventorySlots.get(par1); + + if (var16 != null) { + var17 = var16.getStack(); + ItemStack var20 = var6.getItemStack(); + + if (var17 != null) { + var5 = var17.copy(); + } + + if (var17 == null) { + if (var20 != null && var16.isItemValid(var20)) { + var19 = par2 == 0 ? var20.stackSize : 1; + + if (var19 > var16.getSlotStackLimit()) { + var19 = var16.getSlotStackLimit(); + } + + var16.putStack(var20.splitStack(var19)); + + if (var20.stackSize == 0) { + var6.setItemStack((ItemStack) null); + } + } + } else if (var16.canTakeStack(par4EntityPlayer)) { + if (var20 == null) { + var19 = par2 == 0 ? var17.stackSize : (var17.stackSize + 1) / 2; + var22 = var16.decrStackSize(var19); + var6.setItemStack(var22); + + if (var17.stackSize == 0) { + var16.putStack((ItemStack) null); + } + + var16.onPickupFromSlot(par4EntityPlayer, var6.getItemStack()); + } else if (var16.isItemValid(var20)) { + if (var17.itemID == var20.itemID && var17.getItemDamage() == var20.getItemDamage() && ItemStack.areItemStackTagsEqual(var17, var20)) { + var19 = par2 == 0 ? var20.stackSize : 1; + + if (var19 > var16.getSlotStackLimit() - var17.stackSize) { + var19 = var16.getSlotStackLimit() - var17.stackSize; + } + + if (var19 > var20.getMaxStackSize() - var17.stackSize) { + var19 = var20.getMaxStackSize() - var17.stackSize; + } + + var20.splitStack(var19); + + if (var20.stackSize == 0) { + var6.setItemStack((ItemStack) null); + } + + var17.stackSize += var19; + } else if (var20.stackSize <= var16.getSlotStackLimit()) { + var16.putStack(var20); + var6.setItemStack(var17); + } + } else if (var17.itemID == var20.itemID && var20.getMaxStackSize() > 1 && (!var17.getHasSubtypes() || var17.getItemDamage() == var20.getItemDamage()) && ItemStack.areItemStackTagsEqual(var17, var20)) { + var19 = var17.stackSize; + + if (var19 > 0 && var19 + var20.stackSize <= var20.getMaxStackSize()) { + var20.stackSize += var19; + var17 = var16.decrStackSize(var19); + + if (var17.stackSize == 0) { + var16.putStack((ItemStack) null); + } + + var16.onPickupFromSlot(par4EntityPlayer, var6.getItemStack()); + } + } + } + + var16.onSlotChanged(); + } + } + } else if (par3 == 2 && par2 >= 0 && par2 < 9) { + var16 = (Slot) this.inventorySlots.get(par1); + + if (var16.canTakeStack(par4EntityPlayer)) { + var17 = var6.getStackInSlot(par2); + boolean var18 = var17 == null || var16.inventory == var6 && var16.isItemValid(var17); + var19 = -1; + + if (!var18) { + var19 = var6.getFirstEmptyStack(); + var18 |= var19 > -1; + } + + if (var16.getHasStack() && var18) { + var22 = var16.getStack(); + var6.setInventorySlotContents(par2, var22.copy()); + + if ((var16.inventory != var6 || !var16.isItemValid(var17)) && var17 != null) { + if (var19 > -1) { + var6.addItemStackToInventory(var17); + var16.decrStackSize(var22.stackSize); + var16.putStack((ItemStack) null); + var16.onPickupFromSlot(par4EntityPlayer, var22); + } + } else { + var16.decrStackSize(var22.stackSize); + var16.putStack(var17); + var16.onPickupFromSlot(par4EntityPlayer, var22); + } + } else if (!var16.getHasStack() && var17 != null && var16.isItemValid(var17)) { + var6.setInventorySlotContents(par2, (ItemStack) null); + var16.putStack(var17); + } + } + } else if (par3 == 3 && par4EntityPlayer.capabilities.isCreativeMode && var6.getItemStack() == null && par1 >= 0) { + var16 = (Slot) this.inventorySlots.get(par1); + + if (var16 != null && var16.getHasStack()) { + var17 = var16.getStack().copy(); + var17.stackSize = var17.getMaxStackSize(); + var6.setItemStack(var17); + } + } else if (par3 == 4 && var6.getItemStack() == null && par1 >= 0) { + var16 = (Slot) this.inventorySlots.get(par1); + + if (var16 != null && var16.getHasStack() && var16.canTakeStack(par4EntityPlayer)) { + var17 = var16.decrStackSize(par2 == 0 ? 1 : var16.getStack().stackSize); + var16.onPickupFromSlot(par4EntityPlayer, var17); + par4EntityPlayer.dropPlayerItem(var17); + } + } else if (par3 == 6 && par1 >= 0) { + var16 = (Slot) this.inventorySlots.get(par1); + var17 = var6.getItemStack(); + + if (var17 != null && (var16 == null || !var16.getHasStack() || !var16.canTakeStack(par4EntityPlayer))) { + var9 = par2 == 0 ? 0 : this.inventorySlots.size() - 1; + var19 = par2 == 0 ? 1 : -1; + + for (int var21 = 0; var21 < 2; ++var21) { + for (int var23 = var9; var23 >= 0 && var23 < this.inventorySlots.size() && var17.stackSize < var17.getMaxStackSize(); var23 += var19) { + Slot var24 = (Slot) this.inventorySlots.get(var23); + + if (var24.getHasStack() && func_94527_a(var24, var17, true) && var24.canTakeStack(par4EntityPlayer) && this.func_94530_a(var17, var24) + && (var21 != 0 || var24.getStack().stackSize != var24.getStack().getMaxStackSize())) { + int var14 = Math.min(var17.getMaxStackSize() - var17.stackSize, var24.getStack().stackSize); + ItemStack var15 = var24.decrStackSize(var14); + var17.stackSize += var14; + + if (var15.stackSize <= 0) { + var24.putStack((ItemStack) null); + } + + var24.onPickupFromSlot(par4EntityPlayer, var15); + } + } + } + } + + this.detectAndSendChanges(); + } + } + + return var5; + } + + public boolean func_94530_a(ItemStack par1ItemStack, Slot par2Slot) { + return true; + } + + protected void retrySlotClick(int par1, int par2, boolean par3, EntityPlayer par4EntityPlayer) { + this.slotClick(par1, par2, 1, par4EntityPlayer); + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + InventoryPlayer var2 = par1EntityPlayer.inventory; + + if (var2.getItemStack() != null) { + par1EntityPlayer.dropPlayerItem(var2.getItemStack()); + var2.setItemStack((ItemStack) null); + } + } + + /** + * Callback for when the crafting matrix is changed. + */ + public void onCraftMatrixChanged(IInventory par1IInventory) { + this.detectAndSendChanges(); + } + + /** + * args: slotID, itemStack to put in slot + */ + public void putStackInSlot(int par1, ItemStack par2ItemStack) { + this.getSlot(par1).putStack(par2ItemStack); + } + + /** + * places itemstacks in first x slots, x being aitemstack.lenght + */ + public void putStacksInSlots(ItemStack[] par1ArrayOfItemStack) { + for (int var2 = 0; var2 < par1ArrayOfItemStack.length; ++var2) { + this.getSlot(var2).putStack(par1ArrayOfItemStack[var2]); + } + } + + public void updateProgressBar(int par1, int par2) { + } + + /** + * Gets a unique transaction ID. Parameter is unused. + */ + public short getNextTransactionID(InventoryPlayer par1InventoryPlayer) { + ++this.transactionID; + return this.transactionID; + } + + /** + * NotUsing because adding a player twice is an error + */ + public boolean isPlayerNotUsingContainer(EntityPlayer par1EntityPlayer) { + return !this.playerList.contains(par1EntityPlayer); + } + + /** + * adds or removes the player from the container based on par2 + */ + public void setPlayerIsPresent(EntityPlayer par1EntityPlayer, boolean par2) { + if (par2) { + this.playerList.remove(par1EntityPlayer); + } else { + this.playerList.add(par1EntityPlayer); + } + } + + public abstract boolean canInteractWith(EntityPlayer var1); + + /** + * merges provided ItemStack with the first avaliable one in the + * container/player inventory + */ + protected boolean mergeItemStack(ItemStack par1ItemStack, int par2, int par3, boolean par4) { + boolean var5 = false; + int var6 = par2; + + if (par4) { + var6 = par3 - 1; + } + + Slot var7; + ItemStack var8; + + if (par1ItemStack.isStackable()) { + while (par1ItemStack.stackSize > 0 && (!par4 && var6 < par3 || par4 && var6 >= par2)) { + var7 = (Slot) this.inventorySlots.get(var6); + var8 = var7.getStack(); + + if (var8 != null && var8.itemID == par1ItemStack.itemID && (!par1ItemStack.getHasSubtypes() || par1ItemStack.getItemDamage() == var8.getItemDamage()) && ItemStack.areItemStackTagsEqual(par1ItemStack, var8)) { + int var9 = var8.stackSize + par1ItemStack.stackSize; + + if (var9 <= par1ItemStack.getMaxStackSize()) { + par1ItemStack.stackSize = 0; + var8.stackSize = var9; + var7.onSlotChanged(); + var5 = true; + } else if (var8.stackSize < par1ItemStack.getMaxStackSize()) { + par1ItemStack.stackSize -= par1ItemStack.getMaxStackSize() - var8.stackSize; + var8.stackSize = par1ItemStack.getMaxStackSize(); + var7.onSlotChanged(); + var5 = true; + } + } + + if (par4) { + --var6; + } else { + ++var6; + } + } + } + + if (par1ItemStack.stackSize > 0) { + if (par4) { + var6 = par3 - 1; + } else { + var6 = par2; + } + + while (!par4 && var6 < par3 || par4 && var6 >= par2) { + var7 = (Slot) this.inventorySlots.get(var6); + var8 = var7.getStack(); + + if (var8 == null) { + var7.putStack(par1ItemStack.copy()); + var7.onSlotChanged(); + par1ItemStack.stackSize = 0; + var5 = true; + break; + } + + if (par4) { + --var6; + } else { + ++var6; + } + } + } + + return var5; + } + + public static int func_94529_b(int par0) { + return par0 >> 2 & 3; + } + + public static int func_94532_c(int par0) { + return par0 & 3; + } + + public static int func_94534_d(int par0, int par1) { + return par0 & 3 | (par1 & 3) << 2; + } + + public static boolean func_94528_d(int par0) { + return par0 == 0 || par0 == 1; + } + + protected void func_94533_d() { + this.field_94536_g = 0; + this.field_94537_h.clear(); + } + + public static boolean func_94527_a(Slot par0Slot, ItemStack par1ItemStack, boolean par2) { + boolean var3 = par0Slot == null || !par0Slot.getHasStack(); + + if (par0Slot != null && par0Slot.getHasStack() && par1ItemStack != null && par1ItemStack.isItemEqual(par0Slot.getStack()) && ItemStack.areItemStackTagsEqual(par0Slot.getStack(), par1ItemStack)) { + int var10002 = par2 ? 0 : par1ItemStack.stackSize; + var3 |= par0Slot.getStack().stackSize + var10002 <= par1ItemStack.getMaxStackSize(); + } + + return var3; + } + + public static void func_94525_a(Set par0Set, int par1, ItemStack par2ItemStack, int par3) { + switch (par1) { + case 0: + par2ItemStack.stackSize = MathHelper.floor_float((float) par2ItemStack.stackSize / (float) par0Set.size()); + break; + + case 1: + par2ItemStack.stackSize = 1; + } + + par2ItemStack.stackSize += par3; + } + + public boolean func_94531_b(Slot par1Slot) { + return true; + } + + public static int calcRedstoneFromInventory(IInventory par0IInventory) { + if (par0IInventory == null) { + return 0; + } else { + int var1 = 0; + float var2 = 0.0F; + + for (int var3 = 0; var3 < par0IInventory.getSizeInventory(); ++var3) { + ItemStack var4 = par0IInventory.getStackInSlot(var3); + + if (var4 != null) { + var2 += (float) var4.stackSize / (float) Math.min(par0IInventory.getInventoryStackLimit(), var4.getMaxStackSize()); + ++var1; + } + } + + var2 /= (float) par0IInventory.getSizeInventory(); + return MathHelper.floor_float(var2 * 14.0F) + (var1 > 0 ? 1 : 0); + } + } +} diff --git a/src/main/java/net/minecraft/src/ContainerBeacon.java b/src/main/java/net/minecraft/src/ContainerBeacon.java new file mode 100644 index 0000000..4b20118 --- /dev/null +++ b/src/main/java/net/minecraft/src/ContainerBeacon.java @@ -0,0 +1,124 @@ +package net.minecraft.src; + +public class ContainerBeacon extends Container { + private TileEntityBeacon theBeacon; + + /** + * This beacon's slot where you put in Emerald, Diamond, Gold or Iron Ingot. + */ + private final SlotBeacon beaconSlot; + private int field_82865_g; + private int field_82867_h; + private int field_82868_i; + + public ContainerBeacon(InventoryPlayer par1InventoryPlayer, TileEntityBeacon par2TileEntityBeacon) { + this.theBeacon = par2TileEntityBeacon; + this.addSlotToContainer(this.beaconSlot = new SlotBeacon(this, par2TileEntityBeacon, 0, 136, 110)); + byte var3 = 36; + short var4 = 137; + int var5; + + for (var5 = 0; var5 < 3; ++var5) { + for (int var6 = 0; var6 < 9; ++var6) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var6 + var5 * 9 + 9, var3 + var6 * 18, var4 + var5 * 18)); + } + } + + for (var5 = 0; var5 < 9; ++var5) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var5, var3 + var5 * 18, 58 + var4)); + } + + this.field_82865_g = par2TileEntityBeacon.getLevels(); + this.field_82867_h = par2TileEntityBeacon.getPrimaryEffect(); + this.field_82868_i = par2TileEntityBeacon.getSecondaryEffect(); + } + + public void addCraftingToCrafters(ICrafting par1ICrafting) { + super.addCraftingToCrafters(par1ICrafting); + par1ICrafting.sendProgressBarUpdate(this, 0, this.field_82865_g); + par1ICrafting.sendProgressBarUpdate(this, 1, this.field_82867_h); + par1ICrafting.sendProgressBarUpdate(this, 2, this.field_82868_i); + } + + /** + * Looks for changes made in the container, sends them to every listener. + */ + public void detectAndSendChanges() { + super.detectAndSendChanges(); + } + + public void updateProgressBar(int par1, int par2) { + if (par1 == 0) { + this.theBeacon.setLevels(par2); + } + + if (par1 == 1) { + this.theBeacon.setPrimaryEffect(par2); + } + + if (par1 == 2) { + this.theBeacon.setSecondaryEffect(par2); + } + } + + /** + * Returns the Tile Entity behind this beacon inventory / container + */ + public TileEntityBeacon getBeacon() { + return this.theBeacon; + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.theBeacon.isUseableByPlayer(par1EntityPlayer); + } + + /** + * Called when a player shift-clicks on a slot. You must override this or you + * will crash when someone does that. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 == 0) { + if (!this.mergeItemStack(var5, 1, 37, true)) { + return null; + } + + var4.onSlotChange(var5, var3); + } else if (!this.beaconSlot.getHasStack() && this.beaconSlot.isItemValid(var5) && var5.stackSize == 1) { + if (!this.mergeItemStack(var5, 0, 1, false)) { + return null; + } + } else if (par2 >= 1 && par2 < 28) { + if (!this.mergeItemStack(var5, 28, 37, false)) { + return null; + } + } else if (par2 >= 28 && par2 < 37) { + if (!this.mergeItemStack(var5, 1, 28, false)) { + return null; + } + } else if (!this.mergeItemStack(var5, 1, 37, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } +} diff --git a/src/main/java/net/minecraft/src/ContainerBrewingStand.java b/src/main/java/net/minecraft/src/ContainerBrewingStand.java new file mode 100644 index 0000000..7cfb2f3 --- /dev/null +++ b/src/main/java/net/minecraft/src/ContainerBrewingStand.java @@ -0,0 +1,116 @@ +package net.minecraft.src; + +public class ContainerBrewingStand extends Container { + private TileEntityBrewingStand tileBrewingStand; + + /** Instance of Slot. */ + private final Slot theSlot; + private int brewTime = 0; + + public ContainerBrewingStand(InventoryPlayer par1InventoryPlayer, TileEntityBrewingStand par2TileEntityBrewingStand) { + this.tileBrewingStand = par2TileEntityBrewingStand; + this.addSlotToContainer(new SlotBrewingStandPotion(par1InventoryPlayer.player, par2TileEntityBrewingStand, 0, 56, 46)); + this.addSlotToContainer(new SlotBrewingStandPotion(par1InventoryPlayer.player, par2TileEntityBrewingStand, 1, 79, 53)); + this.addSlotToContainer(new SlotBrewingStandPotion(par1InventoryPlayer.player, par2TileEntityBrewingStand, 2, 102, 46)); + this.theSlot = this.addSlotToContainer(new SlotBrewingStandIngredient(this, par2TileEntityBrewingStand, 3, 79, 17)); + int var3; + + for (var3 = 0; var3 < 3; ++var3) { + for (int var4 = 0; var4 < 9; ++var4) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var4 + var3 * 9 + 9, 8 + var4 * 18, 84 + var3 * 18)); + } + } + + for (var3 = 0; var3 < 9; ++var3) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var3, 8 + var3 * 18, 142)); + } + } + + public void addCraftingToCrafters(ICrafting par1ICrafting) { + super.addCraftingToCrafters(par1ICrafting); + par1ICrafting.sendProgressBarUpdate(this, 0, this.tileBrewingStand.getBrewTime()); + } + + /** + * Looks for changes made in the container, sends them to every listener. + */ + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int var1 = 0; var1 < this.crafters.size(); ++var1) { + ICrafting var2 = (ICrafting) this.crafters.get(var1); + + if (this.brewTime != this.tileBrewingStand.getBrewTime()) { + var2.sendProgressBarUpdate(this, 0, this.tileBrewingStand.getBrewTime()); + } + } + + this.brewTime = this.tileBrewingStand.getBrewTime(); + } + + public void updateProgressBar(int par1, int par2) { + if (par1 == 0) { + this.tileBrewingStand.setBrewTime(par2); + } + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.tileBrewingStand.isUseableByPlayer(par1EntityPlayer); + } + + /** + * Called when a player shift-clicks on a slot. You must override this or you + * will crash when someone does that. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if ((par2 < 0 || par2 > 2) && par2 != 3) { + if (!this.theSlot.getHasStack() && this.theSlot.isItemValid(var5)) { + if (!this.mergeItemStack(var5, 3, 4, false)) { + return null; + } + } else if (SlotBrewingStandPotion.canHoldPotion(var3)) { + if (!this.mergeItemStack(var5, 0, 3, false)) { + return null; + } + } else if (par2 >= 4 && par2 < 31) { + if (!this.mergeItemStack(var5, 31, 40, false)) { + return null; + } + } else if (par2 >= 31 && par2 < 40) { + if (!this.mergeItemStack(var5, 4, 31, false)) { + return null; + } + } else if (!this.mergeItemStack(var5, 4, 40, false)) { + return null; + } + } else { + if (!this.mergeItemStack(var5, 4, 40, true)) { + return null; + } + + var4.onSlotChange(var5, var3); + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } +} diff --git a/src/main/java/net/minecraft/src/ContainerChest.java b/src/main/java/net/minecraft/src/ContainerChest.java new file mode 100644 index 0000000..2b42e79 --- /dev/null +++ b/src/main/java/net/minecraft/src/ContainerChest.java @@ -0,0 +1,80 @@ +package net.minecraft.src; + +public class ContainerChest extends Container { + private IInventory lowerChestInventory; + private int numRows; + + public ContainerChest(IInventory par1IInventory, IInventory par2IInventory) { + this.lowerChestInventory = par2IInventory; + this.numRows = par2IInventory.getSizeInventory() / 9; + par2IInventory.openChest(); + int var3 = (this.numRows - 4) * 18; + int var4; + int var5; + + for (var4 = 0; var4 < this.numRows; ++var4) { + for (var5 = 0; var5 < 9; ++var5) { + this.addSlotToContainer(new Slot(par2IInventory, var5 + var4 * 9, 8 + var5 * 18, 18 + var4 * 18)); + } + } + + for (var4 = 0; var4 < 3; ++var4) { + for (var5 = 0; var5 < 9; ++var5) { + this.addSlotToContainer(new Slot(par1IInventory, var5 + var4 * 9 + 9, 8 + var5 * 18, 103 + var4 * 18 + var3)); + } + } + + for (var4 = 0; var4 < 9; ++var4) { + this.addSlotToContainer(new Slot(par1IInventory, var4, 8 + var4 * 18, 161 + var3)); + } + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.lowerChestInventory.isUseableByPlayer(par1EntityPlayer); + } + + /** + * Called when a player shift-clicks on a slot. You must override this or you + * will crash when someone does that. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 < this.numRows * 9) { + if (!this.mergeItemStack(var5, this.numRows * 9, this.inventorySlots.size(), true)) { + return null; + } + } else if (!this.mergeItemStack(var5, 0, this.numRows * 9, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + } + + return var3; + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + super.onCraftGuiClosed(par1EntityPlayer); + this.lowerChestInventory.closeChest(); + } + + /** + * Return this chest container's lower chest inventory. + */ + public IInventory getLowerChestInventory() { + return this.lowerChestInventory; + } +} diff --git a/src/main/java/net/minecraft/src/ContainerCreative.java b/src/main/java/net/minecraft/src/ContainerCreative.java new file mode 100644 index 0000000..f778845 --- /dev/null +++ b/src/main/java/net/minecraft/src/ContainerCreative.java @@ -0,0 +1,88 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +class ContainerCreative extends Container { + /** the list of items in this container */ + public List itemList = new ArrayList(); + + public ContainerCreative(EntityPlayer par1EntityPlayer) { + InventoryPlayer var2 = par1EntityPlayer.inventory; + int var3; + + for (var3 = 0; var3 < 5; ++var3) { + for (int var4 = 0; var4 < 9; ++var4) { + this.addSlotToContainer(new Slot(GuiContainerCreative.getInventory(), var3 * 9 + var4, 9 + var4 * 18, 18 + var3 * 18)); + } + } + + for (var3 = 0; var3 < 9; ++var3) { + this.addSlotToContainer(new Slot(var2, var3, 9 + var3 * 18, 112)); + } + + this.scrollTo(0.0F); + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return true; + } + + /** + * Updates the gui slots ItemStack's based on scroll position. + */ + public void scrollTo(float par1) { + int var2 = this.itemList.size() / 9 - 5 + 1; + int var3 = (int) ((double) (par1 * (float) var2) + 0.5D); + + if (var3 < 0) { + var3 = 0; + } + + for (int var4 = 0; var4 < 5; ++var4) { + for (int var5 = 0; var5 < 9; ++var5) { + int var6 = var5 + (var4 + var3) * 9; + + if (var6 >= 0 && var6 < this.itemList.size()) { + GuiContainerCreative.getInventory().setInventorySlotContents(var5 + var4 * 9, (ItemStack) this.itemList.get(var6)); + } else { + GuiContainerCreative.getInventory().setInventorySlotContents(var5 + var4 * 9, (ItemStack) null); + } + } + } + } + + /** + * theCreativeContainer seems to be hard coded to 9x5 items + */ + public boolean hasMoreThan1PageOfItemsInList() { + return this.itemList.size() > 45; + } + + protected void retrySlotClick(int par1, int par2, boolean par3, EntityPlayer par4EntityPlayer) { + } + + /** + * Called when a player shift-clicks on a slot. You must override this or you + * will crash when someone does that. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + if (par2 >= this.inventorySlots.size() - 9 && par2 < this.inventorySlots.size()) { + Slot var3 = (Slot) this.inventorySlots.get(par2); + + if (var3 != null && var3.getHasStack()) { + var3.putStack((ItemStack) null); + } + } + + return null; + } + + public boolean func_94530_a(ItemStack par1ItemStack, Slot par2Slot) { + return par2Slot.yDisplayPosition > 90; + } + + public boolean func_94531_b(Slot par1Slot) { + return par1Slot.inventory instanceof InventoryPlayer || par1Slot.yDisplayPosition > 90 && par1Slot.xDisplayPosition <= 162; + } +} diff --git a/src/main/java/net/minecraft/src/ContainerDispenser.java b/src/main/java/net/minecraft/src/ContainerDispenser.java new file mode 100644 index 0000000..eda30b5 --- /dev/null +++ b/src/main/java/net/minecraft/src/ContainerDispenser.java @@ -0,0 +1,67 @@ +package net.minecraft.src; + +public class ContainerDispenser extends Container { + private TileEntityDispenser tileEntityDispenser; + + public ContainerDispenser(IInventory par1IInventory, TileEntityDispenser par2TileEntityDispenser) { + this.tileEntityDispenser = par2TileEntityDispenser; + int var3; + int var4; + + for (var3 = 0; var3 < 3; ++var3) { + for (var4 = 0; var4 < 3; ++var4) { + this.addSlotToContainer(new Slot(par2TileEntityDispenser, var4 + var3 * 3, 62 + var4 * 18, 17 + var3 * 18)); + } + } + + for (var3 = 0; var3 < 3; ++var3) { + for (var4 = 0; var4 < 9; ++var4) { + this.addSlotToContainer(new Slot(par1IInventory, var4 + var3 * 9 + 9, 8 + var4 * 18, 84 + var3 * 18)); + } + } + + for (var3 = 0; var3 < 9; ++var3) { + this.addSlotToContainer(new Slot(par1IInventory, var3, 8 + var3 * 18, 142)); + } + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.tileEntityDispenser.isUseableByPlayer(par1EntityPlayer); + } + + /** + * Called when a player shift-clicks on a slot. You must override this or you + * will crash when someone does that. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 < 9) { + if (!this.mergeItemStack(var5, 9, 45, true)) { + return null; + } + } else if (!this.mergeItemStack(var5, 0, 9, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } +} diff --git a/src/main/java/net/minecraft/src/ContainerEnchantment.java b/src/main/java/net/minecraft/src/ContainerEnchantment.java new file mode 100644 index 0000000..be71b68 --- /dev/null +++ b/src/main/java/net/minecraft/src/ContainerEnchantment.java @@ -0,0 +1,240 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ContainerEnchantment extends Container { + /** SlotEnchantmentTable object with ItemStack to be enchanted */ + public IInventory tableInventory = new SlotEnchantmentTable(this, "Enchant", true, 1); + + /** current world (for bookshelf counting) */ + private World worldPointer; + private int posX; + private int posY; + private int posZ; + private Random rand = new Random(); + + /** used as seed for EnchantmentNameParts (see GuiEnchantment) */ + public long nameSeed; + + /** 3-member array storing the enchantment levels of each slot */ + public int[] enchantLevels = new int[3]; + + public ContainerEnchantment(InventoryPlayer par1InventoryPlayer, World par2World, int par3, int par4, int par5) { + this.worldPointer = par2World; + this.posX = par3; + this.posY = par4; + this.posZ = par5; + this.addSlotToContainer(new SlotEnchantment(this, this.tableInventory, 0, 25, 47)); + int var6; + + for (var6 = 0; var6 < 3; ++var6) { + for (int var7 = 0; var7 < 9; ++var7) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var7 + var6 * 9 + 9, 8 + var7 * 18, 84 + var6 * 18)); + } + } + + for (var6 = 0; var6 < 9; ++var6) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var6, 8 + var6 * 18, 142)); + } + } + + public void addCraftingToCrafters(ICrafting par1ICrafting) { + super.addCraftingToCrafters(par1ICrafting); + par1ICrafting.sendProgressBarUpdate(this, 0, this.enchantLevels[0]); + par1ICrafting.sendProgressBarUpdate(this, 1, this.enchantLevels[1]); + par1ICrafting.sendProgressBarUpdate(this, 2, this.enchantLevels[2]); + } + + /** + * Looks for changes made in the container, sends them to every listener. + */ + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int var1 = 0; var1 < this.crafters.size(); ++var1) { + ICrafting var2 = (ICrafting) this.crafters.get(var1); + var2.sendProgressBarUpdate(this, 0, this.enchantLevels[0]); + var2.sendProgressBarUpdate(this, 1, this.enchantLevels[1]); + var2.sendProgressBarUpdate(this, 2, this.enchantLevels[2]); + } + } + + public void updateProgressBar(int par1, int par2) { + if (par1 >= 0 && par1 <= 2) { + this.enchantLevels[par1] = par2; + } else { + super.updateProgressBar(par1, par2); + } + } + + /** + * Callback for when the crafting matrix is changed. + */ + public void onCraftMatrixChanged(IInventory par1IInventory) { + if (par1IInventory == this.tableInventory) { + ItemStack var2 = par1IInventory.getStackInSlot(0); + int var3; + + if (var2 != null && var2.isItemEnchantable()) { + this.nameSeed = this.rand.nextLong(); + + if (!this.worldPointer.isRemote) { + var3 = 0; + int var4; + + for (var4 = -1; var4 <= 1; ++var4) { + for (int var5 = -1; var5 <= 1; ++var5) { + if ((var4 != 0 || var5 != 0) && this.worldPointer.isAirBlock(this.posX + var5, this.posY, this.posZ + var4) && this.worldPointer.isAirBlock(this.posX + var5, this.posY + 1, this.posZ + var4)) { + if (this.worldPointer.getBlockId(this.posX + var5 * 2, this.posY, this.posZ + var4 * 2) == Block.bookShelf.blockID) { + ++var3; + } + + if (this.worldPointer.getBlockId(this.posX + var5 * 2, this.posY + 1, this.posZ + var4 * 2) == Block.bookShelf.blockID) { + ++var3; + } + + if (var5 != 0 && var4 != 0) { + if (this.worldPointer.getBlockId(this.posX + var5 * 2, this.posY, this.posZ + var4) == Block.bookShelf.blockID) { + ++var3; + } + + if (this.worldPointer.getBlockId(this.posX + var5 * 2, this.posY + 1, this.posZ + var4) == Block.bookShelf.blockID) { + ++var3; + } + + if (this.worldPointer.getBlockId(this.posX + var5, this.posY, this.posZ + var4 * 2) == Block.bookShelf.blockID) { + ++var3; + } + + if (this.worldPointer.getBlockId(this.posX + var5, this.posY + 1, this.posZ + var4 * 2) == Block.bookShelf.blockID) { + ++var3; + } + } + } + } + } + + for (var4 = 0; var4 < 3; ++var4) { + this.enchantLevels[var4] = EnchantmentHelper.calcItemStackEnchantability(this.rand, var4, var3, var2); + } + + this.detectAndSendChanges(); + } + } else { + for (var3 = 0; var3 < 3; ++var3) { + this.enchantLevels[var3] = 0; + } + } + } + } + + /** + * enchants the item on the table using the specified slot; also deducts XP from + * player + */ + public boolean enchantItem(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = this.tableInventory.getStackInSlot(0); + + if (this.enchantLevels[par2] > 0 && var3 != null && (par1EntityPlayer.experienceLevel >= this.enchantLevels[par2] || par1EntityPlayer.capabilities.isCreativeMode)) { + if (!this.worldPointer.isRemote) { + List var4 = EnchantmentHelper.buildEnchantmentList(this.rand, var3, this.enchantLevels[par2]); + boolean var5 = var3.itemID == Item.book.itemID; + + if (var4 != null) { + par1EntityPlayer.addExperienceLevel(-this.enchantLevels[par2]); + + if (var5) { + var3.itemID = Item.enchantedBook.itemID; + } + + int var6 = var5 ? this.rand.nextInt(var4.size()) : -1; + + for (int var7 = 0; var7 < var4.size(); ++var7) { + EnchantmentData var8 = (EnchantmentData) var4.get(var7); + + if (!var5 || var7 == var6) { + if (var5) { + Item.enchantedBook.func_92115_a(var3, var8); + } else { + var3.addEnchantment(var8.enchantmentobj, var8.enchantmentLevel); + } + } + } + + this.onCraftMatrixChanged(this.tableInventory); + } + } + + return true; + } else { + return false; + } + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + super.onCraftGuiClosed(par1EntityPlayer); + + if (!this.worldPointer.isRemote) { + ItemStack var2 = this.tableInventory.getStackInSlotOnClosing(0); + + if (var2 != null) { + par1EntityPlayer.dropPlayerItem(var2); + } + } + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.worldPointer.getBlockId(this.posX, this.posY, this.posZ) != Block.enchantmentTable.blockID ? false + : par1EntityPlayer.getDistanceSq((double) this.posX + 0.5D, (double) this.posY + 0.5D, (double) this.posZ + 0.5D) <= 64.0D; + } + + /** + * Called when a player shift-clicks on a slot. You must override this or you + * will crash when someone does that. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 == 0) { + if (!this.mergeItemStack(var5, 1, 37, true)) { + return null; + } + } else { + if (((Slot) this.inventorySlots.get(0)).getHasStack() || !((Slot) this.inventorySlots.get(0)).isItemValid(var5)) { + return null; + } + + if (var5.hasTagCompound() && var5.stackSize == 1) { + ((Slot) this.inventorySlots.get(0)).putStack(var5.copy()); + var5.stackSize = 0; + } else if (var5.stackSize >= 1) { + ((Slot) this.inventorySlots.get(0)).putStack(new ItemStack(var5.itemID, 1, var5.getItemDamage())); + --var5.stackSize; + } + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } +} diff --git a/src/main/java/net/minecraft/src/ContainerFurnace.java b/src/main/java/net/minecraft/src/ContainerFurnace.java new file mode 100644 index 0000000..a8195c9 --- /dev/null +++ b/src/main/java/net/minecraft/src/ContainerFurnace.java @@ -0,0 +1,132 @@ +package net.minecraft.src; + +public class ContainerFurnace extends Container { + private TileEntityFurnace furnace; + private int lastCookTime = 0; + private int lastBurnTime = 0; + private int lastItemBurnTime = 0; + + public ContainerFurnace(InventoryPlayer par1InventoryPlayer, TileEntityFurnace par2TileEntityFurnace) { + this.furnace = par2TileEntityFurnace; + this.addSlotToContainer(new Slot(par2TileEntityFurnace, 0, 56, 17)); + this.addSlotToContainer(new Slot(par2TileEntityFurnace, 1, 56, 53)); + this.addSlotToContainer(new SlotFurnace(par1InventoryPlayer.player, par2TileEntityFurnace, 2, 116, 35)); + int var3; + + for (var3 = 0; var3 < 3; ++var3) { + for (int var4 = 0; var4 < 9; ++var4) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var4 + var3 * 9 + 9, 8 + var4 * 18, 84 + var3 * 18)); + } + } + + for (var3 = 0; var3 < 9; ++var3) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var3, 8 + var3 * 18, 142)); + } + } + + public void addCraftingToCrafters(ICrafting par1ICrafting) { + super.addCraftingToCrafters(par1ICrafting); + par1ICrafting.sendProgressBarUpdate(this, 0, this.furnace.furnaceCookTime); + par1ICrafting.sendProgressBarUpdate(this, 1, this.furnace.furnaceBurnTime); + par1ICrafting.sendProgressBarUpdate(this, 2, this.furnace.currentItemBurnTime); + } + + /** + * Looks for changes made in the container, sends them to every listener. + */ + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int var1 = 0; var1 < this.crafters.size(); ++var1) { + ICrafting var2 = (ICrafting) this.crafters.get(var1); + + if (this.lastCookTime != this.furnace.furnaceCookTime) { + var2.sendProgressBarUpdate(this, 0, this.furnace.furnaceCookTime); + } + + if (this.lastBurnTime != this.furnace.furnaceBurnTime) { + var2.sendProgressBarUpdate(this, 1, this.furnace.furnaceBurnTime); + } + + if (this.lastItemBurnTime != this.furnace.currentItemBurnTime) { + var2.sendProgressBarUpdate(this, 2, this.furnace.currentItemBurnTime); + } + } + + this.lastCookTime = this.furnace.furnaceCookTime; + this.lastBurnTime = this.furnace.furnaceBurnTime; + this.lastItemBurnTime = this.furnace.currentItemBurnTime; + } + + public void updateProgressBar(int par1, int par2) { + if (par1 == 0) { + this.furnace.furnaceCookTime = par2; + } + + if (par1 == 1) { + this.furnace.furnaceBurnTime = par2; + } + + if (par1 == 2) { + this.furnace.currentItemBurnTime = par2; + } + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.furnace.isUseableByPlayer(par1EntityPlayer); + } + + /** + * Called when a player shift-clicks on a slot. You must override this or you + * will crash when someone does that. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 == 2) { + if (!this.mergeItemStack(var5, 3, 39, true)) { + return null; + } + + var4.onSlotChange(var5, var3); + } else if (par2 != 1 && par2 != 0) { + if (FurnaceRecipes.smelting().getSmeltingResult(var5.getItem().itemID) != null) { + if (!this.mergeItemStack(var5, 0, 1, false)) { + return null; + } + } else if (TileEntityFurnace.isItemFuel(var5)) { + if (!this.mergeItemStack(var5, 1, 2, false)) { + return null; + } + } else if (par2 >= 3 && par2 < 30) { + if (!this.mergeItemStack(var5, 30, 39, false)) { + return null; + } + } else if (par2 >= 30 && par2 < 39 && !this.mergeItemStack(var5, 3, 30, false)) { + return null; + } + } else if (!this.mergeItemStack(var5, 3, 39, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } +} diff --git a/src/main/java/net/minecraft/src/ContainerHopper.java b/src/main/java/net/minecraft/src/ContainerHopper.java new file mode 100644 index 0000000..edad8e1 --- /dev/null +++ b/src/main/java/net/minecraft/src/ContainerHopper.java @@ -0,0 +1,68 @@ +package net.minecraft.src; + +public class ContainerHopper extends Container { + private final IInventory field_94538_a; + + public ContainerHopper(InventoryPlayer par1InventoryPlayer, IInventory par2IInventory) { + this.field_94538_a = par2IInventory; + par2IInventory.openChest(); + byte var3 = 51; + int var4; + + for (var4 = 0; var4 < par2IInventory.getSizeInventory(); ++var4) { + this.addSlotToContainer(new Slot(par2IInventory, var4, 44 + var4 * 18, 20)); + } + + for (var4 = 0; var4 < 3; ++var4) { + for (int var5 = 0; var5 < 9; ++var5) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var5 + var4 * 9 + 9, 8 + var5 * 18, var4 * 18 + var3)); + } + } + + for (var4 = 0; var4 < 9; ++var4) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var4, 8 + var4 * 18, 58 + var3)); + } + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.field_94538_a.isUseableByPlayer(par1EntityPlayer); + } + + /** + * Called when a player shift-clicks on a slot. You must override this or you + * will crash when someone does that. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 < this.field_94538_a.getSizeInventory()) { + if (!this.mergeItemStack(var5, this.field_94538_a.getSizeInventory(), this.inventorySlots.size(), true)) { + return null; + } + } else if (!this.mergeItemStack(var5, 0, this.field_94538_a.getSizeInventory(), false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + } + + return var3; + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + super.onCraftGuiClosed(par1EntityPlayer); + this.field_94538_a.closeChest(); + } +} diff --git a/src/main/java/net/minecraft/src/ContainerMerchant.java b/src/main/java/net/minecraft/src/ContainerMerchant.java new file mode 100644 index 0000000..c7aab62 --- /dev/null +++ b/src/main/java/net/minecraft/src/ContainerMerchant.java @@ -0,0 +1,133 @@ +package net.minecraft.src; + +public class ContainerMerchant extends Container { + /** Instance of Merchant. */ + private IMerchant theMerchant; + private InventoryMerchant merchantInventory; + + /** Instance of World. */ + private final World theWorld; + + public ContainerMerchant(InventoryPlayer par1InventoryPlayer, IMerchant par2IMerchant, World par3World) { + this.theMerchant = par2IMerchant; + this.theWorld = par3World; + this.merchantInventory = new InventoryMerchant(par1InventoryPlayer.player, par2IMerchant); + this.addSlotToContainer(new Slot(this.merchantInventory, 0, 36, 53)); + this.addSlotToContainer(new Slot(this.merchantInventory, 1, 62, 53)); + this.addSlotToContainer(new SlotMerchantResult(par1InventoryPlayer.player, par2IMerchant, this.merchantInventory, 2, 120, 53)); + int var4; + + for (var4 = 0; var4 < 3; ++var4) { + for (int var5 = 0; var5 < 9; ++var5) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var5 + var4 * 9 + 9, 8 + var5 * 18, 84 + var4 * 18)); + } + } + + for (var4 = 0; var4 < 9; ++var4) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var4, 8 + var4 * 18, 142)); + } + } + + public InventoryMerchant getMerchantInventory() { + return this.merchantInventory; + } + + public void addCraftingToCrafters(ICrafting par1ICrafting) { + super.addCraftingToCrafters(par1ICrafting); + } + + /** + * Looks for changes made in the container, sends them to every listener. + */ + public void detectAndSendChanges() { + super.detectAndSendChanges(); + } + + /** + * Callback for when the crafting matrix is changed. + */ + public void onCraftMatrixChanged(IInventory par1IInventory) { + this.merchantInventory.resetRecipeAndSlots(); + super.onCraftMatrixChanged(par1IInventory); + } + + public void setCurrentRecipeIndex(int par1) { + this.merchantInventory.setCurrentRecipeIndex(par1); + } + + public void updateProgressBar(int par1, int par2) { + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.theMerchant.getCustomer() == par1EntityPlayer; + } + + /** + * Called when a player shift-clicks on a slot. You must override this or you + * will crash when someone does that. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 == 2) { + if (!this.mergeItemStack(var5, 3, 39, true)) { + return null; + } + + var4.onSlotChange(var5, var3); + } else if (par2 != 0 && par2 != 1) { + if (par2 >= 3 && par2 < 30) { + if (!this.mergeItemStack(var5, 30, 39, false)) { + return null; + } + } else if (par2 >= 30 && par2 < 39 && !this.mergeItemStack(var5, 3, 30, false)) { + return null; + } + } else if (!this.mergeItemStack(var5, 3, 39, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + super.onCraftGuiClosed(par1EntityPlayer); + this.theMerchant.setCustomer((EntityPlayer) null); + super.onCraftGuiClosed(par1EntityPlayer); + + if (!this.theWorld.isRemote) { + ItemStack var2 = this.merchantInventory.getStackInSlotOnClosing(0); + + if (var2 != null) { + par1EntityPlayer.dropPlayerItem(var2); + } + + var2 = this.merchantInventory.getStackInSlotOnClosing(1); + + if (var2 != null) { + par1EntityPlayer.dropPlayerItem(var2); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/ContainerPlayer.java b/src/main/java/net/minecraft/src/ContainerPlayer.java new file mode 100644 index 0000000..58f98cd --- /dev/null +++ b/src/main/java/net/minecraft/src/ContainerPlayer.java @@ -0,0 +1,133 @@ +package net.minecraft.src; + +public class ContainerPlayer extends Container { + /** The crafting matrix inventory. */ + public InventoryCrafting craftMatrix = new InventoryCrafting(this, 2, 2); + public IInventory craftResult = new InventoryCraftResult(); + + /** Determines if inventory manipulation should be handled. */ + public boolean isLocalWorld = false; + private final EntityPlayer thePlayer; + + public ContainerPlayer(InventoryPlayer par1InventoryPlayer, boolean par2, EntityPlayer par3EntityPlayer) { + this.isLocalWorld = par2; + this.thePlayer = par3EntityPlayer; + this.addSlotToContainer(new SlotCrafting(par1InventoryPlayer.player, this.craftMatrix, this.craftResult, 0, 144, 36)); + int var4; + int var5; + + for (var4 = 0; var4 < 2; ++var4) { + for (var5 = 0; var5 < 2; ++var5) { + this.addSlotToContainer(new Slot(this.craftMatrix, var5 + var4 * 2, 88 + var5 * 18, 26 + var4 * 18)); + } + } + + for (var4 = 0; var4 < 4; ++var4) { + this.addSlotToContainer(new SlotArmor(this, par1InventoryPlayer, par1InventoryPlayer.getSizeInventory() - 1 - var4, 8, 8 + var4 * 18, var4)); + } + + for (var4 = 0; var4 < 3; ++var4) { + for (var5 = 0; var5 < 9; ++var5) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var5 + (var4 + 1) * 9, 8 + var5 * 18, 84 + var4 * 18)); + } + } + + for (var4 = 0; var4 < 9; ++var4) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var4, 8 + var4 * 18, 142)); + } + + this.onCraftMatrixChanged(this.craftMatrix); + } + + /** + * Callback for when the crafting matrix is changed. + */ + public void onCraftMatrixChanged(IInventory par1IInventory) { + this.craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.thePlayer.worldObj)); + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + super.onCraftGuiClosed(par1EntityPlayer); + + for (int var2 = 0; var2 < 4; ++var2) { + ItemStack var3 = this.craftMatrix.getStackInSlotOnClosing(var2); + + if (var3 != null) { + par1EntityPlayer.dropPlayerItem(var3); + } + } + + this.craftResult.setInventorySlotContents(0, (ItemStack) null); + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return true; + } + + /** + * Called when a player shift-clicks on a slot. You must override this or you + * will crash when someone does that. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 == 0) { + if (!this.mergeItemStack(var5, 9, 45, true)) { + return null; + } + + var4.onSlotChange(var5, var3); + } else if (par2 >= 1 && par2 < 5) { + if (!this.mergeItemStack(var5, 9, 45, false)) { + return null; + } + } else if (par2 >= 5 && par2 < 9) { + if (!this.mergeItemStack(var5, 9, 45, false)) { + return null; + } + } else if (var3.getItem() instanceof ItemArmor && !((Slot) this.inventorySlots.get(5 + ((ItemArmor) var3.getItem()).armorType)).getHasStack()) { + int var6 = 5 + ((ItemArmor) var3.getItem()).armorType; + + if (!this.mergeItemStack(var5, var6, var6 + 1, false)) { + return null; + } + } else if (par2 >= 9 && par2 < 36) { + if (!this.mergeItemStack(var5, 36, 45, false)) { + return null; + } + } else if (par2 >= 36 && par2 < 45) { + if (!this.mergeItemStack(var5, 9, 36, false)) { + return null; + } + } else if (!this.mergeItemStack(var5, 9, 45, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } + + public boolean func_94530_a(ItemStack par1ItemStack, Slot par2Slot) { + return par2Slot.inventory != this.craftResult && super.func_94530_a(par1ItemStack, par2Slot); + } +} diff --git a/src/main/java/net/minecraft/src/ContainerRepair.java b/src/main/java/net/minecraft/src/ContainerRepair.java new file mode 100644 index 0000000..fcb9b77 --- /dev/null +++ b/src/main/java/net/minecraft/src/ContainerRepair.java @@ -0,0 +1,406 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.Map; + + + +public class ContainerRepair extends Container { + /** Here comes out item you merged and/or renamed. */ + private IInventory outputSlot = new InventoryCraftResult(); + + /** + * The 2slots where you put your items in that you want to merge and/or rename. + */ + private IInventory inputSlots = new InventoryRepair(this, "Repair", true, 2); + private World theWorld; + private int field_82861_i; + private int field_82858_j; + private int field_82859_k; + + /** The maximum cost of repairing/renaming in the anvil. */ + public int maximumCost = 0; + + /** determined by damage of input item and stackSize of repair materials */ + private int stackSizeToBeUsedInRepair = 0; + private String repairedItemName; + + /** The player that has this container open. */ + private final EntityPlayer thePlayer; + + public ContainerRepair(InventoryPlayer par1InventoryPlayer, World par2World, int par3, int par4, int par5, EntityPlayer par6EntityPlayer) { + this.theWorld = par2World; + this.field_82861_i = par3; + this.field_82858_j = par4; + this.field_82859_k = par5; + this.thePlayer = par6EntityPlayer; + this.addSlotToContainer(new Slot(this.inputSlots, 0, 27, 47)); + this.addSlotToContainer(new Slot(this.inputSlots, 1, 76, 47)); + this.addSlotToContainer(new SlotRepair(this, this.outputSlot, 2, 134, 47, par2World, par3, par4, par5)); + int var7; + + for (var7 = 0; var7 < 3; ++var7) { + for (int var8 = 0; var8 < 9; ++var8) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var8 + var7 * 9 + 9, 8 + var8 * 18, 84 + var7 * 18)); + } + } + + for (var7 = 0; var7 < 9; ++var7) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var7, 8 + var7 * 18, 142)); + } + } + + /** + * Callback for when the crafting matrix is changed. + */ + public void onCraftMatrixChanged(IInventory par1IInventory) { + super.onCraftMatrixChanged(par1IInventory); + + if (par1IInventory == this.inputSlots) { + this.updateRepairOutput(); + } + } + + /** + * called when the Anvil Input Slot changes, calculates the new result and puts + * it in the output slot + */ + public void updateRepairOutput() { + ItemStack var1 = this.inputSlots.getStackInSlot(0); + this.maximumCost = 0; + int var2 = 0; + byte var3 = 0; + int var4 = 0; + + if (var1 == null) { + this.outputSlot.setInventorySlotContents(0, (ItemStack) null); + this.maximumCost = 0; + } else { + ItemStack var5 = var1.copy(); + ItemStack var6 = this.inputSlots.getStackInSlot(1); + Map var7 = EnchantmentHelper.getEnchantments(var5); + boolean var8 = false; + int var19 = var3 + var1.getRepairCost() + (var6 == null ? 0 : var6.getRepairCost()); + this.stackSizeToBeUsedInRepair = 0; + int var9; + int var10; + int var11; + int var13; + int var14; + Iterator var21; + Enchantment var22; + + if (var6 != null) { + var8 = var6.itemID == Item.enchantedBook.itemID && Item.enchantedBook.func_92110_g(var6).tagCount() > 0; + + if (var5.isItemStackDamageable() && Item.itemsList[var5.itemID].getIsRepairable(var1, var6)) { + var9 = Math.min(var5.getItemDamageForDisplay(), var5.getMaxDamage() / 4); + + if (var9 <= 0) { + this.outputSlot.setInventorySlotContents(0, (ItemStack) null); + this.maximumCost = 0; + return; + } + + for (var10 = 0; var9 > 0 && var10 < var6.stackSize; ++var10) { + var11 = var5.getItemDamageForDisplay() - var9; + var5.setItemDamage(var11); + var2 += Math.max(1, var9 / 100) + var7.size(); + var9 = Math.min(var5.getItemDamageForDisplay(), var5.getMaxDamage() / 4); + } + + this.stackSizeToBeUsedInRepair = var10; + } else { + if (!var8 && (var5.itemID != var6.itemID || !var5.isItemStackDamageable())) { + this.outputSlot.setInventorySlotContents(0, (ItemStack) null); + this.maximumCost = 0; + return; + } + + if (var5.isItemStackDamageable() && !var8) { + var9 = var1.getMaxDamage() - var1.getItemDamageForDisplay(); + var10 = var6.getMaxDamage() - var6.getItemDamageForDisplay(); + var11 = var10 + var5.getMaxDamage() * 12 / 100; + int var12 = var9 + var11; + var13 = var5.getMaxDamage() - var12; + + if (var13 < 0) { + var13 = 0; + } + + if (var13 < var5.getItemDamage()) { + var5.setItemDamage(var13); + var2 += Math.max(1, var11 / 100); + } + } + + Map var20 = EnchantmentHelper.getEnchantments(var6); + var21 = var20.keySet().iterator(); + + while (var21.hasNext()) { + var11 = ((Integer) var21.next()).intValue(); + var22 = Enchantment.enchantmentsList[var11]; + var13 = var7.containsKey(Integer.valueOf(var11)) ? ((Integer) var7.get(Integer.valueOf(var11))).intValue() : 0; + var14 = ((Integer) var20.get(Integer.valueOf(var11))).intValue(); + int var10000; + + if (var13 == var14) { + ++var14; + var10000 = var14; + } else { + var10000 = Math.max(var14, var13); + } + + var14 = var10000; + int var15 = var14 - var13; + boolean var16 = var22.canApply(var1); + + if (this.thePlayer.capabilities.isCreativeMode || var1.itemID == ItemEnchantedBook.enchantedBook.itemID) { + var16 = true; + } + + Iterator var17 = var7.keySet().iterator(); + + while (var17.hasNext()) { + int var18 = ((Integer) var17.next()).intValue(); + + if (var18 != var11 && !var22.canApplyTogether(Enchantment.enchantmentsList[var18])) { + var16 = false; + var2 += var15; + } + } + + if (var16) { + if (var14 > var22.getMaxLevel()) { + var14 = var22.getMaxLevel(); + } + + var7.put(Integer.valueOf(var11), Integer.valueOf(var14)); + int var23 = 0; + + switch (var22.getWeight()) { + case 1: + var23 = 8; + break; + + case 2: + var23 = 4; + + case 3: + case 4: + case 6: + case 7: + case 8: + case 9: + default: + break; + + case 5: + var23 = 2; + break; + + case 10: + var23 = 1; + } + + if (var8) { + var23 = Math.max(1, var23 / 2); + } + + var2 += var23 * var15; + } + } + } + } + + if (this.repairedItemName != null && this.repairedItemName.length() > 0 && !this.repairedItemName.equalsIgnoreCase(this.thePlayer.getTranslator().translateNamedKey(var1.getItemName())) + && !this.repairedItemName.equals(var1.getDisplayName())) { + var4 = var1.isItemStackDamageable() ? 7 : var1.stackSize * 5; + var2 += var4; + + if (var1.hasDisplayName()) { + var19 += var4 / 2; + } + + var5.setItemName(this.repairedItemName); + } + + var9 = 0; + + for (var21 = var7.keySet().iterator(); var21.hasNext(); var19 += var9 + var13 * var14) { + var11 = ((Integer) var21.next()).intValue(); + var22 = Enchantment.enchantmentsList[var11]; + var13 = ((Integer) var7.get(Integer.valueOf(var11))).intValue(); + var14 = 0; + ++var9; + + switch (var22.getWeight()) { + case 1: + var14 = 8; + break; + + case 2: + var14 = 4; + + case 3: + case 4: + case 6: + case 7: + case 8: + case 9: + default: + break; + + case 5: + var14 = 2; + break; + + case 10: + var14 = 1; + } + + if (var8) { + var14 = Math.max(1, var14 / 2); + } + } + + if (var8) { + var19 = Math.max(1, var19 / 2); + } + + this.maximumCost = var19 + var2; + + if (var2 <= 0) { + var5 = null; + } + + if (var4 == var2 && var4 > 0 && this.maximumCost >= 40) { + System.out.println("Naming an item only, cost too high; giving discount to cap cost to 39 levels"); + this.maximumCost = 39; + } + + if (this.maximumCost >= 40 && !this.thePlayer.capabilities.isCreativeMode) { + var5 = null; + } + + if (var5 != null) { + var10 = var5.getRepairCost(); + + if (var6 != null && var10 < var6.getRepairCost()) { + var10 = var6.getRepairCost(); + } + + if (var5.hasDisplayName()) { + var10 -= 9; + } + + if (var10 < 0) { + var10 = 0; + } + + var10 += 2; + var5.setRepairCost(var10); + EnchantmentHelper.setEnchantments(var7, var5); + } + + this.outputSlot.setInventorySlotContents(0, var5); + this.detectAndSendChanges(); + } + } + + public void addCraftingToCrafters(ICrafting par1ICrafting) { + super.addCraftingToCrafters(par1ICrafting); + par1ICrafting.sendProgressBarUpdate(this, 0, this.maximumCost); + } + + public void updateProgressBar(int par1, int par2) { + if (par1 == 0) { + this.maximumCost = par2; + } + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + super.onCraftGuiClosed(par1EntityPlayer); + + if (!this.theWorld.isRemote) { + for (int var2 = 0; var2 < this.inputSlots.getSizeInventory(); ++var2) { + ItemStack var3 = this.inputSlots.getStackInSlotOnClosing(var2); + + if (var3 != null) { + par1EntityPlayer.dropPlayerItem(var3); + } + } + } + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.theWorld.getBlockId(this.field_82861_i, this.field_82858_j, this.field_82859_k) != Block.anvil.blockID ? false + : par1EntityPlayer.getDistanceSq((double) this.field_82861_i + 0.5D, (double) this.field_82858_j + 0.5D, (double) this.field_82859_k + 0.5D) <= 64.0D; + } + + /** + * Called when a player shift-clicks on a slot. You must override this or you + * will crash when someone does that. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 == 2) { + if (!this.mergeItemStack(var5, 3, 39, true)) { + return null; + } + + var4.onSlotChange(var5, var3); + } else if (par2 != 0 && par2 != 1) { + if (par2 >= 3 && par2 < 39 && !this.mergeItemStack(var5, 0, 2, false)) { + return null; + } + } else if (!this.mergeItemStack(var5, 3, 39, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } + + /** + * used by the Anvil GUI to update the Item Name being typed by the player + */ + public void updateItemName(String par1Str) { + this.repairedItemName = par1Str; + + if (this.getSlot(2).getHasStack()) { + this.getSlot(2).getStack().setItemName(this.repairedItemName); + } + + this.updateRepairOutput(); + } + + static IInventory getRepairInputInventory(ContainerRepair par0ContainerRepair) { + return par0ContainerRepair.inputSlots; + } + + static int getStackSizeUsedInRepair(ContainerRepair par0ContainerRepair) { + return par0ContainerRepair.stackSizeToBeUsedInRepair; + } +} diff --git a/src/main/java/net/minecraft/src/ContainerSheep.java b/src/main/java/net/minecraft/src/ContainerSheep.java new file mode 100644 index 0000000..f6e079b --- /dev/null +++ b/src/main/java/net/minecraft/src/ContainerSheep.java @@ -0,0 +1,13 @@ +package net.minecraft.src; + +class ContainerSheep extends Container { + final EntitySheep field_90034_a; + + ContainerSheep(EntitySheep par1EntitySheep) { + this.field_90034_a = par1EntitySheep; + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/ContainerWorkbench.java b/src/main/java/net/minecraft/src/ContainerWorkbench.java new file mode 100644 index 0000000..686d3d8 --- /dev/null +++ b/src/main/java/net/minecraft/src/ContainerWorkbench.java @@ -0,0 +1,117 @@ +package net.minecraft.src; + +public class ContainerWorkbench extends Container { + /** The crafting matrix inventory (3x3). */ + public InventoryCrafting craftMatrix = new InventoryCrafting(this, 3, 3); + public IInventory craftResult = new InventoryCraftResult(); + private World worldObj; + private int posX; + private int posY; + private int posZ; + + public ContainerWorkbench(InventoryPlayer par1InventoryPlayer, World par2World, int par3, int par4, int par5) { + this.worldObj = par2World; + this.posX = par3; + this.posY = par4; + this.posZ = par5; + this.addSlotToContainer(new SlotCrafting(par1InventoryPlayer.player, this.craftMatrix, this.craftResult, 0, 124, 35)); + int var6; + int var7; + + for (var6 = 0; var6 < 3; ++var6) { + for (var7 = 0; var7 < 3; ++var7) { + this.addSlotToContainer(new Slot(this.craftMatrix, var7 + var6 * 3, 30 + var7 * 18, 17 + var6 * 18)); + } + } + + for (var6 = 0; var6 < 3; ++var6) { + for (var7 = 0; var7 < 9; ++var7) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var7 + var6 * 9 + 9, 8 + var7 * 18, 84 + var6 * 18)); + } + } + + for (var6 = 0; var6 < 9; ++var6) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var6, 8 + var6 * 18, 142)); + } + + this.onCraftMatrixChanged(this.craftMatrix); + } + + /** + * Callback for when the crafting matrix is changed. + */ + public void onCraftMatrixChanged(IInventory par1IInventory) { + this.craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.worldObj)); + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + super.onCraftGuiClosed(par1EntityPlayer); + + if (!this.worldObj.isRemote) { + for (int var2 = 0; var2 < 9; ++var2) { + ItemStack var3 = this.craftMatrix.getStackInSlotOnClosing(var2); + + if (var3 != null) { + par1EntityPlayer.dropPlayerItem(var3); + } + } + } + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.worldObj.getBlockId(this.posX, this.posY, this.posZ) != Block.workbench.blockID ? false : par1EntityPlayer.getDistanceSq((double) this.posX + 0.5D, (double) this.posY + 0.5D, (double) this.posZ + 0.5D) <= 64.0D; + } + + /** + * Called when a player shift-clicks on a slot. You must override this or you + * will crash when someone does that. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 == 0) { + if (!this.mergeItemStack(var5, 10, 46, true)) { + return null; + } + + var4.onSlotChange(var5, var3); + } else if (par2 >= 10 && par2 < 37) { + if (!this.mergeItemStack(var5, 37, 46, false)) { + return null; + } + } else if (par2 >= 37 && par2 < 46) { + if (!this.mergeItemStack(var5, 10, 37, false)) { + return null; + } + } else if (!this.mergeItemStack(var5, 10, 46, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } + + public boolean func_94530_a(ItemStack par1ItemStack, Slot par2Slot) { + return par2Slot.inventory != this.craftResult && super.func_94530_a(par1ItemStack, par2Slot); + } +} diff --git a/src/main/java/net/minecraft/src/CraftingManager.java b/src/main/java/net/minecraft/src/CraftingManager.java new file mode 100644 index 0000000..57b44a1 --- /dev/null +++ b/src/main/java/net/minecraft/src/CraftingManager.java @@ -0,0 +1,279 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +public class CraftingManager { + /** The static instance of this class */ + private static final CraftingManager instance = new CraftingManager(); + + /** A list of all the recipes added */ + private List recipes = new ArrayList(); + + /** + * Returns the static instance of this class + */ + public static final CraftingManager getInstance() { + return instance; + } + + private CraftingManager() { + (new RecipesTools()).addRecipes(this); + (new RecipesWeapons()).addRecipes(this); + (new RecipesIngots()).addRecipes(this); + (new RecipesFood()).addRecipes(this); + (new RecipesCrafting()).addRecipes(this); + (new RecipesArmor()).addRecipes(this); + (new RecipesDyes()).addRecipes(this); + this.recipes.add(new RecipesArmorDyes()); + this.recipes.add(new RecipesMapCloning()); + this.recipes.add(new RecipesMapExtending()); + this.recipes.add(new RecipeFireworks()); + this.addRecipe(new ItemStack(Item.paper, 3), new Object[] { "###", '#', Item.reed }); + this.addShapelessRecipe(new ItemStack(Item.book, 1), new Object[] { Item.paper, Item.paper, Item.paper, Item.leather }); + this.addShapelessRecipe(new ItemStack(Item.writableBook, 1), new Object[] { Item.book, new ItemStack(Item.dyePowder, 1, 0), Item.feather }); + this.addRecipe(new ItemStack(Block.fence, 2), new Object[] { "###", "###", '#', Item.stick }); + this.addRecipe(new ItemStack(Block.cobblestoneWall, 6, 0), new Object[] { "###", "###", '#', Block.cobblestone }); + this.addRecipe(new ItemStack(Block.cobblestoneWall, 6, 1), new Object[] { "###", "###", '#', Block.cobblestoneMossy }); + this.addRecipe(new ItemStack(Block.netherFence, 6), new Object[] { "###", "###", '#', Block.netherBrick }); + this.addRecipe(new ItemStack(Block.fenceGate, 1), new Object[] { "#W#", "#W#", '#', Item.stick, 'W', Block.planks }); + this.addRecipe(new ItemStack(Block.jukebox, 1), new Object[] { "###", "#X#", "###", '#', Block.planks, 'X', Item.diamond }); + this.addRecipe(new ItemStack(Block.music, 1), new Object[] { "###", "#X#", "###", '#', Block.planks, 'X', Item.redstone }); + this.addRecipe(new ItemStack(Block.bookShelf, 1), new Object[] { "###", "XXX", "###", '#', Block.planks, 'X', Item.book }); + this.addRecipe(new ItemStack(Block.blockSnow, 1), new Object[] { "##", "##", '#', Item.snowball }); + this.addRecipe(new ItemStack(Block.snow, 6), new Object[] { "###", '#', Block.blockSnow }); + this.addRecipe(new ItemStack(Block.blockClay, 1), new Object[] { "##", "##", '#', Item.clay }); + this.addRecipe(new ItemStack(Block.brick, 1), new Object[] { "##", "##", '#', Item.brick }); + this.addRecipe(new ItemStack(Block.glowStone, 1), new Object[] { "##", "##", '#', Item.lightStoneDust }); + this.addRecipe(new ItemStack(Block.blockNetherQuartz, 1), new Object[] { "##", "##", '#', Item.netherQuartz }); + this.addRecipe(new ItemStack(Block.cloth, 1), new Object[] { "##", "##", '#', Item.silk }); + this.addRecipe(new ItemStack(Block.tnt, 1), new Object[] { "X#X", "#X#", "X#X", 'X', Item.gunpowder, '#', Block.sand }); + this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 3), new Object[] { "###", '#', Block.cobblestone }); + this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 0), new Object[] { "###", '#', Block.stone }); + this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 1), new Object[] { "###", '#', Block.sandStone }); + this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 4), new Object[] { "###", '#', Block.brick }); + this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 5), new Object[] { "###", '#', Block.stoneBrick }); + this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 6), new Object[] { "###", '#', Block.netherBrick }); + this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 7), new Object[] { "###", '#', Block.blockNetherQuartz }); + this.addRecipe(new ItemStack(Block.woodSingleSlab, 6, 0), new Object[] { "###", '#', new ItemStack(Block.planks, 1, 0) }); + this.addRecipe(new ItemStack(Block.woodSingleSlab, 6, 2), new Object[] { "###", '#', new ItemStack(Block.planks, 1, 2) }); + this.addRecipe(new ItemStack(Block.woodSingleSlab, 6, 1), new Object[] { "###", '#', new ItemStack(Block.planks, 1, 1) }); + this.addRecipe(new ItemStack(Block.woodSingleSlab, 6, 3), new Object[] { "###", '#', new ItemStack(Block.planks, 1, 3) }); + this.addRecipe(new ItemStack(Block.ladder, 3), new Object[] { "# #", "###", "# #", '#', Item.stick }); + this.addRecipe(new ItemStack(Item.doorWood, 1), new Object[] { "##", "##", "##", '#', Block.planks }); + this.addRecipe(new ItemStack(Block.trapdoor, 2), new Object[] { "###", "###", '#', Block.planks }); + this.addRecipe(new ItemStack(Item.doorIron, 1), new Object[] { "##", "##", "##", '#', Item.ingotIron }); + this.addRecipe(new ItemStack(Item.sign, 3), new Object[] { "###", "###", " X ", '#', Block.planks, 'X', Item.stick }); + this.addRecipe(new ItemStack(Item.cake, 1), new Object[] { "AAA", "BEB", "CCC", 'A', Item.bucketMilk, 'B', Item.sugar, 'C', Item.wheat, 'E', Item.egg }); + this.addRecipe(new ItemStack(Item.sugar, 1), new Object[] { "#", '#', Item.reed }); + this.addRecipe(new ItemStack(Block.planks, 4, 0), new Object[] { "#", '#', new ItemStack(Block.wood, 1, 0) }); + this.addRecipe(new ItemStack(Block.planks, 4, 1), new Object[] { "#", '#', new ItemStack(Block.wood, 1, 1) }); + this.addRecipe(new ItemStack(Block.planks, 4, 2), new Object[] { "#", '#', new ItemStack(Block.wood, 1, 2) }); + this.addRecipe(new ItemStack(Block.planks, 4, 3), new Object[] { "#", '#', new ItemStack(Block.wood, 1, 3) }); + this.addRecipe(new ItemStack(Item.stick, 4), new Object[] { "#", "#", '#', Block.planks }); + this.addRecipe(new ItemStack(Block.torchWood, 4), new Object[] { "X", "#", 'X', Item.coal, '#', Item.stick }); + this.addRecipe(new ItemStack(Block.torchWood, 4), new Object[] { "X", "#", 'X', new ItemStack(Item.coal, 1, 1), '#', Item.stick }); + this.addRecipe(new ItemStack(Item.bowlEmpty, 4), new Object[] { "# #", " # ", '#', Block.planks }); + this.addRecipe(new ItemStack(Item.glassBottle, 3), new Object[] { "# #", " # ", '#', Block.glass }); + this.addRecipe(new ItemStack(Block.rail, 16), new Object[] { "X X", "X#X", "X X", 'X', Item.ingotIron, '#', Item.stick }); + this.addRecipe(new ItemStack(Block.railPowered, 6), new Object[] { "X X", "X#X", "XRX", 'X', Item.ingotGold, 'R', Item.redstone, '#', Item.stick }); + this.addRecipe(new ItemStack(Block.railActivator, 6), new Object[] { "XSX", "X#X", "XSX", 'X', Item.ingotIron, '#', Block.torchRedstoneActive, 'S', Item.stick }); + this.addRecipe(new ItemStack(Block.railDetector, 6), new Object[] { "X X", "X#X", "XRX", 'X', Item.ingotIron, 'R', Item.redstone, '#', Block.pressurePlateStone }); + this.addRecipe(new ItemStack(Item.minecartEmpty, 1), new Object[] { "# #", "###", '#', Item.ingotIron }); + this.addRecipe(new ItemStack(Item.cauldron, 1), new Object[] { "# #", "# #", "###", '#', Item.ingotIron }); + this.addRecipe(new ItemStack(Item.brewingStand, 1), new Object[] { " B ", "###", '#', Block.cobblestone, 'B', Item.blazeRod }); + this.addRecipe(new ItemStack(Block.pumpkinLantern, 1), new Object[] { "A", "B", 'A', Block.pumpkin, 'B', Block.torchWood }); + this.addRecipe(new ItemStack(Item.minecartCrate, 1), new Object[] { "A", "B", 'A', Block.chest, 'B', Item.minecartEmpty }); + this.addRecipe(new ItemStack(Item.minecartPowered, 1), new Object[] { "A", "B", 'A', Block.furnaceIdle, 'B', Item.minecartEmpty }); + this.addRecipe(new ItemStack(Item.minecartTnt, 1), new Object[] { "A", "B", 'A', Block.tnt, 'B', Item.minecartEmpty }); + this.addRecipe(new ItemStack(Item.minecartHopper, 1), new Object[] { "A", "B", 'A', Block.hopperBlock, 'B', Item.minecartEmpty }); + this.addRecipe(new ItemStack(Item.boat, 1), new Object[] { "# #", "###", '#', Block.planks }); + this.addRecipe(new ItemStack(Item.bucketEmpty, 1), new Object[] { "# #", " # ", '#', Item.ingotIron }); + this.addRecipe(new ItemStack(Item.flowerPot, 1), new Object[] { "# #", " # ", '#', Item.brick }); + this.addRecipe(new ItemStack(Item.flintAndSteel, 1), new Object[] { "A ", " B", 'A', Item.ingotIron, 'B', Item.flint }); + this.addRecipe(new ItemStack(Item.bread, 1), new Object[] { "###", '#', Item.wheat }); + this.addRecipe(new ItemStack(Block.stairsWoodOak, 4), new Object[] { "# ", "## ", "###", '#', new ItemStack(Block.planks, 1, 0) }); + this.addRecipe(new ItemStack(Block.stairsWoodBirch, 4), new Object[] { "# ", "## ", "###", '#', new ItemStack(Block.planks, 1, 2) }); + this.addRecipe(new ItemStack(Block.stairsWoodSpruce, 4), new Object[] { "# ", "## ", "###", '#', new ItemStack(Block.planks, 1, 1) }); + this.addRecipe(new ItemStack(Block.stairsWoodJungle, 4), new Object[] { "# ", "## ", "###", '#', new ItemStack(Block.planks, 1, 3) }); + this.addRecipe(new ItemStack(Item.fishingRod, 1), new Object[] { " #", " #X", "# X", '#', Item.stick, 'X', Item.silk }); + this.addRecipe(new ItemStack(Item.carrotOnAStick, 1), new Object[] { "# ", " X", '#', Item.fishingRod, 'X', Item.carrot }).func_92100_c(); + this.addRecipe(new ItemStack(Block.stairsCobblestone, 4), new Object[] { "# ", "## ", "###", '#', Block.cobblestone }); + this.addRecipe(new ItemStack(Block.stairsBrick, 4), new Object[] { "# ", "## ", "###", '#', Block.brick }); + this.addRecipe(new ItemStack(Block.stairsStoneBrick, 4), new Object[] { "# ", "## ", "###", '#', Block.stoneBrick }); + this.addRecipe(new ItemStack(Block.stairsNetherBrick, 4), new Object[] { "# ", "## ", "###", '#', Block.netherBrick }); + this.addRecipe(new ItemStack(Block.stairsSandStone, 4), new Object[] { "# ", "## ", "###", '#', Block.sandStone }); + this.addRecipe(new ItemStack(Block.stairsNetherQuartz, 4), new Object[] { "# ", "## ", "###", '#', Block.blockNetherQuartz }); + this.addRecipe(new ItemStack(Item.painting, 1), new Object[] { "###", "#X#", "###", '#', Item.stick, 'X', Block.cloth }); + this.addRecipe(new ItemStack(Item.itemFrame, 1), new Object[] { "###", "#X#", "###", '#', Item.stick, 'X', Item.leather }); + this.addRecipe(new ItemStack(Item.appleGold, 1, 0), new Object[] { "###", "#X#", "###", '#', Item.goldNugget, 'X', Item.appleRed }); + this.addRecipe(new ItemStack(Item.appleGold, 1, 1), new Object[] { "###", "#X#", "###", '#', Block.blockGold, 'X', Item.appleRed }); + this.addRecipe(new ItemStack(Item.goldenCarrot, 1, 0), new Object[] { "###", "#X#", "###", '#', Item.goldNugget, 'X', Item.carrot }); + this.addRecipe(new ItemStack(Block.lever, 1), new Object[] { "X", "#", '#', Block.cobblestone, 'X', Item.stick }); + this.addRecipe(new ItemStack(Block.tripWireSource, 2), new Object[] { "I", "S", "#", '#', Block.planks, 'S', Item.stick, 'I', Item.ingotIron }); + this.addRecipe(new ItemStack(Block.torchRedstoneActive, 1), new Object[] { "X", "#", '#', Item.stick, 'X', Item.redstone }); + this.addRecipe(new ItemStack(Item.redstoneRepeater, 1), new Object[] { "#X#", "III", '#', Block.torchRedstoneActive, 'X', Item.redstone, 'I', Block.stone }); + this.addRecipe(new ItemStack(Item.comparator, 1), new Object[] { " # ", "#X#", "III", '#', Block.torchRedstoneActive, 'X', Item.netherQuartz, 'I', Block.stone }); + this.addRecipe(new ItemStack(Item.pocketSundial, 1), new Object[] { " # ", "#X#", " # ", '#', Item.ingotGold, 'X', Item.redstone }); + this.addRecipe(new ItemStack(Item.compass, 1), new Object[] { " # ", "#X#", " # ", '#', Item.ingotIron, 'X', Item.redstone }); + this.addRecipe(new ItemStack(Item.emptyMap, 1), new Object[] { "###", "#X#", "###", '#', Item.paper, 'X', Item.compass }); + this.addRecipe(new ItemStack(Block.stoneButton, 1), new Object[] { "#", '#', Block.stone }); + this.addRecipe(new ItemStack(Block.woodenButton, 1), new Object[] { "#", '#', Block.planks }); + this.addRecipe(new ItemStack(Block.pressurePlateStone, 1), new Object[] { "##", '#', Block.stone }); + this.addRecipe(new ItemStack(Block.pressurePlatePlanks, 1), new Object[] { "##", '#', Block.planks }); + this.addRecipe(new ItemStack(Block.pressurePlateIron, 1), new Object[] { "##", '#', Item.ingotIron }); + this.addRecipe(new ItemStack(Block.pressurePlateGold, 1), new Object[] { "##", '#', Item.ingotGold }); + this.addRecipe(new ItemStack(Block.dispenser, 1), new Object[] { "###", "#X#", "#R#", '#', Block.cobblestone, 'X', Item.bow, 'R', Item.redstone }); + this.addRecipe(new ItemStack(Block.dropper, 1), new Object[] { "###", "# #", "#R#", '#', Block.cobblestone, 'R', Item.redstone }); + this.addRecipe(new ItemStack(Block.pistonBase, 1), new Object[] { "TTT", "#X#", "#R#", '#', Block.cobblestone, 'X', Item.ingotIron, 'R', Item.redstone, 'T', Block.planks }); + this.addRecipe(new ItemStack(Block.pistonStickyBase, 1), new Object[] { "S", "P", 'S', Item.slimeBall, 'P', Block.pistonBase }); + this.addRecipe(new ItemStack(Item.bed, 1), new Object[] { "###", "XXX", '#', Block.cloth, 'X', Block.planks }); + this.addRecipe(new ItemStack(Block.enchantmentTable, 1), new Object[] { " B ", "D#D", "###", '#', Block.obsidian, 'B', Item.book, 'D', Item.diamond }); + this.addRecipe(new ItemStack(Block.anvil, 1), new Object[] { "III", " i ", "iii", 'I', Block.blockIron, 'i', Item.ingotIron }); + this.addShapelessRecipe(new ItemStack(Item.eyeOfEnder, 1), new Object[] { Item.enderPearl, Item.blazePowder }); + this.addShapelessRecipe(new ItemStack(Item.fireballCharge, 3), new Object[] { Item.gunpowder, Item.blazePowder, Item.coal }); + this.addShapelessRecipe(new ItemStack(Item.fireballCharge, 3), new Object[] { Item.gunpowder, Item.blazePowder, new ItemStack(Item.coal, 1, 1) }); + this.addRecipe(new ItemStack(Block.daylightSensor), new Object[] { "GGG", "QQQ", "WWW", 'G', Block.glass, 'Q', Item.netherQuartz, 'W', Block.woodSingleSlab }); + this.addRecipe(new ItemStack(Block.hopperBlock), new Object[] { "I I", "ICI", " I ", 'I', Item.ingotIron, 'C', Block.chest }); + Collections.sort(this.recipes, new RecipeSorter(this)); + System.out.println(this.recipes.size() + " recipes"); + } + + ShapedRecipes addRecipe(ItemStack par1ItemStack, Object... par2ArrayOfObj) { + String var3 = ""; + int var4 = 0; + int var5 = 0; + int var6 = 0; + + if (par2ArrayOfObj[var4] instanceof String[]) { + String[] var7 = (String[]) ((String[]) par2ArrayOfObj[var4++]); + + for (int var8 = 0; var8 < var7.length; ++var8) { + String var9 = var7[var8]; + ++var6; + var5 = var9.length(); + var3 = var3 + var9; + } + } else { + while (par2ArrayOfObj[var4] instanceof String) { + String var11 = (String) par2ArrayOfObj[var4++]; + ++var6; + var5 = var11.length(); + var3 = var3 + var11; + } + } + + HashMap var12; + + for (var12 = new HashMap(); var4 < par2ArrayOfObj.length; var4 += 2) { + Character var13 = (Character) par2ArrayOfObj[var4]; + ItemStack var15 = null; + + if (par2ArrayOfObj[var4 + 1] instanceof Item) { + var15 = new ItemStack((Item) par2ArrayOfObj[var4 + 1]); + } else if (par2ArrayOfObj[var4 + 1] instanceof Block) { + var15 = new ItemStack((Block) par2ArrayOfObj[var4 + 1], 1, 32767); + } else if (par2ArrayOfObj[var4 + 1] instanceof ItemStack) { + var15 = (ItemStack) par2ArrayOfObj[var4 + 1]; + } + + var12.put(var13, var15); + } + + ItemStack[] var14 = new ItemStack[var5 * var6]; + + for (int var16 = 0; var16 < var5 * var6; ++var16) { + char var10 = var3.charAt(var16); + + if (var12.containsKey(Character.valueOf(var10))) { + var14[var16] = ((ItemStack) var12.get(Character.valueOf(var10))).copy(); + } else { + var14[var16] = null; + } + } + + ShapedRecipes var17 = new ShapedRecipes(var5, var6, var14, par1ItemStack); + this.recipes.add(var17); + return var17; + } + + void addShapelessRecipe(ItemStack par1ItemStack, Object... par2ArrayOfObj) { + ArrayList var3 = new ArrayList(); + Object[] var4 = par2ArrayOfObj; + int var5 = par2ArrayOfObj.length; + + for (int var6 = 0; var6 < var5; ++var6) { + Object var7 = var4[var6]; + + if (var7 instanceof ItemStack) { + var3.add(((ItemStack) var7).copy()); + } else if (var7 instanceof Item) { + var3.add(new ItemStack((Item) var7)); + } else { + if (!(var7 instanceof Block)) { + throw new RuntimeException("Invalid shapeless recipy!"); + } + + var3.add(new ItemStack((Block) var7)); + } + } + + this.recipes.add(new ShapelessRecipes(par1ItemStack, var3)); + } + + public ItemStack findMatchingRecipe(InventoryCrafting par1InventoryCrafting, World par2World) { + int var3 = 0; + ItemStack var4 = null; + ItemStack var5 = null; + int var6; + + for (var6 = 0; var6 < par1InventoryCrafting.getSizeInventory(); ++var6) { + ItemStack var7 = par1InventoryCrafting.getStackInSlot(var6); + + if (var7 != null) { + if (var3 == 0) { + var4 = var7; + } + + if (var3 == 1) { + var5 = var7; + } + + ++var3; + } + } + + if (var3 == 2 && var4.itemID == var5.itemID && var4.stackSize == 1 && var5.stackSize == 1 && Item.itemsList[var4.itemID].isDamageable()) { + Item var11 = Item.itemsList[var4.itemID]; + int var13 = var11.getMaxDamage() - var4.getItemDamageForDisplay(); + int var8 = var11.getMaxDamage() - var5.getItemDamageForDisplay(); + int var9 = var13 + var8 + var11.getMaxDamage() * 5 / 100; + int var10 = var11.getMaxDamage() - var9; + + if (var10 < 0) { + var10 = 0; + } + + return new ItemStack(var4.itemID, 1, var10); + } else { + for (var6 = 0; var6 < this.recipes.size(); ++var6) { + IRecipe var12 = (IRecipe) this.recipes.get(var6); + + if (var12.matches(par1InventoryCrafting, par2World)) { + return var12.getCraftingResult(par1InventoryCrafting); + } + } + + return null; + } + } + + /** + * returns the List<> of all recipes + */ + public List getRecipeList() { + return this.recipes; + } +} diff --git a/src/main/java/net/minecraft/src/CreativeCrafting.java b/src/main/java/net/minecraft/src/CreativeCrafting.java new file mode 100644 index 0000000..e3c5f12 --- /dev/null +++ b/src/main/java/net/minecraft/src/CreativeCrafting.java @@ -0,0 +1,33 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.client.Minecraft; + +public class CreativeCrafting implements ICrafting { + private final Minecraft mc; + + public CreativeCrafting(Minecraft par1) { + this.mc = par1; + } + + public void sendContainerAndContentsToPlayer(Container par1Container, List par2List) { + } + + /** + * Sends the contents of an inventory slot to the client-side Container. This + * doesn't have to match the actual contents of that slot. Args: Container, slot + * number, slot contents + */ + public void sendSlotContents(Container par1Container, int par2, ItemStack par3ItemStack) { + this.mc.playerController.sendSlotPacket(par3ItemStack, par2); + } + + /** + * Sends two ints to the client-side Container. Used for furnace burning time, + * smelting progress, brewing progress, and enchanting level. Normally the first + * int identifies which variable to update, and the second contains the new + * value. Both are truncated to shorts in non-local SMP. + */ + public void sendProgressBarUpdate(Container par1Container, int par2, int par3) { + } +} diff --git a/src/main/java/net/minecraft/src/CreativeTabBlock.java b/src/main/java/net/minecraft/src/CreativeTabBlock.java new file mode 100644 index 0000000..5f82d25 --- /dev/null +++ b/src/main/java/net/minecraft/src/CreativeTabBlock.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +final class CreativeTabBlock extends CreativeTabs { + CreativeTabBlock(int par1, String par2Str) { + super(par1, par2Str); + } + + /** + * the itemID for the item to be displayed on the tab + */ + public int getTabIconItemIndex() { + return Block.brick.blockID; + } +} diff --git a/src/main/java/net/minecraft/src/CreativeTabBrewing.java b/src/main/java/net/minecraft/src/CreativeTabBrewing.java new file mode 100644 index 0000000..93ef742 --- /dev/null +++ b/src/main/java/net/minecraft/src/CreativeTabBrewing.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +final class CreativeTabBrewing extends CreativeTabs { + CreativeTabBrewing(int par1, String par2Str) { + super(par1, par2Str); + } + + /** + * the itemID for the item to be displayed on the tab + */ + public int getTabIconItemIndex() { + return Item.potion.itemID; + } +} diff --git a/src/main/java/net/minecraft/src/CreativeTabCombat.java b/src/main/java/net/minecraft/src/CreativeTabCombat.java new file mode 100644 index 0000000..bb9e37f --- /dev/null +++ b/src/main/java/net/minecraft/src/CreativeTabCombat.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +import java.util.List; + +final class CreativeTabCombat extends CreativeTabs { + CreativeTabCombat(int par1, String par2Str) { + super(par1, par2Str); + } + + /** + * the itemID for the item to be displayed on the tab + */ + public int getTabIconItemIndex() { + return Item.swordGold.itemID; + } + + /** + * only shows items which have tabToDisplayOn == this + */ + public void displayAllReleventItems(List par1List) { + super.displayAllReleventItems(par1List); + this.func_92116_a(par1List, new EnumEnchantmentType[] { EnumEnchantmentType.armor, EnumEnchantmentType.armor_feet, EnumEnchantmentType.armor_head, EnumEnchantmentType.armor_legs, EnumEnchantmentType.armor_torso, + EnumEnchantmentType.bow, EnumEnchantmentType.weapon }); + } +} diff --git a/src/main/java/net/minecraft/src/CreativeTabDeco.java b/src/main/java/net/minecraft/src/CreativeTabDeco.java new file mode 100644 index 0000000..7be153d --- /dev/null +++ b/src/main/java/net/minecraft/src/CreativeTabDeco.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +final class CreativeTabDeco extends CreativeTabs { + CreativeTabDeco(int par1, String par2Str) { + super(par1, par2Str); + } + + /** + * the itemID for the item to be displayed on the tab + */ + public int getTabIconItemIndex() { + return Block.plantRed.blockID; + } +} diff --git a/src/main/java/net/minecraft/src/CreativeTabFood.java b/src/main/java/net/minecraft/src/CreativeTabFood.java new file mode 100644 index 0000000..c6f6526 --- /dev/null +++ b/src/main/java/net/minecraft/src/CreativeTabFood.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +final class CreativeTabFood extends CreativeTabs { + CreativeTabFood(int par1, String par2Str) { + super(par1, par2Str); + } + + /** + * the itemID for the item to be displayed on the tab + */ + public int getTabIconItemIndex() { + return Item.appleRed.itemID; + } +} diff --git a/src/main/java/net/minecraft/src/CreativeTabInventory.java b/src/main/java/net/minecraft/src/CreativeTabInventory.java new file mode 100644 index 0000000..e8de30a --- /dev/null +++ b/src/main/java/net/minecraft/src/CreativeTabInventory.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +final class CreativeTabInventory extends CreativeTabs { + CreativeTabInventory(int par1, String par2Str) { + super(par1, par2Str); + } + + /** + * the itemID for the item to be displayed on the tab + */ + public int getTabIconItemIndex() { + return Block.chest.blockID; + } +} diff --git a/src/main/java/net/minecraft/src/CreativeTabMaterial.java b/src/main/java/net/minecraft/src/CreativeTabMaterial.java new file mode 100644 index 0000000..8d16d62 --- /dev/null +++ b/src/main/java/net/minecraft/src/CreativeTabMaterial.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +final class CreativeTabMaterial extends CreativeTabs { + CreativeTabMaterial(int par1, String par2Str) { + super(par1, par2Str); + } + + /** + * the itemID for the item to be displayed on the tab + */ + public int getTabIconItemIndex() { + return Item.stick.itemID; + } +} diff --git a/src/main/java/net/minecraft/src/CreativeTabMisc.java b/src/main/java/net/minecraft/src/CreativeTabMisc.java new file mode 100644 index 0000000..67b2ddf --- /dev/null +++ b/src/main/java/net/minecraft/src/CreativeTabMisc.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +import java.util.List; + +final class CreativeTabMisc extends CreativeTabs { + CreativeTabMisc(int par1, String par2Str) { + super(par1, par2Str); + } + + /** + * the itemID for the item to be displayed on the tab + */ + public int getTabIconItemIndex() { + return Item.bucketLava.itemID; + } + + /** + * only shows items which have tabToDisplayOn == this + */ + public void displayAllReleventItems(List par1List) { + super.displayAllReleventItems(par1List); + this.func_92116_a(par1List, new EnumEnchantmentType[] { EnumEnchantmentType.all }); + } +} diff --git a/src/main/java/net/minecraft/src/CreativeTabRedstone.java b/src/main/java/net/minecraft/src/CreativeTabRedstone.java new file mode 100644 index 0000000..3a3234c --- /dev/null +++ b/src/main/java/net/minecraft/src/CreativeTabRedstone.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +final class CreativeTabRedstone extends CreativeTabs { + CreativeTabRedstone(int par1, String par2Str) { + super(par1, par2Str); + } + + /** + * the itemID for the item to be displayed on the tab + */ + public int getTabIconItemIndex() { + return Item.redstone.itemID; + } +} diff --git a/src/main/java/net/minecraft/src/CreativeTabSearch.java b/src/main/java/net/minecraft/src/CreativeTabSearch.java new file mode 100644 index 0000000..8d4b26f --- /dev/null +++ b/src/main/java/net/minecraft/src/CreativeTabSearch.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +final class CreativeTabSearch extends CreativeTabs { + CreativeTabSearch(int par1, String par2Str) { + super(par1, par2Str); + } + + /** + * the itemID for the item to be displayed on the tab + */ + public int getTabIconItemIndex() { + return Item.compass.itemID; + } +} diff --git a/src/main/java/net/minecraft/src/CreativeTabTools.java b/src/main/java/net/minecraft/src/CreativeTabTools.java new file mode 100644 index 0000000..703d30b --- /dev/null +++ b/src/main/java/net/minecraft/src/CreativeTabTools.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +import java.util.List; + +final class CreativeTabTools extends CreativeTabs { + CreativeTabTools(int par1, String par2Str) { + super(par1, par2Str); + } + + /** + * the itemID for the item to be displayed on the tab + */ + public int getTabIconItemIndex() { + return Item.axeIron.itemID; + } + + /** + * only shows items which have tabToDisplayOn == this + */ + public void displayAllReleventItems(List par1List) { + super.displayAllReleventItems(par1List); + this.func_92116_a(par1List, new EnumEnchantmentType[] { EnumEnchantmentType.digger }); + } +} diff --git a/src/main/java/net/minecraft/src/CreativeTabTransport.java b/src/main/java/net/minecraft/src/CreativeTabTransport.java new file mode 100644 index 0000000..ac2b6e8 --- /dev/null +++ b/src/main/java/net/minecraft/src/CreativeTabTransport.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +final class CreativeTabTransport extends CreativeTabs { + CreativeTabTransport(int par1, String par2Str) { + super(par1, par2Str); + } + + /** + * the itemID for the item to be displayed on the tab + */ + public int getTabIconItemIndex() { + return Block.railPowered.blockID; + } +} diff --git a/src/main/java/net/minecraft/src/CreativeTabs.java b/src/main/java/net/minecraft/src/CreativeTabs.java new file mode 100644 index 0000000..72d42f4 --- /dev/null +++ b/src/main/java/net/minecraft/src/CreativeTabs.java @@ -0,0 +1,140 @@ +package net.minecraft.src; + +import java.util.List; + +public class CreativeTabs { + public static final CreativeTabs[] creativeTabArray = new CreativeTabs[12]; + public static final CreativeTabs tabBlock = new CreativeTabBlock(0, "buildingBlocks"); + public static final CreativeTabs tabDecorations = new CreativeTabDeco(1, "decorations"); + public static final CreativeTabs tabRedstone = new CreativeTabRedstone(2, "redstone"); + public static final CreativeTabs tabTransport = new CreativeTabTransport(3, "transportation"); + public static final CreativeTabs tabMisc = new CreativeTabMisc(4, "misc"); + public static final CreativeTabs tabAllSearch = (new CreativeTabSearch(5, "search")).setBackgroundImageName("search.png"); + public static final CreativeTabs tabFood = new CreativeTabFood(6, "food"); + public static final CreativeTabs tabTools = new CreativeTabTools(7, "tools"); + public static final CreativeTabs tabCombat = new CreativeTabCombat(8, "combat"); + public static final CreativeTabs tabBrewing = new CreativeTabBrewing(9, "brewing"); + public static final CreativeTabs tabMaterials = new CreativeTabMaterial(10, "materials"); + public static final CreativeTabs tabInventory = (new CreativeTabInventory(11, "inventory")).setBackgroundImageName("survival_inv.png").setNoScrollbar().setNoTitle(); + private final int tabIndex; + private final String tabLabel; + + /** Texture to use. */ + private String backgroundImageName = "list_items.png"; + private boolean hasScrollbar = true; + + /** Whether to draw the title in the foreground of the creative GUI */ + private boolean drawTitle = true; + + public CreativeTabs(int par1, String par2Str) { + this.tabIndex = par1; + this.tabLabel = par2Str; + creativeTabArray[par1] = this; + } + + public int getTabIndex() { + return this.tabIndex; + } + + public String getTabLabel() { + return this.tabLabel; + } + + /** + * Gets the translated Label. + */ + public String getTranslatedTabLabel() { + return StringTranslate.getInstance().translateKey("itemGroup." + this.getTabLabel()); + } + + public Item getTabIconItem() { + return Item.itemsList[this.getTabIconItemIndex()]; + } + + /** + * the itemID for the item to be displayed on the tab + */ + public int getTabIconItemIndex() { + return 1; + } + + public String getBackgroundImageName() { + return this.backgroundImageName; + } + + public CreativeTabs setBackgroundImageName(String par1Str) { + this.backgroundImageName = par1Str; + return this; + } + + public boolean drawInForegroundOfTab() { + return this.drawTitle; + } + + public CreativeTabs setNoTitle() { + this.drawTitle = false; + return this; + } + + public boolean shouldHidePlayerInventory() { + return this.hasScrollbar; + } + + public CreativeTabs setNoScrollbar() { + this.hasScrollbar = false; + return this; + } + + /** + * returns index % 6 + */ + public int getTabColumn() { + return this.tabIndex % 6; + } + + /** + * returns tabIndex < 6 + */ + public boolean isTabInFirstRow() { + return this.tabIndex < 6; + } + + /** + * only shows items which have tabToDisplayOn == this + */ + public void displayAllReleventItems(List par1List) { + Item[] var2 = Item.itemsList; + int var3 = var2.length; + + for (int var4 = 0; var4 < var3; ++var4) { + Item var5 = var2[var4]; + + if (var5 != null && var5.getCreativeTab() == this) { + var5.getSubItems(var5.itemID, this, par1List); + } + } + } + + public void func_92116_a(List par1List, EnumEnchantmentType... par2ArrayOfEnumEnchantmentType) { + Enchantment[] var3 = Enchantment.enchantmentsList; + int var4 = var3.length; + + for (int var5 = 0; var5 < var4; ++var5) { + Enchantment var6 = var3[var5]; + + if (var6 != null && var6.type != null) { + boolean var7 = false; + + for (int var8 = 0; var8 < par2ArrayOfEnumEnchantmentType.length && !var7; ++var8) { + if (var6.type == par2ArrayOfEnumEnchantmentType[var8]) { + var7 = true; + } + } + + if (var7) { + par1List.add(Item.enchantedBook.func_92111_a(new EnchantmentData(var6, var6.getMaxLevel()))); + } + } + } + } +} diff --git a/src/main/java/net/minecraft/src/DamageSource.java b/src/main/java/net/minecraft/src/DamageSource.java new file mode 100644 index 0000000..d86bf6c --- /dev/null +++ b/src/main/java/net/minecraft/src/DamageSource.java @@ -0,0 +1,211 @@ +package net.minecraft.src; + +public class DamageSource { + public static DamageSource inFire = (new DamageSource("inFire")).setFireDamage(); + public static DamageSource onFire = (new DamageSource("onFire")).setDamageBypassesArmor().setFireDamage(); + public static DamageSource lava = (new DamageSource("lava")).setFireDamage(); + public static DamageSource inWall = (new DamageSource("inWall")).setDamageBypassesArmor(); + public static DamageSource drown = (new DamageSource("drown")).setDamageBypassesArmor(); + public static DamageSource starve = (new DamageSource("starve")).setDamageBypassesArmor(); + public static DamageSource cactus = new DamageSource("cactus"); + public static DamageSource fall = (new DamageSource("fall")).setDamageBypassesArmor(); + public static DamageSource outOfWorld = (new DamageSource("outOfWorld")).setDamageBypassesArmor().setDamageAllowedInCreativeMode(); + public static DamageSource generic = (new DamageSource("generic")).setDamageBypassesArmor(); + public static DamageSource magic = (new DamageSource("magic")).setDamageBypassesArmor().setMagicDamage(); + public static DamageSource wither = (new DamageSource("wither")).setDamageBypassesArmor(); + public static DamageSource anvil = new DamageSource("anvil"); + public static DamageSource fallingBlock = new DamageSource("fallingBlock"); + + /** This kind of damage can be blocked or not. */ + private boolean isUnblockable = false; + private boolean isDamageAllowedInCreativeMode = false; + private float hungerDamage = 0.3F; + + /** This kind of damage is based on fire or not. */ + private boolean fireDamage; + + /** This kind of damage is based on a projectile or not. */ + private boolean projectile; + + /** + * Whether this damage source will have its damage amount scaled based on the + * current difficulty. + */ + private boolean difficultyScaled; + private boolean magicDamage = false; + private boolean explosion = false; + public String damageType; + + public static DamageSource causeMobDamage(EntityLiving par0EntityLiving) { + return new EntityDamageSource("mob", par0EntityLiving); + } + + /** + * returns an EntityDamageSource of type player + */ + public static DamageSource causePlayerDamage(EntityPlayer par0EntityPlayer) { + return new EntityDamageSource("player", par0EntityPlayer); + } + + /** + * returns EntityDamageSourceIndirect of an arrow + */ + public static DamageSource causeArrowDamage(EntityArrow par0EntityArrow, Entity par1Entity) { + return (new EntityDamageSourceIndirect("arrow", par0EntityArrow, par1Entity)).setProjectile(); + } + + /** + * returns EntityDamageSourceIndirect of a fireball + */ + public static DamageSource causeFireballDamage(EntityFireball par0EntityFireball, Entity par1Entity) { + return par1Entity == null ? (new EntityDamageSourceIndirect("onFire", par0EntityFireball, par0EntityFireball)).setFireDamage().setProjectile() + : (new EntityDamageSourceIndirect("fireball", par0EntityFireball, par1Entity)).setFireDamage().setProjectile(); + } + + public static DamageSource causeThrownDamage(Entity par0Entity, Entity par1Entity) { + return (new EntityDamageSourceIndirect("thrown", par0Entity, par1Entity)).setProjectile(); + } + + public static DamageSource causeIndirectMagicDamage(Entity par0Entity, Entity par1Entity) { + return (new EntityDamageSourceIndirect("indirectMagic", par0Entity, par1Entity)).setDamageBypassesArmor().setMagicDamage(); + } + + /** + * Returns the EntityDamageSource of the Thorns enchantment + */ + public static DamageSource causeThornsDamage(Entity par0Entity) { + return (new EntityDamageSource("thorns", par0Entity)).setMagicDamage(); + } + + public static DamageSource setExplosionSource(Explosion par0Explosion) { + return par0Explosion != null && par0Explosion.func_94613_c() != null ? (new EntityDamageSource("explosion.player", par0Explosion.func_94613_c())).setDifficultyScaled().setExplosion() + : (new DamageSource("explosion")).setDifficultyScaled().setExplosion(); + } + + /** + * Returns true if the damage is projectile based. + */ + public boolean isProjectile() { + return this.projectile; + } + + /** + * Define the damage type as projectile based. + */ + public DamageSource setProjectile() { + this.projectile = true; + return this; + } + + public boolean isExplosion() { + return this.explosion; + } + + public DamageSource setExplosion() { + this.explosion = true; + return this; + } + + public boolean isUnblockable() { + return this.isUnblockable; + } + + /** + * How much satiate(food) is consumed by this DamageSource + */ + public float getHungerDamage() { + return this.hungerDamage; + } + + public boolean canHarmInCreative() { + return this.isDamageAllowedInCreativeMode; + } + + protected DamageSource(String par1Str) { + this.damageType = par1Str; + } + + public Entity getSourceOfDamage() { + return this.getEntity(); + } + + public Entity getEntity() { + return null; + } + + protected DamageSource setDamageBypassesArmor() { + this.isUnblockable = true; + this.hungerDamage = 0.0F; + return this; + } + + protected DamageSource setDamageAllowedInCreativeMode() { + this.isDamageAllowedInCreativeMode = true; + return this; + } + + /** + * Define the damage type as fire based. + */ + protected DamageSource setFireDamage() { + this.fireDamage = true; + return this; + } + + /** + * Returns the message to be displayed on player death. + */ + public String getDeathMessage(EntityLiving par1EntityLiving) { + EntityLiving var2 = par1EntityLiving.func_94060_bK(); + String var3 = "death.attack." + this.damageType; + String var4 = var3 + ".player"; + return var2 != null && StatCollector.func_94522_b(var4) ? StatCollector.translateToLocalFormatted(var4, new Object[] { par1EntityLiving.getTranslatedEntityName(), var2.getTranslatedEntityName() }) + : StatCollector.translateToLocalFormatted(var3, new Object[] { par1EntityLiving.getTranslatedEntityName() }); + } + + /** + * Returns true if the damage is fire based. + */ + public boolean isFireDamage() { + return this.fireDamage; + } + + /** + * Return the name of damage type. + */ + public String getDamageType() { + return this.damageType; + } + + /** + * Set whether this damage source will have its damage amount scaled based on + * the current difficulty. + */ + public DamageSource setDifficultyScaled() { + this.difficultyScaled = true; + return this; + } + + /** + * Return whether this damage source will have its damage amount scaled based on + * the current difficulty. + */ + public boolean isDifficultyScaled() { + return this.difficultyScaled; + } + + /** + * Returns true if the damage is magic based. + */ + public boolean isMagicDamage() { + return this.magicDamage; + } + + /** + * Define the damage type as magic based. + */ + public DamageSource setMagicDamage() { + this.magicDamage = true; + return this; + } +} diff --git a/src/main/java/net/minecraft/src/DataWatcher.java b/src/main/java/net/minecraft/src/DataWatcher.java new file mode 100644 index 0000000..779a6b2 --- /dev/null +++ b/src/main/java/net/minecraft/src/DataWatcher.java @@ -0,0 +1,312 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class DataWatcher { + /** When isBlank is true the DataWatcher is not watching any objects */ + private boolean isBlank = true; + private static final HashMap dataTypes = new HashMap(); + private final Map watchedObjects = new HashMap(); + + /** true if one or more object was changed */ + private boolean objectChanged; + + /** + * adds a new object to dataWatcher to watch, to update an already existing + * object see updateObject. Arguments: data Value Id, Object to add + */ + public void addObject(int par1, Object par2Obj) { + Integer var3 = (Integer) dataTypes.get(par2Obj.getClass()); + + if (var3 == null) { + throw new IllegalArgumentException("Unknown data type: " + par2Obj.getClass()); + } else if (par1 > 31) { + throw new IllegalArgumentException("Data value id is too big with " + par1 + "! (Max is " + 31 + ")"); + } else if (this.watchedObjects.containsKey(Integer.valueOf(par1))) { + throw new IllegalArgumentException("Duplicate id value for " + par1 + "!"); + } else { + WatchableObject var4 = new WatchableObject(var3.intValue(), par1, par2Obj); + //this.lock.writeLock().lock(); + this.watchedObjects.put(Integer.valueOf(par1), var4); + //this.lock.writeLock().unlock(); + this.isBlank = false; + } + } + + /** + * Add a new object for the DataWatcher to watch, using the specified data type. + */ + public void addObjectByDataType(int par1, int par2) { + WatchableObject var3 = new WatchableObject(par2, par1, (Object) null); + //this.lock.writeLock().lock(); + this.watchedObjects.put(Integer.valueOf(par1), var3); + //this.lock.writeLock().unlock(); + this.isBlank = false; + } + + /** + * gets the bytevalue of a watchable object + */ + public byte getWatchableObjectByte(int par1) { + return ((Byte) this.getWatchedObject(par1).getObject()).byteValue(); + } + + public short getWatchableObjectShort(int par1) { + return ((Short) this.getWatchedObject(par1).getObject()).shortValue(); + } + + /** + * gets a watchable object and returns it as a Integer + */ + public int getWatchableObjectInt(int par1) { + return ((Integer) this.getWatchedObject(par1).getObject()).intValue(); + } + + /** + * gets a watchable object and returns it as a String + */ + public String getWatchableObjectString(int par1) { + return (String) this.getWatchedObject(par1).getObject(); + } + + /** + * Get a watchable object as an ItemStack. + */ + public ItemStack getWatchableObjectItemStack(int par1) { + return (ItemStack) this.getWatchedObject(par1).getObject(); + } + + /** + * is threadsafe, unless it throws an exception, then + */ + private WatchableObject getWatchedObject(int par1) { + //this.lock.readLock().lock(); + WatchableObject var2; + + var2 = (WatchableObject) this.watchedObjects.get(Integer.valueOf(par1)); + + //this.lock.readLock().unlock(); + return var2; + } + + /** + * updates an already existing object + */ + public void updateObject(int par1, Object par2Obj) { + WatchableObject var3 = this.getWatchedObject(par1); + + if (!par2Obj.equals(var3.getObject())) { + var3.setObject(par2Obj); + var3.setWatched(true); + this.objectChanged = true; + } + } + + public void setObjectWatched(int par1) { + WatchableObject.setWatchableObjectWatched(this.getWatchedObject(par1), true); + this.objectChanged = true; + } + + public boolean hasChanges() { + return this.objectChanged; + } + + /** + * writes every object in passed list to dataoutputstream, terminated by 0x7F + */ + public static void writeObjectsInListToStream(List par0List, DataOutputStream par1DataOutputStream) throws IOException { + if (par0List != null) { + Iterator var2 = par0List.iterator(); + + while (var2.hasNext()) { + WatchableObject var3 = (WatchableObject) var2.next(); + writeWatchableObject(par1DataOutputStream, var3); + } + } + + par1DataOutputStream.writeByte(127); + } + + public List unwatchAndReturnAllWatched() { + ArrayList var1 = null; + + if (this.objectChanged) { + //this.lock.readLock().lock(); + Iterator var2 = this.watchedObjects.values().iterator(); + + while (var2.hasNext()) { + WatchableObject var3 = (WatchableObject) var2.next(); + + if (var3.isWatched()) { + var3.setWatched(false); + + if (var1 == null) { + var1 = new ArrayList(); + } + + var1.add(var3); + } + } + + //this.lock.readLock().unlock(); + } + + this.objectChanged = false; + return var1; + } + + public void writeWatchableObjects(DataOutputStream par1DataOutputStream) throws IOException { + //this.lock.readLock().lock(); + Iterator var2 = this.watchedObjects.values().iterator(); + + while (var2.hasNext()) { + WatchableObject var3 = (WatchableObject) var2.next(); + writeWatchableObject(par1DataOutputStream, var3); + } + + //this.lock.readLock().unlock(); + par1DataOutputStream.writeByte(127); + } + + public List getAllWatched() { + ArrayList var1 = null; + //this.lock.readLock().lock(); + WatchableObject var3; + + for (Iterator var2 = this.watchedObjects.values().iterator(); var2.hasNext(); var1.add(var3)) { + var3 = (WatchableObject) var2.next(); + + if (var1 == null) { + var1 = new ArrayList(); + } + } + + //this.lock.readLock().unlock(); + return var1; + } + + private static void writeWatchableObject(DataOutputStream par0DataOutputStream, WatchableObject par1WatchableObject) throws IOException { + int var2 = (par1WatchableObject.getObjectType() << 5 | par1WatchableObject.getDataValueId() & 31) & 255; + par0DataOutputStream.writeByte(var2); + + switch (par1WatchableObject.getObjectType()) { + case 0: + par0DataOutputStream.writeByte(((Byte) par1WatchableObject.getObject()).byteValue()); + break; + + case 1: + par0DataOutputStream.writeShort(((Short) par1WatchableObject.getObject()).shortValue()); + break; + + case 2: + par0DataOutputStream.writeInt(((Integer) par1WatchableObject.getObject()).intValue()); + break; + + case 3: + par0DataOutputStream.writeFloat(((Float) par1WatchableObject.getObject()).floatValue()); + break; + + case 4: + Packet.writeString((String) par1WatchableObject.getObject(), par0DataOutputStream); + break; + + case 5: + ItemStack var4 = (ItemStack) par1WatchableObject.getObject(); + Packet.writeItemStack(var4, par0DataOutputStream); + break; + + case 6: + ChunkCoordinates var3 = (ChunkCoordinates) par1WatchableObject.getObject(); + par0DataOutputStream.writeInt(var3.posX); + par0DataOutputStream.writeInt(var3.posY); + par0DataOutputStream.writeInt(var3.posZ); + } + } + + public static List readWatchableObjects(DataInputStream par0DataInputStream) throws IOException { + ArrayList var1 = null; + + for (byte var2 = par0DataInputStream.readByte(); var2 != 127; var2 = par0DataInputStream.readByte()) { + if (var1 == null) { + var1 = new ArrayList(); + } + + int var3 = (var2 & 224) >> 5; + int var4 = var2 & 31; + WatchableObject var5 = null; + + switch (var3) { + case 0: + var5 = new WatchableObject(var3, var4, Byte.valueOf(par0DataInputStream.readByte())); + break; + + case 1: + var5 = new WatchableObject(var3, var4, Short.valueOf(par0DataInputStream.readShort())); + break; + + case 2: + var5 = new WatchableObject(var3, var4, Integer.valueOf(par0DataInputStream.readInt())); + break; + + case 3: + var5 = new WatchableObject(var3, var4, Float.valueOf(par0DataInputStream.readFloat())); + break; + + case 4: + var5 = new WatchableObject(var3, var4, Packet.readString(par0DataInputStream, 64)); + break; + + case 5: + var5 = new WatchableObject(var3, var4, Packet.readItemStack(par0DataInputStream)); + break; + + case 6: + int var6 = par0DataInputStream.readInt(); + int var7 = par0DataInputStream.readInt(); + int var8 = par0DataInputStream.readInt(); + var5 = new WatchableObject(var3, var4, new ChunkCoordinates(var6, var7, var8)); + } + + var1.add(var5); + } + + return var1; + } + + public void updateWatchedObjectsFromList(List par1List) { + //this.lock.writeLock().lock(); + Iterator var2 = par1List.iterator(); + + while (var2.hasNext()) { + WatchableObject var3 = (WatchableObject) var2.next(); + WatchableObject var4 = (WatchableObject) this.watchedObjects.get(Integer.valueOf(var3.getDataValueId())); + + if (var4 != null) { + var4.setObject(var3.getObject()); + } + } + + //this.lock.writeLock().unlock(); + } + + public boolean getIsBlank() { + return this.isBlank; + } + + static { + dataTypes.put(Byte.class, Integer.valueOf(0)); + dataTypes.put(Short.class, Integer.valueOf(1)); + dataTypes.put(Integer.class, Integer.valueOf(2)); + dataTypes.put(Float.class, Integer.valueOf(3)); + dataTypes.put(String.class, Integer.valueOf(4)); + dataTypes.put(ItemStack.class, Integer.valueOf(5)); + dataTypes.put(ChunkCoordinates.class, Integer.valueOf(6)); + } +} diff --git a/src/main/java/net/minecraft/src/DerivedWorldInfo.java b/src/main/java/net/minecraft/src/DerivedWorldInfo.java new file mode 100644 index 0000000..c31d828 --- /dev/null +++ b/src/main/java/net/minecraft/src/DerivedWorldInfo.java @@ -0,0 +1,250 @@ +package net.minecraft.src; + +public class DerivedWorldInfo extends WorldInfo { + /** Instance of WorldInfo. */ + private final WorldInfo theWorldInfo; + + public DerivedWorldInfo(WorldInfo par1WorldInfo) { + this.theWorldInfo = par1WorldInfo; + } + + /** + * Gets the NBTTagCompound for the worldInfo + */ + public NBTTagCompound getNBTTagCompound() { + return this.theWorldInfo.getNBTTagCompound(); + } + + /** + * Creates a new NBTTagCompound for the world, with the given NBTTag as the + * "Player" + */ + public NBTTagCompound cloneNBTCompound(NBTTagCompound par1NBTTagCompound) { + return this.theWorldInfo.cloneNBTCompound(par1NBTTagCompound); + } + + /** + * Returns the seed of current world. + */ + public long getSeed() { + return this.theWorldInfo.getSeed(); + } + + /** + * Returns the x spawn position + */ + public int getSpawnX() { + return this.theWorldInfo.getSpawnX(); + } + + /** + * Return the Y axis spawning point of the player. + */ + public int getSpawnY() { + return this.theWorldInfo.getSpawnY(); + } + + /** + * Returns the z spawn position + */ + public int getSpawnZ() { + return this.theWorldInfo.getSpawnZ(); + } + + public long getWorldTotalTime() { + return this.theWorldInfo.getWorldTotalTime(); + } + + /** + * Get current world time + */ + public long getWorldTime() { + return this.theWorldInfo.getWorldTime(); + } + + public long getSizeOnDisk() { + return this.theWorldInfo.getSizeOnDisk(); + } + + /** + * Returns the player's NBTTagCompound to be loaded + */ + public NBTTagCompound getPlayerNBTTagCompound() { + return this.theWorldInfo.getPlayerNBTTagCompound(); + } + + public int getDimension() { + return this.theWorldInfo.getDimension(); + } + + /** + * Get current world name + */ + public String getWorldName() { + return this.theWorldInfo.getWorldName(); + } + + /** + * Returns the save version of this world + */ + public int getSaveVersion() { + return this.theWorldInfo.getSaveVersion(); + } + + /** + * Return the last time the player was in this world. + */ + public long getLastTimePlayed() { + return this.theWorldInfo.getLastTimePlayed(); + } + + /** + * Returns true if it is thundering, false otherwise. + */ + public boolean isThundering() { + return this.theWorldInfo.isThundering(); + } + + /** + * Returns the number of ticks until next thunderbolt. + */ + public int getThunderTime() { + return this.theWorldInfo.getThunderTime(); + } + + /** + * Returns true if it is raining, false otherwise. + */ + public boolean isRaining() { + return this.theWorldInfo.isRaining(); + } + + /** + * Return the number of ticks until rain. + */ + public int getRainTime() { + return this.theWorldInfo.getRainTime(); + } + + /** + * Gets the GameType. + */ + public EnumGameType getGameType() { + return this.theWorldInfo.getGameType(); + } + + /** + * Set the x spawn position to the passed in value + */ + public void setSpawnX(int par1) { + } + + /** + * Sets the y spawn position + */ + public void setSpawnY(int par1) { + } + + /** + * Set the z spawn position to the passed in value + */ + public void setSpawnZ(int par1) { + } + + public void incrementTotalWorldTime(long par1) { + } + + /** + * Set current world time + */ + public void setWorldTime(long par1) { + } + + /** + * Sets the spawn zone position. Args: x, y, z + */ + public void setSpawnPosition(int par1, int par2, int par3) { + } + + public void setWorldName(String par1Str) { + } + + /** + * Sets the save version of the world + */ + public void setSaveVersion(int par1) { + } + + /** + * Sets whether it is thundering or not. + */ + public void setThundering(boolean par1) { + } + + /** + * Defines the number of ticks until next thunderbolt. + */ + public void setThunderTime(int par1) { + } + + /** + * Sets whether it is raining or not. + */ + public void setRaining(boolean par1) { + } + + /** + * Sets the number of ticks until rain. + */ + public void setRainTime(int par1) { + } + + /** + * Get whether the map features (e.g. strongholds) generation is enabled or + * disabled. + */ + public boolean isMapFeaturesEnabled() { + return this.theWorldInfo.isMapFeaturesEnabled(); + } + + /** + * Returns true if hardcore mode is enabled, otherwise false + */ + public boolean isHardcoreModeEnabled() { + return this.theWorldInfo.isHardcoreModeEnabled(); + } + + public WorldType getTerrainType() { + return this.theWorldInfo.getTerrainType(); + } + + public void setTerrainType(WorldType par1WorldType) { + } + + /** + * Returns true if commands are allowed on this World. + */ + public boolean areCommandsAllowed() { + return this.theWorldInfo.areCommandsAllowed(); + } + + /** + * Returns true if the World is initialized. + */ + public boolean isInitialized() { + return this.theWorldInfo.isInitialized(); + } + + /** + * Sets the initialization status of the World. + */ + public void setServerInitialized(boolean par1) { + } + + /** + * Gets the GameRules class Instance. + */ + public GameRules getGameRulesInstance() { + return this.theWorldInfo.getGameRulesInstance(); + } +} diff --git a/src/main/java/net/minecraft/src/DestroyBlockProgress.java b/src/main/java/net/minecraft/src/DestroyBlockProgress.java new file mode 100644 index 0000000..711cb21 --- /dev/null +++ b/src/main/java/net/minecraft/src/DestroyBlockProgress.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +public class DestroyBlockProgress { + /** + * entity ID of the player associated with this partially destroyed Block. Used + * to identify the Blocks in the client Renderer, max 1 per player on a server + */ + private final int miningPlayerEntId; + private final int partialBlockX; + private final int partialBlockY; + private final int partialBlockZ; + + /** + * damage ranges from 1 to 10. -1 causes the client to delete the partial block + * renderer. + */ + private int partialBlockProgress; + + /** + * keeps track of how many ticks this PartiallyDestroyedBlock already exists + */ + private int createdAtCloudUpdateTick; + + public DestroyBlockProgress(int par1, int par2, int par3, int par4) { + this.miningPlayerEntId = par1; + this.partialBlockX = par2; + this.partialBlockY = par3; + this.partialBlockZ = par4; + } + + public int getPartialBlockX() { + return this.partialBlockX; + } + + public int getPartialBlockY() { + return this.partialBlockY; + } + + public int getPartialBlockZ() { + return this.partialBlockZ; + } + + /** + * inserts damage value into this partially destroyed Block. -1 causes client + * renderer to delete it, otherwise ranges from 1 to 10 + */ + public void setPartialBlockDamage(int par1) { + if (par1 > 10) { + par1 = 10; + } + + this.partialBlockProgress = par1; + } + + public int getPartialBlockDamage() { + return this.partialBlockProgress; + } + + /** + * saves the current Cloud update tick into the PartiallyDestroyedBlock + */ + public void setCloudUpdateTick(int par1) { + this.createdAtCloudUpdateTick = par1; + } + + /** + * retrieves the 'date' at which the PartiallyDestroyedBlock was created + */ + public int getCreationCloudUpdateTick() { + return this.createdAtCloudUpdateTick; + } +} diff --git a/src/main/java/net/minecraft/src/Direction.java b/src/main/java/net/minecraft/src/Direction.java new file mode 100644 index 0000000..a29945c --- /dev/null +++ b/src/main/java/net/minecraft/src/Direction.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +public class Direction { + public static final int[] offsetX = new int[] { 0, -1, 0, 1 }; + public static final int[] offsetZ = new int[] { 1, 0, -1, 0 }; + public static final String[] directions = new String[] { "SOUTH", "WEST", "NORTH", "EAST" }; + + /** Maps a Direction value (2D) to a Facing value (3D). */ + public static final int[] directionToFacing = new int[] { 3, 4, 2, 5 }; + + /** Maps a Facing value (3D) to a Direction value (2D). */ + public static final int[] facingToDirection = new int[] { -1, -1, 2, 0, 1, 3 }; + + /** Maps a direction to that opposite of it. */ + public static final int[] rotateOpposite = new int[] { 2, 3, 0, 1 }; + + /** Maps a direction to that to the right of it. */ + public static final int[] rotateRight = new int[] { 1, 2, 3, 0 }; + + /** Maps a direction to that to the left of it. */ + public static final int[] rotateLeft = new int[] { 3, 0, 1, 2 }; + public static final int[][] bedDirection = new int[][] { { 1, 0, 3, 2, 5, 4 }, { 1, 0, 5, 4, 2, 3 }, { 1, 0, 2, 3, 4, 5 }, { 1, 0, 4, 5, 3, 2 } }; + + /** + * Returns the movement direction from a velocity vector. + */ + public static int getMovementDirection(double par0, double par2) { + return MathHelper.abs((float) par0) > MathHelper.abs((float) par2) ? (par0 > 0.0D ? 1 : 3) : (par2 > 0.0D ? 2 : 0); + } +} diff --git a/src/main/java/net/minecraft/src/EffectRenderer.java b/src/main/java/net/minecraft/src/EffectRenderer.java new file mode 100644 index 0000000..36e771c --- /dev/null +++ b/src/main/java/net/minecraft/src/EffectRenderer.java @@ -0,0 +1,229 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EffectRenderer { + /** Reference to the World object. */ + protected World worldObj; + private List[] fxLayers = new List[4]; + private RenderEngine renderer; + + /** RNG. */ + private Random rand = new Random(); + + public EffectRenderer(World par1World, RenderEngine par2RenderEngine) { + if (par1World != null) { + this.worldObj = par1World; + } + + this.renderer = par2RenderEngine; + + for (int var3 = 0; var3 < 4; ++var3) { + this.fxLayers[var3] = new ArrayList(); + } + } + + public void addEffect(EntityFX par1EntityFX) { + int var2 = par1EntityFX.getFXLayer(); + + if (this.fxLayers[var2].size() >= 4000) { + this.fxLayers[var2].remove(0); + } + + this.fxLayers[var2].add(par1EntityFX); + } + + public void updateEffects() { + for (int var1 = 0; var1 < 4; ++var1) { + for (int var2 = 0; var2 < this.fxLayers[var1].size(); ++var2) { + EntityFX var3 = (EntityFX) this.fxLayers[var1].get(var2); + var3.onUpdate(); + + if (var3.isDead) { + this.fxLayers[var1].remove(var2--); + } + } + } + } + + private static final TextureLocation particles = new TextureLocation("/particles.png"); + private static final TextureLocation terrain = new TextureLocation("/terrain.png"); + private static final TextureLocation items = new TextureLocation("/gui/items.png"); + + /** + * Renders all current particles. Args player, partialTickTime + */ + public void renderParticles(Entity par1Entity, float par2) { + float var3 = ActiveRenderInfo.rotationX; + float var4 = ActiveRenderInfo.rotationZ; + float var5 = ActiveRenderInfo.rotationYZ; + float var6 = ActiveRenderInfo.rotationXY; + float var7 = ActiveRenderInfo.rotationXZ; + EntityFX.interpPosX = par1Entity.lastTickPosX + (par1Entity.posX - par1Entity.lastTickPosX) * (double) par2; + EntityFX.interpPosY = par1Entity.lastTickPosY + (par1Entity.posY - par1Entity.lastTickPosY) * (double) par2; + EntityFX.interpPosZ = par1Entity.lastTickPosZ + (par1Entity.posZ - par1Entity.lastTickPosZ) * (double) par2; + + for (int var8 = 0; var8 < 3; ++var8) { + if (!this.fxLayers[var8].isEmpty()) { + switch (var8) { + case 0: + default: + particles.bindTexture(); + break; + case 1: + terrain.bindTexture(); + break; + case 2: + items.bindTexture(); + break; + } + + Tessellator var9 = Tessellator.instance; + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + //EaglerAdapter.glDepthMask(false); + //EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + //EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glAlphaFunc(EaglerAdapter.GL_GREATER, 0.005F); + var9.startDrawingQuads(); + + for (int var10 = 0; var10 < this.fxLayers[var8].size(); ++var10) { + EntityFX var11 = (EntityFX) this.fxLayers[var8].get(var10); + if(var11.particleAlpha == 1.0F) { + var9.setBrightness(var11.getBrightnessForRender(par2)); + var11.renderParticle(var9, par2, var3, var7, var4, var5, var6); + } + } + + var9.draw(); + //EaglerAdapter.glDepthMask(true); + EaglerAdapter.glAlphaFunc(EaglerAdapter.GL_GREATER, 0.1F); + } + } + } + + public void renderTransparentParticles(Entity par1Entity, float par2) { + particles.bindTexture(); + float var3 = ActiveRenderInfo.rotationX; + float var4 = ActiveRenderInfo.rotationZ; + float var5 = ActiveRenderInfo.rotationYZ; + float var6 = ActiveRenderInfo.rotationXY; + float var7 = ActiveRenderInfo.rotationXZ; + + Tessellator var9 = Tessellator.instance; + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + //EaglerAdapter.glDepthMask(false); + var9.startDrawingQuads(); + + for (int var10 = 0; var10 < this.fxLayers[0].size(); ++var10) { + EntityFX var11 = (EntityFX) this.fxLayers[0].get(var10); + if(var11.particleAlpha != 1.0F) { + var9.setBrightness(var11.getBrightnessForRender(par2)); + var11.renderParticle(var9, par2, var3, var7, var4, var5, var6); + } + } + + var9.draw(); + //EaglerAdapter.glDepthMask(true); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + } + + public void renderLitParticles(Entity par1Entity, float par2) { + float var4 = MathHelper.cos(par1Entity.rotationYaw * 0.017453292F); + float var5 = MathHelper.sin(par1Entity.rotationYaw * 0.017453292F); + float var6 = -var5 * MathHelper.sin(par1Entity.rotationPitch * 0.017453292F); + float var7 = var4 * MathHelper.sin(par1Entity.rotationPitch * 0.017453292F); + float var8 = MathHelper.cos(par1Entity.rotationPitch * 0.017453292F); + byte var9 = 3; + + if (!this.fxLayers[var9].isEmpty()) { + Tessellator var10 = Tessellator.instance; + + for (int var11 = 0; var11 < this.fxLayers[var9].size(); ++var11) { + EntityFX var12 = (EntityFX) this.fxLayers[var9].get(var11); + var10.setBrightness(var12.getBrightnessForRender(par2)); + var12.renderParticle(var10, par2, var4, var8, var5, var6, var7); + } + } + } + + public void clearEffects(World par1World) { + this.worldObj = par1World; + + for (int var2 = 0; var2 < 4; ++var2) { + this.fxLayers[var2].clear(); + } + } + + public void addBlockDestroyEffects(int par1, int par2, int par3, int par4, int par5) { + if (par4 != 0) { + Block var6 = Block.blocksList[par4]; + byte var7 = 4; + + for (int var8 = 0; var8 < var7; ++var8) { + for (int var9 = 0; var9 < var7; ++var9) { + for (int var10 = 0; var10 < var7; ++var10) { + double var11 = (double) par1 + ((double) var8 + 0.5D) / (double) var7; + double var13 = (double) par2 + ((double) var9 + 0.5D) / (double) var7; + double var15 = (double) par3 + ((double) var10 + 0.5D) / (double) var7; + int var17 = this.rand.nextInt(6); + this.addEffect((new EntityDiggingFX(this.worldObj, var11, var13, var15, var11 - (double) par1 - 0.5D, var13 - (double) par2 - 0.5D, var15 - (double) par3 - 0.5D, var6, var17, par5, this.renderer)).func_70596_a(par1, + par2, par3)); + } + } + } + } + } + + /** + * Adds block hit particles for the specified block. Args: x, y, z, sideHit + */ + public void addBlockHitEffects(int par1, int par2, int par3, int par4) { + int var5 = this.worldObj.getBlockId(par1, par2, par3); + + if (var5 != 0) { + Block var6 = Block.blocksList[var5]; + float var7 = 0.1F; + double var8 = (double) par1 + this.rand.nextDouble() * (var6.getBlockBoundsMaxX() - var6.getBlockBoundsMinX() - (double) (var7 * 2.0F)) + (double) var7 + var6.getBlockBoundsMinX(); + double var10 = (double) par2 + this.rand.nextDouble() * (var6.getBlockBoundsMaxY() - var6.getBlockBoundsMinY() - (double) (var7 * 2.0F)) + (double) var7 + var6.getBlockBoundsMinY(); + double var12 = (double) par3 + this.rand.nextDouble() * (var6.getBlockBoundsMaxZ() - var6.getBlockBoundsMinZ() - (double) (var7 * 2.0F)) + (double) var7 + var6.getBlockBoundsMinZ(); + + if (par4 == 0) { + var10 = (double) par2 + var6.getBlockBoundsMinY() - (double) var7; + } + + if (par4 == 1) { + var10 = (double) par2 + var6.getBlockBoundsMaxY() + (double) var7; + } + + if (par4 == 2) { + var12 = (double) par3 + var6.getBlockBoundsMinZ() - (double) var7; + } + + if (par4 == 3) { + var12 = (double) par3 + var6.getBlockBoundsMaxZ() + (double) var7; + } + + if (par4 == 4) { + var8 = (double) par1 + var6.getBlockBoundsMinX() - (double) var7; + } + + if (par4 == 5) { + var8 = (double) par1 + var6.getBlockBoundsMaxX() + (double) var7; + } + + this.addEffect((new EntityDiggingFX(this.worldObj, var8, var10, var12, 0.0D, 0.0D, 0.0D, var6, par4, this.worldObj.getBlockMetadata(par1, par2, par3), this.renderer)).func_70596_a(par1, par2, par3).multiplyVelocity(0.2F) + .multipleParticleScaleBy(0.6F)); + } + } + + public String getStatistics() { + return "" + (this.fxLayers[0].size() + this.fxLayers[1].size() + this.fxLayers[2].size()); + } +} diff --git a/src/main/java/net/minecraft/src/Empty3.java b/src/main/java/net/minecraft/src/Empty3.java new file mode 100644 index 0000000..627955d --- /dev/null +++ b/src/main/java/net/minecraft/src/Empty3.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public class Empty3 { + +} diff --git a/src/main/java/net/minecraft/src/EmptyChunk.java b/src/main/java/net/minecraft/src/EmptyChunk.java new file mode 100644 index 0000000..1176069 --- /dev/null +++ b/src/main/java/net/minecraft/src/EmptyChunk.java @@ -0,0 +1,197 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class EmptyChunk extends Chunk { + public EmptyChunk(World par1World, int par2, int par3) { + super(par1World, par2, par3); + } + + /** + * Checks whether the chunk is at the X/Z location specified + */ + public boolean isAtLocation(int par1, int par2) { + return par1 == this.xPosition && par2 == this.zPosition; + } + + /** + * Returns the value in the height map at this x, z coordinate in the chunk + */ + public int getHeightValue(int par1, int par2) { + return 0; + } + + /** + * Generates the height map for a chunk from scratch + */ + public void generateHeightMap() { + } + + /** + * Generates the initial skylight map for the chunk upon generation or load. + */ + public void generateSkylightMap() { + } + + /** + * Return the ID of a block in the chunk. + */ + public int getBlockID(int par1, int par2, int par3) { + return 0; + } + + public int getBlockLightOpacity(int par1, int par2, int par3) { + return 255; + } + + /** + * Sets a blockID of a position within a chunk with metadata. Args: x, y, z, + * blockID, metadata + */ + public boolean setBlockIDWithMetadata(int par1, int par2, int par3, int par4, int par5) { + return true; + } + + /** + * Return the metadata corresponding to the given coordinates inside a chunk. + */ + public int getBlockMetadata(int par1, int par2, int par3) { + return 0; + } + + /** + * Set the metadata of a block in the chunk + */ + public boolean setBlockMetadata(int par1, int par2, int par3, int par4) { + return false; + } + + /** + * Gets the amount of light saved in this block (doesn't adjust for daylight) + */ + public int getSavedLightValue(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4) { + return 0; + } + + /** + * Sets the light value at the coordinate. If enumskyblock is set to sky it sets + * it in the skylightmap and if its a block then into the blocklightmap. Args + * enumSkyBlock, x, y, z, lightValue + */ + public void setLightValue(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4, int par5) { + } + + /** + * Gets the amount of light on a block taking into account sunlight + */ + public int getBlockLightValue(int par1, int par2, int par3, int par4) { + return 0; + } + + /** + * Adds an entity to the chunk. Args: entity + */ + public void addEntity(Entity par1Entity) { + } + + /** + * removes entity using its y chunk coordinate as its index + */ + public void removeEntity(Entity par1Entity) { + } + + /** + * Removes entity at the specified index from the entity array. + */ + public void removeEntityAtIndex(Entity par1Entity, int par2) { + } + + /** + * Returns whether is not a block above this one blocking sight to the sky (done + * via checking against the heightmap) + */ + public boolean canBlockSeeTheSky(int par1, int par2, int par3) { + return false; + } + + /** + * Gets the TileEntity for a given block in this chunk + */ + public TileEntity getChunkBlockTileEntity(int par1, int par2, int par3) { + return null; + } + + /** + * Adds a TileEntity to a chunk + */ + public void addTileEntity(TileEntity par1TileEntity) { + } + + /** + * Sets the TileEntity for a given block in this chunk + */ + public void setChunkBlockTileEntity(int par1, int par2, int par3, TileEntity par4TileEntity) { + } + + /** + * Removes the TileEntity for a given block in this chunk + */ + public void removeChunkBlockTileEntity(int par1, int par2, int par3) { + } + + /** + * Called when this Chunk is loaded by the ChunkProvider + */ + public void onChunkLoad() { + } + + /** + * Called when this Chunk is unloaded by the ChunkProvider + */ + public void onChunkUnload() { + } + + /** + * Sets the isModified flag for this Chunk + */ + public void setChunkModified() { + } + + /** + * Fills the given list of all entities that intersect within the given bounding + * box that aren't the passed entity Args: entity, aabb, listToFill + */ + public void getEntitiesWithinAABBForEntity(Entity par1Entity, AxisAlignedBB par2AxisAlignedBB, List par3List, IEntitySelector par4IEntitySelector) { + } + + /** + * Gets all entities that can be assigned to the specified class. Args: + * entityClass, aabb, listToFill + */ + public void getEntitiesOfTypeWithinAAAB(Class par1Class, AxisAlignedBB par2AxisAlignedBB, List par3List, IEntitySelector par4IEntitySelector) { + } + + /** + * Returns true if this Chunk needs to be saved + */ + public boolean needsSaving(boolean par1) { + return false; + } + + public Random getRandomWithSeed(long par1) { + return new Random(this.worldObj.getSeed() + (long) (this.xPosition * this.xPosition * 4987142) + (long) (this.xPosition * 5947611) + (long) (this.zPosition * this.zPosition) * 4392871L + (long) (this.zPosition * 389711) ^ par1); + } + + public boolean isEmpty() { + return true; + } + + /** + * Returns whether the ExtendedBlockStorages containing levels (in blocks) from + * arg 1 to arg 2 are fully empty (true) or not (false). + */ + public boolean getAreLevelsEmpty(int par1, int par2) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/Enchantment.java b/src/main/java/net/minecraft/src/Enchantment.java new file mode 100644 index 0000000..a99a812 --- /dev/null +++ b/src/main/java/net/minecraft/src/Enchantment.java @@ -0,0 +1,211 @@ +package net.minecraft.src; + +import java.util.ArrayList; + +public abstract class Enchantment { + public static final Enchantment[] enchantmentsList = new Enchantment[256]; + public static final Enchantment[] field_92090_c; + + /** Converts environmental damage to armour damage */ + public static final Enchantment protection = new EnchantmentProtection(0, 10, 0); + + /** Protection against fire */ + public static final Enchantment fireProtection = new EnchantmentProtection(1, 5, 1); + + /** Less fall damage */ + public static final Enchantment featherFalling = new EnchantmentProtection(2, 5, 2); + + /** Protection against explosions */ + public static final Enchantment blastProtection = new EnchantmentProtection(3, 2, 3); + + /** Protection against projectile entities (e.g. arrows) */ + public static final Enchantment projectileProtection = new EnchantmentProtection(4, 5, 4); + + /** + * Decreases the rate of air loss underwater; increases time between damage + * while suffocating + */ + public static final Enchantment respiration = new EnchantmentOxygen(5, 2); + + /** Increases underwater mining rate */ + public static final Enchantment aquaAffinity = new EnchantmentWaterWorker(6, 2); + public static final Enchantment thorns = new EnchantmentThorns(7, 1); + + /** Extra damage to mobs */ + public static final Enchantment sharpness = new EnchantmentDamage(16, 10, 0); + + /** Extra damage to zombies, zombie pigmen and skeletons */ + public static final Enchantment smite = new EnchantmentDamage(17, 5, 1); + + /** Extra damage to spiders, cave spiders and silverfish */ + public static final Enchantment baneOfArthropods = new EnchantmentDamage(18, 5, 2); + + /** Knocks mob and players backwards upon hit */ + public static final Enchantment knockback = new EnchantmentKnockback(19, 5); + + /** Lights mobs on fire */ + public static final Enchantment fireAspect = new EnchantmentFireAspect(20, 2); + + /** Mobs have a chance to drop more loot */ + public static final Enchantment looting = new EnchantmentLootBonus(21, 2, EnumEnchantmentType.weapon); + + /** Faster resource gathering while in use */ + public static final Enchantment efficiency = new EnchantmentDigging(32, 10); + + /** + * Blocks mined will drop themselves, even if it should drop something else + * (e.g. stone will drop stone, not cobblestone) + */ + public static final Enchantment silkTouch = new EnchantmentUntouching(33, 1); + + /** + * Sometimes, the tool's durability will not be spent when the tool is used + */ + public static final Enchantment unbreaking = new EnchantmentDurability(34, 5); + + /** Can multiply the drop rate of items from blocks */ + public static final Enchantment fortune = new EnchantmentLootBonus(35, 2, EnumEnchantmentType.digger); + + /** Power enchantment for bows, add's extra damage to arrows. */ + public static final Enchantment power = new EnchantmentArrowDamage(48, 10); + + /** + * Knockback enchantments for bows, the arrows will knockback the target when + * hit. + */ + public static final Enchantment punch = new EnchantmentArrowKnockback(49, 2); + + /** + * Flame enchantment for bows. Arrows fired by the bow will be on fire. Any + * target hit will also set on fire. + */ + public static final Enchantment flame = new EnchantmentArrowFire(50, 2); + + /** + * Infinity enchantment for bows. The bow will not consume arrows anymore, but + * will still required at least one arrow on inventory use the bow. + */ + public static final Enchantment infinity = new EnchantmentArrowInfinite(51, 1); + public final int effectId; + private final int weight; + + /** The EnumEnchantmentType given to this Enchantment. */ + public EnumEnchantmentType type; + + /** Used in localisation and stats. */ + protected String name; + + protected Enchantment(int par1, int par2, EnumEnchantmentType par3EnumEnchantmentType) { + this.effectId = par1; + this.weight = par2; + this.type = par3EnumEnchantmentType; + + if (enchantmentsList[par1] != null) { + throw new IllegalArgumentException("Duplicate enchantment id!"); + } else { + enchantmentsList[par1] = this; + } + } + + public int getWeight() { + return this.weight; + } + + /** + * Returns the minimum level that the enchantment can have. + */ + public int getMinLevel() { + return 1; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 1; + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 1 + par1 * 10; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return this.getMinEnchantability(par1) + 5; + } + + /** + * Calculates de damage protection of the enchantment based on level and damage + * source passed. + */ + public int calcModifierDamage(int par1, DamageSource par2DamageSource) { + return 0; + } + + /** + * Calculates de (magic) damage done by the enchantment on a living entity based + * on level and entity passed. + */ + public int calcModifierLiving(int par1, EntityLiving par2EntityLiving) { + return 0; + } + + /** + * Determines if the enchantment passed can be applyied together with this + * enchantment. + */ + public boolean canApplyTogether(Enchantment par1Enchantment) { + return this != par1Enchantment; + } + + /** + * Sets the enchantment name + */ + public Enchantment setName(String par1Str) { + this.name = par1Str; + return this; + } + + /** + * Return the name of key in translation table of this enchantment. + */ + public String getName() { + return "enchantment." + this.name; + } + + /** + * Returns the correct traslated name of the enchantment and the level in roman + * numbers. + */ + public String getTranslatedName(int par1) { + String var2 = StatCollector.translateToLocal(this.getName()); + return var2 + " " + StatCollector.translateToLocal("enchantment.level." + par1); + } + + public boolean canApply(ItemStack par1ItemStack) { + return this.type.canEnchantItem(par1ItemStack.getItem()); + } + + static { + ArrayList var0 = new ArrayList(); + Enchantment[] var1 = enchantmentsList; + int var2 = var1.length; + + for (int var3 = 0; var3 < var2; ++var3) { + Enchantment var4 = var1[var3]; + + if (var4 != null) { + var0.add(var4); + } + } + + field_92090_c = (Enchantment[]) var0.toArray(new Enchantment[0]); + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentArrowDamage.java b/src/main/java/net/minecraft/src/EnchantmentArrowDamage.java new file mode 100644 index 0000000..7fbacd4 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentArrowDamage.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentArrowDamage extends Enchantment { + public EnchantmentArrowDamage(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.bow); + this.setName("arrowDamage"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 1 + (par1 - 1) * 10; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return this.getMinEnchantability(par1) + 15; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 5; + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentArrowFire.java b/src/main/java/net/minecraft/src/EnchantmentArrowFire.java new file mode 100644 index 0000000..5c40c5d --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentArrowFire.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentArrowFire extends Enchantment { + public EnchantmentArrowFire(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.bow); + this.setName("arrowFire"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 20; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 1; + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentArrowInfinite.java b/src/main/java/net/minecraft/src/EnchantmentArrowInfinite.java new file mode 100644 index 0000000..9c09943 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentArrowInfinite.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentArrowInfinite extends Enchantment { + public EnchantmentArrowInfinite(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.bow); + this.setName("arrowInfinite"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 20; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 1; + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentArrowKnockback.java b/src/main/java/net/minecraft/src/EnchantmentArrowKnockback.java new file mode 100644 index 0000000..bfdf7cb --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentArrowKnockback.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentArrowKnockback extends Enchantment { + public EnchantmentArrowKnockback(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.bow); + this.setName("arrowKnockback"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 12 + (par1 - 1) * 20; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return this.getMinEnchantability(par1) + 25; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 2; + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentDamage.java b/src/main/java/net/minecraft/src/EnchantmentDamage.java new file mode 100644 index 0000000..773dc58 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentDamage.java @@ -0,0 +1,86 @@ +package net.minecraft.src; + +public class EnchantmentDamage extends Enchantment { + /** Holds the name to be translated of each protection type. */ + private static final String[] protectionName = new String[] { "all", "undead", "arthropods" }; + + /** + * Holds the base factor of enchantability needed to be able to use the enchant. + */ + private static final int[] baseEnchantability = new int[] { 1, 5, 5 }; + + /** + * Holds how much each level increased the enchantability factor to be able to + * use this enchant. + */ + private static final int[] levelEnchantability = new int[] { 11, 8, 8 }; + + /** + * Used on the formula of base enchantability, this is the 'window' factor of + * values to be able to use thing enchant. + */ + private static final int[] thresholdEnchantability = new int[] { 20, 20, 20 }; + + /** + * Defines the type of damage of the enchantment, 0 = all, 1 = undead, 3 = + * arthropods + */ + public final int damageType; + + public EnchantmentDamage(int par1, int par2, int par3) { + super(par1, par2, EnumEnchantmentType.weapon); + this.damageType = par3; + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return baseEnchantability[this.damageType] + (par1 - 1) * levelEnchantability[this.damageType]; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return this.getMinEnchantability(par1) + thresholdEnchantability[this.damageType]; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 5; + } + + /** + * Calculates de (magic) damage done by the enchantment on a living entity based + * on level and entity passed. + */ + public int calcModifierLiving(int par1, EntityLiving par2EntityLiving) { + return this.damageType == 0 ? MathHelper.floor_float((float) par1 * 2.75F) + : (this.damageType == 1 && par2EntityLiving.getCreatureAttribute() == EnumCreatureAttribute.UNDEAD ? MathHelper.floor_float((float) par1 * 4.5F) + : (this.damageType == 2 && par2EntityLiving.getCreatureAttribute() == EnumCreatureAttribute.ARTHROPOD ? MathHelper.floor_float((float) par1 * 4.5F) : 0)); + } + + /** + * Return the name of key in translation table of this enchantment. + */ + public String getName() { + return "enchantment.damage." + protectionName[this.damageType]; + } + + /** + * Determines if the enchantment passed can be applyied together with this + * enchantment. + */ + public boolean canApplyTogether(Enchantment par1Enchantment) { + return !(par1Enchantment instanceof EnchantmentDamage); + } + + public boolean canApply(ItemStack par1ItemStack) { + return par1ItemStack.getItem() instanceof ItemAxe ? true : super.canApply(par1ItemStack); + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentData.java b/src/main/java/net/minecraft/src/EnchantmentData.java new file mode 100644 index 0000000..f007f31 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentData.java @@ -0,0 +1,18 @@ +package net.minecraft.src; + +public class EnchantmentData { + /** Enchantment object associated with this EnchantmentData */ + public final Enchantment enchantmentobj; + + /** Enchantment level associated with this EnchantmentData */ + public final int enchantmentLevel; + + public EnchantmentData(Enchantment par1Enchantment, int par2) { + this.enchantmentobj = par1Enchantment; + this.enchantmentLevel = par2; + } + + public EnchantmentData(int par1, int par2) { + this(Enchantment.enchantmentsList[par1], par2); + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentDigging.java b/src/main/java/net/minecraft/src/EnchantmentDigging.java new file mode 100644 index 0000000..51384d8 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentDigging.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +public class EnchantmentDigging extends Enchantment { + protected EnchantmentDigging(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.digger); + this.setName("digging"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 1 + 10 * (par1 - 1); + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return super.getMinEnchantability(par1) + 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 5; + } + + public boolean canApply(ItemStack par1ItemStack) { + return par1ItemStack.getItem().itemID == Item.shears.itemID ? true : super.canApply(par1ItemStack); + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentDurability.java b/src/main/java/net/minecraft/src/EnchantmentDurability.java new file mode 100644 index 0000000..7d32681 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentDurability.java @@ -0,0 +1,48 @@ +package net.minecraft.src; + +import java.util.Random; + +public class EnchantmentDurability extends Enchantment { + protected EnchantmentDurability(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.digger); + this.setName("durability"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 5 + (par1 - 1) * 8; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return super.getMinEnchantability(par1) + 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 3; + } + + public boolean canApply(ItemStack par1ItemStack) { + return par1ItemStack.isItemStackDamageable() ? true : super.canApply(par1ItemStack); + } + + /** + * Used by ItemStack.attemptDamageItem. Randomly determines if a point of damage + * should be negated using the enchantment level (par1). If the ItemStack is + * Armor then there is a flat 60% chance for damage to be negated no matter the + * enchantment level, otherwise there is a 1-(par/1) chance for damage to be + * negated. + */ + public static boolean negateDamage(ItemStack par0ItemStack, int par1, Random par2Random) { + return par0ItemStack.getItem() instanceof ItemArmor && par2Random.nextFloat() < 0.6F ? false : par2Random.nextInt(par1 + 1) > 0; + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentFireAspect.java b/src/main/java/net/minecraft/src/EnchantmentFireAspect.java new file mode 100644 index 0000000..df46f88 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentFireAspect.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentFireAspect extends Enchantment { + protected EnchantmentFireAspect(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.weapon); + this.setName("fire"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 10 + 20 * (par1 - 1); + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return super.getMinEnchantability(par1) + 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 2; + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentHelper.java b/src/main/java/net/minecraft/src/EnchantmentHelper.java new file mode 100644 index 0000000..6f3f225 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentHelper.java @@ -0,0 +1,350 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + + + +public class EnchantmentHelper { + /** Is the random seed of enchantment effects. */ + private static final Random enchantmentRand = new Random(); + + /** + * Used to calculate the extra armor of enchantments on armors equipped on + * player. + */ + private static final EnchantmentModifierDamage enchantmentModifierDamage = new EnchantmentModifierDamage((Empty3) null); + + /** + * Used to calculate the (magic) extra damage done by enchantments on current + * equipped item of player. + */ + private static final EnchantmentModifierLiving enchantmentModifierLiving = new EnchantmentModifierLiving((Empty3) null); + + /** + * Returns the level of enchantment on the ItemStack passed. + */ + public static int getEnchantmentLevel(int par0, ItemStack par1ItemStack) { + if (par1ItemStack == null) { + return 0; + } else { + NBTTagList var2 = par1ItemStack.getEnchantmentTagList(); + + if (var2 == null) { + return 0; + } else { + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + short var4 = ((NBTTagCompound) var2.tagAt(var3)).getShort("id"); + short var5 = ((NBTTagCompound) var2.tagAt(var3)).getShort("lvl"); + + if (var4 == par0) { + return var5; + } + } + + return 0; + } + } + } + + /** + * Return the enchantments for the specified stack. + */ + public static Map getEnchantments(ItemStack par0ItemStack) { + LinkedHashMap var1 = new LinkedHashMap(); + NBTTagList var2 = par0ItemStack.itemID == Item.enchantedBook.itemID ? Item.enchantedBook.func_92110_g(par0ItemStack) : par0ItemStack.getEnchantmentTagList(); + + if (var2 != null) { + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + short var4 = ((NBTTagCompound) var2.tagAt(var3)).getShort("id"); + short var5 = ((NBTTagCompound) var2.tagAt(var3)).getShort("lvl"); + var1.put(Integer.valueOf(var4), Integer.valueOf(var5)); + } + } + + return var1; + } + + /** + * Set the enchantments for the specified stack. + */ + public static void setEnchantments(Map par0Map, ItemStack par1ItemStack) { + NBTTagList var2 = new NBTTagList(); + Iterator var3 = par0Map.keySet().iterator(); + + while (var3.hasNext()) { + int var4 = ((Integer) var3.next()).intValue(); + NBTTagCompound var5 = new NBTTagCompound(); + var5.setShort("id", (short) var4); + var5.setShort("lvl", (short) ((Integer) par0Map.get(Integer.valueOf(var4))).intValue()); + var2.appendTag(var5); + + if (par1ItemStack.itemID == Item.enchantedBook.itemID) { + Item.enchantedBook.func_92115_a(par1ItemStack, new EnchantmentData(var4, ((Integer) par0Map.get(Integer.valueOf(var4))).intValue())); + } + } + + if (var2.tagCount() > 0) { + if (par1ItemStack.itemID != Item.enchantedBook.itemID) { + par1ItemStack.setTagInfo("ench", var2); + } + } else if (par1ItemStack.hasTagCompound()) { + par1ItemStack.getTagCompound().removeTag("ench"); + } + } + + /** + * Returns the biggest level of the enchantment on the array of ItemStack + * passed. + */ + public static int getMaxEnchantmentLevel(int par0, ItemStack[] par1ArrayOfItemStack) { + if (par1ArrayOfItemStack == null) { + return 0; + } else { + int var2 = 0; + ItemStack[] var3 = par1ArrayOfItemStack; + int var4 = par1ArrayOfItemStack.length; + + for (int var5 = 0; var5 < var4; ++var5) { + ItemStack var6 = var3[var5]; + int var7 = getEnchantmentLevel(par0, var6); + + if (var7 > var2) { + var2 = var7; + } + } + + return var2; + } + } + + /** + * Executes the enchantment modifier on the ItemStack passed. + */ + private static void applyEnchantmentModifier(IEnchantmentModifier par0IEnchantmentModifier, ItemStack par1ItemStack) { + if (par1ItemStack != null) { + NBTTagList var2 = par1ItemStack.getEnchantmentTagList(); + + if (var2 != null) { + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + short var4 = ((NBTTagCompound) var2.tagAt(var3)).getShort("id"); + short var5 = ((NBTTagCompound) var2.tagAt(var3)).getShort("lvl"); + + if (Enchantment.enchantmentsList[var4] != null) { + par0IEnchantmentModifier.calculateModifier(Enchantment.enchantmentsList[var4], var5); + } + } + } + } + } + + /** + * Executes the enchantment modifier on the array of ItemStack passed. + */ + private static void applyEnchantmentModifierArray(IEnchantmentModifier par0IEnchantmentModifier, ItemStack[] par1ArrayOfItemStack) { + ItemStack[] var2 = par1ArrayOfItemStack; + int var3 = par1ArrayOfItemStack.length; + + for (int var4 = 0; var4 < var3; ++var4) { + ItemStack var5 = var2[var4]; + applyEnchantmentModifier(par0IEnchantmentModifier, var5); + } + } + + /** + * Returns the modifier of protection enchantments on armors equipped on player. + */ + public static int getEnchantmentModifierDamage(ItemStack[] par0ArrayOfItemStack, DamageSource par1DamageSource) { + enchantmentModifierDamage.damageModifier = 0; + enchantmentModifierDamage.source = par1DamageSource; + applyEnchantmentModifierArray(enchantmentModifierDamage, par0ArrayOfItemStack); + + if (enchantmentModifierDamage.damageModifier > 25) { + enchantmentModifierDamage.damageModifier = 25; + } + + return (enchantmentModifierDamage.damageModifier + 1 >> 1) + enchantmentRand.nextInt((enchantmentModifierDamage.damageModifier >> 1) + 1); + } + + /** + * Return the (magic) extra damage of the enchantments on player equipped item. + */ + public static int getEnchantmentModifierLiving(EntityLiving par0EntityLiving, EntityLiving par1EntityLiving) { + enchantmentModifierLiving.livingModifier = 0; + enchantmentModifierLiving.entityLiving = par1EntityLiving; + applyEnchantmentModifier(enchantmentModifierLiving, par0EntityLiving.getHeldItem()); + return enchantmentModifierLiving.livingModifier > 0 ? 1 + enchantmentRand.nextInt(enchantmentModifierLiving.livingModifier) : 0; + } + + /** + * Returns the knockback value of enchantments on equipped player item. + */ + public static int getKnockbackModifier(EntityLiving par0EntityLiving, EntityLiving par1EntityLiving) { + return getEnchantmentLevel(Enchantment.knockback.effectId, par0EntityLiving.getHeldItem()); + } + + public static int getFireAspectModifier(EntityLiving par0EntityLiving) { + return getEnchantmentLevel(Enchantment.fireAspect.effectId, par0EntityLiving.getHeldItem()); + } + + /** + * Returns the 'Water Breathing' modifier of enchantments on player equipped + * armors. + */ + public static int getRespiration(EntityLiving par0EntityLiving) { + return getMaxEnchantmentLevel(Enchantment.respiration.effectId, par0EntityLiving.getLastActiveItems()); + } + + /** + * Return the extra efficiency of tools based on enchantments on equipped player + * item. + */ + public static int getEfficiencyModifier(EntityLiving par0EntityLiving) { + return getEnchantmentLevel(Enchantment.efficiency.effectId, par0EntityLiving.getHeldItem()); + } + + /** + * Returns the silk touch status of enchantments on current equipped item of + * player. + */ + public static boolean getSilkTouchModifier(EntityLiving par0EntityLiving) { + return getEnchantmentLevel(Enchantment.silkTouch.effectId, par0EntityLiving.getHeldItem()) > 0; + } + + /** + * Returns the fortune enchantment modifier of the current equipped item of + * player. + */ + public static int getFortuneModifier(EntityLiving par0EntityLiving) { + return getEnchantmentLevel(Enchantment.fortune.effectId, par0EntityLiving.getHeldItem()); + } + + /** + * Returns the looting enchantment modifier of the current equipped item of + * player. + */ + public static int getLootingModifier(EntityLiving par0EntityLiving) { + return getEnchantmentLevel(Enchantment.looting.effectId, par0EntityLiving.getHeldItem()); + } + + /** + * Returns the aqua affinity status of enchantments on current equipped item of + * player. + */ + public static boolean getAquaAffinityModifier(EntityLiving par0EntityLiving) { + return getMaxEnchantmentLevel(Enchantment.aquaAffinity.effectId, par0EntityLiving.getLastActiveItems()) > 0; + } + + public static int func_92098_i(EntityLiving par0EntityLiving) { + return getMaxEnchantmentLevel(Enchantment.thorns.effectId, par0EntityLiving.getLastActiveItems()); + } + + public static ItemStack func_92099_a(Enchantment par0Enchantment, EntityLiving par1EntityLiving) { + ItemStack[] var2 = par1EntityLiving.getLastActiveItems(); + int var3 = var2.length; + + for (int var4 = 0; var4 < var3; ++var4) { + ItemStack var5 = var2[var4]; + + if (var5 != null && getEnchantmentLevel(par0Enchantment.effectId, var5) > 0) { + return var5; + } + } + + return null; + } + + /** + * Returns the enchantability of itemstack, it's uses a singular formula for + * each index (2nd parameter: 0, 1 and 2), cutting to the max enchantability + * power of the table (3rd parameter) + */ + public static int calcItemStackEnchantability(Random par0Random, int par1, int par2, ItemStack par3ItemStack) { + Item var4 = par3ItemStack.getItem(); + int var5 = var4.getItemEnchantability(); + + if (var5 <= 0) { + return 0; + } else { + if (par2 > 15) { + par2 = 15; + } + + int var6 = par0Random.nextInt(8) + 1 + (par2 >> 1) + par0Random.nextInt(par2 + 1); + return par1 == 0 ? Math.max(var6 / 3, 1) : (par1 == 1 ? var6 * 2 / 3 + 1 : Math.max(var6, par2 * 2)); + } + } + + /** + * Adds a random enchantment to the specified item. Args: random, itemStack, + * enchantabilityLevel + */ + public static ItemStack addRandomEnchantment(Random par0Random, ItemStack par1ItemStack, int par2) { + List var3 = buildEnchantmentList(par0Random, par1ItemStack, par2); + boolean var4 = par1ItemStack.itemID == Item.book.itemID; + + if (var4) { + par1ItemStack.itemID = Item.enchantedBook.itemID; + } + + if (var3 != null) { + Iterator var5 = var3.iterator(); + + while (var5.hasNext()) { + EnchantmentData var6 = (EnchantmentData) var5.next(); + + if (var4) { + Item.enchantedBook.func_92115_a(par1ItemStack, var6); + } else { + par1ItemStack.addEnchantment(var6.enchantmentobj, var6.enchantmentLevel); + } + } + } + + return par1ItemStack; + } + + /** + * Create a list of random EnchantmentData (enchantments) that can be added + * together to the ItemStack, the 3rd parameter is the total enchantability + * level. + */ + public static List buildEnchantmentList(Random par0Random, ItemStack par1ItemStack, int par2) { + return new ArrayList(); + } + + /** + * Creates a 'Map' of EnchantmentData (enchantments) possible to add on the + * ItemStack and the enchantability level passed. + */ + public static Map mapEnchantmentData(int par0, ItemStack par1ItemStack) { + Item var2 = par1ItemStack.getItem(); + HashMap var3 = null; + boolean var4 = par1ItemStack.itemID == Item.book.itemID; + Enchantment[] var5 = Enchantment.enchantmentsList; + int var6 = var5.length; + + for (int var7 = 0; var7 < var6; ++var7) { + Enchantment var8 = var5[var7]; + + if (var8 != null && (var8.type.canEnchantItem(var2) || var4)) { + for (int var9 = var8.getMinLevel(); var9 <= var8.getMaxLevel(); ++var9) { + if (par0 >= var8.getMinEnchantability(var9) && par0 <= var8.getMaxEnchantability(var9)) { + if (var3 == null) { + var3 = new HashMap(); + } + + var3.put(Integer.valueOf(var8.effectId), new EnchantmentData(var8, var9)); + } + } + } + } + + return var3; + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentKnockback.java b/src/main/java/net/minecraft/src/EnchantmentKnockback.java new file mode 100644 index 0000000..0c5550b --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentKnockback.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentKnockback extends Enchantment { + protected EnchantmentKnockback(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.weapon); + this.setName("knockback"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 5 + 20 * (par1 - 1); + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return super.getMinEnchantability(par1) + 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 2; + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentLootBonus.java b/src/main/java/net/minecraft/src/EnchantmentLootBonus.java new file mode 100644 index 0000000..3eafeb1 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentLootBonus.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +public class EnchantmentLootBonus extends Enchantment { + protected EnchantmentLootBonus(int par1, int par2, EnumEnchantmentType par3EnumEnchantmentType) { + super(par1, par2, par3EnumEnchantmentType); + this.setName("lootBonus"); + + if (par3EnumEnchantmentType == EnumEnchantmentType.digger) { + this.setName("lootBonusDigger"); + } + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 15 + (par1 - 1) * 9; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return super.getMinEnchantability(par1) + 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 3; + } + + /** + * Determines if the enchantment passed can be applyied together with this + * enchantment. + */ + public boolean canApplyTogether(Enchantment par1Enchantment) { + return super.canApplyTogether(par1Enchantment) && par1Enchantment.effectId != silkTouch.effectId; + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentModifierDamage.java b/src/main/java/net/minecraft/src/EnchantmentModifierDamage.java new file mode 100644 index 0000000..67071f0 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentModifierDamage.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +final class EnchantmentModifierDamage implements IEnchantmentModifier { + /** + * Used to calculate the damage modifier (extra armor) on enchantments that the + * player have on equipped armors. + */ + public int damageModifier; + + /** + * Used as parameter to calculate the damage modifier (extra armor) on + * enchantments that the player have on equipped armors. + */ + public DamageSource source; + + private EnchantmentModifierDamage() { + } + + /** + * Generic method use to calculate modifiers of offensive or defensive + * enchantment values. + */ + public void calculateModifier(Enchantment par1Enchantment, int par2) { + this.damageModifier += par1Enchantment.calcModifierDamage(par2, this.source); + } + + EnchantmentModifierDamage(Empty3 par1Empty3) { + this(); + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentModifierLiving.java b/src/main/java/net/minecraft/src/EnchantmentModifierLiving.java new file mode 100644 index 0000000..386f22d --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentModifierLiving.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +final class EnchantmentModifierLiving implements IEnchantmentModifier { + /** + * Used to calculate the (magic) extra damage based on enchantments of current + * equipped player item. + */ + public int livingModifier; + + /** + * Used as parameter to calculate the (magic) extra damage based on enchantments + * of current equipped player item. + */ + public EntityLiving entityLiving; + + private EnchantmentModifierLiving() { + } + + /** + * Generic method use to calculate modifiers of offensive or defensive + * enchantment values. + */ + public void calculateModifier(Enchantment par1Enchantment, int par2) { + this.livingModifier += par1Enchantment.calcModifierLiving(par2, this.entityLiving); + } + + EnchantmentModifierLiving(Empty3 par1Empty3) { + this(); + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentNameParts.java b/src/main/java/net/minecraft/src/EnchantmentNameParts.java new file mode 100644 index 0000000..b0a0585 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentNameParts.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + +import java.util.Random; + +public class EnchantmentNameParts { + /** The static instance of this class. */ + public static final EnchantmentNameParts instance = new EnchantmentNameParts(); + + /** The RNG used to generate enchant names. */ + private Random rand = new Random(); + + /** List of words used to generate an enchant name. */ + private String[] wordList = "the elder scrolls klaatu berata niktu xyzzy bless curse light darkness fire air earth water hot dry cold wet ignite snuff embiggen twist shorten stretch fiddle destroy imbue galvanize enchant free limited range of towards inside sphere cube self other ball mental physical grow shrink demon elemental spirit animal creature beast humanoid undead fresh stale " + .split(" "); + + /** + * Generates a random enchant name. + */ + public String generateRandomEnchantName() { + int var1 = this.rand.nextInt(2) + 3; + String var2 = ""; + + for (int var3 = 0; var3 < var1; ++var3) { + if (var3 > 0) { + var2 = var2 + " "; + } + + var2 = var2 + this.wordList[this.rand.nextInt(this.wordList.length)]; + } + + return var2; + } + + /** + * Sets the seed for the enchant name RNG. + */ + public void setRandSeed(long par1) { + this.rand.setSeed(par1); + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentOxygen.java b/src/main/java/net/minecraft/src/EnchantmentOxygen.java new file mode 100644 index 0000000..f4e6aa7 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentOxygen.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentOxygen extends Enchantment { + public EnchantmentOxygen(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.armor_head); + this.setName("oxygen"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 10 * par1; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return this.getMinEnchantability(par1) + 30; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 3; + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentProtection.java b/src/main/java/net/minecraft/src/EnchantmentProtection.java new file mode 100644 index 0000000..9324862 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentProtection.java @@ -0,0 +1,118 @@ +package net.minecraft.src; + +public class EnchantmentProtection extends Enchantment { + /** Holds the name to be translated of each protection type. */ + private static final String[] protectionName = new String[] { "all", "fire", "fall", "explosion", "projectile" }; + + /** + * Holds the base factor of enchantability needed to be able to use the enchant. + */ + private static final int[] baseEnchantability = new int[] { 1, 10, 5, 5, 3 }; + + /** + * Holds how much each level increased the enchantability factor to be able to + * use this enchant. + */ + private static final int[] levelEnchantability = new int[] { 11, 8, 6, 8, 6 }; + + /** + * Used on the formula of base enchantability, this is the 'window' factor of + * values to be able to use thing enchant. + */ + private static final int[] thresholdEnchantability = new int[] { 20, 12, 10, 12, 15 }; + + /** + * Defines the type of protection of the enchantment, 0 = all, 1 = fire, 2 = + * fall (feather fall), 3 = explosion and 4 = projectile. + */ + public final int protectionType; + + public EnchantmentProtection(int par1, int par2, int par3) { + super(par1, par2, EnumEnchantmentType.armor); + this.protectionType = par3; + + if (par3 == 2) { + this.type = EnumEnchantmentType.armor_feet; + } + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return baseEnchantability[this.protectionType] + (par1 - 1) * levelEnchantability[this.protectionType]; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return this.getMinEnchantability(par1) + thresholdEnchantability[this.protectionType]; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 4; + } + + /** + * Calculates de damage protection of the enchantment based on level and damage + * source passed. + */ + public int calcModifierDamage(int par1, DamageSource par2DamageSource) { + if (par2DamageSource.canHarmInCreative()) { + return 0; + } else { + float var3 = (float) (6 + par1 * par1) / 3.0F; + return this.protectionType == 0 ? MathHelper.floor_float(var3 * 0.75F) + : (this.protectionType == 1 && par2DamageSource.isFireDamage() ? MathHelper.floor_float(var3 * 1.25F) + : (this.protectionType == 2 && par2DamageSource == DamageSource.fall ? MathHelper.floor_float(var3 * 2.5F) + : (this.protectionType == 3 && par2DamageSource.isExplosion() ? MathHelper.floor_float(var3 * 1.5F) + : (this.protectionType == 4 && par2DamageSource.isProjectile() ? MathHelper.floor_float(var3 * 1.5F) : 0)))); + } + } + + /** + * Return the name of key in translation table of this enchantment. + */ + public String getName() { + return "enchantment.protect." + protectionName[this.protectionType]; + } + + /** + * Determines if the enchantment passed can be applyied together with this + * enchantment. + */ + public boolean canApplyTogether(Enchantment par1Enchantment) { + if (par1Enchantment instanceof EnchantmentProtection) { + EnchantmentProtection var2 = (EnchantmentProtection) par1Enchantment; + return var2.protectionType == this.protectionType ? false : this.protectionType == 2 || var2.protectionType == 2; + } else { + return super.canApplyTogether(par1Enchantment); + } + } + + public static int func_92093_a(Entity par0Entity, int par1) { + int var2 = EnchantmentHelper.getMaxEnchantmentLevel(Enchantment.fireProtection.effectId, par0Entity.getLastActiveItems()); + + if (var2 > 0) { + par1 -= MathHelper.floor_float((float) par1 * (float) var2 * 0.15F); + } + + return par1; + } + + public static double func_92092_a(Entity par0Entity, double par1) { + int var3 = EnchantmentHelper.getMaxEnchantmentLevel(Enchantment.blastProtection.effectId, par0Entity.getLastActiveItems()); + + if (var3 > 0) { + par1 -= (double) MathHelper.floor_double(par1 * (double) ((float) var3 * 0.15F)); + } + + return par1; + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentThorns.java b/src/main/java/net/minecraft/src/EnchantmentThorns.java new file mode 100644 index 0000000..78013b7 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentThorns.java @@ -0,0 +1,61 @@ +package net.minecraft.src; + +import java.util.Random; + +public class EnchantmentThorns extends Enchantment { + public EnchantmentThorns(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.armor_torso); + this.setName("thorns"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 10 + 20 * (par1 - 1); + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return super.getMinEnchantability(par1) + 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 3; + } + + public boolean canApply(ItemStack par1ItemStack) { + return par1ItemStack.getItem() instanceof ItemArmor ? true : super.canApply(par1ItemStack); + } + + public static boolean func_92094_a(int par0, Random par1Random) { + return par0 <= 0 ? false : par1Random.nextFloat() < 0.15F * (float) par0; + } + + public static int func_92095_b(int par0, Random par1Random) { + return par0 > 10 ? par0 - 10 : 1 + par1Random.nextInt(4); + } + + public static void func_92096_a(Entity par0Entity, EntityLiving par1EntityLiving, Random par2Random) { + int var3 = EnchantmentHelper.func_92098_i(par1EntityLiving); + ItemStack var4 = EnchantmentHelper.func_92099_a(Enchantment.thorns, par1EntityLiving); + + if (func_92094_a(var3, par2Random)) { + par0Entity.attackEntityFrom(DamageSource.causeThornsDamage(par1EntityLiving), func_92095_b(var3, par2Random)); + par0Entity.playSound("damage.thorns", 0.5F, 1.0F); + + if (var4 != null) { + var4.damageItem(3, par1EntityLiving); + } + } else if (var4 != null) { + var4.damageItem(1, par1EntityLiving); + } + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentUntouching.java b/src/main/java/net/minecraft/src/EnchantmentUntouching.java new file mode 100644 index 0000000..9d8c8b9 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentUntouching.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +public class EnchantmentUntouching extends Enchantment { + protected EnchantmentUntouching(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.digger); + this.setName("untouching"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 15; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return super.getMinEnchantability(par1) + 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 1; + } + + /** + * Determines if the enchantment passed can be applyied together with this + * enchantment. + */ + public boolean canApplyTogether(Enchantment par1Enchantment) { + return super.canApplyTogether(par1Enchantment) && par1Enchantment.effectId != fortune.effectId; + } + + public boolean canApply(ItemStack par1ItemStack) { + return par1ItemStack.getItem().itemID == Item.shears.itemID ? true : super.canApply(par1ItemStack); + } +} diff --git a/src/main/java/net/minecraft/src/EnchantmentWaterWorker.java b/src/main/java/net/minecraft/src/EnchantmentWaterWorker.java new file mode 100644 index 0000000..94faea5 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnchantmentWaterWorker.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentWaterWorker extends Enchantment { + public EnchantmentWaterWorker(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.armor_head); + this.setName("waterWorker"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 1; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return this.getMinEnchantability(par1) + 40; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 1; + } +} diff --git a/src/main/java/net/minecraft/src/Entity.java b/src/main/java/net/minecraft/src/Entity.java new file mode 100644 index 0000000..5e13afe --- /dev/null +++ b/src/main/java/net/minecraft/src/Entity.java @@ -0,0 +1,1995 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + + + +public abstract class Entity { + private static int nextEntityID = 0; + public int entityId; + public double renderDistanceWeight; + + /** + * Blocks entities from spawning when they do their AABB check to make sure the + * spot is clear of entities that can prevent spawning. + */ + public boolean preventEntitySpawning; + + /** The entity that is riding this entity */ + public Entity riddenByEntity; + + /** The entity we are currently riding */ + public Entity ridingEntity; + public boolean field_98038_p; + + /** Reference to the World object. */ + public World worldObj; + public double prevPosX; + public double prevPosY; + public double prevPosZ; + + /** Entity position X */ + public double posX; + + /** Entity position Y */ + public double posY; + + /** Entity position Z */ + public double posZ; + + /** Entity motion X */ + public double motionX; + + /** Entity motion Y */ + public double motionY; + + /** Entity motion Z */ + public double motionZ; + + /** Entity rotation Yaw */ + public float rotationYaw; + + /** Entity rotation Pitch */ + public float rotationPitch; + public float prevRotationYaw; + public float prevRotationPitch; + + /** Axis aligned bounding box. */ + public final AxisAlignedBB boundingBox; + public boolean onGround; + + /** + * True if after a move this entity has collided with something on X- or Z-axis + */ + public boolean isCollidedHorizontally; + + /** + * True if after a move this entity has collided with something on Y-axis + */ + public boolean isCollidedVertically; + + /** + * True if after a move this entity has collided with something either + * vertically or horizontally + */ + public boolean isCollided; + public boolean velocityChanged; + protected boolean isInWeb; + public boolean field_70135_K; + + /** + * Gets set by setDead, so this must be the flag whether an Entity is dead + * (inactive may be better term) + */ + public boolean isDead; + public float yOffset; + + /** How wide this entity is considered to be */ + public float width; + + /** How high this entity is considered to be */ + public float height; + + /** The previous ticks distance walked multiplied by 0.6 */ + public float prevDistanceWalkedModified; + + /** The distance walked multiplied by 0.6 */ + public float distanceWalkedModified; + public float distanceWalkedOnStepModified; + public float fallDistance; + + /** + * The distance that has to be exceeded in order to triger a new step sound and + * an onEntityWalking event on a block + */ + private int nextStepDistance; + + /** + * The entity's X coordinate at the previous tick, used to calculate position + * during rendering routines + */ + public double lastTickPosX; + + /** + * The entity's Y coordinate at the previous tick, used to calculate position + * during rendering routines + */ + public double lastTickPosY; + + /** + * The entity's Z coordinate at the previous tick, used to calculate position + * during rendering routines + */ + public double lastTickPosZ; + public float ySize; + + /** + * How high this entity can step up when running into a block to try to get over + * it (currently make note the entity will always step up this amount and not + * just the amount needed) + */ + public float stepHeight; + + /** + * Whether this entity won't clip with collision or not (make note it won't + * disable gravity) + */ + public boolean noClip; + + /** + * Reduces the velocity applied by entity collisions by the specified percent. + */ + public float entityCollisionReduction; + protected Random rand; + + /** How many ticks has this entity had ran since being alive */ + public int ticksExisted; + + /** + * The amount of ticks you have to stand inside of fire before be set on fire + */ + public int fireResistance; + private int fire; + + /** + * Whether this entity is currently inside of water (if it handles water + * movement that is) + */ + protected boolean inWater; + + /** + * Remaining time an entity will be "immune" to further damage after being hurt. + */ + public int hurtResistantTime; + private boolean firstUpdate; + + protected boolean isImmuneToFire; + protected DataWatcher dataWatcher; + private double entityRiderPitchDelta; + private double entityRiderYawDelta; + + /** Has this entity been added to the chunk its within */ + public boolean addedToChunk; + public int chunkCoordX; + public int chunkCoordY; + public int chunkCoordZ; + public int serverPosX; + public int serverPosY; + public int serverPosZ; + + /** + * Render entity even if it is outside the camera frustum. Only true in + * EntityFish for now. Used in RenderGlobal: render if ignoreFrustumCheck or in + * frustum. + */ + public boolean ignoreFrustumCheck; + public boolean isAirBorne; + public int timeUntilPortal; + + /** Whether the entity is inside a Portal */ + protected boolean inPortal; + protected int field_82153_h; + + /** Which dimension the player is in (-1 = the Nether, 0 = normal world) */ + public int dimension; + protected int teleportDirection; + private boolean invulnerable; + public EnumEntitySize myEntitySize; + + public Entity() { + this.entityId = nextEntityID++; + this.renderDistanceWeight = 1.0D; + this.preventEntitySpawning = false; + this.boundingBox = AxisAlignedBB.getBoundingBox(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D); + this.onGround = false; + this.isCollided = false; + this.velocityChanged = false; + this.field_70135_K = true; + this.isDead = false; + this.yOffset = 0.0F; + this.width = 0.6F; + this.height = 1.8F; + this.prevDistanceWalkedModified = 0.0F; + this.distanceWalkedModified = 0.0F; + this.distanceWalkedOnStepModified = 0.0F; + this.fallDistance = 0.0F; + this.nextStepDistance = 1; + this.ySize = 0.0F; + this.stepHeight = 0.0F; + this.noClip = false; + this.entityCollisionReduction = 0.0F; + this.rand = new Random(); + this.ticksExisted = 0; + this.fireResistance = 1; + this.fire = 0; + this.inWater = false; + this.hurtResistantTime = 0; + this.firstUpdate = true; + this.isImmuneToFire = false; + this.dataWatcher = new DataWatcher(); + this.addedToChunk = false; + this.teleportDirection = 0; + this.invulnerable = false; + this.myEntitySize = EnumEntitySize.SIZE_2; + this.setPosition(0.0D, 0.0D, 0.0D); + this.dataWatcher.addObject(0, Byte.valueOf((byte) 0)); + this.dataWatcher.addObject(1, Short.valueOf((short) 300)); + this.entityInit(); + } + + protected abstract void entityInit(); + + public DataWatcher getDataWatcher() { + return this.dataWatcher; + } + + public boolean equals(Object par1Obj) { + return par1Obj instanceof Entity ? ((Entity) par1Obj).entityId == this.entityId : false; + } + + public int hashCode() { + return this.entityId; + } + + /** + * Keeps moving the entity up so it isn't colliding with blocks and other + * requirements for this entity to be spawned (only actually used on players + * though its also on Entity) + */ + protected void preparePlayerToSpawn() { + if (this.worldObj != null) { + while (this.posY > 0.0D) { + this.setPosition(this.posX, this.posY, this.posZ); + + if (this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty()) { + break; + } + + ++this.posY; + } + + this.motionX = this.motionY = this.motionZ = 0.0D; + this.rotationPitch = 0.0F; + } + } + + /** + * Will get destroyed next tick. + */ + public void setDead() { + this.isDead = true; + } + + /** + * Sets the width and height of the entity. Args: width, height + */ + protected void setSize(float par1, float par2) { + if (par1 != this.width || par2 != this.height) { + this.width = par1; + this.height = par2; + this.boundingBox.maxX = this.boundingBox.minX + (double) this.width; + this.boundingBox.maxZ = this.boundingBox.minZ + (double) this.width; + this.boundingBox.maxY = this.boundingBox.minY + (double) this.height; + } + + float var3 = par1 % 2.0F; + + if ((double) var3 < 0.375D) { + this.myEntitySize = EnumEntitySize.SIZE_1; + } else if ((double) var3 < 0.75D) { + this.myEntitySize = EnumEntitySize.SIZE_2; + } else if ((double) var3 < 1.0D) { + this.myEntitySize = EnumEntitySize.SIZE_3; + } else if ((double) var3 < 1.375D) { + this.myEntitySize = EnumEntitySize.SIZE_4; + } else if ((double) var3 < 1.75D) { + this.myEntitySize = EnumEntitySize.SIZE_5; + } else { + this.myEntitySize = EnumEntitySize.SIZE_6; + } + } + + /** + * Sets the rotation of the entity + */ + protected void setRotation(float par1, float par2) { + this.rotationYaw = par1 % 360.0F; + this.rotationPitch = par2 % 360.0F; + } + + /** + * Sets the x,y,z of the entity from the given parameters. Also seems to set up + * a bounding box. + */ + public void setPosition(double par1, double par3, double par5) { + this.posX = par1; + this.posY = par3; + this.posZ = par5; + float var7 = this.width / 2.0F; + float var8 = this.height; + this.boundingBox.setBounds(par1 - (double) var7, par3 - (double) this.yOffset + (double) this.ySize, par5 - (double) var7, par1 + (double) var7, par3 - (double) this.yOffset + (double) this.ySize + (double) var8, + par5 + (double) var7); + } + + /** + * Adds par1*0.15 to the entity's yaw, and *subtracts* par2*0.15 from the pitch. + * Clamps pitch from -90 to 90. Both arguments in degrees. + */ + public void setAngles(float par1, float par2) { + float var3 = this.rotationPitch; + float var4 = this.rotationYaw; + this.rotationYaw = (float) ((double) this.rotationYaw + (double) par1 * 0.15D); + this.rotationPitch = (float) ((double) this.rotationPitch - (double) par2 * 0.15D); + + if (this.rotationPitch < -90.0F) { + this.rotationPitch = -90.0F; + } + + if (this.rotationPitch > 90.0F) { + this.rotationPitch = 90.0F; + } + + this.prevRotationPitch += this.rotationPitch - var3; + this.prevRotationYaw += this.rotationYaw - var4; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.onEntityUpdate(); + } + + /** + * Gets called every tick from main Entity class + */ + public void onEntityUpdate() { + this.worldObj.theProfiler.startSection("entityBaseTick"); + + if (this.ridingEntity != null && this.ridingEntity.isDead) { + this.ridingEntity = null; + } + + this.prevDistanceWalkedModified = this.distanceWalkedModified; + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.prevRotationPitch = this.rotationPitch; + this.prevRotationYaw = this.rotationYaw; + int var2; + + if (this.isSprinting() && !this.isInWater()) { + int var5 = MathHelper.floor_double(this.posX); + var2 = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double) this.yOffset); + int var6 = MathHelper.floor_double(this.posZ); + int var4 = this.worldObj.getBlockId(var5, var2, var6); + + if (var4 > 0) { + this.worldObj.spawnParticle("tilecrack_" + var4 + "_" + this.worldObj.getBlockMetadata(var5, var2, var6), this.posX + ((double) this.rand.nextFloat() - 0.5D) * (double) this.width, this.boundingBox.minY + 0.1D, + this.posZ + ((double) this.rand.nextFloat() - 0.5D) * (double) this.width, -this.motionX * 4.0D, 1.5D, -this.motionZ * 4.0D); + } + } + + this.handleWaterMovement(); + + if (this.worldObj.isRemote) { + this.fire = 0; + } else if (this.fire > 0) { + if (this.isImmuneToFire) { + this.fire -= 4; + + if (this.fire < 0) { + this.fire = 0; + } + } else { + if (this.fire % 20 == 0) { + this.attackEntityFrom(DamageSource.onFire, 1); + } + + --this.fire; + } + } + + if (this.handleLavaMovement()) { + this.setOnFireFromLava(); + this.fallDistance *= 0.5F; + } + + if (this.posY < -64.0D) { + this.kill(); + } + + if (!this.worldObj.isRemote) { + this.setFlag(0, this.fire > 0); + this.setFlag(2, this.ridingEntity != null); + } + + this.firstUpdate = false; + this.worldObj.theProfiler.endSection(); + } + + /** + * Return the amount of time this entity should stay in a portal before being + * transported. + */ + public int getMaxInPortalTime() { + return 0; + } + + /** + * Called whenever the entity is walking inside of lava. + */ + protected void setOnFireFromLava() { + if (!this.isImmuneToFire) { + this.attackEntityFrom(DamageSource.lava, 4); + this.setFire(15); + } + } + + /** + * Sets entity to burn for x amount of seconds, cannot lower amount of existing + * fire. + */ + public void setFire(int par1) { + int var2 = par1 * 20; + var2 = EnchantmentProtection.func_92093_a(this, var2); + + if (this.fire < var2) { + this.fire = var2; + } + } + + /** + * Removes fire from entity. + */ + public void extinguish() { + this.fire = 0; + } + + /** + * sets the dead flag. Used when you fall off the bottom of the world. + */ + protected void kill() { + this.setDead(); + } + + /** + * Checks if the offset position from the entity's current position is inside of + * liquid. Args: x, y, z + */ + public boolean isOffsetPositionInLiquid(double par1, double par3, double par5) { + AxisAlignedBB var7 = this.boundingBox.getOffsetBoundingBox(par1, par3, par5); + List var8 = this.worldObj.getCollidingBoundingBoxes(this, var7); + return !var8.isEmpty() ? false : !this.worldObj.isAnyLiquid(var7); + } + + /** + * Tries to moves the entity by the passed in displacement. Args: x, y, z + */ + public void moveEntity(double par1, double par3, double par5) { + if (this.noClip) { + this.boundingBox.offset(par1, par3, par5); + this.posX = (this.boundingBox.minX + this.boundingBox.maxX) / 2.0D; + this.posY = this.boundingBox.minY + (double) this.yOffset - (double) this.ySize; + this.posZ = (this.boundingBox.minZ + this.boundingBox.maxZ) / 2.0D; + } else { + this.worldObj.theProfiler.startSection("move"); + this.ySize *= 0.4F; + double var7 = this.posX; + double var9 = this.posY; + double var11 = this.posZ; + + if (this.isInWeb) { + this.isInWeb = false; + par1 *= 0.25D; + par3 *= 0.05000000074505806D; + par5 *= 0.25D; + this.motionX = 0.0D; + this.motionY = 0.0D; + this.motionZ = 0.0D; + } + + double var13 = par1; + double var15 = par3; + double var17 = par5; + AxisAlignedBB var19 = this.boundingBox.copy(); + boolean var20 = this.onGround && this.isSneaking() && this instanceof EntityPlayer; + + if (var20) { + double var21; + + for (var21 = 0.05D; par1 != 0.0D && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.getOffsetBoundingBox(par1, -1.0D, 0.0D)).isEmpty(); var13 = par1) { + if (par1 < var21 && par1 >= -var21) { + par1 = 0.0D; + } else if (par1 > 0.0D) { + par1 -= var21; + } else { + par1 += var21; + } + } + + for (; par5 != 0.0D && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.getOffsetBoundingBox(0.0D, -1.0D, par5)).isEmpty(); var17 = par5) { + if (par5 < var21 && par5 >= -var21) { + par5 = 0.0D; + } else if (par5 > 0.0D) { + par5 -= var21; + } else { + par5 += var21; + } + } + + while (par1 != 0.0D && par5 != 0.0D && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.getOffsetBoundingBox(par1, -1.0D, par5)).isEmpty()) { + if (par1 < var21 && par1 >= -var21) { + par1 = 0.0D; + } else if (par1 > 0.0D) { + par1 -= var21; + } else { + par1 += var21; + } + + if (par5 < var21 && par5 >= -var21) { + par5 = 0.0D; + } else if (par5 > 0.0D) { + par5 -= var21; + } else { + par5 += var21; + } + + var13 = par1; + var17 = par5; + } + } + + List var34 = this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.addCoord(par1, par3, par5)); + + for (int var22 = 0; var22 < var34.size(); ++var22) { + par3 = ((AxisAlignedBB) var34.get(var22)).calculateYOffset(this.boundingBox, par3); + } + + this.boundingBox.offset(0.0D, par3, 0.0D); + + if (!this.field_70135_K && var15 != par3) { + par5 = 0.0D; + par3 = 0.0D; + par1 = 0.0D; + } + + boolean var35 = this.onGround || var15 != par3 && var15 < 0.0D; + int var23; + + for (var23 = 0; var23 < var34.size(); ++var23) { + par1 = ((AxisAlignedBB) var34.get(var23)).calculateXOffset(this.boundingBox, par1); + } + + this.boundingBox.offset(par1, 0.0D, 0.0D); + + if (!this.field_70135_K && var13 != par1) { + par5 = 0.0D; + par3 = 0.0D; + par1 = 0.0D; + } + + for (var23 = 0; var23 < var34.size(); ++var23) { + par5 = ((AxisAlignedBB) var34.get(var23)).calculateZOffset(this.boundingBox, par5); + } + + this.boundingBox.offset(0.0D, 0.0D, par5); + + if (!this.field_70135_K && var17 != par5) { + par5 = 0.0D; + par3 = 0.0D; + par1 = 0.0D; + } + + double var25; + double var27; + int var30; + double var36; + + if (this.stepHeight > 0.0F && var35 && (var20 || this.ySize < 0.05F) && (var13 != par1 || var17 != par5)) { + var36 = par1; + var25 = par3; + var27 = par5; + par1 = var13; + par3 = (double) this.stepHeight; + par5 = var17; + AxisAlignedBB var29 = this.boundingBox.copy(); + this.boundingBox.setBB(var19); + var34 = this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.addCoord(var13, par3, var17)); + + for (var30 = 0; var30 < var34.size(); ++var30) { + par3 = ((AxisAlignedBB) var34.get(var30)).calculateYOffset(this.boundingBox, par3); + } + + this.boundingBox.offset(0.0D, par3, 0.0D); + + if (!this.field_70135_K && var15 != par3) { + par5 = 0.0D; + par3 = 0.0D; + par1 = 0.0D; + } + + for (var30 = 0; var30 < var34.size(); ++var30) { + par1 = ((AxisAlignedBB) var34.get(var30)).calculateXOffset(this.boundingBox, par1); + } + + this.boundingBox.offset(par1, 0.0D, 0.0D); + + if (!this.field_70135_K && var13 != par1) { + par5 = 0.0D; + par3 = 0.0D; + par1 = 0.0D; + } + + for (var30 = 0; var30 < var34.size(); ++var30) { + par5 = ((AxisAlignedBB) var34.get(var30)).calculateZOffset(this.boundingBox, par5); + } + + this.boundingBox.offset(0.0D, 0.0D, par5); + + if (!this.field_70135_K && var17 != par5) { + par5 = 0.0D; + par3 = 0.0D; + par1 = 0.0D; + } + + if (!this.field_70135_K && var15 != par3) { + par5 = 0.0D; + par3 = 0.0D; + par1 = 0.0D; + } else { + par3 = (double) (-this.stepHeight); + + for (var30 = 0; var30 < var34.size(); ++var30) { + par3 = ((AxisAlignedBB) var34.get(var30)).calculateYOffset(this.boundingBox, par3); + } + + this.boundingBox.offset(0.0D, par3, 0.0D); + } + + if (var36 * var36 + var27 * var27 >= par1 * par1 + par5 * par5) { + par1 = var36; + par3 = var25; + par5 = var27; + this.boundingBox.setBB(var29); + } + } + + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("rest"); + this.posX = (this.boundingBox.minX + this.boundingBox.maxX) / 2.0D; + this.posY = this.boundingBox.minY + (double) this.yOffset - (double) this.ySize; + this.posZ = (this.boundingBox.minZ + this.boundingBox.maxZ) / 2.0D; + this.isCollidedHorizontally = var13 != par1 || var17 != par5; + this.isCollidedVertically = var15 != par3; + this.onGround = var15 != par3 && var15 < 0.0D; + this.isCollided = this.isCollidedHorizontally || this.isCollidedVertically; + this.updateFallState(par3, this.onGround); + + if (var13 != par1) { + this.motionX = 0.0D; + } + + if (var15 != par3) { + this.motionY = 0.0D; + } + + if (var17 != par5) { + this.motionZ = 0.0D; + } + + var36 = this.posX - var7; + var25 = this.posY - var9; + var27 = this.posZ - var11; + + if (this.canTriggerWalking() && !var20 && this.ridingEntity == null) { + int var37 = MathHelper.floor_double(this.posX); + var30 = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double) this.yOffset); + int var31 = MathHelper.floor_double(this.posZ); + int var32 = this.worldObj.getBlockId(var37, var30, var31); + + if (var32 == 0) { + int var33 = this.worldObj.blockGetRenderType(var37, var30 - 1, var31); + + if (var33 == 11 || var33 == 32 || var33 == 21) { + var32 = this.worldObj.getBlockId(var37, var30 - 1, var31); + } + } + + if (var32 != Block.ladder.blockID) { + var25 = 0.0D; + } + + this.distanceWalkedModified = (float) ((double) this.distanceWalkedModified + (double) MathHelper.sqrt_double(var36 * var36 + var27 * var27) * 0.6D); + this.distanceWalkedOnStepModified = (float) ((double) this.distanceWalkedOnStepModified + (double) MathHelper.sqrt_double(var36 * var36 + var25 * var25 + var27 * var27) * 0.6D); + + if (this.distanceWalkedOnStepModified > (float) this.nextStepDistance && var32 > 0) { + this.nextStepDistance = (int) this.distanceWalkedOnStepModified + 1; + + if (this.isInWater()) { + float var39 = MathHelper.sqrt_double(this.motionX * this.motionX * 0.20000000298023224D + this.motionY * this.motionY + this.motionZ * this.motionZ * 0.20000000298023224D) * 0.35F; + + if (var39 > 1.0F) { + var39 = 1.0F; + } + + this.playSound("liquid.swim", var39, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F); + } + + this.playStepSound(var37, var30, var31, var32); + Block.blocksList[var32].onEntityWalking(this.worldObj, var37, var30, var31, this); + } + } + + this.doBlockCollisions(); + boolean var38 = this.isWet(); + + if (this.worldObj.isBoundingBoxBurning(this.boundingBox.contract(0.001D, 0.001D, 0.001D))) { + this.dealFireDamage(1); + + if (!var38) { + ++this.fire; + + if (this.fire == 0) { + this.setFire(8); + } + } + } else if (this.fire <= 0) { + this.fire = -this.fireResistance; + } + + if (var38 && this.fire > 0) { + this.playSound("random.fizz", 0.7F, 1.6F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F); + this.fire = -this.fireResistance; + } + + this.worldObj.theProfiler.endSection(); + } + } + + /** + * Checks for block collisions, and calls the associated onBlockCollided method + * for the collided block. + */ + protected void doBlockCollisions() { + int var1 = MathHelper.floor_double(this.boundingBox.minX + 0.001D); + int var2 = MathHelper.floor_double(this.boundingBox.minY + 0.001D); + int var3 = MathHelper.floor_double(this.boundingBox.minZ + 0.001D); + int var4 = MathHelper.floor_double(this.boundingBox.maxX - 0.001D); + int var5 = MathHelper.floor_double(this.boundingBox.maxY - 0.001D); + int var6 = MathHelper.floor_double(this.boundingBox.maxZ - 0.001D); + + if (this.worldObj.checkChunksExist(var1, var2, var3, var4, var5, var6)) { + for (int var7 = var1; var7 <= var4; ++var7) { + for (int var8 = var2; var8 <= var5; ++var8) { + for (int var9 = var3; var9 <= var6; ++var9) { + int var10 = this.worldObj.getBlockId(var7, var8, var9); + + if (var10 > 0) { + Block.blocksList[var10].onEntityCollidedWithBlock(this.worldObj, var7, var8, var9, this); + } + } + } + } + } + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + StepSound var5 = Block.blocksList[par4].stepSound; + + if (this.worldObj.getBlockId(par1, par2 + 1, par3) == Block.snow.blockID) { + var5 = Block.snow.stepSound; + this.playSound(var5.getStepSound(), var5.getVolume() * 0.15F, var5.getPitch()); + } else if (!Block.blocksList[par4].blockMaterial.isLiquid()) { + this.playSound(var5.getStepSound(), var5.getVolume() * 0.15F, var5.getPitch()); + } + } + + public void playSound(String par1Str, float par2, float par3) { + this.worldObj.playSoundAtEntity(this, par1Str, par2, par3); + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return true; + } + + /** + * Takes in the distance the entity has fallen this tick and whether its on the + * ground to update the fall distance and deal fall damage if landing on the + * ground. Args: distanceFallenThisTick, onGround + */ + protected void updateFallState(double par1, boolean par3) { + if (par3) { + if (this.fallDistance > 0.0F) { + this.fall(this.fallDistance); + this.fallDistance = 0.0F; + } + } else if (par1 < 0.0D) { + this.fallDistance = (float) ((double) this.fallDistance - par1); + } + } + + /** + * returns the bounding box for this entity + */ + public AxisAlignedBB getBoundingBox() { + return null; + } + + /** + * Will deal the specified amount of damage to the entity if the entity isn't + * immune to fire damage. Args: amountDamage + */ + protected void dealFireDamage(int par1) { + if (!this.isImmuneToFire) { + this.attackEntityFrom(DamageSource.inFire, par1); + } + } + + public final boolean isImmuneToFire() { + return this.isImmuneToFire; + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + if (this.riddenByEntity != null) { + this.riddenByEntity.fall(par1); + } + } + + /** + * Checks if this entity is either in water or on an open air block in rain + * (used in wolves). + */ + public boolean isWet() { + return this.inWater || this.worldObj.canLightningStrikeAt(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) + || this.worldObj.canLightningStrikeAt(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY + (double) this.height), MathHelper.floor_double(this.posZ)); + } + + /** + * Checks if this entity is inside water (if inWater field is true as a result + * of handleWaterMovement() returning true) + */ + public boolean isInWater() { + return this.inWater; + } + + /** + * Returns if this entity is in water and will end up adding the waters velocity + * to the entity + */ + public boolean handleWaterMovement() { + if (this.worldObj.handleMaterialAcceleration(this.boundingBox.expand(0.0D, -0.4000000059604645D, 0.0D).contract(0.001D, 0.001D, 0.001D), Material.water, this)) { + if (!this.inWater && !this.firstUpdate) { + float var1 = MathHelper.sqrt_double(this.motionX * this.motionX * 0.20000000298023224D + this.motionY * this.motionY + this.motionZ * this.motionZ * 0.20000000298023224D) * 0.2F; + + if (var1 > 1.0F) { + var1 = 1.0F; + } + + this.playSound("liquid.splash", var1, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F); + float var2 = (float) MathHelper.floor_double(this.boundingBox.minY); + int var3; + float var4; + float var5; + + for (var3 = 0; (float) var3 < 1.0F + this.width * 20.0F; ++var3) { + var4 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + var5 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + this.worldObj.spawnParticle("bubble", this.posX + (double) var4, (double) (var2 + 1.0F), this.posZ + (double) var5, this.motionX, this.motionY - (double) (this.rand.nextFloat() * 0.2F), this.motionZ); + } + + for (var3 = 0; (float) var3 < 1.0F + this.width * 20.0F; ++var3) { + var4 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + var5 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + this.worldObj.spawnParticle("splash", this.posX + (double) var4, (double) (var2 + 1.0F), this.posZ + (double) var5, this.motionX, this.motionY, this.motionZ); + } + } + + this.fallDistance = 0.0F; + this.inWater = true; + this.fire = 0; + } else { + this.inWater = false; + } + + return this.inWater; + } + + /** + * Checks if the current block the entity is within of the specified material + * type + */ + public boolean isInsideOfMaterial(Material par1Material) { + double var2 = this.posY + (double) this.getEyeHeight(); + int var4 = MathHelper.floor_double(this.posX); + int var5 = MathHelper.floor_float((float) MathHelper.floor_double(var2)); + int var6 = MathHelper.floor_double(this.posZ); + int var7 = this.worldObj.getBlockId(var4, var5, var6); + + if (var7 != 0 && Block.blocksList[var7].blockMaterial == par1Material) { + float var8 = BlockFluid.getFluidHeightPercent(this.worldObj.getBlockMetadata(var4, var5, var6)) - 0.11111111F; + float var9 = (float) (var5 + 1) - var8; + return var2 < (double) var9; + } else { + return false; + } + } + + public float getEyeHeight() { + return 0.0F; + } + + /** + * Whether or not the current entity is in lava + */ + public boolean handleLavaMovement() { + return this.worldObj.isMaterialInBB(this.boundingBox.expand(-0.10000000149011612D, -0.4000000059604645D, -0.10000000149011612D), Material.lava); + } + + /** + * Used in both water and by flying objects + */ + public void moveFlying(float par1, float par2, float par3) { + float var4 = par1 * par1 + par2 * par2; + + if (var4 >= 1.0E-4F) { + var4 = MathHelper.sqrt_float(var4); + + if (var4 < 1.0F) { + var4 = 1.0F; + } + + var4 = par3 / var4; + par1 *= var4; + par2 *= var4; + float var5 = MathHelper.sin(this.rotationYaw * (float) Math.PI / 180.0F); + float var6 = MathHelper.cos(this.rotationYaw * (float) Math.PI / 180.0F); + this.motionX += (double) (par1 * var6 - par2 * var5); + this.motionZ += (double) (par2 * var6 + par1 * var5); + } + } + + public int getBrightnessForRender(float par1) { + int var2 = MathHelper.floor_double(this.posX); + int var3 = MathHelper.floor_double(this.posZ); + + if (this.worldObj.blockExists(var2, 0, var3)) { + double var4 = (this.boundingBox.maxY - this.boundingBox.minY) * 0.66D; + int var6 = MathHelper.floor_double(this.posY - (double) this.yOffset + var4); + return this.worldObj.getLightBrightnessForSkyBlocks(var2, var6, var3, 0); + } else { + return 0; + } + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + int var2 = MathHelper.floor_double(this.posX); + int var3 = MathHelper.floor_double(this.posZ); + + if (this.worldObj.blockExists(var2, 0, var3)) { + double var4 = (this.boundingBox.maxY - this.boundingBox.minY) * 0.66D; + int var6 = MathHelper.floor_double(this.posY - (double) this.yOffset + var4); + return this.worldObj.getLightBrightness(var2, var6, var3); + } else { + return 0.0F; + } + } + + /** + * Sets the reference to the World object. + */ + public void setWorld(World par1World) { + this.worldObj = par1World; + this.dimension = par1World.provider.dimensionId; + } + + /** + * Sets the entity's position and rotation. Args: posX, posY, posZ, yaw, pitch + */ + public void setPositionAndRotation(double par1, double par3, double par5, float par7, float par8) { + this.prevPosX = this.posX = par1; + this.prevPosY = this.posY = par3; + this.prevPosZ = this.posZ = par5; + this.prevRotationYaw = this.rotationYaw = par7; + this.prevRotationPitch = this.rotationPitch = par8; + this.ySize = 0.0F; + double var9 = (double) (this.prevRotationYaw - par7); + + if (var9 < -180.0D) { + this.prevRotationYaw += 360.0F; + } + + if (var9 >= 180.0D) { + this.prevRotationYaw -= 360.0F; + } + + this.setPosition(this.posX, this.posY, this.posZ); + this.setRotation(par7, par8); + } + + /** + * Sets the location and Yaw/Pitch of an entity in the world + */ + public void setLocationAndAngles(double par1, double par3, double par5, float par7, float par8) { + this.lastTickPosX = this.prevPosX = this.posX = par1; + this.lastTickPosY = this.prevPosY = this.posY = par3 + (double) this.yOffset; + this.lastTickPosZ = this.prevPosZ = this.posZ = par5; + this.rotationYaw = par7; + this.rotationPitch = par8; + this.setPosition(this.posX, this.posY, this.posZ); + } + + /** + * Returns the distance to the entity. Args: entity + */ + public float getDistanceToEntity(Entity par1Entity) { + float var2 = (float) (this.posX - par1Entity.posX); + float var3 = (float) (this.posY - par1Entity.posY); + float var4 = (float) (this.posZ - par1Entity.posZ); + return MathHelper.sqrt_float(var2 * var2 + var3 * var3 + var4 * var4); + } + + /** + * Gets the squared distance to the position. Args: x, y, z + */ + public double getDistanceSq(double par1, double par3, double par5) { + double var7 = this.posX - par1; + double var9 = this.posY - par3; + double var11 = this.posZ - par5; + return var7 * var7 + var9 * var9 + var11 * var11; + } + + /** + * Gets the distance to the position. Args: x, y, z + */ + public double getDistance(double par1, double par3, double par5) { + double var7 = this.posX - par1; + double var9 = this.posY - par3; + double var11 = this.posZ - par5; + return (double) MathHelper.sqrt_double(var7 * var7 + var9 * var9 + var11 * var11); + } + + /** + * Returns the squared distance to the entity. Args: entity + */ + public double getDistanceSqToEntity(Entity par1Entity) { + double var2 = this.posX - par1Entity.posX; + double var4 = this.posY - par1Entity.posY; + double var6 = this.posZ - par1Entity.posZ; + return var2 * var2 + var4 * var4 + var6 * var6; + } + + /** + * Called by a player entity when they collide with an entity + */ + public void onCollideWithPlayer(EntityPlayer par1EntityPlayer) { + } + + /** + * Applies a velocity to each of the entities pushing them away from each other. + * Args: entity + */ + public void applyEntityCollision(Entity par1Entity) { + if (par1Entity.riddenByEntity != this && par1Entity.ridingEntity != this) { + double var2 = par1Entity.posX - this.posX; + double var4 = par1Entity.posZ - this.posZ; + double var6 = MathHelper.abs_max(var2, var4); + + if (var6 >= 0.009999999776482582D) { + var6 = (double) MathHelper.sqrt_double(var6); + var2 /= var6; + var4 /= var6; + double var8 = 1.0D / var6; + + if (var8 > 1.0D) { + var8 = 1.0D; + } + + var2 *= var8; + var4 *= var8; + var2 *= 0.05000000074505806D; + var4 *= 0.05000000074505806D; + var2 *= (double) (1.0F - this.entityCollisionReduction); + var4 *= (double) (1.0F - this.entityCollisionReduction); + this.addVelocity(-var2, 0.0D, -var4); + par1Entity.addVelocity(var2, 0.0D, var4); + } + } + } + + /** + * Adds to the current velocity of the entity. Args: x, y, z + */ + public void addVelocity(double par1, double par3, double par5) { + this.motionX += par1; + this.motionY += par3; + this.motionZ += par5; + this.isAirBorne = true; + } + + /** + * Sets that this entity has been attacked. + */ + protected void setBeenAttacked() { + this.velocityChanged = true; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + this.setBeenAttacked(); + return false; + } + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return false; + } + + /** + * Returns true if this entity should push and be pushed by other entities when + * colliding. + */ + public boolean canBePushed() { + return false; + } + + /** + * Adds a value to the player score. Currently not actually used and the entity + * passed in does nothing. Args: entity, scoreToAdd + */ + public void addToPlayerScore(Entity par1Entity, int par2) { + } + + /** + * Checks using a Vec3d to determine if this entity is within range of that + * vector to be rendered. Args: vec3D + */ + public boolean isInRangeToRenderVec3D(Vec3 par1Vec3) { + double var2 = this.posX - par1Vec3.xCoord; + double var4 = this.posY - par1Vec3.yCoord; + double var6 = this.posZ - par1Vec3.zCoord; + double var8 = var2 * var2 + var4 * var4 + var6 * var6; + return this.isInRangeToRenderDist(var8); + } + + /** + * Checks if the entity is in range to render by using the past in distance and + * comparing it to its average edge length * 64 * renderDistanceWeight Args: + * distance + */ + public boolean isInRangeToRenderDist(double par1) { + double var3 = this.boundingBox.getAverageEdgeLength(); + var3 *= 64.0D * this.renderDistanceWeight; + return par1 < var3 * var3; + } + + public boolean addNotRiddenEntityID(NBTTagCompound par1NBTTagCompound) { + String var2 = this.getEntityString(); + + if (!this.isDead && var2 != null) { + par1NBTTagCompound.setString("id", var2); + this.writeToNBT(par1NBTTagCompound); + return true; + } else { + return false; + } + } + + /** + * adds the ID of this entity to the NBT given + */ + public boolean addEntityID(NBTTagCompound par1NBTTagCompound) { + String var2 = this.getEntityString(); + + if (!this.isDead && var2 != null && this.riddenByEntity == null) { + par1NBTTagCompound.setString("id", var2); + this.writeToNBT(par1NBTTagCompound); + return true; + } else { + return false; + } + } + + /** + * Save the entity to NBT (calls an abstract helper method to write extra data) + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setTag("Pos", this.newDoubleNBTList(new double[] { this.posX, this.posY + (double) this.ySize, this.posZ })); + par1NBTTagCompound.setTag("Motion", this.newDoubleNBTList(new double[] { this.motionX, this.motionY, this.motionZ })); + par1NBTTagCompound.setTag("Rotation", this.newFloatNBTList(new float[] { this.rotationYaw, this.rotationPitch })); + par1NBTTagCompound.setFloat("FallDistance", this.fallDistance); + par1NBTTagCompound.setShort("Fire", (short) this.fire); + par1NBTTagCompound.setShort("Air", (short) this.getAir()); + par1NBTTagCompound.setBoolean("OnGround", this.onGround); + par1NBTTagCompound.setInteger("Dimension", this.dimension); + par1NBTTagCompound.setBoolean("Invulnerable", this.invulnerable); + par1NBTTagCompound.setInteger("PortalCooldown", this.timeUntilPortal); + this.writeEntityToNBT(par1NBTTagCompound); + + if (this.ridingEntity != null) { + NBTTagCompound var2 = new NBTTagCompound("Riding"); + + if (this.ridingEntity.addNotRiddenEntityID(var2)) { + par1NBTTagCompound.setTag("Riding", var2); + } + } + } + + /** + * Reads the entity from NBT (calls an abstract helper method to read + * specialized data) + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + NBTTagList var2 = par1NBTTagCompound.getTagList("Pos"); + NBTTagList var6 = par1NBTTagCompound.getTagList("Motion"); + NBTTagList var7 = par1NBTTagCompound.getTagList("Rotation"); + this.motionX = ((NBTTagDouble) var6.tagAt(0)).data; + this.motionY = ((NBTTagDouble) var6.tagAt(1)).data; + this.motionZ = ((NBTTagDouble) var6.tagAt(2)).data; + + if (Math.abs(this.motionX) > 10.0D) { + this.motionX = 0.0D; + } + + if (Math.abs(this.motionY) > 10.0D) { + this.motionY = 0.0D; + } + + if (Math.abs(this.motionZ) > 10.0D) { + this.motionZ = 0.0D; + } + + this.prevPosX = this.lastTickPosX = this.posX = ((NBTTagDouble) var2.tagAt(0)).data; + this.prevPosY = this.lastTickPosY = this.posY = ((NBTTagDouble) var2.tagAt(1)).data; + this.prevPosZ = this.lastTickPosZ = this.posZ = ((NBTTagDouble) var2.tagAt(2)).data; + this.prevRotationYaw = this.rotationYaw = ((NBTTagFloat) var7.tagAt(0)).data; + this.prevRotationPitch = this.rotationPitch = ((NBTTagFloat) var7.tagAt(1)).data; + this.fallDistance = par1NBTTagCompound.getFloat("FallDistance"); + this.fire = par1NBTTagCompound.getShort("Fire"); + this.setAir(par1NBTTagCompound.getShort("Air")); + this.onGround = par1NBTTagCompound.getBoolean("OnGround"); + this.dimension = par1NBTTagCompound.getInteger("Dimension"); + this.invulnerable = par1NBTTagCompound.getBoolean("Invulnerable"); + this.timeUntilPortal = par1NBTTagCompound.getInteger("PortalCooldown"); + + this.setPosition(this.posX, this.posY, this.posZ); + this.setRotation(this.rotationYaw, this.rotationPitch); + this.readEntityFromNBT(par1NBTTagCompound); + } + + /** + * Returns the string that identifies this Entity's class + */ + protected final String getEntityString() { + return EntityList.getEntityString(this); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected abstract void readEntityFromNBT(NBTTagCompound var1); + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected abstract void writeEntityToNBT(NBTTagCompound var1); + + /** + * creates a NBT list from the array of doubles passed to this function + */ + protected NBTTagList newDoubleNBTList(double... par1ArrayOfDouble) { + NBTTagList var2 = new NBTTagList(); + double[] var3 = par1ArrayOfDouble; + int var4 = par1ArrayOfDouble.length; + + for (int var5 = 0; var5 < var4; ++var5) { + double var6 = var3[var5]; + var2.appendTag(new NBTTagDouble((String) null, var6)); + } + + return var2; + } + + /** + * Returns a new NBTTagList filled with the specified floats + */ + protected NBTTagList newFloatNBTList(float... par1ArrayOfFloat) { + NBTTagList var2 = new NBTTagList(); + float[] var3 = par1ArrayOfFloat; + int var4 = par1ArrayOfFloat.length; + + for (int var5 = 0; var5 < var4; ++var5) { + float var6 = var3[var5]; + var2.appendTag(new NBTTagFloat((String) null, var6)); + } + + return var2; + } + + public float getShadowSize() { + return this.height / 2.0F; + } + + /** + * Drops an item stack at the entity's position. Args: itemID, count + */ + public EntityItem dropItem(int par1, int par2) { + return this.dropItemWithOffset(par1, par2, 0.0F); + } + + /** + * Drops an item stack with a specified y offset. Args: itemID, count, yOffset + */ + public EntityItem dropItemWithOffset(int par1, int par2, float par3) { + return this.entityDropItem(new ItemStack(par1, par2, 0), par3); + } + + /** + * Drops an item at the position of the entity. + */ + public EntityItem entityDropItem(ItemStack par1ItemStack, float par2) { + EntityItem var3 = new EntityItem(this.worldObj, this.posX, this.posY + (double) par2, this.posZ, par1ItemStack); + var3.delayBeforeCanPickup = 10; + this.worldObj.spawnEntityInWorld(var3); + return var3; + } + + /** + * Checks whether target entity is alive. + */ + public boolean isEntityAlive() { + return !this.isDead; + } + + /** + * Checks if this entity is inside of an opaque block + */ + public boolean isEntityInsideOpaqueBlock() { + for (int var1 = 0; var1 < 8; ++var1) { + float var2 = ((float) ((var1 >> 0) % 2) - 0.5F) * this.width * 0.8F; + float var3 = ((float) ((var1 >> 1) % 2) - 0.5F) * 0.1F; + float var4 = ((float) ((var1 >> 2) % 2) - 0.5F) * this.width * 0.8F; + int var5 = MathHelper.floor_double(this.posX + (double) var2); + int var6 = MathHelper.floor_double(this.posY + (double) this.getEyeHeight() + (double) var3); + int var7 = MathHelper.floor_double(this.posZ + (double) var4); + + if (this.worldObj.isBlockNormalCube(var5, var6, var7)) { + return true; + } + } + + return false; + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + return false; + } + + /** + * Returns a boundingBox used to collide the entity with other entities and + * blocks. This enables the entity to be pushable on contact, like boats or + * minecarts. + */ + public AxisAlignedBB getCollisionBox(Entity par1Entity) { + return null; + } + + /** + * Handles updating while being ridden by an entity + */ + public void updateRidden() { + if (this.ridingEntity.isDead) { + this.ridingEntity = null; + } else { + this.motionX = 0.0D; + this.motionY = 0.0D; + this.motionZ = 0.0D; + this.onUpdate(); + + if (this.ridingEntity != null) { + this.ridingEntity.updateRiderPosition(); + this.entityRiderYawDelta += (double) (this.ridingEntity.rotationYaw - this.ridingEntity.prevRotationYaw); + + for (this.entityRiderPitchDelta += (double) (this.ridingEntity.rotationPitch - this.ridingEntity.prevRotationPitch); this.entityRiderYawDelta >= 180.0D; this.entityRiderYawDelta -= 360.0D) { + ; + } + + while (this.entityRiderYawDelta < -180.0D) { + this.entityRiderYawDelta += 360.0D; + } + + while (this.entityRiderPitchDelta >= 180.0D) { + this.entityRiderPitchDelta -= 360.0D; + } + + while (this.entityRiderPitchDelta < -180.0D) { + this.entityRiderPitchDelta += 360.0D; + } + + double var1 = this.entityRiderYawDelta * 0.5D; + double var3 = this.entityRiderPitchDelta * 0.5D; + float var5 = 10.0F; + + if (var1 > (double) var5) { + var1 = (double) var5; + } + + if (var1 < (double) (-var5)) { + var1 = (double) (-var5); + } + + if (var3 > (double) var5) { + var3 = (double) var5; + } + + if (var3 < (double) (-var5)) { + var3 = (double) (-var5); + } + + this.entityRiderYawDelta -= var1; + this.entityRiderPitchDelta -= var3; + this.rotationYaw = (float) ((double) this.rotationYaw + var1); + this.rotationPitch = (float) ((double) this.rotationPitch + var3); + } + } + } + + public void updateRiderPosition() { + if (this.riddenByEntity != null) { + if (!(this.riddenByEntity instanceof EntityPlayer) || !((EntityPlayer) this.riddenByEntity).func_71066_bF()) { + this.riddenByEntity.lastTickPosX = this.lastTickPosX; + this.riddenByEntity.lastTickPosY = this.lastTickPosY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(); + this.riddenByEntity.lastTickPosZ = this.lastTickPosZ; + } + + this.riddenByEntity.setPosition(this.posX, this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ); + } + } + + /** + * Returns the Y Offset of this entity. + */ + public double getYOffset() { + return (double) this.yOffset; + } + + /** + * Returns the Y offset from the entity's position for any entity riding this + * one. + */ + public double getMountedYOffset() { + return (double) this.height * 0.75D; + } + + /** + * Called when a player mounts an entity. e.g. mounts a pig, mounts a boat. + */ + public void mountEntity(Entity par1Entity) { + this.entityRiderPitchDelta = 0.0D; + this.entityRiderYawDelta = 0.0D; + + if (par1Entity == null) { + if (this.ridingEntity != null) { + this.setLocationAndAngles(this.ridingEntity.posX, this.ridingEntity.boundingBox.minY + (double) this.ridingEntity.height, this.ridingEntity.posZ, this.rotationYaw, this.rotationPitch); + this.ridingEntity.riddenByEntity = null; + } + + this.ridingEntity = null; + } else { + if (this.ridingEntity != null) { + this.ridingEntity.riddenByEntity = null; + } + + this.ridingEntity = par1Entity; + par1Entity.riddenByEntity = this; + } + } + + /** + * Called when a player unounts an entity. + */ + public void unmountEntity(Entity par1Entity) { + double var3 = this.posX; + double var5 = this.posY; + double var7 = this.posZ; + + if (par1Entity != null) { + var3 = par1Entity.posX; + var5 = par1Entity.boundingBox.minY + (double) par1Entity.height; + var7 = par1Entity.posZ; + } + + for (double var9 = -1.5D; var9 < 2.0D; ++var9) { + for (double var11 = -1.5D; var11 < 2.0D; ++var11) { + if (var9 != 0.0D || var11 != 0.0D) { + int var13 = (int) (this.posX + var9); + int var14 = (int) (this.posZ + var11); + AxisAlignedBB var2 = this.boundingBox.getOffsetBoundingBox(var9, 1.0D, var11); + + if (this.worldObj.getCollidingBlockBounds(var2).isEmpty()) { + if (this.worldObj.doesBlockHaveSolidTopSurface(var13, (int) this.posY, var14)) { + this.setLocationAndAngles(this.posX + var9, this.posY + 1.0D, this.posZ + var11, this.rotationYaw, this.rotationPitch); + return; + } + + if (this.worldObj.doesBlockHaveSolidTopSurface(var13, (int) this.posY - 1, var14) || this.worldObj.getBlockMaterial(var13, (int) this.posY - 1, var14) == Material.water) { + var3 = this.posX + var9; + var5 = this.posY + 1.0D; + var7 = this.posZ + var11; + } + } + } + } + } + + this.setLocationAndAngles(var3, var5, var7, this.rotationYaw, this.rotationPitch); + } + + /** + * Sets the position and rotation. Only difference from the other one is no + * bounding on the rotation. Args: posX, posY, posZ, yaw, pitch + */ + public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9) { + this.setPosition(par1, par3, par5); + this.setRotation(par7, par8); + List var10 = this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.contract(0.03125D, 0.0D, 0.03125D)); + + if (!var10.isEmpty()) { + double var11 = 0.0D; + + for (int var13 = 0; var13 < var10.size(); ++var13) { + AxisAlignedBB var14 = (AxisAlignedBB) var10.get(var13); + + if (var14.maxY > var11) { + var11 = var14.maxY; + } + } + + par3 += var11 - this.boundingBox.minY; + this.setPosition(par1, par3, par5); + } + } + + public float getCollisionBorderSize() { + return 0.1F; + } + + /** + * returns a (normalized) vector of where this entity is looking + */ + public Vec3 getLookVec() { + return null; + } + + /** + * Called by portal blocks when an entity is within it. + */ + public void setInPortal() { + if (this.timeUntilPortal > 0) { + this.timeUntilPortal = this.getPortalCooldown(); + } else { + double var1 = this.prevPosX - this.posX; + double var3 = this.prevPosZ - this.posZ; + + if (!this.worldObj.isRemote && !this.inPortal) { + this.teleportDirection = Direction.getMovementDirection(var1, var3); + } + + this.inPortal = true; + } + } + + /** + * Return the amount of cooldown before this entity can use a portal again. + */ + public int getPortalCooldown() { + return 900; + } + + /** + * Sets the velocity to the args. Args: x, y, z + */ + public void setVelocity(double par1, double par3, double par5) { + this.motionX = par1; + this.motionY = par3; + this.motionZ = par5; + } + + public void handleHealthUpdate(byte par1) { + } + + /** + * Setups the entity to do the hurt animation. Only used by packets in + * multiplayer. + */ + public void performHurtAnimation() { + } + + public void updateCloak() { + } + + public ItemStack[] getLastActiveItems() { + return null; + } + + /** + * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. + * Params: Item, slot + */ + public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack) { + } + + /** + * Returns true if the entity is on fire. Used by render to add the fire effect + * on rendering. + */ + public boolean isBurning() { + return this.fire > 0 || this.getFlag(0); + } + + /** + * Returns true if the entity is riding another entity, used by render to rotate + * the legs to be in 'sit' position for players. + */ + public boolean isRiding() { + return this.ridingEntity != null || this.getFlag(2); + } + + /** + * Returns if this entity is sneaking. + */ + public boolean isSneaking() { + return this.getFlag(1); + } + + /** + * Sets the sneaking flag. + */ + public void setSneaking(boolean par1) { + this.setFlag(1, par1); + } + + /** + * Get if the Entity is sprinting. + */ + public boolean isSprinting() { + return this.getFlag(3); + } + + /** + * Set sprinting switch for Entity. + */ + public void setSprinting(boolean par1) { + this.setFlag(3, par1); + } + + public boolean isInvisible() { + return this.getFlag(5); + } + + public boolean func_98034_c(EntityPlayer par1EntityPlayer) { + return this.isInvisible(); + } + + public void setInvisible(boolean par1) { + this.setFlag(5, par1); + } + + public boolean isEating() { + return this.getFlag(4); + } + + public void setEating(boolean par1) { + this.setFlag(4, par1); + } + + /** + * Returns true if the flag is active for the entity. Known flags: 0) is + * burning; 1) is sneaking; 2) is riding something; 3) is sprinting; 4) is + * eating + */ + protected boolean getFlag(int par1) { + return (this.dataWatcher.getWatchableObjectByte(0) & 1 << par1) != 0; + } + + /** + * Enable or disable a entity flag, see getEntityFlag to read the know flags. + */ + protected void setFlag(int par1, boolean par2) { + byte var3 = this.dataWatcher.getWatchableObjectByte(0); + + if (par2) { + this.dataWatcher.updateObject(0, Byte.valueOf((byte) (var3 | 1 << par1))); + } else { + this.dataWatcher.updateObject(0, Byte.valueOf((byte) (var3 & ~(1 << par1)))); + } + } + + public int getAir() { + return this.dataWatcher.getWatchableObjectShort(1); + } + + public void setAir(int par1) { + this.dataWatcher.updateObject(1, Short.valueOf((short) par1)); + } + + /** + * Called when a lightning bolt hits the entity. + */ + public void onStruckByLightning(EntityLightningBolt par1EntityLightningBolt) { + this.dealFireDamage(5); + ++this.fire; + + if (this.fire == 0) { + this.setFire(8); + } + } + + /** + * This method gets called when the entity kills another one. + */ + public void onKillEntity(EntityLiving par1EntityLiving) { + } + + /** + * Adds velocity to push the entity out of blocks at the specified x, y, z + * position Args: x, y, z + */ + protected boolean pushOutOfBlocks(double par1, double par3, double par5) { + int var7 = MathHelper.floor_double(par1); + int var8 = MathHelper.floor_double(par3); + int var9 = MathHelper.floor_double(par5); + double var10 = par1 - (double) var7; + double var12 = par3 - (double) var8; + double var14 = par5 - (double) var9; + List var16 = this.worldObj.getCollidingBlockBounds(this.boundingBox); + + if (var16.isEmpty() && !this.worldObj.func_85174_u(var7, var8, var9)) { + return false; + } else { + boolean var17 = !this.worldObj.func_85174_u(var7 - 1, var8, var9); + boolean var18 = !this.worldObj.func_85174_u(var7 + 1, var8, var9); + boolean var19 = !this.worldObj.func_85174_u(var7, var8 - 1, var9); + boolean var20 = !this.worldObj.func_85174_u(var7, var8 + 1, var9); + boolean var21 = !this.worldObj.func_85174_u(var7, var8, var9 - 1); + boolean var22 = !this.worldObj.func_85174_u(var7, var8, var9 + 1); + byte var23 = 3; + double var24 = 9999.0D; + + if (var17 && var10 < var24) { + var24 = var10; + var23 = 0; + } + + if (var18 && 1.0D - var10 < var24) { + var24 = 1.0D - var10; + var23 = 1; + } + + if (var20 && 1.0D - var12 < var24) { + var24 = 1.0D - var12; + var23 = 3; + } + + if (var21 && var14 < var24) { + var24 = var14; + var23 = 4; + } + + if (var22 && 1.0D - var14 < var24) { + var24 = 1.0D - var14; + var23 = 5; + } + + float var26 = this.rand.nextFloat() * 0.2F + 0.1F; + + if (var23 == 0) { + this.motionX = (double) (-var26); + } + + if (var23 == 1) { + this.motionX = (double) var26; + } + + if (var23 == 2) { + this.motionY = (double) (-var26); + } + + if (var23 == 3) { + this.motionY = (double) var26; + } + + if (var23 == 4) { + this.motionZ = (double) (-var26); + } + + if (var23 == 5) { + this.motionZ = (double) var26; + } + + return true; + } + } + + /** + * Sets the Entity inside a web block. + */ + public void setInWeb() { + this.isInWeb = true; + this.fallDistance = 0.0F; + } + + /** + * Gets the username of the entity. + */ + public String getEntityName() { + String var1 = EntityList.getEntityString(this); + + if (var1 == null) { + var1 = "generic"; + } + + return StatCollector.translateToLocal("entity." + var1 + ".name"); + } + + /** + * Return the Entity parts making up this Entity (currently only for dragons) + */ + public Entity[] getParts() { + return null; + } + + /** + * Returns true if Entity argument is equal to this Entity + */ + public boolean isEntityEqual(Entity par1Entity) { + return this == par1Entity; + } + + public float getRotationYawHead() { + return 0.0F; + } + + /** + * Sets the head's yaw rotation of the entity. + */ + public void setRotationYawHead(float par1) { + } + + /** + * If returns false, the item will not inflict any damage against entities. + */ + public boolean canAttackWithItem() { + return true; + } + + public boolean func_85031_j(Entity par1Entity) { + return false; + } + + public String toString() { + return String.format("%s[\'%s\'/%d, l=\'%s\', x=%.2f, y=%.2f, z=%.2f]", new Object[] { this.getClass().getSimpleName(), this.getEntityName(), Integer.valueOf(this.entityId), + this.worldObj == null ? "~NULL~" : this.worldObj.getWorldInfo().getWorldName(), Double.valueOf(this.posX), Double.valueOf(this.posY), Double.valueOf(this.posZ) }); + } + + /** + * Return whether this entity is invulnerable to damage. + */ + public boolean isEntityInvulnerable() { + return this.invulnerable; + } + + public void func_82149_j(Entity par1Entity) { + this.setLocationAndAngles(par1Entity.posX, par1Entity.posY, par1Entity.posZ, par1Entity.rotationYaw, par1Entity.rotationPitch); + } + + /** + * Copies important data from another entity to this entity. Used when + * teleporting entities between worlds, as this actually deletes the teleporting + * entity and re-creates it on the other side. Params: Entity to copy from, + * unused (always true) + */ + public void copyDataFrom(Entity par1Entity, boolean par2) { + NBTTagCompound var3 = new NBTTagCompound(); + par1Entity.writeToNBT(var3); + this.readFromNBT(var3); + this.timeUntilPortal = par1Entity.timeUntilPortal; + this.teleportDirection = par1Entity.teleportDirection; + } + + /** + * Teleports the entity to another dimension. Params: Dimension number to + * teleport to + */ + public void travelToDimension(int par1) { + + } + + public float func_82146_a(Explosion par1Explosion, World par2World, int par3, int par4, int par5, Block par6Block) { + return par6Block.getExplosionResistance(this); + } + + public boolean func_96091_a(Explosion par1Explosion, World par2World, int par3, int par4, int par5, int par6, float par7) { + return true; + } + + public int func_82143_as() { + return 3; + } + + public int getTeleportDirection() { + return this.teleportDirection; + } + + /** + * Return whether this entity should NOT trigger a pressure plate or a tripwire. + */ + public boolean doesEntityNotTriggerPressurePlate() { + return false; + } + + /** + * Return whether this entity should be rendered as on fire. + */ + public boolean canRenderOnFire() { + return this.isBurning(); + } + + public boolean func_96092_aw() { + return true; + } + + /** + * Returns the translated name of the entity. + */ + public String getTranslatedEntityName() { + return this.getEntityName(); + } +} diff --git a/src/main/java/net/minecraft/src/EntityAgeable.java b/src/main/java/net/minecraft/src/EntityAgeable.java new file mode 100644 index 0000000..3dd961a --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityAgeable.java @@ -0,0 +1,136 @@ +package net.minecraft.src; + +public abstract class EntityAgeable extends EntityCreature { + private float field_98056_d = -1.0F; + private float field_98057_e; + + public abstract EntityAgeable createChild(EntityAgeable var1); + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + + if (var2 != null && var2.itemID == Item.monsterPlacer.itemID && !this.worldObj.isRemote) { + Class var3 = EntityList.getClassFromID(var2.getItemDamage()); + + if (var3 != null && var3.isAssignableFrom(this.getClass())) { + EntityAgeable var4 = this.createChild(this); + + if (var4 != null) { + var4.setGrowingAge(-24000); + var4.setLocationAndAngles(this.posX, this.posY, this.posZ, 0.0F, 0.0F); + this.worldObj.spawnEntityInWorld(var4); + + if (var2.hasDisplayName()) { + var4.func_94058_c(var2.getDisplayName()); + } + + if (!par1EntityPlayer.capabilities.isCreativeMode) { + --var2.stackSize; + + if (var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null); + } + } + } + } + } + + return super.interact(par1EntityPlayer); + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(12, new Integer(0)); + } + + /** + * The age value may be negative or positive or zero. If it's negative, it get's + * incremented on each tick, if it's positive, it get's decremented each tick. + * Don't confuse this with EntityLiving.getAge. With a negative value the Entity + * is considered a child. + */ + public int getGrowingAge() { + return this.dataWatcher.getWatchableObjectInt(12); + } + + /** + * The age value may be negative or positive or zero. If it's negative, it get's + * incremented on each tick, if it's positive, it get's decremented each tick. + * With a negative value the Entity is considered a child. + */ + public void setGrowingAge(int par1) { + this.dataWatcher.updateObject(12, Integer.valueOf(par1)); + this.func_98054_a(this.isChild()); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("Age", this.getGrowingAge()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setGrowingAge(par1NBTTagCompound.getInteger("Age")); + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (this.worldObj.isRemote) { + this.func_98054_a(this.isChild()); + } else { + int var1 = this.getGrowingAge(); + + if (var1 < 0) { + ++var1; + this.setGrowingAge(var1); + } else if (var1 > 0) { + --var1; + this.setGrowingAge(var1); + } + } + } + + /** + * If Animal, checks if the age timer is negative + */ + public boolean isChild() { + return this.getGrowingAge() < 0; + } + + public void func_98054_a(boolean par1) { + this.func_98055_j(par1 ? 0.5F : 1.0F); + } + + /** + * Sets the width and height of the entity. Args: width, height + */ + protected final void setSize(float par1, float par2) { + boolean var3 = this.field_98056_d > 0.0F; + this.field_98056_d = par1; + this.field_98057_e = par2; + + if (!var3) { + this.func_98055_j(1.0F); + } + } + + private void func_98055_j(float par1) { + super.setSize(this.field_98056_d * par1, this.field_98057_e * par1); + } +} diff --git a/src/main/java/net/minecraft/src/EntityAmbientCreature.java b/src/main/java/net/minecraft/src/EntityAmbientCreature.java new file mode 100644 index 0000000..30f1b46 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityAmbientCreature.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public abstract class EntityAmbientCreature extends EntityLiving implements IAnimals { + +} diff --git a/src/main/java/net/minecraft/src/EntityAnimal.java b/src/main/java/net/minecraft/src/EntityAnimal.java new file mode 100644 index 0000000..ae24c03 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityAnimal.java @@ -0,0 +1,316 @@ +package net.minecraft.src; + +import java.util.List; + + + +public abstract class EntityAnimal extends EntityAgeable implements IAnimals { + private int inLove; + + /** + * This is representation of a counter for reproduction progress. (Note that + * this is different from the inLove which represent being in Love-Mode) + */ + private int breeding = 0; + + /** + * main AI tick function, replaces updateEntityActionState + */ + protected void updateAITick() { + if (this.getGrowingAge() != 0) { + this.inLove = 0; + } + + super.updateAITick(); + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (this.getGrowingAge() != 0) { + this.inLove = 0; + } + + if (this.inLove > 0) { + --this.inLove; + String var1 = "heart"; + + if (this.inLove % 10 == 0) { + double var2 = this.rand.nextGaussian() * 0.02D; + double var4 = this.rand.nextGaussian() * 0.02D; + double var6 = this.rand.nextGaussian() * 0.02D; + this.worldObj.spawnParticle(var1, this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, this.posY + 0.5D + (double) (this.rand.nextFloat() * this.height), + this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, var2, var4, var6); + } + } else { + this.breeding = 0; + } + } + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by + * each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) { + if (par1Entity instanceof EntityPlayer) { + if (par2 < 3.0F) { + double var3 = par1Entity.posX - this.posX; + double var5 = par1Entity.posZ - this.posZ; + this.rotationYaw = (float) (Math.atan2(var5, var3) * 180.0D / Math.PI) - 90.0F; + this.hasAttacked = true; + } + + EntityPlayer var7 = (EntityPlayer) par1Entity; + + if (var7.getCurrentEquippedItem() == null || !this.isBreedingItem(var7.getCurrentEquippedItem())) { + this.entityToAttack = null; + } + } else if (par1Entity instanceof EntityAnimal) { + EntityAnimal var8 = (EntityAnimal) par1Entity; + + if (this.getGrowingAge() > 0 && var8.getGrowingAge() < 0) { + if ((double) par2 < 2.5D) { + this.hasAttacked = true; + } + } else if (this.inLove > 0 && var8.inLove > 0) { + if (var8.entityToAttack == null) { + var8.entityToAttack = this; + } + + if (var8.entityToAttack == this && (double) par2 < 3.5D) { + ++var8.inLove; + ++this.inLove; + ++this.breeding; + + if (this.breeding % 4 == 0) { + this.worldObj.spawnParticle("heart", this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, this.posY + 0.5D + (double) (this.rand.nextFloat() * this.height), + this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, 0.0D, 0.0D, 0.0D); + } + + if (this.breeding == 60) { + this.procreate((EntityAnimal) par1Entity); + } + } else { + this.breeding = 0; + } + } else { + this.breeding = 0; + this.entityToAttack = null; + } + } + } + + /** + * Creates a baby animal according to the animal type of the target at the + * actual position and spawns 'love' particles. + */ + private void procreate(EntityAnimal par1EntityAnimal) { + EntityAgeable var2 = this.createChild(par1EntityAnimal); + + if (var2 != null) { + this.setGrowingAge(6000); + par1EntityAnimal.setGrowingAge(6000); + this.inLove = 0; + this.breeding = 0; + this.entityToAttack = null; + par1EntityAnimal.entityToAttack = null; + par1EntityAnimal.breeding = 0; + par1EntityAnimal.inLove = 0; + var2.setGrowingAge(-24000); + var2.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); + + for (int var3 = 0; var3 < 7; ++var3) { + double var4 = this.rand.nextGaussian() * 0.02D; + double var6 = this.rand.nextGaussian() * 0.02D; + double var8 = this.rand.nextGaussian() * 0.02D; + this.worldObj.spawnParticle("heart", this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, this.posY + 0.5D + (double) (this.rand.nextFloat() * this.height), + this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, var4, var6, var8); + } + + this.worldObj.spawnEntityInWorld(var2); + } + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + this.fleeingTick = 60; + this.entityToAttack = null; + this.inLove = 0; + return super.attackEntityFrom(par1DamageSource, par2); + } + } + + /** + * Takes a coordinate in and returns a weight to determine how likely this + * creature will try to path to the block. Args: x, y, z + */ + public float getBlockPathWeight(int par1, int par2, int par3) { + return this.worldObj.getBlockId(par1, par2 - 1, par3) == Block.grass.blockID ? 10.0F : this.worldObj.getLightBrightness(par1, par2, par3) - 0.5F; + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("InLove", this.inLove); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.inLove = par1NBTTagCompound.getInteger("InLove"); + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity + * isn't interested in attacking (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() { + if (this.fleeingTick > 0) { + return null; + } else { + float var1 = 8.0F; + List var2; + int var3; + EntityAnimal var4; + + if (this.inLove > 0) { + var2 = this.worldObj.getEntitiesWithinAABB(this.getClass(), this.boundingBox.expand((double) var1, (double) var1, (double) var1)); + + for (var3 = 0; var3 < var2.size(); ++var3) { + var4 = (EntityAnimal) var2.get(var3); + + if (var4 != this && var4.inLove > 0) { + return var4; + } + } + } else if (this.getGrowingAge() == 0) { + var2 = this.worldObj.getEntitiesWithinAABB(EntityPlayer.class, this.boundingBox.expand((double) var1, (double) var1, (double) var1)); + + for (var3 = 0; var3 < var2.size(); ++var3) { + EntityPlayer var5 = (EntityPlayer) var2.get(var3); + + if (var5.getCurrentEquippedItem() != null && this.isBreedingItem(var5.getCurrentEquippedItem())) { + return var5; + } + } + } else if (this.getGrowingAge() > 0) { + var2 = this.worldObj.getEntitiesWithinAABB(this.getClass(), this.boundingBox.expand((double) var1, (double) var1, (double) var1)); + + for (var3 = 0; var3 < var2.size(); ++var3) { + var4 = (EntityAnimal) var2.get(var3); + + if (var4 != this && var4.getGrowingAge() < 0) { + return var4; + } + } + } + + return null; + } + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.boundingBox.minY); + int var3 = MathHelper.floor_double(this.posZ); + return this.worldObj.getBlockId(var1, var2 - 1, var3) == Block.grass.blockID && this.worldObj.getFullBlockLightValue(var1, var2, var3) > 8 && super.getCanSpawnHere(); + } + + /** + * Get number of ticks, at least during which the living entity will be silent. + */ + public int getTalkInterval() { + return 120; + } + + /** + * Determines if an entity can be despawned, used on idle far away entities + */ + protected boolean canDespawn() { + return false; + } + + /** + * Get the experience points the entity currently has. + */ + protected int getExperiencePoints(EntityPlayer par1EntityPlayer) { + return 1 + this.worldObj.rand.nextInt(3); + } + + /** + * Checks if the parameter is an item which this animal can be fed to breed it + * (wheat, carrots or seeds depending on the animal type) + */ + public boolean isBreedingItem(ItemStack par1ItemStack) { + return par1ItemStack.itemID == Item.wheat.itemID; + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + + if (var2 != null && this.isBreedingItem(var2) && this.getGrowingAge() == 0 && this.inLove <= 0) { + if (!par1EntityPlayer.capabilities.isCreativeMode) { + --var2.stackSize; + + if (var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null); + } + } + + this.inLove = 600; + this.entityToAttack = null; + + for (int var3 = 0; var3 < 7; ++var3) { + double var4 = this.rand.nextGaussian() * 0.02D; + double var6 = this.rand.nextGaussian() * 0.02D; + double var8 = this.rand.nextGaussian() * 0.02D; + this.worldObj.spawnParticle("heart", this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, this.posY + 0.5D + (double) (this.rand.nextFloat() * this.height), + this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, var4, var6, var8); + } + + return true; + } else { + return super.interact(par1EntityPlayer); + } + } + + /** + * Returns if the entity is currently in 'love mode'. + */ + public boolean isInLove() { + return this.inLove > 0; + } + + public void resetInLove() { + this.inLove = 0; + } + + /** + * Returns true if the mob is currently able to mate with the specified mob. + */ + public boolean canMateWith(EntityAnimal par1EntityAnimal) { + return par1EntityAnimal == this ? false : (par1EntityAnimal.getClass() != this.getClass() ? false : this.isInLove() && par1EntityAnimal.isInLove()); + } +} diff --git a/src/main/java/net/minecraft/src/EntityArrow.java b/src/main/java/net/minecraft/src/EntityArrow.java new file mode 100644 index 0000000..b18837a --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityArrow.java @@ -0,0 +1,492 @@ +package net.minecraft.src; + +import java.util.List; + + + +public class EntityArrow extends Entity implements IProjectile { + private int xTile = -1; + private int yTile = -1; + private int zTile = -1; + private int inTile = 0; + private int inData = 0; + private boolean inGround = false; + + /** 1 if the player can pick up the arrow */ + public int canBePickedUp = 0; + + /** Seems to be some sort of timer for animating an arrow. */ + public int arrowShake = 0; + + /** The owner of this arrow. */ + public Entity shootingEntity; + private int ticksInGround; + private int ticksInAir = 0; + private double damage = 2.0D; + + /** The amount of knockback an arrow applies when it hits a mob. */ + private int knockbackStrength; + + public EntityArrow() { + super(); + this.renderDistanceWeight = 10.0D; + this.setSize(0.5F, 0.5F); + } + + public EntityArrow(World par1World, double par2, double par4, double par6) { + super(); + this.setWorld(par1World); + this.renderDistanceWeight = 10.0D; + this.setSize(0.5F, 0.5F); + this.setPosition(par2, par4, par6); + this.yOffset = 0.0F; + } + + public EntityArrow(World par1World, EntityLiving par2EntityLiving, EntityLiving par3EntityLiving, float par4, float par5) { + super(); + this.setWorld(par1World); + this.renderDistanceWeight = 10.0D; + this.shootingEntity = par2EntityLiving; + + if (par2EntityLiving instanceof EntityPlayer) { + this.canBePickedUp = 1; + } + + this.posY = par2EntityLiving.posY + (double) par2EntityLiving.getEyeHeight() - 0.10000000149011612D; + double var6 = par3EntityLiving.posX - par2EntityLiving.posX; + double var8 = par3EntityLiving.boundingBox.minY + (double) (par3EntityLiving.height / 3.0F) - this.posY; + double var10 = par3EntityLiving.posZ - par2EntityLiving.posZ; + double var12 = (double) MathHelper.sqrt_double(var6 * var6 + var10 * var10); + + if (var12 >= 1.0E-7D) { + float var14 = (float) (Math.atan2(var10, var6) * 180.0D / Math.PI) - 90.0F; + float var15 = (float) (-(Math.atan2(var8, var12) * 180.0D / Math.PI)); + double var16 = var6 / var12; + double var18 = var10 / var12; + this.setLocationAndAngles(par2EntityLiving.posX + var16, this.posY, par2EntityLiving.posZ + var18, var14, var15); + this.yOffset = 0.0F; + float var20 = (float) var12 * 0.2F; + this.setThrowableHeading(var6, var8 + (double) var20, var10, par4, par5); + } + } + + public EntityArrow(World par1World, EntityLiving par2EntityLiving, float par3) { + super(); + this.setWorld(par1World); + this.renderDistanceWeight = 10.0D; + this.shootingEntity = par2EntityLiving; + + if (par2EntityLiving instanceof EntityPlayer) { + this.canBePickedUp = 1; + } + + this.setSize(0.5F, 0.5F); + this.setLocationAndAngles(par2EntityLiving.posX, par2EntityLiving.posY + (double) par2EntityLiving.getEyeHeight(), par2EntityLiving.posZ, par2EntityLiving.rotationYaw, par2EntityLiving.rotationPitch); + this.posX -= (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * 0.16F); + this.posY -= 0.10000000149011612D; + this.posZ -= (double) (MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * 0.16F); + this.setPosition(this.posX, this.posY, this.posZ); + this.yOffset = 0.0F; + this.motionX = (double) (-MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI)); + this.motionZ = (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI)); + this.motionY = (double) (-MathHelper.sin(this.rotationPitch / 180.0F * (float) Math.PI)); + this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, par3 * 1.5F, 1.0F); + } + + protected void entityInit() { + this.dataWatcher.addObject(16, Byte.valueOf((byte) 0)); + } + + /** + * Similar to setArrowHeading, it's point the throwable entity to a x, y, z + * direction. + */ + public void setThrowableHeading(double par1, double par3, double par5, float par7, float par8) { + float var9 = MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5); + par1 /= (double) var9; + par3 /= (double) var9; + par5 /= (double) var9; + par1 += this.rand.nextGaussian() * (double) (this.rand.nextBoolean() ? -1 : 1) * 0.007499999832361937D * (double) par8; + par3 += this.rand.nextGaussian() * (double) (this.rand.nextBoolean() ? -1 : 1) * 0.007499999832361937D * (double) par8; + par5 += this.rand.nextGaussian() * (double) (this.rand.nextBoolean() ? -1 : 1) * 0.007499999832361937D * (double) par8; + par1 *= (double) par7; + par3 *= (double) par7; + par5 *= (double) par7; + this.motionX = par1; + this.motionY = par3; + this.motionZ = par5; + float var10 = MathHelper.sqrt_double(par1 * par1 + par5 * par5); + this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(par1, par5) * 180.0D / Math.PI); + this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(par3, (double) var10) * 180.0D / Math.PI); + this.ticksInGround = 0; + } + + /** + * Sets the position and rotation. Only difference from the other one is no + * bounding on the rotation. Args: posX, posY, posZ, yaw, pitch + */ + public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9) { + this.setPosition(par1, par3, par5); + this.setRotation(par7, par8); + } + + /** + * Sets the velocity to the args. Args: x, y, z + */ + public void setVelocity(double par1, double par3, double par5) { + this.motionX = par1; + this.motionY = par3; + this.motionZ = par5; + + if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) { + float var7 = MathHelper.sqrt_double(par1 * par1 + par5 * par5); + this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(par1, par5) * 180.0D / Math.PI); + this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(par3, (double) var7) * 180.0D / Math.PI); + this.prevRotationPitch = this.rotationPitch; + this.prevRotationYaw = this.rotationYaw; + this.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); + this.ticksInGround = 0; + } + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) { + float var1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); + this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(this.motionY, (double) var1) * 180.0D / Math.PI); + } + + int var16 = this.worldObj.getBlockId(this.xTile, this.yTile, this.zTile); + + if (var16 > 0) { + Block.blocksList[var16].setBlockBoundsBasedOnState(this.worldObj, this.xTile, this.yTile, this.zTile); + AxisAlignedBB var2 = Block.blocksList[var16].getCollisionBoundingBoxFromPool(this.worldObj, this.xTile, this.yTile, this.zTile); + + if (var2 != null && var2.isVecInside(this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ))) { + this.inGround = true; + } + } + + if (this.arrowShake > 0) { + --this.arrowShake; + } + + if (this.inGround) { + int var18 = this.worldObj.getBlockId(this.xTile, this.yTile, this.zTile); + int var19 = this.worldObj.getBlockMetadata(this.xTile, this.yTile, this.zTile); + + if (var18 == this.inTile && var19 == this.inData) { + ++this.ticksInGround; + + if (this.ticksInGround == 1200) { + this.setDead(); + } + } else { + this.inGround = false; + this.motionX *= (double) (this.rand.nextFloat() * 0.2F); + this.motionY *= (double) (this.rand.nextFloat() * 0.2F); + this.motionZ *= (double) (this.rand.nextFloat() * 0.2F); + this.ticksInGround = 0; + this.ticksInAir = 0; + } + } else { + ++this.ticksInAir; + Vec3 var17 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + Vec3 var3 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); + MovingObjectPosition var4 = this.worldObj.rayTraceBlocks_do_do(var17, var3, false, true); + var17 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + var3 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); + + if (var4 != null) { + var3 = this.worldObj.getWorldVec3Pool().getVecFromPool(var4.hitVec.xCoord, var4.hitVec.yCoord, var4.hitVec.zCoord); + } + + Entity var5 = null; + List var6 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D)); + double var7 = 0.0D; + int var9; + float var11; + + for (var9 = 0; var9 < var6.size(); ++var9) { + Entity var10 = (Entity) var6.get(var9); + + if (var10.canBeCollidedWith() && (var10 != this.shootingEntity || this.ticksInAir >= 5)) { + var11 = 0.3F; + AxisAlignedBB var12 = var10.boundingBox.expand((double) var11, (double) var11, (double) var11); + MovingObjectPosition var13 = var12.calculateIntercept(var17, var3); + + if (var13 != null) { + double var14 = var17.distanceTo(var13.hitVec); + + if (var14 < var7 || var7 == 0.0D) { + var5 = var10; + var7 = var14; + } + } + } + } + + if (var5 != null) { + var4 = new MovingObjectPosition(var5); + } + + if (var4 != null && var4.entityHit != null && var4.entityHit instanceof EntityPlayer) { + EntityPlayer var20 = (EntityPlayer) var4.entityHit; + + if (var20.capabilities.disableDamage || this.shootingEntity instanceof EntityPlayer && !((EntityPlayer) this.shootingEntity).func_96122_a(var20)) { + var4 = null; + } + } + + float var21; + float var27; + + if (var4 != null) { + if (var4.entityHit != null) { + var21 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); + int var22 = MathHelper.ceiling_double_int((double) var21 * this.damage); + + if (this.getIsCritical()) { + var22 += this.rand.nextInt(var22 / 2 + 2); + } + + DamageSource var23 = null; + + if (this.shootingEntity == null) { + var23 = DamageSource.causeArrowDamage(this, this); + } else { + var23 = DamageSource.causeArrowDamage(this, this.shootingEntity); + } + + if (this.isBurning() && !(var4.entityHit instanceof EntityEnderman)) { + var4.entityHit.setFire(5); + } + + if (var4.entityHit.attackEntityFrom(var23, var22)) { + if (var4.entityHit instanceof EntityLiving) { + EntityLiving var25 = (EntityLiving) var4.entityHit; + + if (!this.worldObj.isRemote) { + var25.setArrowCountInEntity(var25.getArrowCountInEntity() + 1); + } + + if (this.knockbackStrength > 0) { + var27 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + + if (var27 > 0.0F) { + var4.entityHit.addVelocity(this.motionX * (double) this.knockbackStrength * 0.6000000238418579D / (double) var27, 0.1D, + this.motionZ * (double) this.knockbackStrength * 0.6000000238418579D / (double) var27); + } + } + + if (this.shootingEntity != null) { + EnchantmentThorns.func_92096_a(this.shootingEntity, var25, this.rand); + } + } + + this.playSound("random.bowhit", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + + if (!(var4.entityHit instanceof EntityEnderman)) { + this.setDead(); + } + } else { + this.motionX *= -0.10000000149011612D; + this.motionY *= -0.10000000149011612D; + this.motionZ *= -0.10000000149011612D; + this.rotationYaw += 180.0F; + this.prevRotationYaw += 180.0F; + this.ticksInAir = 0; + } + } else { + this.xTile = var4.blockX; + this.yTile = var4.blockY; + this.zTile = var4.blockZ; + this.inTile = this.worldObj.getBlockId(this.xTile, this.yTile, this.zTile); + this.inData = this.worldObj.getBlockMetadata(this.xTile, this.yTile, this.zTile); + this.motionX = (double) ((float) (var4.hitVec.xCoord - this.posX)); + this.motionY = (double) ((float) (var4.hitVec.yCoord - this.posY)); + this.motionZ = (double) ((float) (var4.hitVec.zCoord - this.posZ)); + var21 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); + this.posX -= this.motionX / (double) var21 * 0.05000000074505806D; + this.posY -= this.motionY / (double) var21 * 0.05000000074505806D; + this.posZ -= this.motionZ / (double) var21 * 0.05000000074505806D; + this.playSound("random.bowhit", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + this.inGround = true; + this.arrowShake = 7; + this.setIsCritical(false); + + if (this.inTile != 0) { + Block.blocksList[this.inTile].onEntityCollidedWithBlock(this.worldObj, this.xTile, this.yTile, this.zTile, this); + } + } + } + + if (this.getIsCritical()) { + for (var9 = 0; var9 < 4; ++var9) { + this.worldObj.spawnParticle("crit", this.posX + this.motionX * (double) var9 / 4.0D, this.posY + this.motionY * (double) var9 / 4.0D, this.posZ + this.motionZ * (double) var9 / 4.0D, -this.motionX, -this.motionY + 0.2D, + -this.motionZ); + } + } + + this.posX += this.motionX; + this.posY += this.motionY; + this.posZ += this.motionZ; + var21 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); + + for (this.rotationPitch = (float) (Math.atan2(this.motionY, (double) var21) * 180.0D / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) { + ; + } + + while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { + this.prevRotationPitch += 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw < -180.0F) { + this.prevRotationYaw -= 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { + this.prevRotationYaw += 360.0F; + } + + this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; + this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; + float var24 = 0.99F; + var11 = 0.05F; + + if (this.isInWater()) { + for (int var26 = 0; var26 < 4; ++var26) { + var27 = 0.25F; + this.worldObj.spawnParticle("bubble", this.posX - this.motionX * (double) var27, this.posY - this.motionY * (double) var27, this.posZ - this.motionZ * (double) var27, this.motionX, this.motionY, this.motionZ); + } + + var24 = 0.8F; + } + + this.motionX *= (double) var24; + this.motionY *= (double) var24; + this.motionZ *= (double) var24; + this.motionY -= (double) var11; + this.setPosition(this.posX, this.posY, this.posZ); + this.doBlockCollisions(); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setShort("xTile", (short) this.xTile); + par1NBTTagCompound.setShort("yTile", (short) this.yTile); + par1NBTTagCompound.setShort("zTile", (short) this.zTile); + par1NBTTagCompound.setByte("inTile", (byte) this.inTile); + par1NBTTagCompound.setByte("inData", (byte) this.inData); + par1NBTTagCompound.setByte("shake", (byte) this.arrowShake); + par1NBTTagCompound.setByte("inGround", (byte) (this.inGround ? 1 : 0)); + par1NBTTagCompound.setByte("pickup", (byte) this.canBePickedUp); + par1NBTTagCompound.setDouble("damage", this.damage); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.xTile = par1NBTTagCompound.getShort("xTile"); + this.yTile = par1NBTTagCompound.getShort("yTile"); + this.zTile = par1NBTTagCompound.getShort("zTile"); + this.inTile = par1NBTTagCompound.getByte("inTile") & 255; + this.inData = par1NBTTagCompound.getByte("inData") & 255; + this.arrowShake = par1NBTTagCompound.getByte("shake") & 255; + this.inGround = par1NBTTagCompound.getByte("inGround") == 1; + + if (par1NBTTagCompound.hasKey("damage")) { + this.damage = par1NBTTagCompound.getDouble("damage"); + } + + if (par1NBTTagCompound.hasKey("pickup")) { + this.canBePickedUp = par1NBTTagCompound.getByte("pickup"); + } else if (par1NBTTagCompound.hasKey("player")) { + this.canBePickedUp = par1NBTTagCompound.getBoolean("player") ? 1 : 0; + } + } + + /** + * Called by a player entity when they collide with an entity + */ + public void onCollideWithPlayer(EntityPlayer par1EntityPlayer) { + if (!this.worldObj.isRemote && this.inGround && this.arrowShake <= 0) { + boolean var2 = this.canBePickedUp == 1 || this.canBePickedUp == 2 && par1EntityPlayer.capabilities.isCreativeMode; + + if (this.canBePickedUp == 1 && !par1EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Item.arrow, 1))) { + var2 = false; + } + + if (var2) { + this.playSound("random.pop", 0.2F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + par1EntityPlayer.onItemPickup(this, 1); + this.setDead(); + } + } + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + public float getShadowSize() { + return 0.0F; + } + + public void setDamage(double par1) { + this.damage = par1; + } + + public double getDamage() { + return this.damage; + } + + /** + * Sets the amount of knockback the arrow applies when it hits a mob. + */ + public void setKnockbackStrength(int par1) { + this.knockbackStrength = par1; + } + + /** + * If returns false, the item will not inflict any damage against entities. + */ + public boolean canAttackWithItem() { + return false; + } + + /** + * Whether the arrow has a stream of critical hit particles flying behind it. + */ + public void setIsCritical(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 1))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -2))); + } + } + + /** + * Whether the arrow has a stream of critical hit particles flying behind it. + */ + public boolean getIsCritical() { + byte var1 = this.dataWatcher.getWatchableObjectByte(16); + return (var1 & 1) != 0; + } +} diff --git a/src/main/java/net/minecraft/src/EntityAuraFX.java b/src/main/java/net/minecraft/src/EntityAuraFX.java new file mode 100644 index 0000000..2e4af77 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityAuraFX.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + + + +public class EntityAuraFX extends EntityFX { + public EntityAuraFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + super(par1World, par2, par4, par6, par8, par10, par12); + float var14 = this.rand.nextFloat() * 0.1F + 0.2F; + this.particleRed = var14; + this.particleGreen = var14; + this.particleBlue = var14; + this.setParticleTextureIndex(0); + this.setSize(0.02F, 0.02F); + this.particleScale *= this.rand.nextFloat() * 0.6F + 0.5F; + this.motionX *= 0.019999999552965164D; + this.motionY *= 0.019999999552965164D; + this.motionZ *= 0.019999999552965164D; + this.particleMaxAge = (int) (20.0D / (Math.random() * 0.8D + 0.2D)); + this.noClip = true; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.99D; + this.motionY *= 0.99D; + this.motionZ *= 0.99D; + + if (this.particleMaxAge-- <= 0) { + this.setDead(); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityBat.java b/src/main/java/net/minecraft/src/EntityBat.java new file mode 100644 index 0000000..5b8974c --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityBat.java @@ -0,0 +1,250 @@ +package net.minecraft.src; + +import java.util.Calendar; + + + +public class EntityBat extends EntityAmbientCreature { + /** + * randomly selected ChunkCoordinates in a 7x6x7 box around the bat (y offset -2 + * to 4) towards which it will fly. upon getting close a new target will be + * selected + */ + private ChunkCoordinates currentFlightTarget; + + public EntityBat() { + super(); + this.setSize(0.5F, 0.9F); + this.setIsBatHanging(true); + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte) 0)); + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 0.1F; + } + + /** + * Gets the pitch of living sounds in living entities. + */ + protected float getSoundPitch() { + return super.getSoundPitch() * 0.95F; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return this.getIsBatHanging() && this.rand.nextInt(4) != 0 ? null : "mob.bat.idle"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.bat.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.bat.death"; + } + + /** + * Returns true if this entity should push and be pushed by other entities when + * colliding. + */ + public boolean canBePushed() { + return false; + } + + protected void collideWithEntity(Entity par1Entity) { + } + + protected void func_85033_bc() { + } + + public int getMaxHealth() { + return 6; + } + + public boolean getIsBatHanging() { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + public void setIsBatHanging(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 1))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -2))); + } + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() { + return true; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.getIsBatHanging()) { + this.motionX = this.motionY = this.motionZ = 0.0D; + this.posY = (double) MathHelper.floor_double(this.posY) + 1.0D - (double) this.height; + } else { + this.motionY *= 0.6000000238418579D; + } + } + + protected void updateAITasks() { + super.updateAITasks(); + + if (this.getIsBatHanging()) { + if (!this.worldObj.isBlockNormalCube(MathHelper.floor_double(this.posX), (int) this.posY + 1, MathHelper.floor_double(this.posZ))) { + this.setIsBatHanging(false); + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1015, (int) this.posX, (int) this.posY, (int) this.posZ, 0); + } else { + if (this.rand.nextInt(200) == 0) { + this.rotationYawHead = (float) this.rand.nextInt(360); + } + + if (this.worldObj.getClosestPlayerToEntity(this, 4.0D) != null) { + this.setIsBatHanging(false); + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1015, (int) this.posX, (int) this.posY, (int) this.posZ, 0); + } + } + } else { + if (this.currentFlightTarget != null && (!this.worldObj.isAirBlock(this.currentFlightTarget.posX, this.currentFlightTarget.posY, this.currentFlightTarget.posZ) || this.currentFlightTarget.posY < 1)) { + this.currentFlightTarget = null; + } + + if (this.currentFlightTarget == null || this.rand.nextInt(30) == 0 || this.currentFlightTarget.getDistanceSquared((int) this.posX, (int) this.posY, (int) this.posZ) < 4.0F) { + this.currentFlightTarget = new ChunkCoordinates((int) this.posX + this.rand.nextInt(7) - this.rand.nextInt(7), (int) this.posY + this.rand.nextInt(6) - 2, (int) this.posZ + this.rand.nextInt(7) - this.rand.nextInt(7)); + } + + double var1 = (double) this.currentFlightTarget.posX + 0.5D - this.posX; + double var3 = (double) this.currentFlightTarget.posY + 0.1D - this.posY; + double var5 = (double) this.currentFlightTarget.posZ + 0.5D - this.posZ; + this.motionX += (Math.signum(var1) * 0.5D - this.motionX) * 0.10000000149011612D; + this.motionY += (Math.signum(var3) * 0.699999988079071D - this.motionY) * 0.10000000149011612D; + this.motionZ += (Math.signum(var5) * 0.5D - this.motionZ) * 0.10000000149011612D; + float var7 = (float) (Math.atan2(this.motionZ, this.motionX) * 180.0D / Math.PI) - 90.0F; + float var8 = MathHelper.wrapAngleTo180_float(var7 - this.rotationYaw); + this.moveForward = 0.5F; + this.rotationYaw += var8; + + if (this.rand.nextInt(100) == 0 && this.worldObj.isBlockNormalCube(MathHelper.floor_double(this.posX), (int) this.posY + 1, MathHelper.floor_double(this.posZ))) { + this.setIsBatHanging(true); + } + } + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * Takes in the distance the entity has fallen this tick and whether its on the + * ground to update the fall distance and deal fall damage if landing on the + * ground. Args: distanceFallenThisTick, onGround + */ + protected void updateFallState(double par1, boolean par3) { + } + + /** + * Return whether this entity should NOT trigger a pressure plate or a tripwire. + */ + public boolean doesEntityNotTriggerPressurePlate() { + return true; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + if (!this.worldObj.isRemote && this.getIsBatHanging()) { + this.setIsBatHanging(false); + } + + return super.attackEntityFrom(par1DamageSource, par2); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.dataWatcher.updateObject(16, Byte.valueOf(par1NBTTagCompound.getByte("BatFlags"))); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setByte("BatFlags", this.dataWatcher.getWatchableObjectByte(16)); + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + int var1 = MathHelper.floor_double(this.boundingBox.minY); + + if (var1 >= 63) { + return false; + } else { + int var2 = MathHelper.floor_double(this.posX); + int var3 = MathHelper.floor_double(this.posZ); + int var4 = this.worldObj.getBlockLightValue(var2, var1, var3); + byte var5 = 4; + Calendar var6 = this.worldObj.getCurrentDate(); + + if ((var6.get(2) + 1 != 10 || var6.get(5) < 20) && (var6.get(2) + 1 != 11 || var6.get(5) > 3)) { + if (this.rand.nextBoolean()) { + return false; + } + } else { + var5 = 7; + } + + return var4 > this.rand.nextInt(var5) ? false : super.getCanSpawnHere(); + } + } + + /** + * Initialize this creature. + */ + public void initCreature() { + } +} diff --git a/src/main/java/net/minecraft/src/EntityBlaze.java b/src/main/java/net/minecraft/src/EntityBlaze.java new file mode 100644 index 0000000..d12943a --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityBlaze.java @@ -0,0 +1,208 @@ +package net.minecraft.src; + + + +public class EntityBlaze extends EntityMob { + /** Random offset used in floating behaviour */ + private float heightOffset = 0.5F; + + /** ticks until heightOffset is randomized */ + private int heightOffsetUpdateTime; + private int field_70846_g; + + public EntityBlaze() { + super(); + this.isImmuneToFire = true; + this.experienceValue = 10; + } + + public int getMaxHealth() { + return 20; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte) 0)); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.blaze.breathe"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.blaze.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.blaze.death"; + } + + public int getBrightnessForRender(float par1) { + return 15728880; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + return 1.0F; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (!this.worldObj.isRemote) { + if (this.isWet()) { + this.attackEntityFrom(DamageSource.drown, 1); + } + + --this.heightOffsetUpdateTime; + + if (this.heightOffsetUpdateTime <= 0) { + this.heightOffsetUpdateTime = 100; + this.heightOffset = 0.5F + (float) this.rand.nextGaussian() * 3.0F; + } + + if (this.getEntityToAttack() != null && this.getEntityToAttack().posY + (double) this.getEntityToAttack().getEyeHeight() > this.posY + (double) this.getEyeHeight() + (double) this.heightOffset) { + this.motionY += (0.30000001192092896D - this.motionY) * 0.30000001192092896D; + } + } + + if (this.rand.nextInt(24) == 0) { + this.worldObj.playSoundEffect(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, "fire.fire", 1.0F + this.rand.nextFloat(), this.rand.nextFloat() * 0.7F + 0.3F); + } + + if (!this.onGround && this.motionY < 0.0D) { + this.motionY *= 0.6D; + } + + for (int var1 = 0; var1 < 2; ++var1) { + this.worldObj.spawnParticle("largesmoke", this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.width, this.posY + this.rand.nextDouble() * (double) this.height, + this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.width, 0.0D, 0.0D, 0.0D); + } + + super.onLivingUpdate(); + } + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by + * each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) { + if (this.attackTime <= 0 && par2 < 2.0F && par1Entity.boundingBox.maxY > this.boundingBox.minY && par1Entity.boundingBox.minY < this.boundingBox.maxY) { + this.attackTime = 20; + this.attackEntityAsMob(par1Entity); + } else if (par2 < 30.0F) { + double var3 = par1Entity.posX - this.posX; + double var5 = par1Entity.boundingBox.minY + (double) (par1Entity.height / 2.0F) - (this.posY + (double) (this.height / 2.0F)); + double var7 = par1Entity.posZ - this.posZ; + + if (this.attackTime == 0) { + ++this.field_70846_g; + + if (this.field_70846_g == 1) { + this.attackTime = 60; + this.func_70844_e(true); + } else if (this.field_70846_g <= 4) { + this.attackTime = 6; + } else { + this.attackTime = 100; + this.field_70846_g = 0; + this.func_70844_e(false); + } + + if (this.field_70846_g > 1) { + float var9 = MathHelper.sqrt_float(par2) * 0.5F; + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1009, (int) this.posX, (int) this.posY, (int) this.posZ, 0); + + for (int var10 = 0; var10 < 1; ++var10) { + EntitySmallFireball var11 = new EntitySmallFireball(this.worldObj, this, var3 + this.rand.nextGaussian() * (double) var9, var5, var7 + this.rand.nextGaussian() * (double) var9); + var11.posY = this.posY + (double) (this.height / 2.0F) + 0.5D; + this.worldObj.spawnEntityInWorld(var11); + } + } + } + + this.rotationYaw = (float) (Math.atan2(var7, var3) * 180.0D / Math.PI) - 90.0F; + this.hasAttacked = true; + } + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.blazeRod.itemID; + } + + /** + * Returns true if the entity is on fire. Used by render to add the fire effect + * on rendering. + */ + public boolean isBurning() { + return this.func_70845_n(); + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + if (par1) { + int var3 = this.rand.nextInt(2 + par2); + + for (int var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.blazeRod.itemID, 1); + } + } + } + + public boolean func_70845_n() { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + public void func_70844_e(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + var2 = (byte) (var2 | 1); + } else { + var2 &= -2; + } + + this.dataWatcher.updateObject(16, Byte.valueOf(var2)); + } + + /** + * Checks to make sure the light is not too bright where the mob is spawning + */ + protected boolean isValidLightLevel() { + return true; + } + + /** + * Returns the amount of damage a mob should deal. + */ + public int getAttackStrength(Entity par1Entity) { + return 6; + } +} diff --git a/src/main/java/net/minecraft/src/EntityBoat.java b/src/main/java/net/minecraft/src/EntityBoat.java new file mode 100644 index 0000000..23a69e1 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityBoat.java @@ -0,0 +1,472 @@ +package net.minecraft.src; + +import java.util.List; + + + +public class EntityBoat extends Entity { + private boolean field_70279_a; + private double speedMultiplier; + private int boatPosRotationIncrements; + private double boatX; + private double boatY; + private double boatZ; + private double boatYaw; + private double boatPitch; + private double velocityX; + private double velocityY; + private double velocityZ; + + public EntityBoat() { + super(); + this.field_70279_a = true; + this.speedMultiplier = 0.07D; + this.preventEntitySpawning = true; + this.setSize(1.5F, 0.6F); + this.yOffset = this.height / 2.0F; + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + protected void entityInit() { + this.dataWatcher.addObject(17, new Integer(0)); + this.dataWatcher.addObject(18, new Integer(1)); + this.dataWatcher.addObject(19, new Integer(0)); + } + + /** + * Returns a boundingBox used to collide the entity with other entities and + * blocks. This enables the entity to be pushable on contact, like boats or + * minecarts. + */ + public AxisAlignedBB getCollisionBox(Entity par1Entity) { + return par1Entity.boundingBox; + } + + /** + * returns the bounding box for this entity + */ + public AxisAlignedBB getBoundingBox() { + return this.boundingBox; + } + + /** + * Returns true if this entity should push and be pushed by other entities when + * colliding. + */ + public boolean canBePushed() { + return true; + } + + public EntityBoat(World par1World, double par2, double par4, double par6) { + this(); + this.setWorld(par1World); + this.setPosition(par2, par4 + (double) this.yOffset, par6); + this.motionX = 0.0D; + this.motionY = 0.0D; + this.motionZ = 0.0D; + this.prevPosX = par2; + this.prevPosY = par4; + this.prevPosZ = par6; + } + + /** + * Returns the Y offset from the entity's position for any entity riding this + * one. + */ + public double getMountedYOffset() { + return (double) this.height * 0.0D - 0.30000001192092896D; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else if (!this.worldObj.isRemote && !this.isDead) { + this.setForwardDirection(-this.getForwardDirection()); + this.setTimeSinceHit(10); + this.setDamageTaken(this.getDamageTaken() + par2 * 10); + this.setBeenAttacked(); + boolean var3 = par1DamageSource.getEntity() instanceof EntityPlayer && ((EntityPlayer) par1DamageSource.getEntity()).capabilities.isCreativeMode; + + if (var3 || this.getDamageTaken() > 40) { + if (this.riddenByEntity != null) { + this.riddenByEntity.mountEntity(this); + } + + if (!var3) { + this.dropItemWithOffset(Item.boat.itemID, 1, 0.0F); + } + + this.setDead(); + } + + return true; + } else { + return true; + } + } + + /** + * Setups the entity to do the hurt animation. Only used by packets in + * multiplayer. + */ + public void performHurtAnimation() { + this.setForwardDirection(-this.getForwardDirection()); + this.setTimeSinceHit(10); + this.setDamageTaken(this.getDamageTaken() * 11); + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return !this.isDead; + } + + /** + * Sets the position and rotation. Only difference from the other one is no + * bounding on the rotation. Args: posX, posY, posZ, yaw, pitch + */ + public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9) { + if (this.field_70279_a) { + this.boatPosRotationIncrements = par9 + 5; + } else { + double var10 = par1 - this.posX; + double var12 = par3 - this.posY; + double var14 = par5 - this.posZ; + double var16 = var10 * var10 + var12 * var12 + var14 * var14; + + if (var16 <= 1.0D) { + return; + } + + this.boatPosRotationIncrements = 3; + } + + this.boatX = par1; + this.boatY = par3; + this.boatZ = par5; + this.boatYaw = (double) par7; + this.boatPitch = (double) par8; + this.motionX = this.velocityX; + this.motionY = this.velocityY; + this.motionZ = this.velocityZ; + } + + /** + * Sets the velocity to the args. Args: x, y, z + */ + public void setVelocity(double par1, double par3, double par5) { + this.velocityX = this.motionX = par1; + this.velocityY = this.motionY = par3; + this.velocityZ = this.motionZ = par5; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.getTimeSinceHit() > 0) { + this.setTimeSinceHit(this.getTimeSinceHit() - 1); + } + + if (this.getDamageTaken() > 0) { + this.setDamageTaken(this.getDamageTaken() - 1); + } + + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + byte var1 = 5; + double var2 = 0.0D; + + for (int var4 = 0; var4 < var1; ++var4) { + double var5 = this.boundingBox.minY + (this.boundingBox.maxY - this.boundingBox.minY) * (double) (var4 + 0) / (double) var1 - 0.125D; + double var7 = this.boundingBox.minY + (this.boundingBox.maxY - this.boundingBox.minY) * (double) (var4 + 1) / (double) var1 - 0.125D; + AxisAlignedBB var9 = AxisAlignedBB.getAABBPool().getAABB(this.boundingBox.minX, var5, this.boundingBox.minZ, this.boundingBox.maxX, var7, this.boundingBox.maxZ); + + if (this.worldObj.isAABBInMaterial(var9, Material.water)) { + var2 += 1.0D / (double) var1; + } + } + + double var23 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + double var6; + double var8; + + if (var23 > 0.26249999999999996D) { + var6 = Math.cos((double) this.rotationYaw * Math.PI / 180.0D); + var8 = Math.sin((double) this.rotationYaw * Math.PI / 180.0D); + + for (int var10 = 0; (double) var10 < 1.0D + var23 * 60.0D; ++var10) { + double var11 = (double) (this.rand.nextFloat() * 2.0F - 1.0F); + double var13 = (double) (this.rand.nextInt(2) * 2 - 1) * 0.7D; + double var15; + double var17; + + if (this.rand.nextBoolean()) { + var15 = this.posX - var6 * var11 * 0.8D + var8 * var13; + var17 = this.posZ - var8 * var11 * 0.8D - var6 * var13; + this.worldObj.spawnParticle("splash", var15, this.posY - 0.125D, var17, this.motionX, this.motionY, this.motionZ); + } else { + var15 = this.posX + var6 + var8 * var11 * 0.7D; + var17 = this.posZ + var8 - var6 * var11 * 0.7D; + this.worldObj.spawnParticle("splash", var15, this.posY - 0.125D, var17, this.motionX, this.motionY, this.motionZ); + } + } + } + + double var12; + double var25; + + if (this.worldObj.isRemote && this.field_70279_a) { + if (this.boatPosRotationIncrements > 0) { + var6 = this.posX + (this.boatX - this.posX) / (double) this.boatPosRotationIncrements; + var8 = this.posY + (this.boatY - this.posY) / (double) this.boatPosRotationIncrements; + var25 = this.posZ + (this.boatZ - this.posZ) / (double) this.boatPosRotationIncrements; + var12 = MathHelper.wrapAngleTo180_double(this.boatYaw - (double) this.rotationYaw); + this.rotationYaw = (float) ((double) this.rotationYaw + var12 / (double) this.boatPosRotationIncrements); + this.rotationPitch = (float) ((double) this.rotationPitch + (this.boatPitch - (double) this.rotationPitch) / (double) this.boatPosRotationIncrements); + --this.boatPosRotationIncrements; + this.setPosition(var6, var8, var25); + this.setRotation(this.rotationYaw, this.rotationPitch); + } else { + var6 = this.posX + this.motionX; + var8 = this.posY + this.motionY; + var25 = this.posZ + this.motionZ; + this.setPosition(var6, var8, var25); + + if (this.onGround) { + this.motionX *= 0.5D; + this.motionY *= 0.5D; + this.motionZ *= 0.5D; + } + + this.motionX *= 0.9900000095367432D; + this.motionY *= 0.949999988079071D; + this.motionZ *= 0.9900000095367432D; + } + } else { + if (var2 < 1.0D) { + var6 = var2 * 2.0D - 1.0D; + this.motionY += 0.03999999910593033D * var6; + } else { + if (this.motionY < 0.0D) { + this.motionY /= 2.0D; + } + + this.motionY += 0.007000000216066837D; + } + + if (this.riddenByEntity != null) { + this.motionX += this.riddenByEntity.motionX * this.speedMultiplier; + this.motionZ += this.riddenByEntity.motionZ * this.speedMultiplier; + } + + var6 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + + if (var6 > 0.35D) { + var8 = 0.35D / var6; + this.motionX *= var8; + this.motionZ *= var8; + var6 = 0.35D; + } + + if (var6 > var23 && this.speedMultiplier < 0.35D) { + this.speedMultiplier += (0.35D - this.speedMultiplier) / 35.0D; + + if (this.speedMultiplier > 0.35D) { + this.speedMultiplier = 0.35D; + } + } else { + this.speedMultiplier -= (this.speedMultiplier - 0.07D) / 35.0D; + + if (this.speedMultiplier < 0.07D) { + this.speedMultiplier = 0.07D; + } + } + + if (this.onGround) { + this.motionX *= 0.5D; + this.motionY *= 0.5D; + this.motionZ *= 0.5D; + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (this.isCollidedHorizontally && var23 > 0.2D) { + if (!this.worldObj.isRemote && !this.isDead) { + this.setDead(); + int var24; + + for (var24 = 0; var24 < 3; ++var24) { + this.dropItemWithOffset(Block.planks.blockID, 1, 0.0F); + } + + for (var24 = 0; var24 < 2; ++var24) { + this.dropItemWithOffset(Item.stick.itemID, 1, 0.0F); + } + } + } else { + this.motionX *= 0.9900000095367432D; + this.motionY *= 0.949999988079071D; + this.motionZ *= 0.9900000095367432D; + } + + this.rotationPitch = 0.0F; + var8 = (double) this.rotationYaw; + var25 = this.prevPosX - this.posX; + var12 = this.prevPosZ - this.posZ; + + if (var25 * var25 + var12 * var12 > 0.001D) { + var8 = (double) ((float) (Math.atan2(var12, var25) * 180.0D / Math.PI)); + } + + double var14 = MathHelper.wrapAngleTo180_double(var8 - (double) this.rotationYaw); + + if (var14 > 20.0D) { + var14 = 20.0D; + } + + if (var14 < -20.0D) { + var14 = -20.0D; + } + + this.rotationYaw = (float) ((double) this.rotationYaw + var14); + this.setRotation(this.rotationYaw, this.rotationPitch); + + if (!this.worldObj.isRemote) { + List var16 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + int var26; + + if (var16 != null && !var16.isEmpty()) { + for (var26 = 0; var26 < var16.size(); ++var26) { + Entity var18 = (Entity) var16.get(var26); + + if (var18 != this.riddenByEntity && var18.canBePushed() && var18 instanceof EntityBoat) { + var18.applyEntityCollision(this); + } + } + } + + for (var26 = 0; var26 < 4; ++var26) { + int var27 = MathHelper.floor_double(this.posX + ((double) (var26 % 2) - 0.5D) * 0.8D); + int var19 = MathHelper.floor_double(this.posZ + ((double) (var26 / 2) - 0.5D) * 0.8D); + + for (int var20 = 0; var20 < 2; ++var20) { + int var21 = MathHelper.floor_double(this.posY) + var20; + int var22 = this.worldObj.getBlockId(var27, var21, var19); + + if (var22 == Block.snow.blockID) { + this.worldObj.setBlockToAir(var27, var21, var19); + } else if (var22 == Block.waterlily.blockID) { + this.worldObj.destroyBlock(var27, var21, var19, true); + } + } + } + + if (this.riddenByEntity != null && this.riddenByEntity.isDead) { + this.riddenByEntity = null; + } + } + } + } + + public void updateRiderPosition() { + if (this.riddenByEntity != null) { + double var1 = Math.cos((double) this.rotationYaw * Math.PI / 180.0D) * 0.4D; + double var3 = Math.sin((double) this.rotationYaw * Math.PI / 180.0D) * 0.4D; + this.riddenByEntity.setPosition(this.posX + var1, this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ + var3); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + } + + public float getShadowSize() { + return 0.0F; + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityPlayer && this.riddenByEntity != par1EntityPlayer) { + return true; + } else { + if (!this.worldObj.isRemote) { + par1EntityPlayer.mountEntity(this); + } + + return true; + } + } + + /** + * Sets the damage taken from the last hit. + */ + public void setDamageTaken(int par1) { + this.dataWatcher.updateObject(19, Integer.valueOf(par1)); + } + + /** + * Gets the damage taken from the last hit. + */ + public int getDamageTaken() { + return this.dataWatcher.getWatchableObjectInt(19); + } + + /** + * Sets the time to count down from since the last time entity was hit. + */ + public void setTimeSinceHit(int par1) { + this.dataWatcher.updateObject(17, Integer.valueOf(par1)); + } + + /** + * Gets the time since the last hit. + */ + public int getTimeSinceHit() { + return this.dataWatcher.getWatchableObjectInt(17); + } + + /** + * Sets the forward direction of the entity. + */ + public void setForwardDirection(int par1) { + this.dataWatcher.updateObject(18, Integer.valueOf(par1)); + } + + /** + * Gets the forward direction of the entity. + */ + public int getForwardDirection() { + return this.dataWatcher.getWatchableObjectInt(18); + } + + public void func_70270_d(boolean par1) { + this.field_70279_a = par1; + } +} diff --git a/src/main/java/net/minecraft/src/EntityBodyHelper.java b/src/main/java/net/minecraft/src/EntityBodyHelper.java new file mode 100644 index 0000000..a626585 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityBodyHelper.java @@ -0,0 +1,55 @@ +package net.minecraft.src; + + + +public class EntityBodyHelper { + /** Instance of EntityLiving. */ + private EntityLiving theLiving; + private int field_75666_b = 0; + private float field_75667_c = 0.0F; + + public EntityBodyHelper(EntityLiving par1EntityLiving) { + this.theLiving = par1EntityLiving; + } + + public void func_75664_a() { + double var1 = this.theLiving.posX - this.theLiving.prevPosX; + double var3 = this.theLiving.posZ - this.theLiving.prevPosZ; + + if (var1 * var1 + var3 * var3 > 2.500000277905201E-7D) { + this.theLiving.renderYawOffset = this.theLiving.rotationYaw; + this.theLiving.rotationYawHead = this.func_75665_a(this.theLiving.renderYawOffset, this.theLiving.rotationYawHead, 75.0F); + this.field_75667_c = this.theLiving.rotationYawHead; + this.field_75666_b = 0; + } else { + float var5 = 75.0F; + + if (Math.abs(this.theLiving.rotationYawHead - this.field_75667_c) > 15.0F) { + this.field_75666_b = 0; + this.field_75667_c = this.theLiving.rotationYawHead; + } else { + ++this.field_75666_b; + + if (this.field_75666_b > 10) { + var5 = Math.max(1.0F - (float) (this.field_75666_b - 10) / 10.0F, 0.0F) * 75.0F; + } + } + + this.theLiving.renderYawOffset = this.func_75665_a(this.theLiving.rotationYawHead, this.theLiving.renderYawOffset, var5); + } + } + + private float func_75665_a(float par1, float par2, float par3) { + float var4 = MathHelper.wrapAngleTo180_float(par1 - par2); + + if (var4 < -par3) { + var4 = -par3; + } + + if (var4 >= par3) { + var4 = par3; + } + + return par1 - var4; + } +} diff --git a/src/main/java/net/minecraft/src/EntityBreakingFX.java b/src/main/java/net/minecraft/src/EntityBreakingFX.java new file mode 100644 index 0000000..4c6e140 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityBreakingFX.java @@ -0,0 +1,52 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityBreakingFX extends EntityFX { + public EntityBreakingFX(World par1World, double par2, double par4, double par6, Item par8Item, RenderEngine par9RenderEngine) { + super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); + this.setParticleIcon(par9RenderEngine, par8Item.getIconFromDamage(0)); + this.particleRed = this.particleGreen = this.particleBlue = 1.0F; + this.particleGravity = Block.blockSnow.blockParticleGravity; + this.particleScale /= 2.0F; + } + + public EntityBreakingFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, Item par14Item, RenderEngine par15RenderEngine) { + this(par1World, par2, par4, par6, par14Item, par15RenderEngine); + this.motionX *= 0.10000000149011612D; + this.motionY *= 0.10000000149011612D; + this.motionZ *= 0.10000000149011612D; + this.motionX += par8; + this.motionY += par10; + this.motionZ += par12; + } + + public int getFXLayer() { + return 2; + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = ((float) this.particleTextureIndexX + this.particleTextureJitterX / 4.0F) / 16.0F; + float var9 = var8 + 0.015609375F; + float var10 = ((float) this.particleTextureIndexY + this.particleTextureJitterY / 4.0F) / 16.0F; + float var11 = var10 + 0.015609375F; + float var12 = 0.1F * this.particleScale; + + if (this.particleIcon != null) { + var8 = this.particleIcon.getInterpolatedU((double) (this.particleTextureJitterX / 4.0F * 16.0F)); + var9 = this.particleIcon.getInterpolatedU((double) ((this.particleTextureJitterX + 1.0F) / 4.0F * 16.0F)); + var10 = this.particleIcon.getInterpolatedV((double) (this.particleTextureJitterY / 4.0F * 16.0F)); + var11 = this.particleIcon.getInterpolatedV((double) ((this.particleTextureJitterY + 1.0F) / 4.0F * 16.0F)); + } + + float var13 = (float) (this.prevPosX + (this.posX - this.prevPosX) * (double) par2 - interpPosX); + float var14 = (float) (this.prevPosY + (this.posY - this.prevPosY) * (double) par2 - interpPosY); + float var15 = (float) (this.prevPosZ + (this.posZ - this.prevPosZ) * (double) par2 - interpPosZ); + float var16 = 1.0F; + par1Tessellator.setColorOpaque_F(var16 * this.particleRed, var16 * this.particleGreen, var16 * this.particleBlue); + par1Tessellator.addVertexWithUV((double) (var13 - par3 * var12 - par6 * var12), (double) (var14 - par4 * var12), (double) (var15 - par5 * var12 - par7 * var12), (double) var8, (double) var11); + par1Tessellator.addVertexWithUV((double) (var13 - par3 * var12 + par6 * var12), (double) (var14 + par4 * var12), (double) (var15 - par5 * var12 + par7 * var12), (double) var8, (double) var10); + par1Tessellator.addVertexWithUV((double) (var13 + par3 * var12 + par6 * var12), (double) (var14 + par4 * var12), (double) (var15 + par5 * var12 + par7 * var12), (double) var9, (double) var10); + par1Tessellator.addVertexWithUV((double) (var13 + par3 * var12 - par6 * var12), (double) (var14 - par4 * var12), (double) (var15 + par5 * var12 - par7 * var12), (double) var9, (double) var11); + } +} diff --git a/src/main/java/net/minecraft/src/EntityBubbleFX.java b/src/main/java/net/minecraft/src/EntityBubbleFX.java new file mode 100644 index 0000000..d8e54c4 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityBubbleFX.java @@ -0,0 +1,41 @@ +package net.minecraft.src; + + + +public class EntityBubbleFX extends EntityFX { + public EntityBubbleFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + super(par1World, par2, par4, par6, par8, par10, par12); + this.particleRed = 1.0F; + this.particleGreen = 1.0F; + this.particleBlue = 1.0F; + this.setParticleTextureIndex(32); + this.setSize(0.02F, 0.02F); + this.particleScale *= this.rand.nextFloat() * 0.6F + 0.2F; + this.motionX = par8 * 0.20000000298023224D + (double) ((float) (Math.random() * 2.0D - 1.0D) * 0.02F); + this.motionY = par10 * 0.20000000298023224D + (double) ((float) (Math.random() * 2.0D - 1.0D) * 0.02F); + this.motionZ = par12 * 0.20000000298023224D + (double) ((float) (Math.random() * 2.0D - 1.0D) * 0.02F); + this.particleMaxAge = (int) (8.0D / (Math.random() * 0.8D + 0.2D)); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.motionY += 0.002D; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.8500000238418579D; + this.motionY *= 0.8500000238418579D; + this.motionZ *= 0.8500000238418579D; + + if (this.worldObj.getBlockMaterial(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) != Material.water) { + this.setDead(); + } + + if (this.particleMaxAge-- <= 0) { + this.setDead(); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityCaveSpider.java b/src/main/java/net/minecraft/src/EntityCaveSpider.java new file mode 100644 index 0000000..e21bd20 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityCaveSpider.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + +public class EntityCaveSpider extends EntitySpider { + public EntityCaveSpider() { + super(); + this.setSize(0.7F, 0.5F); + } + + public int getMaxHealth() { + return 12; + } + + /** + * How large the spider should be scaled. + */ + public float spiderScaleAmount() { + return 0.7F; + } + + public boolean attackEntityAsMob(Entity par1Entity) { + if (super.attackEntityAsMob(par1Entity)) { + if (par1Entity instanceof EntityLiving) { + byte var2 = 0; + + if (this.worldObj.difficultySetting > 1) { + if (this.worldObj.difficultySetting == 2) { + var2 = 7; + } else if (this.worldObj.difficultySetting == 3) { + var2 = 15; + } + } + + if (var2 > 0) { + ((EntityLiving) par1Entity).addPotionEffect(new PotionEffect(Potion.poison.id, var2 * 20, 0)); + } + } + + return true; + } else { + return false; + } + } + + /** + * Initialize this creature. + */ + public void initCreature() { + } +} diff --git a/src/main/java/net/minecraft/src/EntityChicken.java b/src/main/java/net/minecraft/src/EntityChicken.java new file mode 100644 index 0000000..09c6ea8 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityChicken.java @@ -0,0 +1,151 @@ +package net.minecraft.src; + +public class EntityChicken extends EntityAnimal { + public boolean field_70885_d = false; + public float field_70886_e = 0.0F; + public float destPos = 0.0F; + public float field_70884_g; + public float field_70888_h; + public float field_70889_i = 1.0F; + + /** The time until the next egg is spawned. */ + public int timeUntilNextEgg; + + public EntityChicken() { + super(); + this.setSize(0.3F, 0.7F); + this.timeUntilNextEgg = this.rand.nextInt(6000) + 6000; + float var2 = 0.25F; + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + public int getMaxHealth() { + return 4; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + super.onLivingUpdate(); + this.field_70888_h = this.field_70886_e; + this.field_70884_g = this.destPos; + this.destPos = (float) ((double) this.destPos + (double) (this.onGround ? -1 : 4) * 0.3D); + + if (this.destPos < 0.0F) { + this.destPos = 0.0F; + } + + if (this.destPos > 1.0F) { + this.destPos = 1.0F; + } + + if (!this.onGround && this.field_70889_i < 1.0F) { + this.field_70889_i = 1.0F; + } + + this.field_70889_i = (float) ((double) this.field_70889_i * 0.9D); + + if (!this.onGround && this.motionY < 0.0D) { + this.motionY *= 0.6D; + } + + this.field_70886_e += this.field_70889_i * 2.0F; + + if (!this.isChild() && !this.worldObj.isRemote && --this.timeUntilNextEgg <= 0) { + this.playSound("mob.chicken.plop", 1.0F, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F); + this.dropItem(Item.egg.itemID, 1); + this.timeUntilNextEgg = this.rand.nextInt(6000) + 6000; + } + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.chicken.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.chicken.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.chicken.hurt"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.chicken.step", 0.15F, 1.0F); + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.feather.itemID; + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(3) + this.rand.nextInt(1 + par2); + + for (int var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.feather.itemID, 1); + } + + if (this.isBurning()) { + this.dropItem(Item.chickenCooked.itemID, 1); + } else { + this.dropItem(Item.chickenRaw.itemID, 1); + } + } + + /** + * This function is used when two same-species animals in 'love mode' breed to + * generate the new baby animal. + */ + public EntityChicken spawnBabyAnimal(EntityAgeable par1EntityAgeable) { + EntityChicken c = new EntityChicken(); + c.setWorld(worldObj); + return c; + } + + /** + * Checks if the parameter is an item which this animal can be fed to breed it + * (wheat, carrots or seeds depending on the animal type) + */ + public boolean isBreedingItem(ItemStack par1ItemStack) { + return par1ItemStack != null && par1ItemStack.getItem() instanceof ItemSeeds; + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.spawnBabyAnimal(par1EntityAgeable); + } +} diff --git a/src/main/java/net/minecraft/src/EntityClientPlayerMP.java b/src/main/java/net/minecraft/src/EntityClientPlayerMP.java new file mode 100644 index 0000000..bae502a --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityClientPlayerMP.java @@ -0,0 +1,223 @@ +package net.minecraft.src; + +import net.minecraft.client.Minecraft; + +public class EntityClientPlayerMP extends EntityPlayerSP { + public NetClientHandler sendQueue; + private double oldPosX; + + /** Old Minimum Y of the bounding box */ + private double oldMinY; + private double oldPosY; + private double oldPosZ; + private float oldRotationYaw; + private float oldRotationPitch; + + /** Check if was on ground last update */ + private boolean wasOnGround = false; + + /** should the player stop sneaking? */ + private boolean shouldStopSneaking = false; + private boolean wasSneaking = false; + private int field_71168_co = 0; + + /** has the client player's health been set? */ + private boolean hasSetHealth = false; + + public EntityClientPlayerMP(Minecraft par1Minecraft, World par2World, String par3Session, NetClientHandler par4NetClientHandler) { + super(par1Minecraft, par2World, par3Session, 0); + this.sendQueue = par4NetClientHandler; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + return false; + } + + /** + * Heal living entity (param: amount of half-hearts) + */ + public void heal(int par1) { + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (this.worldObj.blockExists(MathHelper.floor_double(this.posX), 0, MathHelper.floor_double(this.posZ))) { + super.onUpdate(); + this.sendMotionUpdates(); + } + } + + /** + * Send updated motion and position information to the server + */ + public void sendMotionUpdates() { + boolean var1 = this.isSprinting(); + + if (var1 != this.wasSneaking) { + if (var1) { + this.sendQueue.addToSendQueue(new Packet19EntityAction(this, 4)); + } else { + this.sendQueue.addToSendQueue(new Packet19EntityAction(this, 5)); + } + + this.wasSneaking = var1; + } + + boolean var2 = this.isSneaking(); + + if (var2 != this.shouldStopSneaking) { + if (var2) { + this.sendQueue.addToSendQueue(new Packet19EntityAction(this, 1)); + } else { + this.sendQueue.addToSendQueue(new Packet19EntityAction(this, 2)); + } + + this.shouldStopSneaking = var2; + } + + double var3 = this.posX - this.oldPosX; + double var5 = this.boundingBox.minY - this.oldMinY; + double var7 = this.posZ - this.oldPosZ; + double var9 = (double) (this.rotationYaw - this.oldRotationYaw); + double var11 = (double) (this.rotationPitch - this.oldRotationPitch); + boolean var13 = var3 * var3 + var5 * var5 + var7 * var7 > 9.0E-4D || this.field_71168_co >= 20; + boolean var14 = var9 != 0.0D || var11 != 0.0D; + + if (this.ridingEntity != null) { + this.sendQueue.addToSendQueue(new Packet13PlayerLookMove(this.motionX, -999.0D, -999.0D, this.motionZ, this.rotationYaw, this.rotationPitch, this.onGround)); + var13 = false; + } else if (var13 && var14) { + this.sendQueue.addToSendQueue(new Packet13PlayerLookMove(this.posX, this.boundingBox.minY, this.posY, this.posZ, this.rotationYaw, this.rotationPitch, this.onGround)); + } else if (var13) { + this.sendQueue.addToSendQueue(new Packet11PlayerPosition(this.posX, this.boundingBox.minY, this.posY, this.posZ, this.onGround)); + } else if (var14) { + this.sendQueue.addToSendQueue(new Packet12PlayerLook(this.rotationYaw, this.rotationPitch, this.onGround)); + } else { + this.sendQueue.addToSendQueue(new Packet10Flying(this.onGround)); + } + + ++this.field_71168_co; + this.wasOnGround = this.onGround; + + if (var13) { + this.oldPosX = this.posX; + this.oldMinY = this.boundingBox.minY; + this.oldPosY = this.posY; + this.oldPosZ = this.posZ; + this.field_71168_co = 0; + } + + if (var14) { + this.oldRotationYaw = this.rotationYaw; + this.oldRotationPitch = this.rotationPitch; + } + } + + /** + * Called when player presses the drop item key + */ + public EntityItem dropOneItem(boolean par1) { + int var2 = par1 ? 3 : 4; + this.sendQueue.addToSendQueue(new Packet14BlockDig(var2, 0, 0, 0, 0)); + return null; + } + + /** + * Joins the passed in entity item with the world. Args: entityItem + */ + protected void joinEntityItemWithWorld(EntityItem par1EntityItem) { + } + + /** + * Sends a chat message from the player. Args: chatMessage + */ + public void sendChatMessage(String par1Str) { + this.sendQueue.addToSendQueue(new Packet3Chat(par1Str)); + } + + /** + * Swings the item the player is holding. + */ + public void swingItem() { + super.swingItem(); + this.sendQueue.addToSendQueue(new Packet18Animation(this, 1)); + } + + public void respawnPlayer() { + this.sendQueue.addToSendQueue(new Packet205ClientCommand(1)); + } + + /** + * Deals damage to the entity. If its a EntityPlayer then will take damage from + * the armor first and then health second with the reduced value. Args: + * damageAmount + */ + protected void damageEntity(DamageSource par1DamageSource, int par2) { + if (!this.isEntityInvulnerable()) { + this.setEntityHealth(this.getHealth() - par2); + } + } + + /** + * sets current screen to null (used on escape buttons of GUIs) + */ + public void closeScreen() { + this.sendQueue.addToSendQueue(new Packet101CloseWindow(this.openContainer.windowId)); + this.func_92015_f(); + } + + public void func_92015_f() { + this.inventory.setItemStack((ItemStack) null); + super.closeScreen(); + } + + /** + * Updates health locally. + */ + public void setHealth(int par1) { + if (this.hasSetHealth) { + super.setHealth(par1); + } else { + this.setEntityHealth(par1); + this.hasSetHealth = true; + } + } + + /** + * Adds a value to a statistic field. + */ + public void addStat(StatBase par1StatBase, int par2) { + if (par1StatBase != null) { + if (par1StatBase.isIndependent) { + super.addStat(par1StatBase, par2); + } + } + } + + /** + * Used by NetClientHandler.handleStatistic + */ + public void incrementStat(StatBase par1StatBase, int par2) { + if (par1StatBase != null) { + if (!par1StatBase.isIndependent) { + super.addStat(par1StatBase, par2); + } + } + } + + /** + * Sends the player's abilities to the server (if there is one). + */ + public void sendPlayerAbilities() { + this.sendQueue.addToSendQueue(new Packet202PlayerAbilities(this.capabilities)); + } + + public boolean func_71066_bF() { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/EntityCloudFX.java b/src/main/java/net/minecraft/src/EntityCloudFX.java new file mode 100644 index 0000000..6e987e3 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityCloudFX.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityCloudFX extends EntityFX { + float field_70569_a; + + public EntityCloudFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); + float var14 = 2.5F; + this.motionX *= 0.10000000149011612D; + this.motionY *= 0.10000000149011612D; + this.motionZ *= 0.10000000149011612D; + this.motionX += par8; + this.motionY += par10; + this.motionZ += par12; + this.particleRed = this.particleGreen = this.particleBlue = 1.0F - (float) (Math.random() * 0.30000001192092896D); + this.particleScale *= 0.75F; + this.particleScale *= var14; + this.field_70569_a = this.particleScale; + this.particleMaxAge = (int) (8.0D / (Math.random() * 0.8D + 0.3D)); + this.particleMaxAge = (int) ((float) this.particleMaxAge * var14); + this.noClip = false; + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = ((float) this.particleAge + par2) / (float) this.particleMaxAge * 32.0F; + + if (var8 < 0.0F) { + var8 = 0.0F; + } + + if (var8 > 1.0F) { + var8 = 1.0F; + } + + this.particleScale = this.field_70569_a * var8; + super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + + this.setParticleTextureIndex(7 - this.particleAge * 8 / this.particleMaxAge); + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9599999785423279D; + this.motionY *= 0.9599999785423279D; + this.motionZ *= 0.9599999785423279D; + EntityPlayer var1 = this.worldObj.getClosestPlayerToEntity(this, 2.0D); + + if (var1 != null && this.posY > var1.boundingBox.minY) { + this.posY += (var1.boundingBox.minY - this.posY) * 0.2D; + this.motionY += (var1.motionY - this.motionY) * 0.2D; + this.setPosition(this.posX, this.posY, this.posZ); + } + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityCow.java b/src/main/java/net/minecraft/src/EntityCow.java new file mode 100644 index 0000000..53fc22f --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityCow.java @@ -0,0 +1,119 @@ +package net.minecraft.src; + +public class EntityCow extends EntityAnimal { + public EntityCow() { + super(); + this.setSize(0.9F, 1.3F); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + public int getMaxHealth() { + return 10; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.cow.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.cow.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.cow.hurt"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.cow.step", 0.15F, 1.0F); + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 0.4F; + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.leather.itemID; + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(3) + this.rand.nextInt(1 + par2); + int var4; + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.leather.itemID, 1); + } + + var3 = this.rand.nextInt(3) + 1 + this.rand.nextInt(1 + par2); + + for (var4 = 0; var4 < var3; ++var4) { + if (this.isBurning()) { + this.dropItem(Item.beefCooked.itemID, 1); + } else { + this.dropItem(Item.beefRaw.itemID, 1); + } + } + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + + if (var2 != null && var2.itemID == Item.bucketEmpty.itemID) { + if (--var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, new ItemStack(Item.bucketMilk)); + } else if (!par1EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Item.bucketMilk))) { + par1EntityPlayer.dropPlayerItem(new ItemStack(Item.bucketMilk.itemID, 1, 0)); + } + + return true; + } else { + return super.interact(par1EntityPlayer); + } + } + + /** + * This function is used when two same-species animals in 'love mode' breed to + * generate the new baby animal. + */ + public EntityCow spawnBabyAnimal(EntityAgeable par1EntityAgeable) { + EntityCow c = new EntityCow(); + c.setWorld(worldObj); + return c; + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.spawnBabyAnimal(par1EntityAgeable); + } +} diff --git a/src/main/java/net/minecraft/src/EntityCreature.java b/src/main/java/net/minecraft/src/EntityCreature.java new file mode 100644 index 0000000..0a1e68f --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityCreature.java @@ -0,0 +1,245 @@ +package net.minecraft.src; + + + +public abstract class EntityCreature extends EntityLiving { + private PathEntity pathToEntity; + + /** The Entity this EntityCreature is set to attack. */ + protected Entity entityToAttack; + + /** + * returns true if a creature has attacked recently only used for creepers and + * skeletons + */ + protected boolean hasAttacked = false; + + /** Used to make a creature speed up and wander away when hit. */ + protected int fleeingTick = 0; + + /** + * Disables a mob's ability to move on its own while true. + */ + protected boolean isMovementCeased() { + return false; + } + + protected void updateEntityActionState() { + this.worldObj.theProfiler.startSection("ai"); + + if (this.fleeingTick > 0) { + --this.fleeingTick; + } + + this.hasAttacked = this.isMovementCeased(); + float var1 = 16.0F; + + if (this.entityToAttack == null) { + this.entityToAttack = this.findPlayerToAttack(); + + if (this.entityToAttack != null) { + this.pathToEntity = this.worldObj.getPathEntityToEntity(this, this.entityToAttack, var1, true, false, false, true); + } + } else if (this.entityToAttack.isEntityAlive()) { + float var2 = this.entityToAttack.getDistanceToEntity(this); + + if (this.canEntityBeSeen(this.entityToAttack)) { + this.attackEntity(this.entityToAttack, var2); + } + } else { + this.entityToAttack = null; + } + + this.worldObj.theProfiler.endSection(); + + if (!this.hasAttacked && this.entityToAttack != null && (this.pathToEntity == null || this.rand.nextInt(20) == 0)) { + this.pathToEntity = this.worldObj.getPathEntityToEntity(this, this.entityToAttack, var1, true, false, false, true); + } else if (!this.hasAttacked && (this.pathToEntity == null && this.rand.nextInt(180) == 0 || this.rand.nextInt(120) == 0 || this.fleeingTick > 0) && this.entityAge < 100) { + this.updateWanderPath(); + } + + int var21 = MathHelper.floor_double(this.boundingBox.minY + 0.5D); + boolean var3 = this.isInWater(); + boolean var4 = this.handleLavaMovement(); + this.rotationPitch = 0.0F; + + if (this.pathToEntity != null && this.rand.nextInt(100) != 0) { + this.worldObj.theProfiler.startSection("followpath"); + Vec3 var5 = this.pathToEntity.getPosition(this); + double var6 = (double) (this.width * 2.0F); + + while (var5 != null && var5.squareDistanceTo(this.posX, var5.yCoord, this.posZ) < var6 * var6) { + this.pathToEntity.incrementPathIndex(); + + if (this.pathToEntity.isFinished()) { + var5 = null; + this.pathToEntity = null; + } else { + var5 = this.pathToEntity.getPosition(this); + } + } + + this.isJumping = false; + + if (var5 != null) { + double var8 = var5.xCoord - this.posX; + double var10 = var5.zCoord - this.posZ; + double var12 = var5.yCoord - (double) var21; + float var14 = (float) (Math.atan2(var10, var8) * 180.0D / Math.PI) - 90.0F; + float var15 = MathHelper.wrapAngleTo180_float(var14 - this.rotationYaw); + this.moveForward = this.moveSpeed; + + if (var15 > 30.0F) { + var15 = 30.0F; + } + + if (var15 < -30.0F) { + var15 = -30.0F; + } + + this.rotationYaw += var15; + + if (this.hasAttacked && this.entityToAttack != null) { + double var16 = this.entityToAttack.posX - this.posX; + double var18 = this.entityToAttack.posZ - this.posZ; + float var20 = this.rotationYaw; + this.rotationYaw = (float) (Math.atan2(var18, var16) * 180.0D / Math.PI) - 90.0F; + var15 = (var20 - this.rotationYaw + 90.0F) * (float) Math.PI / 180.0F; + this.moveStrafing = -MathHelper.sin(var15) * this.moveForward * 1.0F; + this.moveForward = MathHelper.cos(var15) * this.moveForward * 1.0F; + } + + if (var12 > 0.0D) { + this.isJumping = true; + } + } + + if (this.entityToAttack != null) { + this.faceEntity(this.entityToAttack, 30.0F, 30.0F); + } + + if (this.isCollidedHorizontally && !this.hasPath()) { + this.isJumping = true; + } + + if (this.rand.nextFloat() < 0.8F && (var3 || var4)) { + this.isJumping = true; + } + + this.worldObj.theProfiler.endSection(); + } else { + super.updateEntityActionState(); + this.pathToEntity = null; + } + } + + /** + * Time remaining during which the Animal is sped up and flees. + */ + protected void updateWanderPath() { + this.worldObj.theProfiler.startSection("stroll"); + boolean var1 = false; + int var2 = -1; + int var3 = -1; + int var4 = -1; + float var5 = -99999.0F; + + for (int var6 = 0; var6 < 10; ++var6) { + int var7 = MathHelper.floor_double(this.posX + (double) this.rand.nextInt(13) - 6.0D); + int var8 = MathHelper.floor_double(this.posY + (double) this.rand.nextInt(7) - 3.0D); + int var9 = MathHelper.floor_double(this.posZ + (double) this.rand.nextInt(13) - 6.0D); + float var10 = this.getBlockPathWeight(var7, var8, var9); + + if (var10 > var5) { + var5 = var10; + var2 = var7; + var3 = var8; + var4 = var9; + var1 = true; + } + } + + if (var1) { + this.pathToEntity = this.worldObj.getEntityPathToXYZ(this, var2, var3, var4, 10.0F, true, false, false, true); + } + + this.worldObj.theProfiler.endSection(); + } + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by + * each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) { + } + + /** + * Takes a coordinate in and returns a weight to determine how likely this + * creature will try to path to the block. Args: x, y, z + */ + public float getBlockPathWeight(int par1, int par2, int par3) { + return 0.0F; + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity + * isn't interested in attacking (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() { + return null; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.boundingBox.minY); + int var3 = MathHelper.floor_double(this.posZ); + return super.getCanSpawnHere() && this.getBlockPathWeight(var1, var2, var3) >= 0.0F; + } + + /** + * Returns true if entity has a path to follow + */ + public boolean hasPath() { + return this.pathToEntity != null; + } + + /** + * sets the Entities walk path in EntityCreature + */ + public void setPathToEntity(PathEntity par1PathEntity) { + this.pathToEntity = par1PathEntity; + } + + /** + * Returns current entities target + */ + public Entity getEntityToAttack() { + return this.entityToAttack; + } + + /** + * Sets the entity which is to be attacked. + */ + public void setTarget(Entity par1Entity) { + this.entityToAttack = par1Entity; + } + + /** + * This method returns a value to be applied directly to entity speed, this + * factor is less than 1 when a slowdown potion effect is applied, more than 1 + * when a haste potion effect is applied and 2 for fleeing entities. + */ + public float getSpeedModifier() { + float var1 = super.getSpeedModifier(); + + if (this.fleeingTick > 0 && !this.isAIEnabled()) { + var1 *= 2.0F; + } + + return var1; + } +} diff --git a/src/main/java/net/minecraft/src/EntityCreeper.java b/src/main/java/net/minecraft/src/EntityCreeper.java new file mode 100644 index 0000000..8ce04b0 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityCreeper.java @@ -0,0 +1,193 @@ +package net.minecraft.src; + +public class EntityCreeper extends EntityMob { + /** + * Time when this creeper was last in an active state (Messed up code here, + * probably causes creeper animation to go weird) + */ + private int lastActiveTime; + + /** + * The amount of time since the creeper was close enough to the player to ignite + */ + private int timeSinceIgnited; + private int fuseTime = 30; + + /** Explosion radius for this creeper. */ + private int explosionRadius = 3; + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + public int func_82143_as() { + return this.getAttackTarget() == null ? 3 : 3 + (this.health - 1); + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + super.fall(par1); + this.timeSinceIgnited = (int) ((float) this.timeSinceIgnited + par1 * 1.5F); + + if (this.timeSinceIgnited > this.fuseTime - 5) { + this.timeSinceIgnited = this.fuseTime - 5; + } + } + + public int getMaxHealth() { + return 20; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, Byte.valueOf((byte) -1)); + this.dataWatcher.addObject(17, Byte.valueOf((byte) 0)); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + + if (this.dataWatcher.getWatchableObjectByte(17) == 1) { + par1NBTTagCompound.setBoolean("powered", true); + } + + par1NBTTagCompound.setShort("Fuse", (short) this.fuseTime); + par1NBTTagCompound.setByte("ExplosionRadius", (byte) this.explosionRadius); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.dataWatcher.updateObject(17, Byte.valueOf((byte) (par1NBTTagCompound.getBoolean("powered") ? 1 : 0))); + + if (par1NBTTagCompound.hasKey("Fuse")) { + this.fuseTime = par1NBTTagCompound.getShort("Fuse"); + } + + if (par1NBTTagCompound.hasKey("ExplosionRadius")) { + this.explosionRadius = par1NBTTagCompound.getByte("ExplosionRadius"); + } + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (this.isEntityAlive()) { + this.lastActiveTime = this.timeSinceIgnited; + int var1 = this.getCreeperState(); + + if (var1 > 0 && this.timeSinceIgnited == 0) { + this.playSound("random.fuse", 1.0F, 0.5F); + } + + this.timeSinceIgnited += var1; + + if (this.timeSinceIgnited < 0) { + this.timeSinceIgnited = 0; + } + + if (this.timeSinceIgnited >= this.fuseTime) { + this.timeSinceIgnited = this.fuseTime; + + if (!this.worldObj.isRemote) { + boolean var2 = this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing"); + + if (this.getPowered()) { + this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float) (this.explosionRadius * 2), var2); + } else { + this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float) this.explosionRadius, var2); + } + + this.setDead(); + } + } + } + + super.onUpdate(); + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.creeper.say"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.creeper.death"; + } + + /** + * Called when the mob's health reaches 0. + */ + public void onDeath(DamageSource par1DamageSource) { + super.onDeath(par1DamageSource); + + if (par1DamageSource.getEntity() instanceof EntitySkeleton) { + int var2 = Item.record13.itemID + this.rand.nextInt(Item.recordWait.itemID - Item.record13.itemID + 1); + this.dropItem(var2, 1); + } + } + + public boolean attackEntityAsMob(Entity par1Entity) { + return true; + } + + /** + * Returns true if the creeper is powered by a lightning bolt. + */ + public boolean getPowered() { + return this.dataWatcher.getWatchableObjectByte(17) == 1; + } + + /** + * Params: (Float)Render tick. Returns the intensity of the creeper's flash when + * it is ignited. + */ + public float getCreeperFlashIntensity(float par1) { + return ((float) this.lastActiveTime + (float) (this.timeSinceIgnited - this.lastActiveTime) * par1) / (float) (this.fuseTime - 2); + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.gunpowder.itemID; + } + + /** + * Returns the current state of creeper, -1 is idle, 1 is 'in fuse' + */ + public int getCreeperState() { + return this.dataWatcher.getWatchableObjectByte(16); + } + + /** + * Sets the state of creeper, -1 to idle and 1 to be 'in fuse' + */ + public void setCreeperState(int par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) par1)); + } + + /** + * Called when a lightning bolt hits the entity. + */ + public void onStruckByLightning(EntityLightningBolt par1EntityLightningBolt) { + super.onStruckByLightning(par1EntityLightningBolt); + this.dataWatcher.updateObject(17, Byte.valueOf((byte) 1)); + } +} diff --git a/src/main/java/net/minecraft/src/EntityCrit2FX.java b/src/main/java/net/minecraft/src/EntityCrit2FX.java new file mode 100644 index 0000000..b5e161e --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityCrit2FX.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityCrit2FX extends EntityFX { + /** Entity that had been hit and done the Critical hit on. */ + private Entity theEntity; + private int currentLife; + private int maximumLife; + private String particleName; + + public EntityCrit2FX(World par1World, Entity par2Entity) { + this(par1World, par2Entity, "crit"); + } + + public EntityCrit2FX(World par1World, Entity par2Entity, String par3Str) { + super(par1World, par2Entity.posX, par2Entity.boundingBox.minY + (double) (par2Entity.height / 2.0F), par2Entity.posZ, par2Entity.motionX, par2Entity.motionY, par2Entity.motionZ); + this.currentLife = 0; + this.maximumLife = 0; + this.theEntity = par2Entity; + this.maximumLife = 3; + this.particleName = par3Str; + this.onUpdate(); + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + for (int var1 = 0; var1 < 16; ++var1) { + double var2 = (double) (this.rand.nextFloat() * 2.0F - 1.0F); + double var4 = (double) (this.rand.nextFloat() * 2.0F - 1.0F); + double var6 = (double) (this.rand.nextFloat() * 2.0F - 1.0F); + + if (var2 * var2 + var4 * var4 + var6 * var6 <= 1.0D) { + double var8 = this.theEntity.posX + var2 * (double) this.theEntity.width / 4.0D; + double var10 = this.theEntity.boundingBox.minY + (double) (this.theEntity.height / 2.0F) + var4 * (double) this.theEntity.height / 4.0D; + double var12 = this.theEntity.posZ + var6 * (double) this.theEntity.width / 4.0D; + this.worldObj.spawnParticle(this.particleName, var8, var10, var12, var2, var4 + 0.2D, var6); + } + } + + ++this.currentLife; + + if (this.currentLife >= this.maximumLife) { + this.setDead(); + } + } + + public int getFXLayer() { + return 3; + } +} diff --git a/src/main/java/net/minecraft/src/EntityCritFX.java b/src/main/java/net/minecraft/src/EntityCritFX.java new file mode 100644 index 0000000..2385c55 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityCritFX.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityCritFX extends EntityFX { + float field_70561_a; + + public EntityCritFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + this(par1World, par2, par4, par6, par8, par10, par12, 1.0F); + } + + public EntityCritFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float par14) { + super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); + this.motionX *= 0.10000000149011612D; + this.motionY *= 0.10000000149011612D; + this.motionZ *= 0.10000000149011612D; + this.motionX += par8 * 0.4D; + this.motionY += par10 * 0.4D; + this.motionZ += par12 * 0.4D; + this.particleRed = this.particleGreen = this.particleBlue = (float) (Math.random() * 0.30000001192092896D + 0.6000000238418579D); + this.particleScale *= 0.75F; + this.particleScale *= par14; + this.field_70561_a = this.particleScale; + this.particleMaxAge = (int) (6.0D / (Math.random() * 0.8D + 0.6D)); + this.particleMaxAge = (int) ((float) this.particleMaxAge * par14); + this.noClip = false; + this.setParticleTextureIndex(65); + this.onUpdate(); + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = ((float) this.particleAge + par2) / (float) this.particleMaxAge * 32.0F; + + if (var8 < 0.0F) { + var8 = 0.0F; + } + + if (var8 > 1.0F) { + var8 = 1.0F; + } + + this.particleScale = this.field_70561_a * var8; + super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.particleGreen = (float) ((double) this.particleGreen * 0.96D); + this.particleBlue = (float) ((double) this.particleBlue * 0.9D); + this.motionX *= 0.699999988079071D; + this.motionY *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + this.motionY -= 0.019999999552965164D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityDamageSource.java b/src/main/java/net/minecraft/src/EntityDamageSource.java new file mode 100644 index 0000000..5d64c7e --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityDamageSource.java @@ -0,0 +1,34 @@ +package net.minecraft.src; + +public class EntityDamageSource extends DamageSource { + protected Entity damageSourceEntity; + + public EntityDamageSource(String par1Str, Entity par2Entity) { + super(par1Str); + this.damageSourceEntity = par2Entity; + } + + public Entity getEntity() { + return this.damageSourceEntity; + } + + /** + * Returns the message to be displayed on player death. + */ + public String getDeathMessage(EntityLiving par1EntityLiving) { + ItemStack var2 = this.damageSourceEntity instanceof EntityLiving ? ((EntityLiving) this.damageSourceEntity).getHeldItem() : null; + String var3 = "death.attack." + this.damageType; + String var4 = var3 + ".item"; + return var2 != null && var2.hasDisplayName() && StatCollector.func_94522_b(var4) + ? StatCollector.translateToLocalFormatted(var4, new Object[] { par1EntityLiving.getTranslatedEntityName(), this.damageSourceEntity.getTranslatedEntityName(), var2.getDisplayName() }) + : StatCollector.translateToLocalFormatted(var3, new Object[] { par1EntityLiving.getTranslatedEntityName(), this.damageSourceEntity.getTranslatedEntityName() }); + } + + /** + * Return whether this damage source will have its damage amount scaled based on + * the current difficulty. + */ + public boolean isDifficultyScaled() { + return this.damageSourceEntity != null && this.damageSourceEntity instanceof EntityLiving && !(this.damageSourceEntity instanceof EntityPlayer); + } +} diff --git a/src/main/java/net/minecraft/src/EntityDamageSourceIndirect.java b/src/main/java/net/minecraft/src/EntityDamageSourceIndirect.java new file mode 100644 index 0000000..bb01178 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityDamageSourceIndirect.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +public class EntityDamageSourceIndirect extends EntityDamageSource { + private Entity indirectEntity; + + public EntityDamageSourceIndirect(String par1Str, Entity par2Entity, Entity par3Entity) { + super(par1Str, par2Entity); + this.indirectEntity = par3Entity; + } + + public Entity getSourceOfDamage() { + return this.damageSourceEntity; + } + + public Entity getEntity() { + return this.indirectEntity; + } + + /** + * Returns the message to be displayed on player death. + */ + public String getDeathMessage(EntityLiving par1EntityLiving) { + String var2 = this.indirectEntity == null ? this.damageSourceEntity.getTranslatedEntityName() : this.indirectEntity.getTranslatedEntityName(); + ItemStack var3 = this.indirectEntity instanceof EntityLiving ? ((EntityLiving) this.indirectEntity).getHeldItem() : null; + String var4 = "death.attack." + this.damageType; + String var5 = var4 + ".item"; + return var3 != null && var3.hasDisplayName() && StatCollector.func_94522_b(var5) ? StatCollector.translateToLocalFormatted(var5, new Object[] { par1EntityLiving.getTranslatedEntityName(), var2, var3.getDisplayName() }) + : StatCollector.translateToLocalFormatted(var4, new Object[] { par1EntityLiving.getTranslatedEntityName(), var2 }); + } +} diff --git a/src/main/java/net/minecraft/src/EntityDiggingFX.java b/src/main/java/net/minecraft/src/EntityDiggingFX.java new file mode 100644 index 0000000..9e3ed68 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityDiggingFX.java @@ -0,0 +1,73 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityDiggingFX extends EntityFX { + private Block blockInstance; + + public EntityDiggingFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, Block par14Block, int par15, int par16, RenderEngine par17RenderEngine) { + super(par1World, par2, par4, par6, par8, par10, par12); + this.blockInstance = par14Block; + this.setParticleIcon(par17RenderEngine, par14Block.getIcon(0, par16)); + this.particleGravity = par14Block.blockParticleGravity; + this.particleRed = this.particleGreen = this.particleBlue = 0.6F; + this.particleScale /= 2.0F; + } + + public EntityDiggingFX func_70596_a(int par1, int par2, int par3) { + if (this.blockInstance == Block.grass) { + return this; + } else { + int var4 = this.blockInstance.colorMultiplier(this.worldObj, par1, par2, par3); + this.particleRed *= (float) (var4 >> 16 & 255) / 255.0F; + this.particleGreen *= (float) (var4 >> 8 & 255) / 255.0F; + this.particleBlue *= (float) (var4 & 255) / 255.0F; + return this; + } + } + + /** + * Creates a new EntityDiggingFX with the block render color applied to the base + * particle color + */ + public EntityDiggingFX applyRenderColor(int par1) { + if (this.blockInstance == Block.grass) { + return this; + } else { + int var2 = this.blockInstance.getRenderColor(par1); + this.particleRed *= (float) (var2 >> 16 & 255) / 255.0F; + this.particleGreen *= (float) (var2 >> 8 & 255) / 255.0F; + this.particleBlue *= (float) (var2 & 255) / 255.0F; + return this; + } + } + + public int getFXLayer() { + return 1; + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = ((float) this.particleTextureIndexX + this.particleTextureJitterX / 4.0F) / 16.0F; + float var9 = var8 + 0.015609375F; + float var10 = ((float) this.particleTextureIndexY + this.particleTextureJitterY / 4.0F) / 16.0F; + float var11 = var10 + 0.015609375F; + float var12 = 0.1F * this.particleScale; + + if (this.particleIcon != null) { + var8 = this.particleIcon.getInterpolatedU((double) (this.particleTextureJitterX / 4.0F * 16.0F)); + var9 = this.particleIcon.getInterpolatedU((double) ((this.particleTextureJitterX + 1.0F) / 4.0F * 16.0F)); + var10 = this.particleIcon.getInterpolatedV((double) (this.particleTextureJitterY / 4.0F * 16.0F)); + var11 = this.particleIcon.getInterpolatedV((double) ((this.particleTextureJitterY + 1.0F) / 4.0F * 16.0F)); + } + + float var13 = (float) (this.prevPosX + (this.posX - this.prevPosX) * (double) par2 - interpPosX); + float var14 = (float) (this.prevPosY + (this.posY - this.prevPosY) * (double) par2 - interpPosY); + float var15 = (float) (this.prevPosZ + (this.posZ - this.prevPosZ) * (double) par2 - interpPosZ); + float var16 = 1.0F; + par1Tessellator.setColorOpaque_F(var16 * this.particleRed, var16 * this.particleGreen, var16 * this.particleBlue); + par1Tessellator.addVertexWithUV((double) (var13 - par3 * var12 - par6 * var12), (double) (var14 - par4 * var12), (double) (var15 - par5 * var12 - par7 * var12), (double) var8, (double) var11); + par1Tessellator.addVertexWithUV((double) (var13 - par3 * var12 + par6 * var12), (double) (var14 + par4 * var12), (double) (var15 - par5 * var12 + par7 * var12), (double) var8, (double) var10); + par1Tessellator.addVertexWithUV((double) (var13 + par3 * var12 + par6 * var12), (double) (var14 + par4 * var12), (double) (var15 + par5 * var12 + par7 * var12), (double) var9, (double) var10); + par1Tessellator.addVertexWithUV((double) (var13 + par3 * var12 - par6 * var12), (double) (var14 - par4 * var12), (double) (var15 + par5 * var12 - par7 * var12), (double) var9, (double) var11); + } +} diff --git a/src/main/java/net/minecraft/src/EntityDragon.java b/src/main/java/net/minecraft/src/EntityDragon.java new file mode 100644 index 0000000..2535b2f --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityDragon.java @@ -0,0 +1,661 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + + + +public class EntityDragon extends EntityLiving implements IBossDisplayData, IEntityMultiPart { + public double targetX; + public double targetY; + public double targetZ; + + /** + * Ring buffer array for the last 64 Y-positions and yaw rotations. Used to + * calculate offsets for the animations. + */ + public double[][] ringBuffer = new double[64][3]; + + /** + * Index into the ring buffer. Incremented once per tick and restarts at 0 once + * it reaches the end of the buffer. + */ + public int ringBufferIndex = -1; + + /** An array containing all body parts of this dragon */ + public EntityDragonPart[] dragonPartArray; + + /** The head bounding box of a dragon */ + public EntityDragonPart dragonPartHead; + + /** The body bounding box of a dragon */ + public EntityDragonPart dragonPartBody; + public EntityDragonPart dragonPartTail1; + public EntityDragonPart dragonPartTail2; + public EntityDragonPart dragonPartTail3; + public EntityDragonPart dragonPartWing1; + public EntityDragonPart dragonPartWing2; + + /** Animation time at previous tick. */ + public float prevAnimTime = 0.0F; + + /** + * Animation time, used to control the speed of the animation cycles (wings + * flapping, jaw opening, etc.) + */ + public float animTime = 0.0F; + + /** Force selecting a new flight target at next tick if set to true. */ + public boolean forceNewTarget = false; + + /** + * Activated if the dragon is flying though obsidian, white stone or bedrock. + * Slows movement and animation speed. + */ + public boolean slowed = false; + private Entity target; + public int deathTicks = 0; + + /** The current endercrystal that is healing this dragon */ + public EntityEnderCrystal healingEnderCrystal = null; + + public EntityDragon() { + super(); + this.dragonPartArray = new EntityDragonPart[] { this.dragonPartHead = new EntityDragonPart(this, "head", 6.0F, 6.0F), this.dragonPartBody = new EntityDragonPart(this, "body", 8.0F, 8.0F), + this.dragonPartTail1 = new EntityDragonPart(this, "tail", 4.0F, 4.0F), this.dragonPartTail2 = new EntityDragonPart(this, "tail", 4.0F, 4.0F), this.dragonPartTail3 = new EntityDragonPart(this, "tail", 4.0F, 4.0F), + this.dragonPartWing1 = new EntityDragonPart(this, "wing", 4.0F, 4.0F), this.dragonPartWing2 = new EntityDragonPart(this, "wing", 4.0F, 4.0F) }; + this.setEntityHealth(this.getMaxHealth()); + this.setSize(16.0F, 8.0F); + this.noClip = true; + this.isImmuneToFire = true; + this.targetY = 100.0D; + this.ignoreFrustumCheck = true; + } + + public int getMaxHealth() { + return 200; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Integer(this.getMaxHealth())); + } + + /** + * Returns a double[3] array with movement offsets, used to calculate trailing + * tail/neck positions. [0] = yaw offset, [1] = y offset, [2] = unused, always + * 0. Parameters: buffer index offset, partial ticks. + */ + public double[] getMovementOffsets(int par1, float par2) { + if (this.health <= 0) { + par2 = 0.0F; + } + + par2 = 1.0F - par2; + int var3 = this.ringBufferIndex - par1 * 1 & 63; + int var4 = this.ringBufferIndex - par1 * 1 - 1 & 63; + double[] var5 = new double[3]; + double var6 = this.ringBuffer[var3][0]; + double var8 = MathHelper.wrapAngleTo180_double(this.ringBuffer[var4][0] - var6); + var5[0] = var6 + var8 * (double) par2; + var6 = this.ringBuffer[var3][1]; + var8 = this.ringBuffer[var4][1] - var6; + var5[1] = var6 + var8 * (double) par2; + var5[2] = this.ringBuffer[var3][2] + (this.ringBuffer[var4][2] - this.ringBuffer[var3][2]) * (double) par2; + return var5; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + float var1; + float var2; + + if (!this.worldObj.isRemote) { + this.dataWatcher.updateObject(16, Integer.valueOf(this.health)); + } else { + var1 = MathHelper.cos(this.animTime * (float) Math.PI * 2.0F); + var2 = MathHelper.cos(this.prevAnimTime * (float) Math.PI * 2.0F); + + if (var2 <= -0.3F && var1 >= -0.3F) { + this.worldObj.playSound(this.posX, this.posY, this.posZ, "mob.enderdragon.wings", 5.0F, 0.8F + this.rand.nextFloat() * 0.3F, false); + } + } + + this.prevAnimTime = this.animTime; + float var3; + + if (this.health <= 0) { + var1 = (this.rand.nextFloat() - 0.5F) * 8.0F; + var2 = (this.rand.nextFloat() - 0.5F) * 4.0F; + var3 = (this.rand.nextFloat() - 0.5F) * 8.0F; + this.worldObj.spawnParticle("largeexplode", this.posX + (double) var1, this.posY + 2.0D + (double) var2, this.posZ + (double) var3, 0.0D, 0.0D, 0.0D); + } else { + this.updateDragonEnderCrystal(); + var1 = 0.2F / (MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ) * 10.0F + 1.0F); + var1 *= (float) Math.pow(2.0D, this.motionY); + + if (this.slowed) { + this.animTime += var1 * 0.5F; + } else { + this.animTime += var1; + } + + this.rotationYaw = MathHelper.wrapAngleTo180_float(this.rotationYaw); + + if (this.ringBufferIndex < 0) { + for (int var25 = 0; var25 < this.ringBuffer.length; ++var25) { + this.ringBuffer[var25][0] = (double) this.rotationYaw; + this.ringBuffer[var25][1] = this.posY; + } + } + + if (++this.ringBufferIndex == this.ringBuffer.length) { + this.ringBufferIndex = 0; + } + + this.ringBuffer[this.ringBufferIndex][0] = (double) this.rotationYaw; + this.ringBuffer[this.ringBufferIndex][1] = this.posY; + double var4; + double var6; + double var8; + double var26; + float var31; + + if (this.worldObj.isRemote) { + if (this.newPosRotationIncrements > 0) { + var26 = this.posX + (this.newPosX - this.posX) / (double) this.newPosRotationIncrements; + var4 = this.posY + (this.newPosY - this.posY) / (double) this.newPosRotationIncrements; + var6 = this.posZ + (this.newPosZ - this.posZ) / (double) this.newPosRotationIncrements; + var8 = MathHelper.wrapAngleTo180_double(this.newRotationYaw - (double) this.rotationYaw); + this.rotationYaw = (float) ((double) this.rotationYaw + var8 / (double) this.newPosRotationIncrements); + this.rotationPitch = (float) ((double) this.rotationPitch + (this.newRotationPitch - (double) this.rotationPitch) / (double) this.newPosRotationIncrements); + --this.newPosRotationIncrements; + this.setPosition(var26, var4, var6); + this.setRotation(this.rotationYaw, this.rotationPitch); + } + } else { + var26 = this.targetX - this.posX; + var4 = this.targetY - this.posY; + var6 = this.targetZ - this.posZ; + var8 = var26 * var26 + var4 * var4 + var6 * var6; + + if (this.target != null) { + this.targetX = this.target.posX; + this.targetZ = this.target.posZ; + double var10 = this.targetX - this.posX; + double var12 = this.targetZ - this.posZ; + double var14 = Math.sqrt(var10 * var10 + var12 * var12); + double var16 = 0.4000000059604645D + var14 / 80.0D - 1.0D; + + if (var16 > 10.0D) { + var16 = 10.0D; + } + + this.targetY = this.target.boundingBox.minY + var16; + } else { + this.targetX += this.rand.nextGaussian() * 2.0D; + this.targetZ += this.rand.nextGaussian() * 2.0D; + } + + if (this.forceNewTarget || var8 < 100.0D || var8 > 22500.0D || this.isCollidedHorizontally || this.isCollidedVertically) { + this.setNewTarget(); + } + + var4 /= (double) MathHelper.sqrt_double(var26 * var26 + var6 * var6); + var31 = 0.6F; + + if (var4 < (double) (-var31)) { + var4 = (double) (-var31); + } + + if (var4 > (double) var31) { + var4 = (double) var31; + } + + this.motionY += var4 * 0.10000000149011612D; + this.rotationYaw = MathHelper.wrapAngleTo180_float(this.rotationYaw); + double var11 = 180.0D - Math.atan2(var26, var6) * 180.0D / Math.PI; + double var13 = MathHelper.wrapAngleTo180_double(var11 - (double) this.rotationYaw); + + if (var13 > 50.0D) { + var13 = 50.0D; + } + + if (var13 < -50.0D) { + var13 = -50.0D; + } + + Vec3 var15 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.targetX - this.posX, this.targetY - this.posY, this.targetZ - this.posZ).normalize(); + Vec3 var39 = this.worldObj.getWorldVec3Pool().getVecFromPool((double) MathHelper.sin(this.rotationYaw * (float) Math.PI / 180.0F), this.motionY, (double) (-MathHelper.cos(this.rotationYaw * (float) Math.PI / 180.0F))) + .normalize(); + float var17 = (float) (var39.dotProduct(var15) + 0.5D) / 1.5F; + + if (var17 < 0.0F) { + var17 = 0.0F; + } + + this.randomYawVelocity *= 0.8F; + float var18 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ) * 1.0F + 1.0F; + double var19 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ) * 1.0D + 1.0D; + + if (var19 > 40.0D) { + var19 = 40.0D; + } + + this.randomYawVelocity = (float) ((double) this.randomYawVelocity + var13 * (0.699999988079071D / var19 / (double) var18)); + this.rotationYaw += this.randomYawVelocity * 0.1F; + float var21 = (float) (2.0D / (var19 + 1.0D)); + float var22 = 0.06F; + this.moveFlying(0.0F, -1.0F, var22 * (var17 * var21 + (1.0F - var21))); + + if (this.slowed) { + this.moveEntity(this.motionX * 0.800000011920929D, this.motionY * 0.800000011920929D, this.motionZ * 0.800000011920929D); + } else { + this.moveEntity(this.motionX, this.motionY, this.motionZ); + } + + Vec3 var23 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.motionX, this.motionY, this.motionZ).normalize(); + float var24 = (float) (var23.dotProduct(var39) + 1.0D) / 2.0F; + var24 = 0.8F + 0.15F * var24; + this.motionX *= (double) var24; + this.motionZ *= (double) var24; + this.motionY *= 0.9100000262260437D; + } + + this.renderYawOffset = this.rotationYaw; + this.dragonPartHead.width = this.dragonPartHead.height = 3.0F; + this.dragonPartTail1.width = this.dragonPartTail1.height = 2.0F; + this.dragonPartTail2.width = this.dragonPartTail2.height = 2.0F; + this.dragonPartTail3.width = this.dragonPartTail3.height = 2.0F; + this.dragonPartBody.height = 3.0F; + this.dragonPartBody.width = 5.0F; + this.dragonPartWing1.height = 2.0F; + this.dragonPartWing1.width = 4.0F; + this.dragonPartWing2.height = 3.0F; + this.dragonPartWing2.width = 4.0F; + var2 = (float) (this.getMovementOffsets(5, 1.0F)[1] - this.getMovementOffsets(10, 1.0F)[1]) * 10.0F / 180.0F * (float) Math.PI; + var3 = MathHelper.cos(var2); + float var27 = -MathHelper.sin(var2); + float var5 = this.rotationYaw * (float) Math.PI / 180.0F; + float var28 = MathHelper.sin(var5); + float var7 = MathHelper.cos(var5); + this.dragonPartBody.onUpdate(); + this.dragonPartBody.setLocationAndAngles(this.posX + (double) (var28 * 0.5F), this.posY, this.posZ - (double) (var7 * 0.5F), 0.0F, 0.0F); + this.dragonPartWing1.onUpdate(); + this.dragonPartWing1.setLocationAndAngles(this.posX + (double) (var7 * 4.5F), this.posY + 2.0D, this.posZ + (double) (var28 * 4.5F), 0.0F, 0.0F); + this.dragonPartWing2.onUpdate(); + this.dragonPartWing2.setLocationAndAngles(this.posX - (double) (var7 * 4.5F), this.posY + 2.0D, this.posZ - (double) (var28 * 4.5F), 0.0F, 0.0F); + + if (!this.worldObj.isRemote && this.hurtTime == 0) { + this.collideWithEntities(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.dragonPartWing1.boundingBox.expand(4.0D, 2.0D, 4.0D).offset(0.0D, -2.0D, 0.0D))); + this.collideWithEntities(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.dragonPartWing2.boundingBox.expand(4.0D, 2.0D, 4.0D).offset(0.0D, -2.0D, 0.0D))); + this.attackEntitiesInList(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.dragonPartHead.boundingBox.expand(1.0D, 1.0D, 1.0D))); + } + + double[] var29 = this.getMovementOffsets(5, 1.0F); + double[] var9 = this.getMovementOffsets(0, 1.0F); + var31 = MathHelper.sin(this.rotationYaw * (float) Math.PI / 180.0F - this.randomYawVelocity * 0.01F); + float var33 = MathHelper.cos(this.rotationYaw * (float) Math.PI / 180.0F - this.randomYawVelocity * 0.01F); + this.dragonPartHead.onUpdate(); + this.dragonPartHead.setLocationAndAngles(this.posX + (double) (var31 * 5.5F * var3), this.posY + (var9[1] - var29[1]) * 1.0D + (double) (var27 * 5.5F), this.posZ - (double) (var33 * 5.5F * var3), 0.0F, 0.0F); + + for (int var30 = 0; var30 < 3; ++var30) { + EntityDragonPart var32 = null; + + if (var30 == 0) { + var32 = this.dragonPartTail1; + } + + if (var30 == 1) { + var32 = this.dragonPartTail2; + } + + if (var30 == 2) { + var32 = this.dragonPartTail3; + } + + double[] var34 = this.getMovementOffsets(12 + var30 * 2, 1.0F); + float var35 = this.rotationYaw * (float) Math.PI / 180.0F + this.simplifyAngle(var34[0] - var29[0]) * (float) Math.PI / 180.0F * 1.0F; + float var37 = MathHelper.sin(var35); + float var36 = MathHelper.cos(var35); + float var38 = 1.5F; + float var40 = (float) (var30 + 1) * 2.0F; + var32.onUpdate(); + var32.setLocationAndAngles(this.posX - (double) ((var28 * var38 + var37 * var40) * var3), this.posY + (var34[1] - var29[1]) * 1.0D - (double) ((var40 + var38) * var27) + 1.5D, + this.posZ + (double) ((var7 * var38 + var36 * var40) * var3), 0.0F, 0.0F); + } + + if (!this.worldObj.isRemote) { + this.slowed = this.destroyBlocksInAABB(this.dragonPartHead.boundingBox) | this.destroyBlocksInAABB(this.dragonPartBody.boundingBox); + } + } + } + + /** + * Updates the state of the enderdragon's current endercrystal. + */ + private void updateDragonEnderCrystal() { + if (this.healingEnderCrystal != null) { + if (this.healingEnderCrystal.isDead) { + if (!this.worldObj.isRemote) { + this.attackEntityFromPart(this.dragonPartHead, DamageSource.setExplosionSource((Explosion) null), 10); + } + + this.healingEnderCrystal = null; + } else if (this.ticksExisted % 10 == 0 && this.getHealth() < this.getMaxHealth()) { + this.setEntityHealth(this.getHealth() + 1); + } + } + + if (this.rand.nextInt(10) == 0) { + float var1 = 32.0F; + List var2 = this.worldObj.getEntitiesWithinAABB(EntityEnderCrystal.class, this.boundingBox.expand((double) var1, (double) var1, (double) var1)); + EntityEnderCrystal var3 = null; + double var4 = Double.MAX_VALUE; + Iterator var6 = var2.iterator(); + + while (var6.hasNext()) { + EntityEnderCrystal var7 = (EntityEnderCrystal) var6.next(); + double var8 = var7.getDistanceSqToEntity(this); + + if (var8 < var4) { + var4 = var8; + var3 = var7; + } + } + + this.healingEnderCrystal = var3; + } + } + + /** + * Pushes all entities inside the list away from the enderdragon. + */ + private void collideWithEntities(List par1List) { + double var2 = (this.dragonPartBody.boundingBox.minX + this.dragonPartBody.boundingBox.maxX) / 2.0D; + double var4 = (this.dragonPartBody.boundingBox.minZ + this.dragonPartBody.boundingBox.maxZ) / 2.0D; + Iterator var6 = par1List.iterator(); + + while (var6.hasNext()) { + Entity var7 = (Entity) var6.next(); + + if (var7 instanceof EntityLiving) { + double var8 = var7.posX - var2; + double var10 = var7.posZ - var4; + double var12 = var8 * var8 + var10 * var10; + var7.addVelocity(var8 / var12 * 4.0D, 0.20000000298023224D, var10 / var12 * 4.0D); + } + } + } + + /** + * Attacks all entities inside this list, dealing 5 hearts of damage. + */ + private void attackEntitiesInList(List par1List) { + for (int var2 = 0; var2 < par1List.size(); ++var2) { + Entity var3 = (Entity) par1List.get(var2); + + if (var3 instanceof EntityLiving) { + var3.attackEntityFrom(DamageSource.causeMobDamage(this), 10); + } + } + } + + /** + * Sets a new target for the flight AI. It can be a random coordinate or a + * nearby player. + */ + private void setNewTarget() { + this.forceNewTarget = false; + + if (this.rand.nextInt(2) == 0 && !this.worldObj.playerEntities.isEmpty()) { + this.target = (Entity) this.worldObj.playerEntities.get(this.rand.nextInt(this.worldObj.playerEntities.size())); + } else { + boolean var1 = false; + + do { + this.targetX = 0.0D; + this.targetY = (double) (70.0F + this.rand.nextFloat() * 50.0F); + this.targetZ = 0.0D; + this.targetX += (double) (this.rand.nextFloat() * 120.0F - 60.0F); + this.targetZ += (double) (this.rand.nextFloat() * 120.0F - 60.0F); + double var2 = this.posX - this.targetX; + double var4 = this.posY - this.targetY; + double var6 = this.posZ - this.targetZ; + var1 = var2 * var2 + var4 * var4 + var6 * var6 > 100.0D; + } while (!var1); + + this.target = null; + } + } + + /** + * Simplifies the value of a number by adding/subtracting 180 to the point that + * the number is between -180 and 180. + */ + private float simplifyAngle(double par1) { + return (float) MathHelper.wrapAngleTo180_double(par1); + } + + /** + * Destroys all blocks that aren't associated with 'The End' inside the given + * bounding box. + */ + private boolean destroyBlocksInAABB(AxisAlignedBB par1AxisAlignedBB) { + int var2 = MathHelper.floor_double(par1AxisAlignedBB.minX); + int var3 = MathHelper.floor_double(par1AxisAlignedBB.minY); + int var4 = MathHelper.floor_double(par1AxisAlignedBB.minZ); + int var5 = MathHelper.floor_double(par1AxisAlignedBB.maxX); + int var6 = MathHelper.floor_double(par1AxisAlignedBB.maxY); + int var7 = MathHelper.floor_double(par1AxisAlignedBB.maxZ); + boolean var8 = false; + boolean var9 = false; + + for (int var10 = var2; var10 <= var5; ++var10) { + for (int var11 = var3; var11 <= var6; ++var11) { + for (int var12 = var4; var12 <= var7; ++var12) { + int var13 = this.worldObj.getBlockId(var10, var11, var12); + + if (var13 != 0) { + if (var13 != Block.obsidian.blockID && var13 != Block.whiteStone.blockID && var13 != Block.bedrock.blockID && this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")) { + var9 = this.worldObj.setBlockToAir(var10, var11, var12) || var9; + } else { + var8 = true; + } + } + } + } + } + + if (var9) { + double var16 = par1AxisAlignedBB.minX + (par1AxisAlignedBB.maxX - par1AxisAlignedBB.minX) * (double) this.rand.nextFloat(); + double var17 = par1AxisAlignedBB.minY + (par1AxisAlignedBB.maxY - par1AxisAlignedBB.minY) * (double) this.rand.nextFloat(); + double var14 = par1AxisAlignedBB.minZ + (par1AxisAlignedBB.maxZ - par1AxisAlignedBB.minZ) * (double) this.rand.nextFloat(); + this.worldObj.spawnParticle("largeexplode", var16, var17, var14, 0.0D, 0.0D, 0.0D); + } + + return var8; + } + + public boolean attackEntityFromPart(EntityDragonPart par1EntityDragonPart, DamageSource par2DamageSource, int par3) { + if (par1EntityDragonPart != this.dragonPartHead) { + par3 = par3 / 4 + 1; + } + + float var4 = this.rotationYaw * (float) Math.PI / 180.0F; + float var5 = MathHelper.sin(var4); + float var6 = MathHelper.cos(var4); + this.targetX = this.posX + (double) (var5 * 5.0F) + (double) ((this.rand.nextFloat() - 0.5F) * 2.0F); + this.targetY = this.posY + (double) (this.rand.nextFloat() * 3.0F) + 1.0D; + this.targetZ = this.posZ - (double) (var6 * 5.0F) + (double) ((this.rand.nextFloat() - 0.5F) * 2.0F); + this.target = null; + + if (par2DamageSource.getEntity() instanceof EntityPlayer || par2DamageSource.isExplosion()) { + this.func_82195_e(par2DamageSource, par3); + } + + return true; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + return false; + } + + protected boolean func_82195_e(DamageSource par1DamageSource, int par2) { + return super.attackEntityFrom(par1DamageSource, par2); + } + + /** + * handles entity death timer, experience orb and particle creation + */ + protected void onDeathUpdate() { + ++this.deathTicks; + + if (this.deathTicks >= 180 && this.deathTicks <= 200) { + float var1 = (this.rand.nextFloat() - 0.5F) * 8.0F; + float var2 = (this.rand.nextFloat() - 0.5F) * 4.0F; + float var3 = (this.rand.nextFloat() - 0.5F) * 8.0F; + this.worldObj.spawnParticle("hugeexplosion", this.posX + (double) var1, this.posY + 2.0D + (double) var2, this.posZ + (double) var3, 0.0D, 0.0D, 0.0D); + } + + int var4; + int var5; + + if (!this.worldObj.isRemote) { + if (this.deathTicks > 150 && this.deathTicks % 5 == 0) { + var4 = 1000; + + while (var4 > 0) { + var5 = EntityXPOrb.getXPSplit(var4); + var4 -= var5; + this.worldObj.spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, var5)); + } + } + + if (this.deathTicks == 1) { + this.worldObj.func_82739_e(1018, (int) this.posX, (int) this.posY, (int) this.posZ, 0); + } + } + + this.moveEntity(0.0D, 0.10000000149011612D, 0.0D); + this.renderYawOffset = this.rotationYaw += 20.0F; + + if (this.deathTicks == 200 && !this.worldObj.isRemote) { + var4 = 2000; + + while (var4 > 0) { + var5 = EntityXPOrb.getXPSplit(var4); + var4 -= var5; + this.worldObj.spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, var5)); + } + + this.createEnderPortal(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posZ)); + this.setDead(); + } + } + + /** + * Creates the ender portal leading back to the normal world after defeating the + * enderdragon. + */ + private void createEnderPortal(int par1, int par2) { + byte var3 = 64; + BlockEndPortal.bossDefeated = true; + byte var4 = 4; + + for (int var5 = var3 - 1; var5 <= var3 + 32; ++var5) { + for (int var6 = par1 - var4; var6 <= par1 + var4; ++var6) { + for (int var7 = par2 - var4; var7 <= par2 + var4; ++var7) { + double var8 = (double) (var6 - par1); + double var10 = (double) (var7 - par2); + double var12 = var8 * var8 + var10 * var10; + + if (var12 <= ((double) var4 - 0.5D) * ((double) var4 - 0.5D)) { + if (var5 < var3) { + if (var12 <= ((double) (var4 - 1) - 0.5D) * ((double) (var4 - 1) - 0.5D)) { + this.worldObj.setBlock(var6, var5, var7, Block.bedrock.blockID); + } + } else if (var5 > var3) { + this.worldObj.setBlock(var6, var5, var7, 0); + } else if (var12 > ((double) (var4 - 1) - 0.5D) * ((double) (var4 - 1) - 0.5D)) { + this.worldObj.setBlock(var6, var5, var7, Block.bedrock.blockID); + } else { + this.worldObj.setBlock(var6, var5, var7, Block.endPortal.blockID); + } + } + } + } + } + + this.worldObj.setBlock(par1, var3 + 0, par2, Block.bedrock.blockID); + this.worldObj.setBlock(par1, var3 + 1, par2, Block.bedrock.blockID); + this.worldObj.setBlock(par1, var3 + 2, par2, Block.bedrock.blockID); + this.worldObj.setBlock(par1 - 1, var3 + 2, par2, Block.torchWood.blockID); + this.worldObj.setBlock(par1 + 1, var3 + 2, par2, Block.torchWood.blockID); + this.worldObj.setBlock(par1, var3 + 2, par2 - 1, Block.torchWood.blockID); + this.worldObj.setBlock(par1, var3 + 2, par2 + 1, Block.torchWood.blockID); + this.worldObj.setBlock(par1, var3 + 3, par2, Block.bedrock.blockID); + this.worldObj.setBlock(par1, var3 + 4, par2, Block.dragonEgg.blockID); + BlockEndPortal.bossDefeated = false; + } + + /** + * Makes the entity despawn if requirements are reached + */ + protected void despawnEntity() { + } + + /** + * Return the Entity parts making up this Entity (currently only for dragons) + */ + public Entity[] getParts() { + return this.dragonPartArray; + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return false; + } + + /** + * Returns the health points of the dragon. + */ + public int getBossHealth() { + return this.dataWatcher.getWatchableObjectInt(16); + } + + public World func_82194_d() { + return this.worldObj; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.enderdragon.growl"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.enderdragon.hit"; + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 5.0F; + } +} diff --git a/src/main/java/net/minecraft/src/EntityDragonPart.java b/src/main/java/net/minecraft/src/EntityDragonPart.java new file mode 100644 index 0000000..08deae7 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityDragonPart.java @@ -0,0 +1,54 @@ +package net.minecraft.src; + +public class EntityDragonPart extends Entity { + /** The dragon entity this dragon part belongs to */ + public final IEntityMultiPart entityDragonObj; + + /** The name of the Dragon Part */ + public final String name; + + public EntityDragonPart(IEntityMultiPart par1, String par2, float par3, float par4) { + super(); + this.setWorld(par1.func_82194_d()); + this.setSize(par3, par4); + this.entityDragonObj = par1; + this.name = par2; + } + + protected void entityInit() { + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return true; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + return this.isEntityInvulnerable() ? false : this.entityDragonObj.attackEntityFromPart(this, par1DamageSource, par2); + } + + /** + * Returns true if Entity argument is equal to this Entity + */ + public boolean isEntityEqual(Entity par1Entity) { + return this == par1Entity || this.entityDragonObj == par1Entity; + } +} diff --git a/src/main/java/net/minecraft/src/EntityDropParticleFX.java b/src/main/java/net/minecraft/src/EntityDropParticleFX.java new file mode 100644 index 0000000..d693e35 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityDropParticleFX.java @@ -0,0 +1,108 @@ +package net.minecraft.src; + + + +public class EntityDropParticleFX extends EntityFX { + /** the material type for dropped items/blocks */ + private Material materialType; + + /** The height of the current bob */ + private int bobTimer; + + public EntityDropParticleFX(World par1World, double par2, double par4, double par6, Material par8Material) { + super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); + this.motionX = this.motionY = this.motionZ = 0.0D; + + if (par8Material == Material.water) { + this.particleRed = 0.0F; + this.particleGreen = 0.0F; + this.particleBlue = 1.0F; + this.particleAlpha = 0.4F; + } else { + this.particleRed = 1.0F; + this.particleGreen = 0.0F; + this.particleBlue = 0.0F; + } + + this.setParticleTextureIndex(113); + this.setSize(0.01F, 0.01F); + this.particleGravity = 0.06F; + this.materialType = par8Material; + this.bobTimer = 40; + this.particleMaxAge = (int) (64.0D / (Math.random() * 0.8D + 0.2D)); + this.motionX = this.motionY = this.motionZ = 0.0D; + } + + public int getBrightnessForRender(float par1) { + return this.materialType == Material.water ? super.getBrightnessForRender(par1) : 257; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + return this.materialType == Material.water ? super.getBrightness(par1) : 1.0F; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.materialType == Material.water) { + this.particleRed = 0.2F; + this.particleGreen = 0.3F; + this.particleBlue = 1.0F; + } else { + this.particleRed = 1.0F; + this.particleGreen = 16.0F / (float) (40 - this.bobTimer + 16); + this.particleBlue = 4.0F / (float) (40 - this.bobTimer + 8); + } + + this.motionY -= (double) this.particleGravity; + + if (this.bobTimer-- > 0) { + this.motionX *= 0.02D; + this.motionY *= 0.02D; + this.motionZ *= 0.02D; + this.setParticleTextureIndex(113); + } else { + this.setParticleTextureIndex(112); + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.9800000190734863D; + this.motionZ *= 0.9800000190734863D; + + if (this.particleMaxAge-- <= 0) { + this.setDead(); + } + + if (this.onGround) { + if (this.materialType == Material.water) { + this.setDead(); + this.worldObj.spawnParticle("splash", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D); + } else { + this.setParticleTextureIndex(114); + } + + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + + Material var1 = this.worldObj.getBlockMaterial(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)); + + if (var1.isLiquid() || var1.isSolid()) { + double var2 = (double) ((float) (MathHelper.floor_double(this.posY) + 1) + - BlockFluid.getFluidHeightPercent(this.worldObj.getBlockMetadata(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)))); + + if (this.posY < var2) { + this.setDead(); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityEgg.java b/src/main/java/net/minecraft/src/EntityEgg.java new file mode 100644 index 0000000..2494c58 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityEgg.java @@ -0,0 +1,48 @@ +package net.minecraft.src; + +public class EntityEgg extends EntityThrowable { + public EntityEgg() { + super(); + } + + public EntityEgg(World par1World, EntityLiving par2EntityLiving) { + super(par1World, par2EntityLiving); + } + + public EntityEgg(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + } + + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (par1MovingObjectPosition.entityHit != null) { + par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), 0); + } + + if (!this.worldObj.isRemote && this.rand.nextInt(8) == 0) { + byte var2 = 1; + + if (this.rand.nextInt(32) == 0) { + var2 = 4; + } + + for (int var3 = 0; var3 < var2; ++var3) { + EntityChicken var4 = new EntityChicken(); + var4.setWorld(worldObj); + var4.setGrowingAge(-24000); + var4.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F); + this.worldObj.spawnEntityInWorld(var4); + } + } + + for (int var5 = 0; var5 < 8; ++var5) { + this.worldObj.spawnParticle("snowballpoof", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D); + } + + if (!this.worldObj.isRemote) { + this.setDead(); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityEggInfo.java b/src/main/java/net/minecraft/src/EntityEggInfo.java new file mode 100644 index 0000000..7ce2a86 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityEggInfo.java @@ -0,0 +1,18 @@ +package net.minecraft.src; + +public class EntityEggInfo { + /** The entityID of the spawned mob */ + public int spawnedID; + + /** Base color of the egg */ + public int primaryColor; + + /** Color of the egg spots */ + public int secondaryColor; + + public EntityEggInfo(int par1, int par2, int par3) { + this.spawnedID = par1; + this.primaryColor = par2; + this.secondaryColor = par3; + } +} diff --git a/src/main/java/net/minecraft/src/EntityEnchantmentTableParticleFX.java b/src/main/java/net/minecraft/src/EntityEnchantmentTableParticleFX.java new file mode 100644 index 0000000..392af94 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityEnchantmentTableParticleFX.java @@ -0,0 +1,76 @@ +package net.minecraft.src; + + + +public class EntityEnchantmentTableParticleFX extends EntityFX { + private float field_70565_a; + private double field_70568_aq; + private double field_70567_ar; + private double field_70566_as; + + public EntityEnchantmentTableParticleFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + super(par1World, par2, par4, par6, par8, par10, par12); + this.motionX = par8; + this.motionY = par10; + this.motionZ = par12; + this.field_70568_aq = this.posX = par2; + this.field_70567_ar = this.posY = par4; + this.field_70566_as = this.posZ = par6; + float var14 = this.rand.nextFloat() * 0.6F + 0.4F; + this.field_70565_a = this.particleScale = this.rand.nextFloat() * 0.5F + 0.2F; + this.particleRed = this.particleGreen = this.particleBlue = 1.0F * var14; + this.particleGreen *= 0.9F; + this.particleRed *= 0.9F; + this.particleMaxAge = (int) (Math.random() * 10.0D) + 30; + this.noClip = true; + this.setParticleTextureIndex((int) (Math.random() * 26.0D + 1.0D + 224.0D)); + } + + public int getBrightnessForRender(float par1) { + int var2 = super.getBrightnessForRender(par1); + float var3 = (float) this.particleAge / (float) this.particleMaxAge; + var3 *= var3; + var3 *= var3; + int var4 = var2 & 255; + int var5 = var2 >> 16 & 255; + var5 += (int) (var3 * 15.0F * 16.0F); + + if (var5 > 240) { + var5 = 240; + } + + return var4 | var5 << 16; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + float var2 = super.getBrightness(par1); + float var3 = (float) this.particleAge / (float) this.particleMaxAge; + var3 *= var3; + var3 *= var3; + return var2 * (1.0F - var3) + var3; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + float var1 = (float) this.particleAge / (float) this.particleMaxAge; + var1 = 1.0F - var1; + float var2 = 1.0F - var1; + var2 *= var2; + var2 *= var2; + this.posX = this.field_70568_aq + this.motionX * (double) var1; + this.posY = this.field_70567_ar + this.motionY * (double) var1 - (double) (var2 * 1.2F); + this.posZ = this.field_70566_as + this.motionZ * (double) var1; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityEnderCrystal.java b/src/main/java/net/minecraft/src/EntityEnderCrystal.java new file mode 100644 index 0000000..d46b2b1 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityEnderCrystal.java @@ -0,0 +1,100 @@ +package net.minecraft.src; + +public class EntityEnderCrystal extends Entity { + /** Used to create the rotation animation when rendering the crystal. */ + public int innerRotation; + public int health; + + public EntityEnderCrystal() { + super(); + this.innerRotation = 0; + this.preventEntitySpawning = true; + this.setSize(2.0F, 2.0F); + this.yOffset = this.height / 2.0F; + this.health = 5; + this.innerRotation = this.rand.nextInt(100000); + } + + public EntityEnderCrystal(World par1World, double par2, double par4, double par6) { + this(); + this.setWorld(par1World); + this.setPosition(par2, par4, par6); + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + protected void entityInit() { + this.dataWatcher.addObject(8, Integer.valueOf(this.health)); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + ++this.innerRotation; + this.dataWatcher.updateObject(8, Integer.valueOf(this.health)); + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.posY); + int var3 = MathHelper.floor_double(this.posZ); + + if (this.worldObj.getBlockId(var1, var2, var3) != Block.fire.blockID) { + this.worldObj.setBlock(var1, var2, var3, Block.fire.blockID); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + } + + public float getShadowSize() { + return 0.0F; + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return true; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + if (!this.isDead && !this.worldObj.isRemote) { + this.health = 0; + + if (this.health <= 0) { + this.setDead(); + + if (!this.worldObj.isRemote) { + this.worldObj.createExplosion((Entity) null, this.posX, this.posY, this.posZ, 6.0F, true); + } + } + } + + return true; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityEnderEye.java b/src/main/java/net/minecraft/src/EntityEnderEye.java new file mode 100644 index 0000000..20f7e8d --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityEnderEye.java @@ -0,0 +1,200 @@ +package net.minecraft.src; + + + +public class EntityEnderEye extends Entity { + public int field_70226_a = 0; + + /** 'x' location the eye should float towards. */ + private double targetX; + + /** 'y' location the eye should float towards. */ + private double targetY; + + /** 'z' location the eye should float towards. */ + private double targetZ; + private int despawnTimer; + private boolean shatterOrDrop; + + public EntityEnderEye() { + super(); + this.setSize(0.25F, 0.25F); + } + + protected void entityInit() { + } + + /** + * Checks if the entity is in range to render by using the past in distance and + * comparing it to its average edge length * 64 * renderDistanceWeight Args: + * distance + */ + public boolean isInRangeToRenderDist(double par1) { + double var3 = this.boundingBox.getAverageEdgeLength() * 4.0D; + var3 *= 64.0D; + return par1 < var3 * var3; + } + + public EntityEnderEye(World par1World, double par2, double par4, double par6) { + super(); + this.setWorld(par1World); + this.despawnTimer = 0; + this.setSize(0.25F, 0.25F); + this.setPosition(par2, par4, par6); + this.yOffset = 0.0F; + } + + /** + * The location the eye should float/move towards. Currently used for moving + * towards the nearest stronghold. Args: strongholdX, strongholdY, strongholdZ + */ + public void moveTowards(double par1, int par3, double par4) { + double var6 = par1 - this.posX; + double var8 = par4 - this.posZ; + float var10 = MathHelper.sqrt_double(var6 * var6 + var8 * var8); + + if (var10 > 12.0F) { + this.targetX = this.posX + var6 / (double) var10 * 12.0D; + this.targetZ = this.posZ + var8 / (double) var10 * 12.0D; + this.targetY = this.posY + 8.0D; + } else { + this.targetX = par1; + this.targetY = (double) par3; + this.targetZ = par4; + } + + this.despawnTimer = 0; + this.shatterOrDrop = this.rand.nextInt(5) > 0; + } + + /** + * Sets the velocity to the args. Args: x, y, z + */ + public void setVelocity(double par1, double par3, double par5) { + this.motionX = par1; + this.motionY = par3; + this.motionZ = par5; + + if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) { + float var7 = MathHelper.sqrt_double(par1 * par1 + par5 * par5); + this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(par1, par5) * 180.0D / Math.PI); + this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(par3, (double) var7) * 180.0D / Math.PI); + } + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.lastTickPosX = this.posX; + this.lastTickPosY = this.posY; + this.lastTickPosZ = this.posZ; + super.onUpdate(); + this.posX += this.motionX; + this.posY += this.motionY; + this.posZ += this.motionZ; + float var1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); + + for (this.rotationPitch = (float) (Math.atan2(this.motionY, (double) var1) * 180.0D / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) { + ; + } + + while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { + this.prevRotationPitch += 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw < -180.0F) { + this.prevRotationYaw -= 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { + this.prevRotationYaw += 360.0F; + } + + this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; + this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; + + if (!this.worldObj.isRemote) { + double var2 = this.targetX - this.posX; + double var4 = this.targetZ - this.posZ; + float var6 = (float) Math.sqrt(var2 * var2 + var4 * var4); + float var7 = (float) Math.atan2(var4, var2); + double var8 = (double) var1 + (double) (var6 - var1) * 0.0025D; + + if (var6 < 1.0F) { + var8 *= 0.8D; + this.motionY *= 0.8D; + } + + this.motionX = Math.cos((double) var7) * var8; + this.motionZ = Math.sin((double) var7) * var8; + + if (this.posY < this.targetY) { + this.motionY += (1.0D - this.motionY) * 0.014999999664723873D; + } else { + this.motionY += (-1.0D - this.motionY) * 0.014999999664723873D; + } + } + + float var10 = 0.25F; + + if (this.isInWater()) { + for (int var3 = 0; var3 < 4; ++var3) { + this.worldObj.spawnParticle("bubble", this.posX - this.motionX * (double) var10, this.posY - this.motionY * (double) var10, this.posZ - this.motionZ * (double) var10, this.motionX, this.motionY, this.motionZ); + } + } else { + this.worldObj.spawnParticle("portal", this.posX - this.motionX * (double) var10 + this.rand.nextDouble() * 0.6D - 0.3D, this.posY - this.motionY * (double) var10 - 0.5D, + this.posZ - this.motionZ * (double) var10 + this.rand.nextDouble() * 0.6D - 0.3D, this.motionX, this.motionY, this.motionZ); + } + + if (!this.worldObj.isRemote) { + this.setPosition(this.posX, this.posY, this.posZ); + ++this.despawnTimer; + + if (this.despawnTimer > 80 && !this.worldObj.isRemote) { + this.setDead(); + + if (this.shatterOrDrop) { + this.worldObj.spawnEntityInWorld(new EntityItem(this.worldObj, this.posX, this.posY, this.posZ, new ItemStack(Item.eyeOfEnder))); + } else { + this.worldObj.playAuxSFX(2003, (int) Math.round(this.posX), (int) Math.round(this.posY), (int) Math.round(this.posZ), 0); + } + } + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + } + + public float getShadowSize() { + return 0.0F; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + return 1.0F; + } + + public int getBrightnessForRender(float par1) { + return 15728880; + } + + /** + * If returns false, the item will not inflict any damage against entities. + */ + public boolean canAttackWithItem() { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/EntityEnderPearl.java b/src/main/java/net/minecraft/src/EntityEnderPearl.java new file mode 100644 index 0000000..840cd47 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityEnderPearl.java @@ -0,0 +1,28 @@ +package net.minecraft.src; + +public class EntityEnderPearl extends EntityThrowable { + public EntityEnderPearl() { + super(); + } + + public EntityEnderPearl(World par1World, EntityLiving par2EntityLiving) { + super(par1World, par2EntityLiving); + } + + public EntityEnderPearl(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + } + + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (par1MovingObjectPosition.entityHit != null) { + par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), 0); + } + + for (int var2 = 0; var2 < 32; ++var2) { + this.worldObj.spawnParticle("portal", this.posX, this.posY + this.rand.nextDouble() * 2.0D, this.posZ, this.rand.nextGaussian(), 0.0D, this.rand.nextGaussian()); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityEnderman.java b/src/main/java/net/minecraft/src/EntityEnderman.java new file mode 100644 index 0000000..0ce6b8f --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityEnderman.java @@ -0,0 +1,416 @@ +package net.minecraft.src; + +public class EntityEnderman extends EntityMob { + private static boolean[] carriableBlocks = new boolean[256]; + + /** + * Counter to delay the teleportation of an enderman towards the currently + * attacked target + */ + private int teleportDelay = 0; + private int field_70826_g = 0; + private boolean field_104003_g; + + public EntityEnderman() { + super(); + this.moveSpeed = 0.2F; + this.setSize(0.6F, 2.9F); + this.stepHeight = 1.0F; + } + + public int getMaxHealth() { + return 40; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte) 0)); + this.dataWatcher.addObject(17, new Byte((byte) 0)); + this.dataWatcher.addObject(18, new Byte((byte) 0)); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setShort("carried", (short) this.getCarried()); + par1NBTTagCompound.setShort("carriedData", (short) this.getCarryingData()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setCarried(par1NBTTagCompound.getShort("carried")); + this.setCarryingData(par1NBTTagCompound.getShort("carriedData")); + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity + * isn't interested in attacking (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() { + EntityPlayer var1 = this.worldObj.getClosestVulnerablePlayerToEntity(this, 64.0D); + + if (var1 != null) { + if (this.shouldAttackPlayer(var1)) { + this.field_104003_g = true; + + if (this.field_70826_g == 0) { + this.worldObj.playSoundAtEntity(var1, "mob.endermen.stare", 1.0F, 1.0F); + } + + if (this.field_70826_g++ == 5) { + this.field_70826_g = 0; + this.setScreaming(true); + return var1; + } + } else { + this.field_70826_g = 0; + } + } + + return null; + } + + /** + * Checks to see if this enderman should be attacking this player + */ + private boolean shouldAttackPlayer(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.armorInventory[3]; + + if (var2 != null && var2.itemID == Block.pumpkin.blockID) { + return false; + } else { + Vec3 var3 = par1EntityPlayer.getLook(1.0F).normalize(); + Vec3 var4 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX - par1EntityPlayer.posX, this.boundingBox.minY + (double) (this.height / 2.0F) - (par1EntityPlayer.posY + (double) par1EntityPlayer.getEyeHeight()), + this.posZ - par1EntityPlayer.posZ); + double var5 = var4.lengthVector(); + var4 = var4.normalize(); + double var7 = var3.dotProduct(var4); + return var7 > 1.0D - 0.025D / var5 ? par1EntityPlayer.canEntityBeSeen(this) : false; + } + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (this.isWet()) { + this.attackEntityFrom(DamageSource.drown, 1); + } + + this.moveSpeed = this.entityToAttack != null ? 6.5F : 0.3F; + int var1; + + if (!this.worldObj.isRemote && this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")) { + int var2; + int var3; + int var4; + + if (this.getCarried() == 0) { + if (this.rand.nextInt(20) == 0) { + var1 = MathHelper.floor_double(this.posX - 2.0D + this.rand.nextDouble() * 4.0D); + var2 = MathHelper.floor_double(this.posY + this.rand.nextDouble() * 3.0D); + var3 = MathHelper.floor_double(this.posZ - 2.0D + this.rand.nextDouble() * 4.0D); + var4 = this.worldObj.getBlockId(var1, var2, var3); + + if (carriableBlocks[var4]) { + this.setCarried(this.worldObj.getBlockId(var1, var2, var3)); + this.setCarryingData(this.worldObj.getBlockMetadata(var1, var2, var3)); + this.worldObj.setBlock(var1, var2, var3, 0); + } + } + } else if (this.rand.nextInt(2000) == 0) { + var1 = MathHelper.floor_double(this.posX - 1.0D + this.rand.nextDouble() * 2.0D); + var2 = MathHelper.floor_double(this.posY + this.rand.nextDouble() * 2.0D); + var3 = MathHelper.floor_double(this.posZ - 1.0D + this.rand.nextDouble() * 2.0D); + var4 = this.worldObj.getBlockId(var1, var2, var3); + int var5 = this.worldObj.getBlockId(var1, var2 - 1, var3); + + if (var4 == 0 && var5 > 0 && Block.blocksList[var5].renderAsNormalBlock()) { + this.worldObj.setBlock(var1, var2, var3, this.getCarried(), this.getCarryingData(), 3); + this.setCarried(0); + } + } + } + + for (var1 = 0; var1 < 2; ++var1) { + this.worldObj.spawnParticle("portal", this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.width, this.posY + this.rand.nextDouble() * (double) this.height - 0.25D, + this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.width, (this.rand.nextDouble() - 0.5D) * 2.0D, -this.rand.nextDouble(), (this.rand.nextDouble() - 0.5D) * 2.0D); + } + + if (this.worldObj.isDaytime() && !this.worldObj.isRemote) { + float var6 = this.getBrightness(1.0F); + + if (var6 > 0.5F && this.worldObj.canBlockSeeTheSky(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) && this.rand.nextFloat() * 30.0F < (var6 - 0.4F) * 2.0F) { + this.entityToAttack = null; + this.setScreaming(false); + this.field_104003_g = false; + this.teleportRandomly(); + } + } + + if (this.isWet() || this.isBurning()) { + this.entityToAttack = null; + this.setScreaming(false); + this.field_104003_g = false; + this.teleportRandomly(); + } + + if (this.isScreaming() && !this.field_104003_g && this.rand.nextInt(100) == 0) { + this.setScreaming(false); + } + + this.isJumping = false; + + if (this.entityToAttack != null) { + this.faceEntity(this.entityToAttack, 100.0F, 100.0F); + } + + if (!this.worldObj.isRemote && this.isEntityAlive()) { + if (this.entityToAttack != null) { + if (this.entityToAttack instanceof EntityPlayer && this.shouldAttackPlayer((EntityPlayer) this.entityToAttack)) { + this.moveStrafing = this.moveForward = 0.0F; + this.moveSpeed = 0.0F; + + if (this.entityToAttack.getDistanceSqToEntity(this) < 16.0D) { + this.teleportRandomly(); + } + + this.teleportDelay = 0; + } else if (this.entityToAttack.getDistanceSqToEntity(this) > 256.0D && this.teleportDelay++ >= 30 && this.teleportToEntity(this.entityToAttack)) { + this.teleportDelay = 0; + } + } else { + this.setScreaming(false); + this.teleportDelay = 0; + } + } + + super.onLivingUpdate(); + } + + /** + * Teleport the enderman to a random nearby position + */ + protected boolean teleportRandomly() { + double var1 = this.posX + (this.rand.nextDouble() - 0.5D) * 64.0D; + double var3 = this.posY + (double) (this.rand.nextInt(64) - 32); + double var5 = this.posZ + (this.rand.nextDouble() - 0.5D) * 64.0D; + return this.teleportTo(var1, var3, var5); + } + + /** + * Teleport the enderman to another entity + */ + protected boolean teleportToEntity(Entity par1Entity) { + Vec3 var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX - par1Entity.posX, this.boundingBox.minY + (double) (this.height / 2.0F) - par1Entity.posY + (double) par1Entity.getEyeHeight(), this.posZ - par1Entity.posZ); + var2 = var2.normalize(); + double var3 = 16.0D; + double var5 = this.posX + (this.rand.nextDouble() - 0.5D) * 8.0D - var2.xCoord * var3; + double var7 = this.posY + (double) (this.rand.nextInt(16) - 8) - var2.yCoord * var3; + double var9 = this.posZ + (this.rand.nextDouble() - 0.5D) * 8.0D - var2.zCoord * var3; + return this.teleportTo(var5, var7, var9); + } + + /** + * Teleport the enderman + */ + protected boolean teleportTo(double par1, double par3, double par5) { + double var7 = this.posX; + double var9 = this.posY; + double var11 = this.posZ; + this.posX = par1; + this.posY = par3; + this.posZ = par5; + boolean var13 = false; + int var14 = MathHelper.floor_double(this.posX); + int var15 = MathHelper.floor_double(this.posY); + int var16 = MathHelper.floor_double(this.posZ); + int var18; + + if (this.worldObj.blockExists(var14, var15, var16)) { + boolean var17 = false; + + while (!var17 && var15 > 0) { + var18 = this.worldObj.getBlockId(var14, var15 - 1, var16); + + if (var18 != 0 && Block.blocksList[var18].blockMaterial.blocksMovement()) { + var17 = true; + } else { + --this.posY; + --var15; + } + } + + if (var17) { + this.setPosition(this.posX, this.posY, this.posZ); + + if (this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() && !this.worldObj.isAnyLiquid(this.boundingBox)) { + var13 = true; + } + } + } + + if (!var13) { + this.setPosition(var7, var9, var11); + return false; + } else { + short var30 = 128; + + for (var18 = 0; var18 < var30; ++var18) { + double var19 = (double) var18 / ((double) var30 - 1.0D); + float var21 = (this.rand.nextFloat() - 0.5F) * 0.2F; + float var22 = (this.rand.nextFloat() - 0.5F) * 0.2F; + float var23 = (this.rand.nextFloat() - 0.5F) * 0.2F; + double var24 = var7 + (this.posX - var7) * var19 + (this.rand.nextDouble() - 0.5D) * (double) this.width * 2.0D; + double var26 = var9 + (this.posY - var9) * var19 + this.rand.nextDouble() * (double) this.height; + double var28 = var11 + (this.posZ - var11) * var19 + (this.rand.nextDouble() - 0.5D) * (double) this.width * 2.0D; + this.worldObj.spawnParticle("portal", var24, var26, var28, (double) var21, (double) var22, (double) var23); + } + + this.worldObj.playSoundEffect(var7, var9, var11, "mob.endermen.portal", 1.0F, 1.0F); + this.playSound("mob.endermen.portal", 1.0F, 1.0F); + return true; + } + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return this.isScreaming() ? "mob.endermen.scream" : "mob.endermen.idle"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.endermen.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.endermen.death"; + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.enderPearl.itemID; + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.getDropItemId(); + + if (var3 > 0) { + int var4 = this.rand.nextInt(2 + par2); + + for (int var5 = 0; var5 < var4; ++var5) { + this.dropItem(var3, 1); + } + } + } + + /** + * Set the id of the block an enderman carries + */ + public void setCarried(int par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (par1 & 255))); + } + + /** + * Get the id of the block an enderman carries + */ + public int getCarried() { + return this.dataWatcher.getWatchableObjectByte(16); + } + + /** + * Set the metadata of the block an enderman carries + */ + public void setCarryingData(int par1) { + this.dataWatcher.updateObject(17, Byte.valueOf((byte) (par1 & 255))); + } + + /** + * Get the metadata of the block an enderman carries + */ + public int getCarryingData() { + return this.dataWatcher.getWatchableObjectByte(17); + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + this.setScreaming(true); + + if (par1DamageSource instanceof EntityDamageSource && par1DamageSource.getEntity() instanceof EntityPlayer) { + this.field_104003_g = true; + } + + if (par1DamageSource instanceof EntityDamageSourceIndirect) { + this.field_104003_g = false; + + for (int var3 = 0; var3 < 64; ++var3) { + if (this.teleportRandomly()) { + return true; + } + } + + return false; + } else { + return super.attackEntityFrom(par1DamageSource, par2); + } + } + } + + public boolean isScreaming() { + return this.dataWatcher.getWatchableObjectByte(18) > 0; + } + + public void setScreaming(boolean par1) { + this.dataWatcher.updateObject(18, Byte.valueOf((byte) (par1 ? 1 : 0))); + } + + /** + * Returns the amount of damage a mob should deal. + */ + public int getAttackStrength(Entity par1Entity) { + return 7; + } + + static { + carriableBlocks[Block.grass.blockID] = true; + carriableBlocks[Block.dirt.blockID] = true; + carriableBlocks[Block.sand.blockID] = true; + carriableBlocks[Block.gravel.blockID] = true; + carriableBlocks[Block.plantYellow.blockID] = true; + carriableBlocks[Block.plantRed.blockID] = true; + carriableBlocks[Block.mushroomBrown.blockID] = true; + carriableBlocks[Block.mushroomRed.blockID] = true; + carriableBlocks[Block.tnt.blockID] = true; + carriableBlocks[Block.cactus.blockID] = true; + carriableBlocks[Block.blockClay.blockID] = true; + carriableBlocks[Block.pumpkin.blockID] = true; + carriableBlocks[Block.melon.blockID] = true; + carriableBlocks[Block.mycelium.blockID] = true; + } +} diff --git a/src/main/java/net/minecraft/src/EntityExpBottle.java b/src/main/java/net/minecraft/src/EntityExpBottle.java new file mode 100644 index 0000000..7ae60e7 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityExpBottle.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + + + +public class EntityExpBottle extends EntityThrowable { + public EntityExpBottle() { + super(); + } + + public EntityExpBottle(World par1World, EntityLiving par2EntityLiving) { + super(par1World, par2EntityLiving); + } + + public EntityExpBottle(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + } + + /** + * Gets the amount of gravity to apply to the thrown entity with each tick. + */ + protected float getGravityVelocity() { + return 0.07F; + } + + protected float func_70182_d() { + return 0.7F; + } + + protected float func_70183_g() { + return -20.0F; + } + + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (!this.worldObj.isRemote) { + this.worldObj.playAuxSFX(2002, (int) Math.round(this.posX), (int) Math.round(this.posY), (int) Math.round(this.posZ), 0); + int var2 = 3 + this.worldObj.rand.nextInt(5) + this.worldObj.rand.nextInt(5); + + while (var2 > 0) { + int var3 = EntityXPOrb.getXPSplit(var2); + var2 -= var3; + this.worldObj.spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, var3)); + } + + this.setDead(); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityExplodeFX.java b/src/main/java/net/minecraft/src/EntityExplodeFX.java new file mode 100644 index 0000000..9a7bab2 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityExplodeFX.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + + + +public class EntityExplodeFX extends EntityFX { + public EntityExplodeFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + super(par1World, par2, par4, par6, par8, par10, par12); + this.motionX = par8 + (double) ((float) (Math.random() * 2.0D - 1.0D) * 0.05F); + this.motionY = par10 + (double) ((float) (Math.random() * 2.0D - 1.0D) * 0.05F); + this.motionZ = par12 + (double) ((float) (Math.random() * 2.0D - 1.0D) * 0.05F); + this.particleRed = this.particleGreen = this.particleBlue = this.rand.nextFloat() * 0.3F + 0.7F; + this.particleScale = this.rand.nextFloat() * this.rand.nextFloat() * 6.0F + 1.0F; + this.particleMaxAge = (int) (16.0D / ((double) this.rand.nextFloat() * 0.8D + 0.2D)) + 2; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + + this.setParticleTextureIndex(7 - this.particleAge * 8 / this.particleMaxAge); + this.motionY += 0.004D; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.8999999761581421D; + this.motionY *= 0.8999999761581421D; + this.motionZ *= 0.8999999761581421D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityFX.java b/src/main/java/net/minecraft/src/EntityFX.java new file mode 100644 index 0000000..71ff452 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFX.java @@ -0,0 +1,224 @@ +package net.minecraft.src; + + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityFX extends Entity { + protected int particleTextureIndexX; + protected int particleTextureIndexY; + protected float particleTextureJitterX; + protected float particleTextureJitterY; + protected int particleAge; + protected int particleMaxAge; + protected float particleScale; + protected float particleGravity; + + /** The red amount of color. Used as a percentage, 1.0 = 255 and 0.0 = 0. */ + protected float particleRed; + + /** + * The green amount of color. Used as a percentage, 1.0 = 255 and 0.0 = 0. + */ + protected float particleGreen; + + /** + * The blue amount of color. Used as a percentage, 1.0 = 255 and 0.0 = 0. + */ + protected float particleBlue; + + /** Particle alpha */ + protected float particleAlpha; + + /** The icon field from which the given particle pulls its texture. */ + protected Icon particleIcon; + public static double interpPosX; + public static double interpPosY; + public static double interpPosZ; + + protected EntityFX(World par1World, double par2, double par4, double par6) { + super(); + this.setWorld(par1World); + this.particleAge = 0; + this.particleMaxAge = 0; + this.particleAlpha = 1.0F; + this.particleIcon = null; + this.setSize(0.2F, 0.2F); + this.yOffset = this.height / 2.0F; + this.setPosition(par2, par4, par6); + this.lastTickPosX = par2; + this.lastTickPosY = par4; + this.lastTickPosZ = par6; + this.particleRed = this.particleGreen = this.particleBlue = 1.0F; + this.particleTextureJitterX = this.rand.nextFloat() * 3.0F; + this.particleTextureJitterY = this.rand.nextFloat() * 3.0F; + this.particleScale = (this.rand.nextFloat() * 0.5F + 0.5F) * 2.0F; + this.particleMaxAge = (int) (4.0F / (this.rand.nextFloat() * 0.9F + 0.1F)); + this.particleAge = 0; + } + + public EntityFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + this(par1World, par2, par4, par6); + this.motionX = par8 + (double) ((float) (Math.random() * 2.0D - 1.0D) * 0.4F); + this.motionY = par10 + (double) ((float) (Math.random() * 2.0D - 1.0D) * 0.4F); + this.motionZ = par12 + (double) ((float) (Math.random() * 2.0D - 1.0D) * 0.4F); + float var14 = (float) (Math.random() + Math.random() + 1.0D) * 0.15F; + float var15 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); + this.motionX = this.motionX / (double) var15 * (double) var14 * 0.4000000059604645D; + this.motionY = this.motionY / (double) var15 * (double) var14 * 0.4000000059604645D + 0.10000000149011612D; + this.motionZ = this.motionZ / (double) var15 * (double) var14 * 0.4000000059604645D; + } + + public EntityFX multiplyVelocity(float par1) { + this.motionX *= (double) par1; + this.motionY = (this.motionY - 0.10000000149011612D) * (double) par1 + 0.10000000149011612D; + this.motionZ *= (double) par1; + return this; + } + + public EntityFX multipleParticleScaleBy(float par1) { + this.setSize(0.2F * par1, 0.2F * par1); + this.particleScale *= par1; + return this; + } + + public void setRBGColorF(float par1, float par2, float par3) { + this.particleRed = par1; + this.particleGreen = par2; + this.particleBlue = par3; + } + + /** + * Sets the particle alpha (float) + */ + public void setAlphaF(float par1) { + this.particleAlpha = par1; + } + + public float getRedColorF() { + return this.particleRed; + } + + public float getGreenColorF() { + return this.particleGreen; + } + + public float getBlueColorF() { + return this.particleBlue; + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + protected void entityInit() { + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + + this.motionY -= 0.04D * (double) this.particleGravity; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.9800000190734863D; + this.motionZ *= 0.9800000190734863D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = (float) this.particleTextureIndexX / 16.0F; + float var9 = var8 + 0.0624375F; + float var10 = (float) this.particleTextureIndexY / 16.0F; + float var11 = var10 + 0.0624375F; + float var12 = 0.1F * this.particleScale; + + if (this.particleIcon != null) { + var8 = this.particleIcon.getMinU(); + var9 = this.particleIcon.getMaxU(); + var10 = this.particleIcon.getMinV(); + var11 = this.particleIcon.getMaxV(); + } + + float var13 = (float) (this.prevPosX + (this.posX - this.prevPosX) * (double) par2 - interpPosX); + float var14 = (float) (this.prevPosY + (this.posY - this.prevPosY) * (double) par2 - interpPosY); + float var15 = (float) (this.prevPosZ + (this.posZ - this.prevPosZ) * (double) par2 - interpPosZ); + float var16 = 1.0F; + par1Tessellator.setColorRGBA_F(this.particleRed * var16, this.particleGreen * var16, this.particleBlue * var16, this.particleAlpha); + par1Tessellator.addVertexWithUV((double) (var13 - par3 * var12 - par6 * var12), (double) (var14 - par4 * var12), (double) (var15 - par5 * var12 - par7 * var12), (double) var9, (double) var11); + par1Tessellator.addVertexWithUV((double) (var13 - par3 * var12 + par6 * var12), (double) (var14 + par4 * var12), (double) (var15 - par5 * var12 + par7 * var12), (double) var9, (double) var10); + par1Tessellator.addVertexWithUV((double) (var13 + par3 * var12 + par6 * var12), (double) (var14 + par4 * var12), (double) (var15 + par5 * var12 + par7 * var12), (double) var8, (double) var10); + par1Tessellator.addVertexWithUV((double) (var13 + par3 * var12 - par6 * var12), (double) (var14 - par4 * var12), (double) (var15 + par5 * var12 - par7 * var12), (double) var8, (double) var11); + } + + public int getFXLayer() { + return 0; + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + } + + public void setParticleIcon(RenderEngine par1RenderEngine, Icon par2Icon) { + if (this.getFXLayer() == 1) { + this.particleIcon = par2Icon; + } else { + if (this.getFXLayer() != 2) { + throw new RuntimeException("Invalid call to Particle.setTex, use coordinate methods"); + } + + this.particleIcon = par2Icon; + } + } + + /** + * Public method to set private field particleTextureIndex. + */ + public void setParticleTextureIndex(int par1) { + if (this.getFXLayer() != 0) { + throw new RuntimeException("Invalid call to Particle.setMiscTex"); + } else { + this.particleTextureIndexX = par1 % 16; + this.particleTextureIndexY = par1 / 16; + } + } + + public void nextTextureIndexX() { + ++this.particleTextureIndexX; + } + + /** + * If returns false, the item will not inflict any damage against entities. + */ + public boolean canAttackWithItem() { + return false; + } + + public String toString() { + return this.getClass().getSimpleName() + ", Pos (" + this.posX + "," + this.posY + "," + this.posZ + "), RGBA (" + this.particleRed + "," + this.particleGreen + "," + this.particleBlue + "," + this.particleAlpha + "), Age " + + this.particleAge; + } +} diff --git a/src/main/java/net/minecraft/src/EntityFallingSand.java b/src/main/java/net/minecraft/src/EntityFallingSand.java new file mode 100644 index 0000000..26aa0e8 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFallingSand.java @@ -0,0 +1,265 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; + + + +public class EntityFallingSand extends Entity { + public int blockID; + public int metadata; + + /** How long the block has been falling for. */ + public int fallTime; + public boolean shouldDropItem; + private boolean isBreakingAnvil; + private boolean isAnvil; + + /** Maximum amount of damage dealt to entities hit by falling block */ + private int fallHurtMax; + + /** Actual damage dealt to entities hit by falling block */ + private float fallHurtAmount; + public NBTTagCompound fallingBlockTileEntityData; + + public EntityFallingSand() { + super(); + this.fallTime = 0; + this.shouldDropItem = true; + this.isBreakingAnvil = false; + this.isAnvil = false; + this.fallHurtMax = 40; + this.fallHurtAmount = 2.0F; + this.fallingBlockTileEntityData = null; + } + + public EntityFallingSand(World par1World, double par2, double par4, double par6, int par8) { + this(par1World, par2, par4, par6, par8, 0); + } + + public EntityFallingSand(World par1World, double par2, double par4, double par6, int par8, int par9) { + super(); + this.setWorld(par1World); + this.fallTime = 0; + this.shouldDropItem = true; + this.isBreakingAnvil = false; + this.isAnvil = false; + this.fallHurtMax = 40; + this.fallHurtAmount = 2.0F; + this.fallingBlockTileEntityData = null; + this.blockID = par8; + this.metadata = par9; + this.preventEntitySpawning = true; + this.setSize(0.98F, 0.98F); + this.yOffset = this.height / 2.0F; + this.setPosition(par2, par4, par6); + this.motionX = 0.0D; + this.motionY = 0.0D; + this.motionZ = 0.0D; + this.prevPosX = par2; + this.prevPosY = par4; + this.prevPosZ = par6; + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + protected void entityInit() { + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return !this.isDead; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (this.blockID == 0) { + this.setDead(); + } else { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + ++this.fallTime; + this.motionY -= 0.03999999910593033D; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.9800000190734863D; + this.motionZ *= 0.9800000190734863D; + + if (!this.worldObj.isRemote) { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.posY); + int var3 = MathHelper.floor_double(this.posZ); + + if (this.fallTime == 1) { + if (this.worldObj.getBlockId(var1, var2, var3) != this.blockID) { + this.setDead(); + return; + } + + this.worldObj.setBlockToAir(var1, var2, var3); + } + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + this.motionY *= -0.5D; + + if (this.worldObj.getBlockId(var1, var2, var3) != Block.pistonMoving.blockID) { + this.setDead(); + + if (!this.isBreakingAnvil && this.worldObj.canPlaceEntityOnSide(this.blockID, var1, var2, var3, true, 1, (Entity) null, (ItemStack) null) && !BlockSand.canFallBelow(this.worldObj, var1, var2 - 1, var3) + && this.worldObj.setBlock(var1, var2, var3, this.blockID, this.metadata, 3)) { + if (Block.blocksList[this.blockID] instanceof BlockSand) { + ((BlockSand) Block.blocksList[this.blockID]).onFinishFalling(this.worldObj, var1, var2, var3, this.metadata); + } + + if (this.fallingBlockTileEntityData != null && Block.blocksList[this.blockID] instanceof ITileEntityProvider) { + TileEntity var4 = this.worldObj.getBlockTileEntity(var1, var2, var3); + + if (var4 != null) { + NBTTagCompound var5 = new NBTTagCompound(); + var4.writeToNBT(var5); + Iterator var6 = this.fallingBlockTileEntityData.getTags().iterator(); + + while (var6.hasNext()) { + NBTBase var7 = (NBTBase) var6.next(); + + if (!var7.getName().equals("x") && !var7.getName().equals("y") && !var7.getName().equals("z")) { + var5.setTag(var7.getName(), var7.copy()); + } + } + + var4.readFromNBT(var5); + var4.onInventoryChanged(); + } + } + } else if (this.shouldDropItem && !this.isBreakingAnvil) { + this.entityDropItem(new ItemStack(this.blockID, 1, Block.blocksList[this.blockID].damageDropped(this.metadata)), 0.0F); + } + } + } else if (this.fallTime > 100 && !this.worldObj.isRemote && (var2 < 1 || var2 > 256) || this.fallTime > 600) { + if (this.shouldDropItem) { + this.entityDropItem(new ItemStack(this.blockID, 1, Block.blocksList[this.blockID].damageDropped(this.metadata)), 0.0F); + } + + this.setDead(); + } + } + } + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + if (this.isAnvil) { + int var2 = MathHelper.ceiling_float_int(par1 - 1.0F); + + if (var2 > 0) { + ArrayList var3 = new ArrayList(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox)); + DamageSource var4 = this.blockID == Block.anvil.blockID ? DamageSource.anvil : DamageSource.fallingBlock; + Iterator var5 = var3.iterator(); + + while (var5.hasNext()) { + Entity var6 = (Entity) var5.next(); + var6.attackEntityFrom(var4, Math.min(MathHelper.floor_float((float) var2 * this.fallHurtAmount), this.fallHurtMax)); + } + + if (this.blockID == Block.anvil.blockID && (double) this.rand.nextFloat() < 0.05000000074505806D + (double) var2 * 0.05D) { + int var7 = this.metadata >> 2; + int var8 = this.metadata & 3; + ++var7; + + if (var7 > 2) { + this.isBreakingAnvil = true; + } else { + this.metadata = var8 | var7 << 2; + } + } + } + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setByte("Tile", (byte) this.blockID); + par1NBTTagCompound.setInteger("TileID", this.blockID); + par1NBTTagCompound.setByte("Data", (byte) this.metadata); + par1NBTTagCompound.setByte("Time", (byte) this.fallTime); + par1NBTTagCompound.setBoolean("DropItem", this.shouldDropItem); + par1NBTTagCompound.setBoolean("HurtEntities", this.isAnvil); + par1NBTTagCompound.setFloat("FallHurtAmount", this.fallHurtAmount); + par1NBTTagCompound.setInteger("FallHurtMax", this.fallHurtMax); + + if (this.fallingBlockTileEntityData != null) { + par1NBTTagCompound.setCompoundTag("TileEntityData", this.fallingBlockTileEntityData); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + if (par1NBTTagCompound.hasKey("TileID")) { + this.blockID = par1NBTTagCompound.getInteger("TileID"); + } else { + this.blockID = par1NBTTagCompound.getByte("Tile") & 255; + } + + this.metadata = par1NBTTagCompound.getByte("Data") & 255; + this.fallTime = par1NBTTagCompound.getByte("Time") & 255; + + if (par1NBTTagCompound.hasKey("HurtEntities")) { + this.isAnvil = par1NBTTagCompound.getBoolean("HurtEntities"); + this.fallHurtAmount = par1NBTTagCompound.getFloat("FallHurtAmount"); + this.fallHurtMax = par1NBTTagCompound.getInteger("FallHurtMax"); + } else if (this.blockID == Block.anvil.blockID) { + this.isAnvil = true; + } + + if (par1NBTTagCompound.hasKey("DropItem")) { + this.shouldDropItem = par1NBTTagCompound.getBoolean("DropItem"); + } + + if (par1NBTTagCompound.hasKey("TileEntityData")) { + this.fallingBlockTileEntityData = par1NBTTagCompound.getCompoundTag("TileEntityData"); + } + + if (this.blockID == 0) { + this.blockID = Block.sand.blockID; + } + } + + public float getShadowSize() { + return 0.0F; + } + + public World getWorld() { + return this.worldObj; + } + + public void setIsAnvil(boolean par1) { + this.isAnvil = par1; + } + + /** + * Return whether this entity should be rendered as on fire. + */ + public boolean canRenderOnFire() { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/EntityFireball.java b/src/main/java/net/minecraft/src/EntityFireball.java new file mode 100644 index 0000000..837670b --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFireball.java @@ -0,0 +1,292 @@ +package net.minecraft.src; + +import java.util.List; + + + +public abstract class EntityFireball extends Entity { + private int xTile = -1; + private int yTile = -1; + private int zTile = -1; + private int inTile = 0; + private boolean inGround = false; + public EntityLiving shootingEntity; + private int ticksAlive; + private int ticksInAir = 0; + public double accelerationX; + public double accelerationY; + public double accelerationZ; + + public EntityFireball() { + super(); + this.setSize(1.0F, 1.0F); + } + + protected void entityInit() { + } + + /** + * Checks if the entity is in range to render by using the past in distance and + * comparing it to its average edge length * 64 * renderDistanceWeight Args: + * distance + */ + public boolean isInRangeToRenderDist(double par1) { + double var3 = this.boundingBox.getAverageEdgeLength() * 4.0D; + var3 *= 64.0D; + return par1 < var3 * var3; + } + + public EntityFireball(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + super(); + this.setWorld(par1World); + this.setSize(1.0F, 1.0F); + this.setLocationAndAngles(par2, par4, par6, this.rotationYaw, this.rotationPitch); + this.setPosition(par2, par4, par6); + double var14 = (double) MathHelper.sqrt_double(par8 * par8 + par10 * par10 + par12 * par12); + this.accelerationX = par8 / var14 * 0.1D; + this.accelerationY = par10 / var14 * 0.1D; + this.accelerationZ = par12 / var14 * 0.1D; + } + + public EntityFireball(World par1World, EntityLiving par2EntityLiving, double par3, double par5, double par7) { + super(); + this.setWorld(par1World); + this.shootingEntity = par2EntityLiving; + this.setSize(1.0F, 1.0F); + this.setLocationAndAngles(par2EntityLiving.posX, par2EntityLiving.posY, par2EntityLiving.posZ, par2EntityLiving.rotationYaw, par2EntityLiving.rotationPitch); + this.setPosition(this.posX, this.posY, this.posZ); + this.yOffset = 0.0F; + this.motionX = this.motionY = this.motionZ = 0.0D; + par3 += this.rand.nextGaussian() * 0.4D; + par5 += this.rand.nextGaussian() * 0.4D; + par7 += this.rand.nextGaussian() * 0.4D; + double var9 = (double) MathHelper.sqrt_double(par3 * par3 + par5 * par5 + par7 * par7); + this.accelerationX = par3 / var9 * 0.1D; + this.accelerationY = par5 / var9 * 0.1D; + this.accelerationZ = par7 / var9 * 0.1D; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (!this.worldObj.isRemote && (this.shootingEntity != null && this.shootingEntity.isDead || !this.worldObj.blockExists((int) this.posX, (int) this.posY, (int) this.posZ))) { + this.setDead(); + } else { + super.onUpdate(); + this.setFire(1); + + if (this.inGround) { + int var1 = this.worldObj.getBlockId(this.xTile, this.yTile, this.zTile); + + if (var1 == this.inTile) { + ++this.ticksAlive; + + if (this.ticksAlive == 600) { + this.setDead(); + } + + return; + } + + this.inGround = false; + this.motionX *= (double) (this.rand.nextFloat() * 0.2F); + this.motionY *= (double) (this.rand.nextFloat() * 0.2F); + this.motionZ *= (double) (this.rand.nextFloat() * 0.2F); + this.ticksAlive = 0; + this.ticksInAir = 0; + } else { + ++this.ticksInAir; + } + + Vec3 var15 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + Vec3 var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); + MovingObjectPosition var3 = this.worldObj.rayTraceBlocks(var15, var2); + var15 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); + + if (var3 != null) { + var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(var3.hitVec.xCoord, var3.hitVec.yCoord, var3.hitVec.zCoord); + } + + Entity var4 = null; + List var5 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D)); + double var6 = 0.0D; + + for (int var8 = 0; var8 < var5.size(); ++var8) { + Entity var9 = (Entity) var5.get(var8); + + if (var9.canBeCollidedWith() && (!var9.isEntityEqual(this.shootingEntity) || this.ticksInAir >= 25)) { + float var10 = 0.3F; + AxisAlignedBB var11 = var9.boundingBox.expand((double) var10, (double) var10, (double) var10); + MovingObjectPosition var12 = var11.calculateIntercept(var15, var2); + + if (var12 != null) { + double var13 = var15.distanceTo(var12.hitVec); + + if (var13 < var6 || var6 == 0.0D) { + var4 = var9; + var6 = var13; + } + } + } + } + + if (var4 != null) { + var3 = new MovingObjectPosition(var4); + } + + if (var3 != null) { + this.onImpact(var3); + } + + this.posX += this.motionX; + this.posY += this.motionY; + this.posZ += this.motionZ; + float var16 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.rotationYaw = (float) (Math.atan2(this.motionZ, this.motionX) * 180.0D / Math.PI) + 90.0F; + + for (this.rotationPitch = (float) (Math.atan2((double) var16, this.motionY) * 180.0D / Math.PI) - 90.0F; this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) { + ; + } + + while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { + this.prevRotationPitch += 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw < -180.0F) { + this.prevRotationYaw -= 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { + this.prevRotationYaw += 360.0F; + } + + this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; + this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; + float var17 = this.getMotionFactor(); + + if (this.isInWater()) { + for (int var18 = 0; var18 < 4; ++var18) { + float var19 = 0.25F; + this.worldObj.spawnParticle("bubble", this.posX - this.motionX * (double) var19, this.posY - this.motionY * (double) var19, this.posZ - this.motionZ * (double) var19, this.motionX, this.motionY, this.motionZ); + } + + var17 = 0.8F; + } + + this.motionX += this.accelerationX; + this.motionY += this.accelerationY; + this.motionZ += this.accelerationZ; + this.motionX *= (double) var17; + this.motionY *= (double) var17; + this.motionZ *= (double) var17; + this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D); + this.setPosition(this.posX, this.posY, this.posZ); + } + } + + /** + * Return the motion factor for this projectile. The factor is multiplied by the + * original motion. + */ + protected float getMotionFactor() { + return 0.95F; + } + + /** + * Called when this EntityFireball hits a block or entity. + */ + protected abstract void onImpact(MovingObjectPosition var1); + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setShort("xTile", (short) this.xTile); + par1NBTTagCompound.setShort("yTile", (short) this.yTile); + par1NBTTagCompound.setShort("zTile", (short) this.zTile); + par1NBTTagCompound.setByte("inTile", (byte) this.inTile); + par1NBTTagCompound.setByte("inGround", (byte) (this.inGround ? 1 : 0)); + par1NBTTagCompound.setTag("direction", this.newDoubleNBTList(new double[] { this.motionX, this.motionY, this.motionZ })); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.xTile = par1NBTTagCompound.getShort("xTile"); + this.yTile = par1NBTTagCompound.getShort("yTile"); + this.zTile = par1NBTTagCompound.getShort("zTile"); + this.inTile = par1NBTTagCompound.getByte("inTile") & 255; + this.inGround = par1NBTTagCompound.getByte("inGround") == 1; + + if (par1NBTTagCompound.hasKey("direction")) { + NBTTagList var2 = par1NBTTagCompound.getTagList("direction"); + this.motionX = ((NBTTagDouble) var2.tagAt(0)).data; + this.motionY = ((NBTTagDouble) var2.tagAt(1)).data; + this.motionZ = ((NBTTagDouble) var2.tagAt(2)).data; + } else { + this.setDead(); + } + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return true; + } + + public float getCollisionBorderSize() { + return 1.0F; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + this.setBeenAttacked(); + + if (par1DamageSource.getEntity() != null) { + Vec3 var3 = par1DamageSource.getEntity().getLookVec(); + + if (var3 != null) { + this.motionX = var3.xCoord; + this.motionY = var3.yCoord; + this.motionZ = var3.zCoord; + this.accelerationX = this.motionX * 0.1D; + this.accelerationY = this.motionY * 0.1D; + this.accelerationZ = this.motionZ * 0.1D; + } + + if (par1DamageSource.getEntity() instanceof EntityLiving) { + this.shootingEntity = (EntityLiving) par1DamageSource.getEntity(); + } + + return true; + } else { + return false; + } + } + } + + public float getShadowSize() { + return 0.0F; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + return 1.0F; + } + + public int getBrightnessForRender(float par1) { + return 15728880; + } +} diff --git a/src/main/java/net/minecraft/src/EntityFireworkOverlayFX.java b/src/main/java/net/minecraft/src/EntityFireworkOverlayFX.java new file mode 100644 index 0000000..27a1e8d --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFireworkOverlayFX.java @@ -0,0 +1,28 @@ +package net.minecraft.src; + + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityFireworkOverlayFX extends EntityFX { + protected EntityFireworkOverlayFX(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + this.particleMaxAge = 4; + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = 0.25F; + float var9 = var8 + 0.25F; + float var10 = 0.125F; + float var11 = var10 + 0.25F; + float var12 = 7.1F * MathHelper.sin(((float) this.particleAge + par2 - 1.0F) * 0.25F * (float) Math.PI); + this.particleAlpha = 0.6F - ((float) this.particleAge + par2 - 1.0F) * 0.25F * 0.5F; + float var13 = (float) (this.prevPosX + (this.posX - this.prevPosX) * (double) par2 - interpPosX); + float var14 = (float) (this.prevPosY + (this.posY - this.prevPosY) * (double) par2 - interpPosY); + float var15 = (float) (this.prevPosZ + (this.posZ - this.prevPosZ) * (double) par2 - interpPosZ); + par1Tessellator.setColorRGBA_F(this.particleRed, this.particleGreen, this.particleBlue, this.particleAlpha); + par1Tessellator.addVertexWithUV((double) (var13 - par3 * var12 - par6 * var12), (double) (var14 - par4 * var12), (double) (var15 - par5 * var12 - par7 * var12), (double) var9, (double) var11); + par1Tessellator.addVertexWithUV((double) (var13 - par3 * var12 + par6 * var12), (double) (var14 + par4 * var12), (double) (var15 - par5 * var12 + par7 * var12), (double) var9, (double) var10); + par1Tessellator.addVertexWithUV((double) (var13 + par3 * var12 + par6 * var12), (double) (var14 + par4 * var12), (double) (var15 + par5 * var12 + par7 * var12), (double) var8, (double) var10); + par1Tessellator.addVertexWithUV((double) (var13 + par3 * var12 - par6 * var12), (double) (var14 - par4 * var12), (double) (var15 + par5 * var12 - par7 * var12), (double) var8, (double) var11); + } +} diff --git a/src/main/java/net/minecraft/src/EntityFireworkRocket.java b/src/main/java/net/minecraft/src/EntityFireworkRocket.java new file mode 100644 index 0000000..dc2d156 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFireworkRocket.java @@ -0,0 +1,191 @@ +package net.minecraft.src; + + + +public class EntityFireworkRocket extends Entity { + /** The age of the firework in ticks. */ + private int fireworkAge; + + /** + * The lifetime of the firework in ticks. When the age reaches the lifetime the + * firework explodes. + */ + private int lifetime; + + public EntityFireworkRocket() { + super(); + this.setSize(0.25F, 0.25F); + } + + protected void entityInit() { + this.dataWatcher.addObjectByDataType(8, 5); + } + + /** + * Checks if the entity is in range to render by using the past in distance and + * comparing it to its average edge length * 64 * renderDistanceWeight Args: + * distance + */ + public boolean isInRangeToRenderDist(double par1) { + return par1 < 4096.0D; + } + + public EntityFireworkRocket(World par1World, double par2, double par4, double par6, ItemStack par8ItemStack) { + super(); + this.setWorld(par1World); + this.fireworkAge = 0; + this.setSize(0.25F, 0.25F); + this.setPosition(par2, par4, par6); + this.yOffset = 0.0F; + int var9 = 1; + + if (par8ItemStack != null && par8ItemStack.hasTagCompound()) { + this.dataWatcher.updateObject(8, par8ItemStack); + NBTTagCompound var10 = par8ItemStack.getTagCompound(); + NBTTagCompound var11 = var10.getCompoundTag("Fireworks"); + + if (var11 != null) { + var9 += var11.getByte("Flight"); + } + } + + this.motionX = this.rand.nextGaussian() * 0.001D; + this.motionZ = this.rand.nextGaussian() * 0.001D; + this.motionY = 0.05D; + this.lifetime = 10 * var9 + this.rand.nextInt(6) + this.rand.nextInt(7); + } + + /** + * Sets the velocity to the args. Args: x, y, z + */ + public void setVelocity(double par1, double par3, double par5) { + this.motionX = par1; + this.motionY = par3; + this.motionZ = par5; + + if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) { + float var7 = MathHelper.sqrt_double(par1 * par1 + par5 * par5); + this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(par1, par5) * 180.0D / Math.PI); + this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(par3, (double) var7) * 180.0D / Math.PI); + } + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.lastTickPosX = this.posX; + this.lastTickPosY = this.posY; + this.lastTickPosZ = this.posZ; + super.onUpdate(); + this.motionX *= 1.15D; + this.motionZ *= 1.15D; + this.motionY += 0.04D; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + float var1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); + + for (this.rotationPitch = (float) (Math.atan2(this.motionY, (double) var1) * 180.0D / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) { + ; + } + + while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { + this.prevRotationPitch += 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw < -180.0F) { + this.prevRotationYaw -= 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { + this.prevRotationYaw += 360.0F; + } + + this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; + this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; + + if (this.fireworkAge == 0) { + this.worldObj.playSoundAtEntity(this, "fireworks.launch", 3.0F, 1.0F); + } + + ++this.fireworkAge; + + if (this.worldObj.isRemote && this.fireworkAge % 2 < 2) { + this.worldObj.spawnParticle("fireworksSpark", this.posX, this.posY - 0.3D, this.posZ, this.rand.nextGaussian() * 0.05D, -this.motionY * 0.5D, this.rand.nextGaussian() * 0.05D); + } + + if (!this.worldObj.isRemote && this.fireworkAge > this.lifetime) { + this.worldObj.setEntityState(this, (byte) 17); + this.setDead(); + } + } + + public void handleHealthUpdate(byte par1) { + if (par1 == 17 && this.worldObj.isRemote) { + ItemStack var2 = this.dataWatcher.getWatchableObjectItemStack(8); + NBTTagCompound var3 = null; + + if (var2 != null && var2.hasTagCompound()) { + var3 = var2.getTagCompound().getCompoundTag("Fireworks"); + } + + this.worldObj.func_92088_a(this.posX, this.posY, this.posZ, this.motionX, this.motionY, this.motionZ, var3); + } + + super.handleHealthUpdate(par1); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setInteger("Life", this.fireworkAge); + par1NBTTagCompound.setInteger("LifeTime", this.lifetime); + ItemStack var2 = this.dataWatcher.getWatchableObjectItemStack(8); + + if (var2 != null) { + NBTTagCompound var3 = new NBTTagCompound(); + var2.writeToNBT(var3); + par1NBTTagCompound.setCompoundTag("FireworksItem", var3); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.fireworkAge = par1NBTTagCompound.getInteger("Life"); + this.lifetime = par1NBTTagCompound.getInteger("LifeTime"); + NBTTagCompound var2 = par1NBTTagCompound.getCompoundTag("FireworksItem"); + + if (var2 != null) { + ItemStack var3 = ItemStack.loadItemStackFromNBT(var2); + + if (var3 != null) { + this.dataWatcher.updateObject(8, var3); + } + } + } + + public float getShadowSize() { + return 0.0F; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + return super.getBrightness(par1); + } + + public int getBrightnessForRender(float par1) { + return super.getBrightnessForRender(par1); + } + + /** + * If returns false, the item will not inflict any damage against entities. + */ + public boolean canAttackWithItem() { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/EntityFireworkSparkFX.java b/src/main/java/net/minecraft/src/EntityFireworkSparkFX.java new file mode 100644 index 0000000..95e234d --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFireworkSparkFX.java @@ -0,0 +1,131 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityFireworkSparkFX extends EntityFX { + private int field_92049_a = 160; + private boolean field_92054_ax; + private boolean field_92048_ay; + private final EffectRenderer field_92047_az; + private float field_92050_aA; + private float field_92051_aB; + private float field_92052_aC; + private boolean field_92053_aD; + + public EntityFireworkSparkFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, EffectRenderer par14EffectRenderer) { + super(par1World, par2, par4, par6); + this.motionX = par8; + this.motionY = par10; + this.motionZ = par12; + this.field_92047_az = par14EffectRenderer; + this.particleScale *= 0.75F; + this.particleMaxAge = 48 + this.rand.nextInt(12); + this.noClip = false; + } + + public void func_92045_e(boolean par1) { + this.field_92054_ax = par1; + } + + public void func_92043_f(boolean par1) { + this.field_92048_ay = par1; + } + + public void func_92044_a(int par1) { + float var2 = (float) ((par1 & 16711680) >> 16) / 255.0F; + float var3 = (float) ((par1 & 65280) >> 8) / 255.0F; + float var4 = (float) ((par1 & 255) >> 0) / 255.0F; + float var5 = 1.0F; + this.setRBGColorF(var2 * var5, var3 * var5, var4 * var5); + } + + public void func_92046_g(int par1) { + this.field_92050_aA = (float) ((par1 & 16711680) >> 16) / 255.0F; + this.field_92051_aB = (float) ((par1 & 65280) >> 8) / 255.0F; + this.field_92052_aC = (float) ((par1 & 255) >> 0) / 255.0F; + this.field_92053_aD = true; + } + + /** + * returns the bounding box for this entity + */ + public AxisAlignedBB getBoundingBox() { + return null; + } + + /** + * Returns true if this entity should push and be pushed by other entities when + * colliding. + */ + public boolean canBePushed() { + return false; + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + if (!this.field_92048_ay || this.particleAge < this.particleMaxAge / 3 || (this.particleAge + this.particleMaxAge) / 3 % 2 == 0) { + super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); + } + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + + if (this.particleAge > this.particleMaxAge / 2) { + this.setAlphaF(1.0F - ((float) this.particleAge - (float) (this.particleMaxAge / 2)) / (float) this.particleMaxAge); + + if (this.field_92053_aD) { + this.particleRed += (this.field_92050_aA - this.particleRed) * 0.2F; + this.particleGreen += (this.field_92051_aB - this.particleGreen) * 0.2F; + this.particleBlue += (this.field_92052_aC - this.particleBlue) * 0.2F; + } + } + + this.setParticleTextureIndex(this.field_92049_a + (7 - this.particleAge * 8 / this.particleMaxAge)); + this.motionY -= 0.004D; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9100000262260437D; + this.motionY *= 0.9100000262260437D; + this.motionZ *= 0.9100000262260437D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + + if (this.field_92054_ax && this.particleAge < this.particleMaxAge / 2 && (this.particleAge + this.particleMaxAge) % 2 == 0) { + EntityFireworkSparkFX var1 = new EntityFireworkSparkFX(this.worldObj, this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D, this.field_92047_az); + var1.setRBGColorF(this.particleRed, this.particleGreen, this.particleBlue); + var1.particleAge = var1.particleMaxAge / 2; + + if (this.field_92053_aD) { + var1.field_92053_aD = true; + var1.field_92050_aA = this.field_92050_aA; + var1.field_92051_aB = this.field_92051_aB; + var1.field_92052_aC = this.field_92052_aC; + } + + var1.field_92048_ay = this.field_92048_ay; + this.field_92047_az.addEffect(var1); + } + } + + public int getBrightnessForRender(float par1) { + return 15728880; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + return 1.0F; + } +} diff --git a/src/main/java/net/minecraft/src/EntityFireworkStarterFX.java b/src/main/java/net/minecraft/src/EntityFireworkStarterFX.java new file mode 100644 index 0000000..48a6f51 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFireworkStarterFX.java @@ -0,0 +1,208 @@ +package net.minecraft.src; + + +import net.lax1dude.eaglercraft.adapter.Tessellator; +import net.minecraft.client.Minecraft; + +public class EntityFireworkStarterFX extends EntityFX { + private int field_92042_ax = 0; + private final EffectRenderer field_92040_ay; + private NBTTagList fireworkExplosions; + boolean field_92041_a; + + public EntityFireworkStarterFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, EffectRenderer par14EffectRenderer, NBTTagCompound par15NBTTagCompound) { + super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); + this.motionX = par8; + this.motionY = par10; + this.motionZ = par12; + this.field_92040_ay = par14EffectRenderer; + this.particleMaxAge = 8; + + if (par15NBTTagCompound != null) { + this.fireworkExplosions = par15NBTTagCompound.getTagList("Explosions"); + + if (this.fireworkExplosions.tagCount() == 0) { + this.fireworkExplosions = null; + } else { + this.particleMaxAge = this.fireworkExplosions.tagCount() * 2 - 1; + + for (int var16 = 0; var16 < this.fireworkExplosions.tagCount(); ++var16) { + NBTTagCompound var17 = (NBTTagCompound) this.fireworkExplosions.tagAt(var16); + + if (var17.getBoolean("Flicker")) { + this.field_92041_a = true; + this.particleMaxAge += 15; + break; + } + } + } + } + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + boolean var1; + + if (this.field_92042_ax == 0 && this.fireworkExplosions != null) { + var1 = this.func_92037_i(); + boolean var2 = false; + + if (this.fireworkExplosions.tagCount() >= 3) { + var2 = true; + } else { + for (int var3 = 0; var3 < this.fireworkExplosions.tagCount(); ++var3) { + NBTTagCompound var4 = (NBTTagCompound) this.fireworkExplosions.tagAt(var3); + + if (var4.getByte("Type") == 1) { + var2 = true; + break; + } + } + } + + String var15 = "fireworks." + (var2 ? "largeBlast" : "blast") + (var1 ? "_far" : ""); + this.worldObj.playSound(this.posX, this.posY, this.posZ, var15, 20.0F, 0.95F + this.rand.nextFloat() * 0.1F, true); + } + + if (this.field_92042_ax % 2 == 0 && this.fireworkExplosions != null && this.field_92042_ax / 2 < this.fireworkExplosions.tagCount()) { + int var13 = this.field_92042_ax / 2; + NBTTagCompound var14 = (NBTTagCompound) this.fireworkExplosions.tagAt(var13); + byte var17 = var14.getByte("Type"); + boolean var18 = var14.getBoolean("Trail"); + boolean var5 = var14.getBoolean("Flicker"); + int[] var6 = var14.getIntArray("Colors"); + int[] var7 = var14.getIntArray("FadeColors"); + + if (var17 == 1) { + this.func_92035_a(0.5D, 4, var6, var7, var18, var5); + } else if (var17 == 2) { + this.func_92038_a(0.5D, + new double[][] { { 0.0D, 1.0D }, { 0.3455D, 0.309D }, { 0.9511D, 0.309D }, { 0.3795918367346939D, -0.12653061224489795D }, { 0.6122448979591837D, -0.8040816326530612D }, { 0.0D, -0.35918367346938773D } }, var6, var7, + var18, var5, false); + } else if (var17 == 3) { + this.func_92038_a(0.5D, + new double[][] { { 0.0D, 0.2D }, { 0.2D, 0.2D }, { 0.2D, 0.6D }, { 0.6D, 0.6D }, { 0.6D, 0.2D }, { 0.2D, 0.2D }, { 0.2D, 0.0D }, { 0.4D, 0.0D }, { 0.4D, -0.6D }, { 0.2D, -0.6D }, { 0.2D, -0.4D }, { 0.0D, -0.4D } }, + var6, var7, var18, var5, true); + } else if (var17 == 4) { + this.func_92036_a(var6, var7, var18, var5); + } else { + this.func_92035_a(0.25D, 2, var6, var7, var18, var5); + } + + int var8 = var6[0]; + float var9 = (float) ((var8 & 16711680) >> 16) / 255.0F; + float var10 = (float) ((var8 & 65280) >> 8) / 255.0F; + float var11 = (float) ((var8 & 255) >> 0) / 255.0F; + EntityFireworkOverlayFX var12 = new EntityFireworkOverlayFX(this.worldObj, this.posX, this.posY, this.posZ); + var12.setRBGColorF(var9, var10, var11); + this.field_92040_ay.addEffect(var12); + } + + ++this.field_92042_ax; + + if (this.field_92042_ax > this.particleMaxAge) { + if (this.field_92041_a) { + var1 = this.func_92037_i(); + String var16 = "fireworks." + (var1 ? "twinkle_far" : "twinkle"); + this.worldObj.playSound(this.posX, this.posY, this.posZ, var16, 20.0F, 0.9F + this.rand.nextFloat() * 0.15F, true); + } + + this.setDead(); + } + } + + private boolean func_92037_i() { + Minecraft var1 = Minecraft.getMinecraft(); + return var1 == null || var1.renderViewEntity == null || var1.renderViewEntity.getDistanceSq(this.posX, this.posY, this.posZ) >= 256.0D; + } + + private void func_92034_a(double par1, double par3, double par5, double par7, double par9, double par11, int[] par13ArrayOfInteger, int[] par14ArrayOfInteger, boolean par15, boolean par16) { + EntityFireworkSparkFX var17 = new EntityFireworkSparkFX(this.worldObj, par1, par3, par5, par7, par9, par11, this.field_92040_ay); + var17.func_92045_e(par15); + var17.func_92043_f(par16); + int var18 = this.rand.nextInt(par13ArrayOfInteger.length); + var17.func_92044_a(par13ArrayOfInteger[var18]); + + if (par14ArrayOfInteger != null && par14ArrayOfInteger.length > 0) { + var17.func_92046_g(par14ArrayOfInteger[this.rand.nextInt(par14ArrayOfInteger.length)]); + } + + this.field_92040_ay.addEffect(var17); + } + + private void func_92035_a(double par1, int par3, int[] par4ArrayOfInteger, int[] par5ArrayOfInteger, boolean par6, boolean par7) { + double var8 = this.posX; + double var10 = this.posY; + double var12 = this.posZ; + + for (int var14 = -par3; var14 <= par3; ++var14) { + for (int var15 = -par3; var15 <= par3; ++var15) { + for (int var16 = -par3; var16 <= par3; ++var16) { + double var17 = (double) var15 + (this.rand.nextDouble() - this.rand.nextDouble()) * 0.5D; + double var19 = (double) var14 + (this.rand.nextDouble() - this.rand.nextDouble()) * 0.5D; + double var21 = (double) var16 + (this.rand.nextDouble() - this.rand.nextDouble()) * 0.5D; + double var23 = (double) MathHelper.sqrt_double(var17 * var17 + var19 * var19 + var21 * var21) / par1 + this.rand.nextGaussian() * 0.05D; + this.func_92034_a(var8, var10, var12, var17 / var23, var19 / var23, var21 / var23, par4ArrayOfInteger, par5ArrayOfInteger, par6, par7); + + if (var14 != -par3 && var14 != par3 && var15 != -par3 && var15 != par3) { + var16 += par3 * 2 - 1; + } + } + } + } + } + + private void func_92038_a(double par1, double[][] par3ArrayOfDouble, int[] par4ArrayOfInteger, int[] par5ArrayOfInteger, boolean par6, boolean par7, boolean par8) { + double var9 = par3ArrayOfDouble[0][0]; + double var11 = par3ArrayOfDouble[0][1]; + this.func_92034_a(this.posX, this.posY, this.posZ, var9 * par1, var11 * par1, 0.0D, par4ArrayOfInteger, par5ArrayOfInteger, par6, par7); + float var13 = this.rand.nextFloat() * (float) Math.PI; + double var14 = par8 ? 0.034D : 0.34D; + + for (int var16 = 0; var16 < 3; ++var16) { + double var17 = (double) var13 + (double) ((float) var16 * (float) Math.PI) * var14; + double var19 = var9; + double var21 = var11; + + for (int var23 = 1; var23 < par3ArrayOfDouble.length; ++var23) { + double var24 = par3ArrayOfDouble[var23][0]; + double var26 = par3ArrayOfDouble[var23][1]; + + for (double var28 = 0.25D; var28 <= 1.0D; var28 += 0.25D) { + double var30 = (var19 + (var24 - var19) * var28) * par1; + double var32 = (var21 + (var26 - var21) * var28) * par1; + double var34 = var30 * Math.sin(var17); + var30 *= Math.cos(var17); + + for (double var36 = -1.0D; var36 <= 1.0D; var36 += 2.0D) { + this.func_92034_a(this.posX, this.posY, this.posZ, var30 * var36, var32, var34 * var36, par4ArrayOfInteger, par5ArrayOfInteger, par6, par7); + } + } + + var19 = var24; + var21 = var26; + } + } + } + + private void func_92036_a(int[] par1ArrayOfInteger, int[] par2ArrayOfInteger, boolean par3, boolean par4) { + double var5 = this.rand.nextGaussian() * 0.05D; + double var7 = this.rand.nextGaussian() * 0.05D; + + for (int var9 = 0; var9 < 70; ++var9) { + double var10 = this.motionX * 0.5D + this.rand.nextGaussian() * 0.15D + var5; + double var12 = this.motionZ * 0.5D + this.rand.nextGaussian() * 0.15D + var7; + double var14 = this.motionY * 0.5D + this.rand.nextDouble() * 0.5D; + this.func_92034_a(this.posX, this.posY, this.posZ, var10, var14, var12, par1ArrayOfInteger, par2ArrayOfInteger, par3, par4); + } + } + + public int getFXLayer() { + return 0; + } +} diff --git a/src/main/java/net/minecraft/src/EntityFishHook.java b/src/main/java/net/minecraft/src/EntityFishHook.java new file mode 100644 index 0000000..212dcc9 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFishHook.java @@ -0,0 +1,441 @@ +package net.minecraft.src; + +import java.util.List; + + + +public class EntityFishHook extends Entity { + /** The tile this entity is on, X position */ + private int xTile; + + /** The tile this entity is on, Y position */ + private int yTile; + + /** The tile this entity is on, Z position */ + private int zTile; + private int inTile; + private boolean inGround; + public int shake; + public EntityPlayer angler; + private int ticksInGround; + private int ticksInAir; + + /** the number of ticks remaining until this fish can no longer be caught */ + private int ticksCatchable; + + /** + * The entity that the fishing rod is connected to, if any. When you right click + * on the fishing rod and the hook falls on to an entity, this it that entity. + */ + public Entity bobber; + private int fishPosRotationIncrements; + private double fishX; + private double fishY; + private double fishZ; + private double fishYaw; + private double fishPitch; + private double velocityX; + private double velocityY; + private double velocityZ; + + public EntityFishHook() { + super(); + this.xTile = -1; + this.yTile = -1; + this.zTile = -1; + this.inTile = 0; + this.inGround = false; + this.shake = 0; + this.ticksInAir = 0; + this.ticksCatchable = 0; + this.bobber = null; + this.setSize(0.25F, 0.25F); + this.ignoreFrustumCheck = true; + } + + public EntityFishHook(World par1World, double par2, double par4, double par6, EntityPlayer par8EntityPlayer) { + this(); + this.setWorld(par1World); + this.setPosition(par2, par4, par6); + this.ignoreFrustumCheck = true; + this.angler = par8EntityPlayer; + par8EntityPlayer.fishEntity = this; + } + + public EntityFishHook(World par1World, EntityPlayer par2EntityPlayer) { + super(); + this.setWorld(par1World); + this.xTile = -1; + this.yTile = -1; + this.zTile = -1; + this.inTile = 0; + this.inGround = false; + this.shake = 0; + this.ticksInAir = 0; + this.ticksCatchable = 0; + this.bobber = null; + this.ignoreFrustumCheck = true; + this.angler = par2EntityPlayer; + this.angler.fishEntity = this; + this.setSize(0.25F, 0.25F); + this.setLocationAndAngles(par2EntityPlayer.posX, par2EntityPlayer.posY + 1.62D - (double) par2EntityPlayer.yOffset, par2EntityPlayer.posZ, par2EntityPlayer.rotationYaw, par2EntityPlayer.rotationPitch); + this.posX -= (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * 0.16F); + this.posY -= 0.10000000149011612D; + this.posZ -= (double) (MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * 0.16F); + this.setPosition(this.posX, this.posY, this.posZ); + this.yOffset = 0.0F; + float var3 = 0.4F; + this.motionX = (double) (-MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI) * var3); + this.motionZ = (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI) * var3); + this.motionY = (double) (-MathHelper.sin(this.rotationPitch / 180.0F * (float) Math.PI) * var3); + this.calculateVelocity(this.motionX, this.motionY, this.motionZ, 1.5F, 1.0F); + } + + protected void entityInit() { + } + + /** + * Checks if the entity is in range to render by using the past in distance and + * comparing it to its average edge length * 64 * renderDistanceWeight Args: + * distance + */ + public boolean isInRangeToRenderDist(double par1) { + double var3 = this.boundingBox.getAverageEdgeLength() * 4.0D; + var3 *= 64.0D; + return par1 < var3 * var3; + } + + public void calculateVelocity(double par1, double par3, double par5, float par7, float par8) { + float var9 = MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5); + par1 /= (double) var9; + par3 /= (double) var9; + par5 /= (double) var9; + par1 += this.rand.nextGaussian() * 0.007499999832361937D * (double) par8; + par3 += this.rand.nextGaussian() * 0.007499999832361937D * (double) par8; + par5 += this.rand.nextGaussian() * 0.007499999832361937D * (double) par8; + par1 *= (double) par7; + par3 *= (double) par7; + par5 *= (double) par7; + this.motionX = par1; + this.motionY = par3; + this.motionZ = par5; + float var10 = MathHelper.sqrt_double(par1 * par1 + par5 * par5); + this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(par1, par5) * 180.0D / Math.PI); + this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(par3, (double) var10) * 180.0D / Math.PI); + this.ticksInGround = 0; + } + + /** + * Sets the position and rotation. Only difference from the other one is no + * bounding on the rotation. Args: posX, posY, posZ, yaw, pitch + */ + public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9) { + this.fishX = par1; + this.fishY = par3; + this.fishZ = par5; + this.fishYaw = (double) par7; + this.fishPitch = (double) par8; + this.fishPosRotationIncrements = par9; + this.motionX = this.velocityX; + this.motionY = this.velocityY; + this.motionZ = this.velocityZ; + } + + /** + * Sets the velocity to the args. Args: x, y, z + */ + public void setVelocity(double par1, double par3, double par5) { + this.velocityX = this.motionX = par1; + this.velocityY = this.motionY = par3; + this.velocityZ = this.motionZ = par5; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.fishPosRotationIncrements > 0) { + double var21 = this.posX + (this.fishX - this.posX) / (double) this.fishPosRotationIncrements; + double var22 = this.posY + (this.fishY - this.posY) / (double) this.fishPosRotationIncrements; + double var23 = this.posZ + (this.fishZ - this.posZ) / (double) this.fishPosRotationIncrements; + double var7 = MathHelper.wrapAngleTo180_double(this.fishYaw - (double) this.rotationYaw); + this.rotationYaw = (float) ((double) this.rotationYaw + var7 / (double) this.fishPosRotationIncrements); + this.rotationPitch = (float) ((double) this.rotationPitch + (this.fishPitch - (double) this.rotationPitch) / (double) this.fishPosRotationIncrements); + --this.fishPosRotationIncrements; + this.setPosition(var21, var22, var23); + this.setRotation(this.rotationYaw, this.rotationPitch); + } else { + if (!this.worldObj.isRemote) { + ItemStack var1 = this.angler.getCurrentEquippedItem(); + + if (this.angler.isDead || !this.angler.isEntityAlive() || var1 == null || var1.getItem() != Item.fishingRod || this.getDistanceSqToEntity(this.angler) > 1024.0D) { + this.setDead(); + this.angler.fishEntity = null; + return; + } + + if (this.bobber != null) { + if (!this.bobber.isDead) { + this.posX = this.bobber.posX; + this.posY = this.bobber.boundingBox.minY + (double) this.bobber.height * 0.8D; + this.posZ = this.bobber.posZ; + return; + } + + this.bobber = null; + } + } + + if (this.shake > 0) { + --this.shake; + } + + if (this.inGround) { + int var19 = this.worldObj.getBlockId(this.xTile, this.yTile, this.zTile); + + if (var19 == this.inTile) { + ++this.ticksInGround; + + if (this.ticksInGround == 1200) { + this.setDead(); + } + + return; + } + + this.inGround = false; + this.motionX *= (double) (this.rand.nextFloat() * 0.2F); + this.motionY *= (double) (this.rand.nextFloat() * 0.2F); + this.motionZ *= (double) (this.rand.nextFloat() * 0.2F); + this.ticksInGround = 0; + this.ticksInAir = 0; + } else { + ++this.ticksInAir; + } + + Vec3 var20 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + Vec3 var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); + MovingObjectPosition var3 = this.worldObj.rayTraceBlocks(var20, var2); + var20 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); + + if (var3 != null) { + var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(var3.hitVec.xCoord, var3.hitVec.yCoord, var3.hitVec.zCoord); + } + + Entity var4 = null; + List var5 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D)); + double var6 = 0.0D; + double var13; + + for (int var8 = 0; var8 < var5.size(); ++var8) { + Entity var9 = (Entity) var5.get(var8); + + if (var9.canBeCollidedWith() && (var9 != this.angler || this.ticksInAir >= 5)) { + float var10 = 0.3F; + AxisAlignedBB var11 = var9.boundingBox.expand((double) var10, (double) var10, (double) var10); + MovingObjectPosition var12 = var11.calculateIntercept(var20, var2); + + if (var12 != null) { + var13 = var20.distanceTo(var12.hitVec); + + if (var13 < var6 || var6 == 0.0D) { + var4 = var9; + var6 = var13; + } + } + } + } + + if (var4 != null) { + var3 = new MovingObjectPosition(var4); + } + + if (var3 != null) { + if (var3.entityHit != null) { + if (var3.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.angler), 0)) { + this.bobber = var3.entityHit; + } + } else { + this.inGround = true; + } + } + + if (!this.inGround) { + this.moveEntity(this.motionX, this.motionY, this.motionZ); + float var24 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); + + for (this.rotationPitch = (float) (Math.atan2(this.motionY, (double) var24) * 180.0D / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) { + ; + } + + while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { + this.prevRotationPitch += 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw < -180.0F) { + this.prevRotationYaw -= 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { + this.prevRotationYaw += 360.0F; + } + + this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; + this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; + float var25 = 0.92F; + + if (this.onGround || this.isCollidedHorizontally) { + var25 = 0.5F; + } + + byte var26 = 5; + double var27 = 0.0D; + + for (int var28 = 0; var28 < var26; ++var28) { + double var14 = this.boundingBox.minY + (this.boundingBox.maxY - this.boundingBox.minY) * (double) (var28 + 0) / (double) var26 - 0.125D + 0.125D; + double var16 = this.boundingBox.minY + (this.boundingBox.maxY - this.boundingBox.minY) * (double) (var28 + 1) / (double) var26 - 0.125D + 0.125D; + AxisAlignedBB var18 = AxisAlignedBB.getAABBPool().getAABB(this.boundingBox.minX, var14, this.boundingBox.minZ, this.boundingBox.maxX, var16, this.boundingBox.maxZ); + + if (this.worldObj.isAABBInMaterial(var18, Material.water)) { + var27 += 1.0D / (double) var26; + } + } + + if (var27 > 0.0D) { + if (this.ticksCatchable > 0) { + --this.ticksCatchable; + } else { + short var29 = 500; + + if (this.worldObj.canLightningStrikeAt(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY) + 1, MathHelper.floor_double(this.posZ))) { + var29 = 300; + } + + if (this.rand.nextInt(var29) == 0) { + this.ticksCatchable = this.rand.nextInt(30) + 10; + this.motionY -= 0.20000000298023224D; + this.playSound("random.splash", 0.25F, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F); + float var30 = (float) MathHelper.floor_double(this.boundingBox.minY); + int var15; + float var17; + float var31; + + for (var15 = 0; (float) var15 < 1.0F + this.width * 20.0F; ++var15) { + var31 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + var17 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + this.worldObj.spawnParticle("bubble", this.posX + (double) var31, (double) (var30 + 1.0F), this.posZ + (double) var17, this.motionX, this.motionY - (double) (this.rand.nextFloat() * 0.2F), this.motionZ); + } + + for (var15 = 0; (float) var15 < 1.0F + this.width * 20.0F; ++var15) { + var31 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + var17 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + this.worldObj.spawnParticle("splash", this.posX + (double) var31, (double) (var30 + 1.0F), this.posZ + (double) var17, this.motionX, this.motionY, this.motionZ); + } + } + } + } + + if (this.ticksCatchable > 0) { + this.motionY -= (double) (this.rand.nextFloat() * this.rand.nextFloat() * this.rand.nextFloat()) * 0.2D; + } + + var13 = var27 * 2.0D - 1.0D; + this.motionY += 0.03999999910593033D * var13; + + if (var27 > 0.0D) { + var25 = (float) ((double) var25 * 0.9D); + this.motionY *= 0.8D; + } + + this.motionX *= (double) var25; + this.motionY *= (double) var25; + this.motionZ *= (double) var25; + this.setPosition(this.posX, this.posY, this.posZ); + } + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setShort("xTile", (short) this.xTile); + par1NBTTagCompound.setShort("yTile", (short) this.yTile); + par1NBTTagCompound.setShort("zTile", (short) this.zTile); + par1NBTTagCompound.setByte("inTile", (byte) this.inTile); + par1NBTTagCompound.setByte("shake", (byte) this.shake); + par1NBTTagCompound.setByte("inGround", (byte) (this.inGround ? 1 : 0)); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.xTile = par1NBTTagCompound.getShort("xTile"); + this.yTile = par1NBTTagCompound.getShort("yTile"); + this.zTile = par1NBTTagCompound.getShort("zTile"); + this.inTile = par1NBTTagCompound.getByte("inTile") & 255; + this.shake = par1NBTTagCompound.getByte("shake") & 255; + this.inGround = par1NBTTagCompound.getByte("inGround") == 1; + } + + public float getShadowSize() { + return 0.0F; + } + + public int catchFish() { + if (this.worldObj.isRemote) { + return 0; + } else { + byte var1 = 0; + + if (this.bobber != null) { + double var2 = this.angler.posX - this.posX; + double var4 = this.angler.posY - this.posY; + double var6 = this.angler.posZ - this.posZ; + double var8 = (double) MathHelper.sqrt_double(var2 * var2 + var4 * var4 + var6 * var6); + double var10 = 0.1D; + this.bobber.motionX += var2 * var10; + this.bobber.motionY += var4 * var10 + (double) MathHelper.sqrt_double(var8) * 0.08D; + this.bobber.motionZ += var6 * var10; + var1 = 3; + } else if (this.ticksCatchable > 0) { + EntityItem var13 = new EntityItem(this.worldObj, this.posX, this.posY, this.posZ, new ItemStack(Item.fishRaw)); + double var3 = this.angler.posX - this.posX; + double var5 = this.angler.posY - this.posY; + double var7 = this.angler.posZ - this.posZ; + double var9 = (double) MathHelper.sqrt_double(var3 * var3 + var5 * var5 + var7 * var7); + double var11 = 0.1D; + var13.motionX = var3 * var11; + var13.motionY = var5 * var11 + (double) MathHelper.sqrt_double(var9) * 0.08D; + var13.motionZ = var7 * var11; + this.worldObj.spawnEntityInWorld(var13); + this.angler.worldObj.spawnEntityInWorld(new EntityXPOrb(this.angler.worldObj, this.angler.posX, this.angler.posY + 0.5D, this.angler.posZ + 0.5D, this.rand.nextInt(6) + 1)); + var1 = 1; + } + + if (this.inGround) { + var1 = 2; + } + + this.setDead(); + this.angler.fishEntity = null; + return var1; + } + } + + /** + * Will get destroyed next tick. + */ + public void setDead() { + super.setDead(); + + if (this.angler != null) { + this.angler.fishEntity = null; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityFlameFX.java b/src/main/java/net/minecraft/src/EntityFlameFX.java new file mode 100644 index 0000000..65dc2ee --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFlameFX.java @@ -0,0 +1,94 @@ +package net.minecraft.src; + + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityFlameFX extends EntityFX { + /** the scale of the flame FX */ + private float flameScale; + + public EntityFlameFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + super(par1World, par2, par4, par6, par8, par10, par12); + this.motionX = this.motionX * 0.009999999776482582D + par8; + this.motionY = this.motionY * 0.009999999776482582D + par10; + this.motionZ = this.motionZ * 0.009999999776482582D + par12; + double var10000 = par2 + (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.05F); + var10000 = par4 + (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.05F); + var10000 = par6 + (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.05F); + this.flameScale = this.particleScale; + this.particleRed = this.particleGreen = this.particleBlue = 1.0F; + this.particleMaxAge = (int) (8.0D / (Math.random() * 0.8D + 0.2D)) + 4; + this.noClip = true; + this.setParticleTextureIndex(48); + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = ((float) this.particleAge + par2) / (float) this.particleMaxAge; + this.particleScale = this.flameScale * (1.0F - var8 * var8 * 0.5F); + super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); + } + + public int getBrightnessForRender(float par1) { + float var2 = ((float) this.particleAge + par1) / (float) this.particleMaxAge; + + if (var2 < 0.0F) { + var2 = 0.0F; + } + + if (var2 > 1.0F) { + var2 = 1.0F; + } + + int var3 = super.getBrightnessForRender(par1); + int var4 = var3 & 255; + int var5 = var3 >> 16 & 255; + var4 += (int) (var2 * 15.0F * 16.0F); + + if (var4 > 240) { + var4 = 240; + } + + return var4 | var5 << 16; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + float var2 = ((float) this.particleAge + par1) / (float) this.particleMaxAge; + + if (var2 < 0.0F) { + var2 = 0.0F; + } + + if (var2 > 1.0F) { + var2 = 1.0F; + } + + float var3 = super.getBrightness(par1); + return var3 * var2 + (1.0F - var2); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9599999785423279D; + this.motionY *= 0.9599999785423279D; + this.motionZ *= 0.9599999785423279D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityFlying.java b/src/main/java/net/minecraft/src/EntityFlying.java new file mode 100644 index 0000000..13269c4 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFlying.java @@ -0,0 +1,85 @@ +package net.minecraft.src; + +public abstract class EntityFlying extends EntityLiving { + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * Takes in the distance the entity has fallen this tick and whether its on the + * ground to update the fall distance and deal fall damage if landing on the + * ground. Args: distanceFallenThisTick, onGround + */ + protected void updateFallState(double par1, boolean par3) { + } + + /** + * Moves the entity based on the specified heading. Args: strafe, forward + */ + public void moveEntityWithHeading(float par1, float par2) { + if (this.isInWater()) { + this.moveFlying(par1, par2, 0.02F); + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.800000011920929D; + this.motionY *= 0.800000011920929D; + this.motionZ *= 0.800000011920929D; + } else if (this.handleLavaMovement()) { + this.moveFlying(par1, par2, 0.02F); + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.5D; + this.motionY *= 0.5D; + this.motionZ *= 0.5D; + } else { + float var3 = 0.91F; + + if (this.onGround) { + var3 = 0.54600006F; + int var4 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)); + + if (var4 > 0) { + var3 = Block.blocksList[var4].slipperiness * 0.91F; + } + } + + float var8 = 0.16277136F / (var3 * var3 * var3); + this.moveFlying(par1, par2, this.onGround ? 0.1F * var8 : 0.02F); + var3 = 0.91F; + + if (this.onGround) { + var3 = 0.54600006F; + int var5 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)); + + if (var5 > 0) { + var3 = Block.blocksList[var5].slipperiness * 0.91F; + } + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= (double) var3; + this.motionY *= (double) var3; + this.motionZ *= (double) var3; + } + + this.prevLimbYaw = this.limbYaw; + double var10 = this.posX - this.prevPosX; + double var9 = this.posZ - this.prevPosZ; + float var7 = MathHelper.sqrt_double(var10 * var10 + var9 * var9) * 4.0F; + + if (var7 > 1.0F) { + var7 = 1.0F; + } + + this.limbYaw += (var7 - this.limbYaw) * 0.4F; + this.limbSwing += this.limbYaw; + } + + /** + * returns true if this entity is by a ladder, false otherwise + */ + public boolean isOnLadder() { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/EntityFootStepFX.java b/src/main/java/net/minecraft/src/EntityFootStepFX.java new file mode 100644 index 0000000..9d0e2b4 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFootStepFX.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityFootStepFX extends EntityFX { + private int field_70576_a = 0; + private int field_70578_aq = 0; + private RenderEngine currentFootSteps; + + public EntityFootStepFX(RenderEngine par1RenderEngine, World par2World, double par3, double par5, double par7) { + super(par2World, par3, par5, par7, 0.0D, 0.0D, 0.0D); + this.currentFootSteps = par1RenderEngine; + this.motionX = this.motionY = this.motionZ = 0.0D; + this.field_70578_aq = 200; + } + + private static final TextureLocation fp = new TextureLocation("/misc/footprint.png"); + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = ((float) this.field_70576_a + par2) / (float) this.field_70578_aq; + var8 *= var8; + float var9 = 2.0F - var8 * 2.0F; + + if (var9 > 1.0F) { + var9 = 1.0F; + } + + var9 *= 0.2F; + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + float var10 = 0.125F; + float var11 = (float) (this.posX - interpPosX); + float var12 = (float) (this.posY - interpPosY); + float var13 = (float) (this.posZ - interpPosZ); + float var14 = this.worldObj.getLightBrightness(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)); + fp.bindTexture(); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + par1Tessellator.startDrawingQuads(); + par1Tessellator.setColorRGBA_F(var14, var14, var14, var9); + par1Tessellator.addVertexWithUV((double) (var11 - var10), (double) var12, (double) (var13 + var10), 0.0D, 1.0D); + par1Tessellator.addVertexWithUV((double) (var11 + var10), (double) var12, (double) (var13 + var10), 1.0D, 1.0D); + par1Tessellator.addVertexWithUV((double) (var11 + var10), (double) var12, (double) (var13 - var10), 1.0D, 0.0D); + par1Tessellator.addVertexWithUV((double) (var11 - var10), (double) var12, (double) (var13 - var10), 0.0D, 0.0D); + par1Tessellator.draw(); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + ++this.field_70576_a; + + if (this.field_70576_a == this.field_70578_aq) { + this.setDead(); + } + } + + public int getFXLayer() { + return 3; + } +} diff --git a/src/main/java/net/minecraft/src/EntityGhast.java b/src/main/java/net/minecraft/src/EntityGhast.java new file mode 100644 index 0000000..cb2ec52 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityGhast.java @@ -0,0 +1,251 @@ +package net.minecraft.src; + + + +public class EntityGhast extends EntityFlying implements IMob { + public int courseChangeCooldown = 0; + public double waypointX; + public double waypointY; + public double waypointZ; + private Entity targetedEntity = null; + + /** Cooldown time between target loss and new target aquirement. */ + private int aggroCooldown = 0; + public int prevAttackCounter = 0; + public int attackCounter = 0; + + /** The explosion radius of spawned fireballs. */ + private int explosionStrength = 1; + + public EntityGhast() { + this.setSize(4.0F, 4.0F); + this.isImmuneToFire = true; + this.experienceValue = 5; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else if ("fireball".equals(par1DamageSource.getDamageType()) && par1DamageSource.getEntity() instanceof EntityPlayer) { + super.attackEntityFrom(par1DamageSource, 1000); + ((EntityPlayer) par1DamageSource.getEntity()).triggerAchievement(AchievementList.ghast); + return true; + } else { + return super.attackEntityFrom(par1DamageSource, par2); + } + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, Byte.valueOf((byte) 0)); + } + + public int getMaxHealth() { + return 10; + } + + protected void updateEntityActionState() { + if (!this.worldObj.isRemote && this.worldObj.difficultySetting == 0) { + this.setDead(); + } + + this.despawnEntity(); + this.prevAttackCounter = this.attackCounter; + double var1 = this.waypointX - this.posX; + double var3 = this.waypointY - this.posY; + double var5 = this.waypointZ - this.posZ; + double var7 = var1 * var1 + var3 * var3 + var5 * var5; + + if (var7 < 1.0D || var7 > 3600.0D) { + this.waypointX = this.posX + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F); + this.waypointY = this.posY + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F); + this.waypointZ = this.posZ + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F); + } + + if (this.courseChangeCooldown-- <= 0) { + this.courseChangeCooldown += this.rand.nextInt(5) + 2; + var7 = (double) MathHelper.sqrt_double(var7); + + if (this.isCourseTraversable(this.waypointX, this.waypointY, this.waypointZ, var7)) { + this.motionX += var1 / var7 * 0.1D; + this.motionY += var3 / var7 * 0.1D; + this.motionZ += var5 / var7 * 0.1D; + } else { + this.waypointX = this.posX; + this.waypointY = this.posY; + this.waypointZ = this.posZ; + } + } + + if (this.targetedEntity != null && this.targetedEntity.isDead) { + this.targetedEntity = null; + } + + if (this.targetedEntity == null || this.aggroCooldown-- <= 0) { + this.targetedEntity = this.worldObj.getClosestVulnerablePlayerToEntity(this, 100.0D); + + if (this.targetedEntity != null) { + this.aggroCooldown = 20; + } + } + + double var9 = 64.0D; + + if (this.targetedEntity != null && this.targetedEntity.getDistanceSqToEntity(this) < var9 * var9) { + double var11 = this.targetedEntity.posX - this.posX; + double var13 = this.targetedEntity.boundingBox.minY + (double) (this.targetedEntity.height / 2.0F) - (this.posY + (double) (this.height / 2.0F)); + double var15 = this.targetedEntity.posZ - this.posZ; + this.renderYawOffset = this.rotationYaw = -((float) Math.atan2(var11, var15)) * 180.0F / (float) Math.PI; + + if (this.canEntityBeSeen(this.targetedEntity)) { + if (this.attackCounter == 10) { + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1007, (int) this.posX, (int) this.posY, (int) this.posZ, 0); + } + + ++this.attackCounter; + + if (this.attackCounter == 20) { + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1008, (int) this.posX, (int) this.posY, (int) this.posZ, 0); + EntityLargeFireball var17 = new EntityLargeFireball(this.worldObj, this, var11, var13, var15); + var17.field_92057_e = this.explosionStrength; + double var18 = 4.0D; + Vec3 var20 = this.getLook(1.0F); + var17.posX = this.posX + var20.xCoord * var18; + var17.posY = this.posY + (double) (this.height / 2.0F) + 0.5D; + var17.posZ = this.posZ + var20.zCoord * var18; + this.worldObj.spawnEntityInWorld(var17); + this.attackCounter = -40; + } + } else if (this.attackCounter > 0) { + --this.attackCounter; + } + } else { + this.renderYawOffset = this.rotationYaw = -((float) Math.atan2(this.motionX, this.motionZ)) * 180.0F / (float) Math.PI; + + if (this.attackCounter > 0) { + --this.attackCounter; + } + } + + if (!this.worldObj.isRemote) { + byte var21 = this.dataWatcher.getWatchableObjectByte(16); + byte var12 = (byte) (this.attackCounter > 10 ? 1 : 0); + + if (var21 != var12) { + this.dataWatcher.updateObject(16, Byte.valueOf(var12)); + } + } + } + + /** + * True if the ghast has an unobstructed line of travel to the waypoint. + */ + private boolean isCourseTraversable(double par1, double par3, double par5, double par7) { + double var9 = (this.waypointX - this.posX) / par7; + double var11 = (this.waypointY - this.posY) / par7; + double var13 = (this.waypointZ - this.posZ) / par7; + AxisAlignedBB var15 = this.boundingBox.copy(); + + for (int var16 = 1; (double) var16 < par7; ++var16) { + var15.offset(var9, var11, var13); + + if (!this.worldObj.getCollidingBoundingBoxes(this, var15).isEmpty()) { + return false; + } + } + + return true; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.ghast.moan"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.ghast.scream"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.ghast.death"; + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.gunpowder.itemID; + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(2) + this.rand.nextInt(1 + par2); + int var4; + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.ghastTear.itemID, 1); + } + + var3 = this.rand.nextInt(3) + this.rand.nextInt(1 + par2); + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.gunpowder.itemID, 1); + } + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 10.0F; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + return this.rand.nextInt(20) == 0 && super.getCanSpawnHere() && this.worldObj.difficultySetting > 0; + } + + /** + * Will return how many at most can spawn in a chunk at once. + */ + public int getMaxSpawnedInChunk() { + return 1; + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("ExplosionPower", this.explosionStrength); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("ExplosionPower")) { + this.explosionStrength = par1NBTTagCompound.getInteger("ExplosionPower"); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityGolem.java b/src/main/java/net/minecraft/src/EntityGolem.java new file mode 100644 index 0000000..81d5fa1 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityGolem.java @@ -0,0 +1,45 @@ +package net.minecraft.src; + +public abstract class EntityGolem extends EntityCreature implements IAnimals { + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "none"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "none"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "none"; + } + + /** + * Get number of ticks, at least during which the living entity will be silent. + */ + public int getTalkInterval() { + return 120; + } + + /** + * Determines if an entity can be despawned, used on idle far away entities + */ + protected boolean canDespawn() { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/EntityHanging.java b/src/main/java/net/minecraft/src/EntityHanging.java new file mode 100644 index 0000000..188a5ab --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityHanging.java @@ -0,0 +1,300 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + + + +public abstract class EntityHanging extends Entity { + private int tickCounter1; + public int hangingDirection; + public int xPosition; + public int yPosition; + public int zPosition; + + public EntityHanging() { + super(); + this.tickCounter1 = 0; + this.hangingDirection = 0; + this.yOffset = 0.0F; + this.setSize(0.5F, 0.5F); + } + + public EntityHanging(World par1World, int par2, int par3, int par4, int par5) { + this(); + this.setWorld(par1World); + this.xPosition = par2; + this.yPosition = par3; + this.zPosition = par4; + } + + protected void entityInit() { + } + + public void setDirection(int par1) { + this.hangingDirection = par1; + this.prevRotationYaw = this.rotationYaw = (float) (par1 * 90); + float var2 = (float) this.func_82329_d(); + float var3 = (float) this.func_82330_g(); + float var4 = (float) this.func_82329_d(); + + if (par1 != 2 && par1 != 0) { + var2 = 0.5F; + } else { + var4 = 0.5F; + this.rotationYaw = this.prevRotationYaw = (float) (Direction.rotateOpposite[par1] * 90); + } + + var2 /= 32.0F; + var3 /= 32.0F; + var4 /= 32.0F; + float var5 = (float) this.xPosition + 0.5F; + float var6 = (float) this.yPosition + 0.5F; + float var7 = (float) this.zPosition + 0.5F; + float var8 = 0.5625F; + + if (par1 == 2) { + var7 -= var8; + } + + if (par1 == 1) { + var5 -= var8; + } + + if (par1 == 0) { + var7 += var8; + } + + if (par1 == 3) { + var5 += var8; + } + + if (par1 == 2) { + var5 -= this.func_70517_b(this.func_82329_d()); + } + + if (par1 == 1) { + var7 += this.func_70517_b(this.func_82329_d()); + } + + if (par1 == 0) { + var5 += this.func_70517_b(this.func_82329_d()); + } + + if (par1 == 3) { + var7 -= this.func_70517_b(this.func_82329_d()); + } + + var6 += this.func_70517_b(this.func_82330_g()); + this.setPosition((double) var5, (double) var6, (double) var7); + float var9 = -0.03125F; + this.boundingBox.setBounds((double) (var5 - var2 - var9), (double) (var6 - var3 - var9), (double) (var7 - var4 - var9), (double) (var5 + var2 + var9), (double) (var6 + var3 + var9), (double) (var7 + var4 + var9)); + } + + private float func_70517_b(int par1) { + return par1 == 32 ? 0.5F : (par1 == 64 ? 0.5F : 0.0F); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (this.tickCounter1++ == 100 && !this.worldObj.isRemote) { + this.tickCounter1 = 0; + + if (!this.isDead && !this.onValidSurface()) { + this.setDead(); + this.dropItemStack(); + } + } + } + + /** + * checks to make sure painting can be placed there + */ + public boolean onValidSurface() { + if (!this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty()) { + return false; + } else { + int var1 = Math.max(1, this.func_82329_d() / 16); + int var2 = Math.max(1, this.func_82330_g() / 16); + int var3 = this.xPosition; + int var4 = this.yPosition; + int var5 = this.zPosition; + + if (this.hangingDirection == 2) { + var3 = MathHelper.floor_double(this.posX - (double) ((float) this.func_82329_d() / 32.0F)); + } + + if (this.hangingDirection == 1) { + var5 = MathHelper.floor_double(this.posZ - (double) ((float) this.func_82329_d() / 32.0F)); + } + + if (this.hangingDirection == 0) { + var3 = MathHelper.floor_double(this.posX - (double) ((float) this.func_82329_d() / 32.0F)); + } + + if (this.hangingDirection == 3) { + var5 = MathHelper.floor_double(this.posZ - (double) ((float) this.func_82329_d() / 32.0F)); + } + + var4 = MathHelper.floor_double(this.posY - (double) ((float) this.func_82330_g() / 32.0F)); + + for (int var6 = 0; var6 < var1; ++var6) { + for (int var7 = 0; var7 < var2; ++var7) { + Material var8; + + if (this.hangingDirection != 2 && this.hangingDirection != 0) { + var8 = this.worldObj.getBlockMaterial(this.xPosition, var4 + var7, var5 + var6); + } else { + var8 = this.worldObj.getBlockMaterial(var3 + var6, var4 + var7, this.zPosition); + } + + if (!var8.isSolid()) { + return false; + } + } + } + + List var9 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox); + Iterator var10 = var9.iterator(); + Entity var11; + + do { + if (!var10.hasNext()) { + return true; + } + + var11 = (Entity) var10.next(); + } while (!(var11 instanceof EntityHanging)); + + return false; + } + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return true; + } + + public boolean func_85031_j(Entity par1Entity) { + return par1Entity instanceof EntityPlayer ? this.attackEntityFrom(DamageSource.causePlayerDamage((EntityPlayer) par1Entity), 0) : false; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + if (!this.isDead && !this.worldObj.isRemote) { + this.setDead(); + this.setBeenAttacked(); + EntityPlayer var3 = null; + + if (par1DamageSource.getEntity() instanceof EntityPlayer) { + var3 = (EntityPlayer) par1DamageSource.getEntity(); + } + + if (var3 != null && var3.capabilities.isCreativeMode) { + return true; + } + + this.dropItemStack(); + } + + return true; + } + } + + /** + * Tries to moves the entity by the passed in displacement. Args: x, y, z + */ + public void moveEntity(double par1, double par3, double par5) { + if (!this.worldObj.isRemote && !this.isDead && par1 * par1 + par3 * par3 + par5 * par5 > 0.0D) { + this.setDead(); + this.dropItemStack(); + } + } + + /** + * Adds to the current velocity of the entity. Args: x, y, z + */ + public void addVelocity(double par1, double par3, double par5) { + if (!this.worldObj.isRemote && !this.isDead && par1 * par1 + par3 * par3 + par5 * par5 > 0.0D) { + this.setDead(); + this.dropItemStack(); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setByte("Direction", (byte) this.hangingDirection); + par1NBTTagCompound.setInteger("TileX", this.xPosition); + par1NBTTagCompound.setInteger("TileY", this.yPosition); + par1NBTTagCompound.setInteger("TileZ", this.zPosition); + + switch (this.hangingDirection) { + case 0: + par1NBTTagCompound.setByte("Dir", (byte) 2); + break; + + case 1: + par1NBTTagCompound.setByte("Dir", (byte) 1); + break; + + case 2: + par1NBTTagCompound.setByte("Dir", (byte) 0); + break; + + case 3: + par1NBTTagCompound.setByte("Dir", (byte) 3); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + if (par1NBTTagCompound.hasKey("Direction")) { + this.hangingDirection = par1NBTTagCompound.getByte("Direction"); + } else { + switch (par1NBTTagCompound.getByte("Dir")) { + case 0: + this.hangingDirection = 2; + break; + + case 1: + this.hangingDirection = 1; + break; + + case 2: + this.hangingDirection = 0; + break; + + case 3: + this.hangingDirection = 3; + } + } + + this.xPosition = par1NBTTagCompound.getInteger("TileX"); + this.yPosition = par1NBTTagCompound.getInteger("TileY"); + this.zPosition = par1NBTTagCompound.getInteger("TileZ"); + this.setDirection(this.hangingDirection); + } + + public abstract int func_82329_d(); + + public abstract int func_82330_g(); + + /** + * Drop the item currently on this item frame. + */ + public abstract void dropItemStack(); +} diff --git a/src/main/java/net/minecraft/src/EntityHeartFX.java b/src/main/java/net/minecraft/src/EntityHeartFX.java new file mode 100644 index 0000000..1f37e9b --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityHeartFX.java @@ -0,0 +1,69 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityHeartFX extends EntityFX { + float particleScaleOverTime; + + public EntityHeartFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + this(par1World, par2, par4, par6, par8, par10, par12, 2.0F); + } + + public EntityHeartFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float par14) { + super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); + this.motionX *= 0.009999999776482582D; + this.motionY *= 0.009999999776482582D; + this.motionZ *= 0.009999999776482582D; + this.motionY += 0.1D; + this.particleScale *= 0.75F; + this.particleScale *= par14; + this.particleScaleOverTime = this.particleScale; + this.particleMaxAge = 16; + this.noClip = false; + this.setParticleTextureIndex(80); + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = ((float) this.particleAge + par2) / (float) this.particleMaxAge * 32.0F; + + if (var8 < 0.0F) { + var8 = 0.0F; + } + + if (var8 > 1.0F) { + var8 = 1.0F; + } + + this.particleScale = this.particleScaleOverTime * var8; + super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (this.posY == this.prevPosY) { + this.motionX *= 1.1D; + this.motionZ *= 1.1D; + } + + this.motionX *= 0.8600000143051147D; + this.motionY *= 0.8600000143051147D; + this.motionZ *= 0.8600000143051147D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityHugeExplodeFX.java b/src/main/java/net/minecraft/src/EntityHugeExplodeFX.java new file mode 100644 index 0000000..f1aa3c0 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityHugeExplodeFX.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityHugeExplodeFX extends EntityFX { + private int timeSinceStart = 0; + + /** the maximum time for the explosion */ + private int maximumTime = 0; + + public EntityHugeExplodeFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); + this.maximumTime = 8; + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + for (int var1 = 0; var1 < 6; ++var1) { + double var2 = this.posX + (this.rand.nextDouble() - this.rand.nextDouble()) * 4.0D; + double var4 = this.posY + (this.rand.nextDouble() - this.rand.nextDouble()) * 4.0D; + double var6 = this.posZ + (this.rand.nextDouble() - this.rand.nextDouble()) * 4.0D; + this.worldObj.spawnParticle("largeexplode", var2, var4, var6, (double) ((float) this.timeSinceStart / (float) this.maximumTime), 0.0D, 0.0D); + } + + ++this.timeSinceStart; + + if (this.timeSinceStart == this.maximumTime) { + this.setDead(); + } + } + + public int getFXLayer() { + return 1; + } +} diff --git a/src/main/java/net/minecraft/src/EntityIronGolem.java b/src/main/java/net/minecraft/src/EntityIronGolem.java new file mode 100644 index 0000000..0832f81 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityIronGolem.java @@ -0,0 +1,211 @@ +package net.minecraft.src; + +public class EntityIronGolem extends EntityGolem { + /** deincrements, and a distance-to-home check is done at 0 */ + private int homeCheckTimer = 0; + private int attackTimer; + private int holdRoseTick; + + public EntityIronGolem() { + super(); + this.setSize(1.4F, 2.9F); + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, Byte.valueOf((byte) 0)); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + /** + * main AI tick function, replaces updateEntityActionState + */ + protected void updateAITick() { + + super.updateAITick(); + } + + public int getMaxHealth() { + return 100; + } + + /** + * Decrements the entity's air supply when underwater + */ + protected int decreaseAirSupply(int par1) { + return par1; + } + + protected void collideWithEntity(Entity par1Entity) { + if (par1Entity instanceof IMob && this.getRNG().nextInt(20) == 0) { + this.setAttackTarget((EntityLiving) par1Entity); + } + + super.collideWithEntity(par1Entity); + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (this.attackTimer > 0) { + --this.attackTimer; + } + + if (this.holdRoseTick > 0) { + --this.holdRoseTick; + } + + if (this.motionX * this.motionX + this.motionZ * this.motionZ > 2.500000277905201E-7D && this.rand.nextInt(5) == 0) { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double) this.yOffset); + int var3 = MathHelper.floor_double(this.posZ); + int var4 = this.worldObj.getBlockId(var1, var2, var3); + + if (var4 > 0) { + this.worldObj.spawnParticle("tilecrack_" + var4 + "_" + this.worldObj.getBlockMetadata(var1, var2, var3), this.posX + ((double) this.rand.nextFloat() - 0.5D) * (double) this.width, this.boundingBox.minY + 0.1D, + this.posZ + ((double) this.rand.nextFloat() - 0.5D) * (double) this.width, 4.0D * ((double) this.rand.nextFloat() - 0.5D), 0.5D, ((double) this.rand.nextFloat() - 0.5D) * 4.0D); + } + } + } + + /** + * Returns true if this entity can attack entities of the specified class. + */ + public boolean canAttackClass(Class par1Class) { + return this.isPlayerCreated() && EntityPlayer.class.isAssignableFrom(par1Class) ? false : super.canAttackClass(par1Class); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setBoolean("PlayerCreated", this.isPlayerCreated()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setPlayerCreated(par1NBTTagCompound.getBoolean("PlayerCreated")); + } + + public boolean attackEntityAsMob(Entity par1Entity) { + this.attackTimer = 10; + this.worldObj.setEntityState(this, (byte) 4); + boolean var2 = par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), 7 + this.rand.nextInt(15)); + + if (var2) { + par1Entity.motionY += 0.4000000059604645D; + } + + this.playSound("mob.irongolem.throw", 1.0F, 1.0F); + return var2; + } + + public void handleHealthUpdate(byte par1) { + if (par1 == 4) { + this.attackTimer = 10; + this.playSound("mob.irongolem.throw", 1.0F, 1.0F); + } else if (par1 == 11) { + this.holdRoseTick = 400; + } else { + super.handleHealthUpdate(par1); + } + } + + public int getAttackTimer() { + return this.attackTimer; + } + + public void setHoldingRose(boolean par1) { + this.holdRoseTick = par1 ? 400 : 0; + this.worldObj.setEntityState(this, (byte) 11); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "none"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.irongolem.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.irongolem.death"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.irongolem.walk", 1.0F, 1.0F); + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(3); + int var4; + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Block.plantRed.blockID, 1); + } + + var4 = 3 + this.rand.nextInt(3); + + for (int var5 = 0; var5 < var4; ++var5) { + this.dropItem(Item.ingotIron.itemID, 1); + } + } + + public int getHoldRoseTick() { + return this.holdRoseTick; + } + + public boolean isPlayerCreated() { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + public void setPlayerCreated(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 1))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -2))); + } + } + + /** + * Called when the mob's health reaches 0. + */ + public void onDeath(DamageSource par1DamageSource) { + + super.onDeath(par1DamageSource); + } +} diff --git a/src/main/java/net/minecraft/src/EntityItem.java b/src/main/java/net/minecraft/src/EntityItem.java new file mode 100644 index 0000000..c94ba2d --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityItem.java @@ -0,0 +1,325 @@ +package net.minecraft.src; + +import java.util.Iterator; + + + +public class EntityItem extends Entity { + /** + * The age of this EntityItem (used to animate it up and down as well as expire + * it) + */ + public int age; + public int delayBeforeCanPickup; + + /** The health of this EntityItem. (For example, damage for tools) */ + private int health; + + /** The EntityItem's random initial float height. */ + public float hoverStart; + + public EntityItem(World par1World, double par2, double par4, double par6) { + super(); + this.setWorld(par1World); + this.age = 0; + this.health = 5; + this.hoverStart = (float) (Math.random() * Math.PI * 2.0D); + this.setSize(0.25F, 0.25F); + this.yOffset = this.height / 2.0F; + this.setPosition(par2, par4, par6); + this.rotationYaw = (float) (Math.random() * 360.0D); + this.motionX = (double) ((float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D)); + this.motionY = 0.20000000298023224D; + this.motionZ = (double) ((float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D)); + } + + public EntityItem(World par1World, double par2, double par4, double par6, ItemStack par8ItemStack) { + this(par1World, par2, par4, par6); + this.setEntityItemStack(par8ItemStack); + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + public EntityItem() { + super(); + this.age = 0; + this.health = 5; + this.hoverStart = (float) (Math.random() * Math.PI * 2.0D); + this.setSize(0.25F, 0.25F); + this.yOffset = this.height / 2.0F; + } + + protected void entityInit() { + this.getDataWatcher().addObjectByDataType(10, 5); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.delayBeforeCanPickup > 0) { + --this.delayBeforeCanPickup; + } + + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.motionY -= 0.03999999910593033D; + this.noClip = this.pushOutOfBlocks(this.posX, (this.boundingBox.minY + this.boundingBox.maxY) / 2.0D, this.posZ); + this.moveEntity(this.motionX, this.motionY, this.motionZ); + boolean var1 = (int) this.prevPosX != (int) this.posX || (int) this.prevPosY != (int) this.posY || (int) this.prevPosZ != (int) this.posZ; + + if (var1 || this.ticksExisted % 25 == 0) { + if (this.worldObj.getBlockMaterial(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) == Material.lava) { + this.motionY = 0.20000000298023224D; + this.motionX = (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F); + this.motionZ = (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F); + this.playSound("random.fizz", 0.4F, 2.0F + this.rand.nextFloat() * 0.4F); + } + + if (!this.worldObj.isRemote) { + this.searchForOtherItemsNearby(); + } + } + + float var2 = 0.98F; + + if (this.onGround) { + var2 = 0.58800006F; + int var3 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)); + + if (var3 > 0) { + var2 = Block.blocksList[var3].slipperiness * 0.98F; + } + } + + this.motionX *= (double) var2; + this.motionY *= 0.9800000190734863D; + this.motionZ *= (double) var2; + + if (this.onGround) { + this.motionY *= -0.5D; + } + + ++this.age; + + if (!this.worldObj.isRemote && this.age >= 6000) { + this.setDead(); + } + } + + /** + * Looks for other itemstacks nearby and tries to stack them together + */ + private void searchForOtherItemsNearby() { + Iterator var1 = this.worldObj.getEntitiesWithinAABB(EntityItem.class, this.boundingBox.expand(0.5D, 0.0D, 0.5D)).iterator(); + + while (var1.hasNext()) { + EntityItem var2 = (EntityItem) var1.next(); + this.combineItems(var2); + } + } + + /** + * Tries to merge this item with the item passed as the parameter. Returns true + * if successful. Either this item or the other item will be removed from the + * world. + */ + public boolean combineItems(EntityItem par1EntityItem) { + if (par1EntityItem == this) { + return false; + } else if (par1EntityItem.isEntityAlive() && this.isEntityAlive()) { + ItemStack var2 = this.getEntityItem(); + ItemStack var3 = par1EntityItem.getEntityItem(); + + if (var3.getItem() != var2.getItem()) { + return false; + } else if (var3.hasTagCompound() ^ var2.hasTagCompound()) { + return false; + } else if (var3.hasTagCompound() && !var3.getTagCompound().equals(var2.getTagCompound())) { + return false; + } else if (var3.getItem().getHasSubtypes() && var3.getItemDamage() != var2.getItemDamage()) { + return false; + } else if (var3.stackSize < var2.stackSize) { + return par1EntityItem.combineItems(this); + } else if (var3.stackSize + var2.stackSize > var3.getMaxStackSize()) { + return false; + } else { + var3.stackSize += var2.stackSize; + par1EntityItem.delayBeforeCanPickup = Math.max(par1EntityItem.delayBeforeCanPickup, this.delayBeforeCanPickup); + par1EntityItem.age = Math.min(par1EntityItem.age, this.age); + par1EntityItem.setEntityItemStack(var3); + this.setDead(); + return true; + } + } else { + return false; + } + } + + /** + * sets the age of the item so that it'll despawn one minute after it has been + * dropped (instead of five). Used when items are dropped from players in + * creative mode + */ + public void setAgeToCreativeDespawnTime() { + this.age = 4800; + } + + /** + * Returns if this entity is in water and will end up adding the waters velocity + * to the entity + */ + public boolean handleWaterMovement() { + return this.worldObj.handleMaterialAcceleration(this.boundingBox, Material.water, this); + } + + /** + * Will deal the specified amount of damage to the entity if the entity isn't + * immune to fire damage. Args: amountDamage + */ + protected void dealFireDamage(int par1) { + this.attackEntityFrom(DamageSource.inFire, par1); + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else if (this.getEntityItem() != null && this.getEntityItem().itemID == Item.netherStar.itemID && par1DamageSource.isExplosion()) { + return false; + } else { + this.setBeenAttacked(); + this.health -= par2; + + if (this.health <= 0) { + this.setDead(); + } + + return false; + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setShort("Health", (short) ((byte) this.health)); + par1NBTTagCompound.setShort("Age", (short) this.age); + + if (this.getEntityItem() != null) { + par1NBTTagCompound.setCompoundTag("Item", this.getEntityItem().writeToNBT(new NBTTagCompound())); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.health = par1NBTTagCompound.getShort("Health") & 255; + this.age = par1NBTTagCompound.getShort("Age"); + NBTTagCompound var2 = par1NBTTagCompound.getCompoundTag("Item"); + this.setEntityItemStack(ItemStack.loadItemStackFromNBT(var2)); + + if (this.getEntityItem() == null) { + this.setDead(); + } + } + + /** + * Called by a player entity when they collide with an entity + */ + public void onCollideWithPlayer(EntityPlayer par1EntityPlayer) { + if (!this.worldObj.isRemote) { + ItemStack var2 = this.getEntityItem(); + int var3 = var2.stackSize; + + if (this.delayBeforeCanPickup == 0 && par1EntityPlayer.inventory.addItemStackToInventory(var2)) { + if (var2.itemID == Block.wood.blockID) { + par1EntityPlayer.triggerAchievement(AchievementList.mineWood); + } + + if (var2.itemID == Item.leather.itemID) { + par1EntityPlayer.triggerAchievement(AchievementList.killCow); + } + + if (var2.itemID == Item.diamond.itemID) { + par1EntityPlayer.triggerAchievement(AchievementList.diamonds); + } + + if (var2.itemID == Item.blazeRod.itemID) { + par1EntityPlayer.triggerAchievement(AchievementList.blazeRod); + } + + this.playSound("random.pop", 0.2F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + par1EntityPlayer.onItemPickup(this, var3); + + if (var2.stackSize <= 0) { + this.setDead(); + } + } + } + } + + /** + * Gets the username of the entity. + */ + public String getEntityName() { + return StatCollector.translateToLocal("item." + this.getEntityItem().getItemName()); + } + + /** + * If returns false, the item will not inflict any damage against entities. + */ + public boolean canAttackWithItem() { + return false; + } + + /** + * Teleports the entity to another dimension. Params: Dimension number to + * teleport to + */ + public void travelToDimension(int par1) { + super.travelToDimension(par1); + + if (!this.worldObj.isRemote) { + this.searchForOtherItemsNearby(); + } + } + + /** + * Returns the ItemStack corresponding to the Entity (Note: if no item exists, + * will log an error but still return an ItemStack containing Block.stone) + */ + public ItemStack getEntityItem() { + ItemStack var1 = this.getDataWatcher().getWatchableObjectItemStack(10); + + if (var1 == null) { + if (this.worldObj != null) { + System.err.println("Item entity " + this.entityId + " has no item?!"); + } + + return new ItemStack(Block.stone); + } else { + return var1; + } + } + + /** + * Sets the ItemStack for this entity + */ + public void setEntityItemStack(ItemStack par1ItemStack) { + this.getDataWatcher().updateObject(10, par1ItemStack); + this.getDataWatcher().setObjectWatched(10); + } +} diff --git a/src/main/java/net/minecraft/src/EntityItemFrame.java b/src/main/java/net/minecraft/src/EntityItemFrame.java new file mode 100644 index 0000000..7de14ed --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityItemFrame.java @@ -0,0 +1,129 @@ +package net.minecraft.src; + +public class EntityItemFrame extends EntityHanging { + /** Chance for this item frame's item to drop from the frame. */ + private float itemDropChance = 1.0F; + + public EntityItemFrame() { + super(); + } + + public EntityItemFrame(World par1World, int par2, int par3, int par4, int par5) { + super(par1World, par2, par3, par4, par5); + this.setDirection(par5); + } + + protected void entityInit() { + this.getDataWatcher().addObjectByDataType(2, 5); + this.getDataWatcher().addObject(3, Byte.valueOf((byte) 0)); + } + + public int func_82329_d() { + return 9; + } + + public int func_82330_g() { + return 9; + } + + /** + * Checks if the entity is in range to render by using the past in distance and + * comparing it to its average edge length * 64 * renderDistanceWeight Args: + * distance + */ + public boolean isInRangeToRenderDist(double par1) { + double var3 = 16.0D; + var3 *= 64.0D * this.renderDistanceWeight; + return par1 < var3 * var3; + } + + /** + * Drop the item currently on this item frame. + */ + public void dropItemStack() { + this.entityDropItem(new ItemStack(Item.itemFrame), 0.0F); + ItemStack var1 = this.getDisplayedItem(); + + if (var1 != null && this.rand.nextFloat() < this.itemDropChance) { + var1 = var1.copy(); + var1.setItemFrame((EntityItemFrame) null); + this.entityDropItem(var1, 0.0F); + } + } + + public ItemStack getDisplayedItem() { + return this.getDataWatcher().getWatchableObjectItemStack(2); + } + + public void setDisplayedItem(ItemStack par1ItemStack) { + par1ItemStack = par1ItemStack.copy(); + par1ItemStack.stackSize = 1; + par1ItemStack.setItemFrame(this); + this.getDataWatcher().updateObject(2, par1ItemStack); + this.getDataWatcher().setObjectWatched(2); + } + + /** + * Return the rotation of the item currently on this frame. + */ + public int getRotation() { + return this.getDataWatcher().getWatchableObjectByte(3); + } + + public void setItemRotation(int par1) { + this.getDataWatcher().updateObject(3, Byte.valueOf((byte) (par1 % 4))); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + if (this.getDisplayedItem() != null) { + par1NBTTagCompound.setCompoundTag("Item", this.getDisplayedItem().writeToNBT(new NBTTagCompound())); + par1NBTTagCompound.setByte("ItemRotation", (byte) this.getRotation()); + par1NBTTagCompound.setFloat("ItemDropChance", this.itemDropChance); + } + + super.writeEntityToNBT(par1NBTTagCompound); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + NBTTagCompound var2 = par1NBTTagCompound.getCompoundTag("Item"); + + if (var2 != null && !var2.hasNoTags()) { + this.setDisplayedItem(ItemStack.loadItemStackFromNBT(var2)); + this.setItemRotation(par1NBTTagCompound.getByte("ItemRotation")); + + if (par1NBTTagCompound.hasKey("ItemDropChance")) { + this.itemDropChance = par1NBTTagCompound.getFloat("ItemDropChance"); + } + } + + super.readEntityFromNBT(par1NBTTagCompound); + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + if (this.getDisplayedItem() == null) { + ItemStack var2 = par1EntityPlayer.getHeldItem(); + + if (var2 != null && !this.worldObj.isRemote) { + this.setDisplayedItem(var2); + + if (!par1EntityPlayer.capabilities.isCreativeMode && --var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null); + } + } + } else if (!this.worldObj.isRemote) { + this.setItemRotation(this.getRotation() + 1); + } + + return true; + } +} diff --git a/src/main/java/net/minecraft/src/EntityJumpHelper.java b/src/main/java/net/minecraft/src/EntityJumpHelper.java new file mode 100644 index 0000000..ab0ab8e --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityJumpHelper.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +public class EntityJumpHelper { + private EntityLiving entity; + private boolean isJumping = false; + + public EntityJumpHelper(EntityLiving par1EntityLiving) { + this.entity = par1EntityLiving; + } + + public void setJumping() { + this.isJumping = true; + } + + /** + * Called to actually make the entity jump if isJumping is true. + */ + public void doJump() { + this.entity.setJumping(this.isJumping); + this.isJumping = false; + } +} diff --git a/src/main/java/net/minecraft/src/EntityLargeExplodeFX.java b/src/main/java/net/minecraft/src/EntityLargeExplodeFX.java new file mode 100644 index 0000000..4318829 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityLargeExplodeFX.java @@ -0,0 +1,75 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityLargeExplodeFX extends EntityFX { + private int field_70581_a = 0; + private int field_70584_aq = 0; + + /** The Rendering Engine. */ + private RenderEngine theRenderEngine; + private float field_70582_as; + + public EntityLargeExplodeFX(RenderEngine par1RenderEngine, World par2World, double par3, double par5, double par7, double par9, double par11, double par13) { + super(par2World, par3, par5, par7, 0.0D, 0.0D, 0.0D); + this.theRenderEngine = par1RenderEngine; + this.field_70584_aq = 6 + this.rand.nextInt(4); + this.particleRed = this.particleGreen = this.particleBlue = this.rand.nextFloat() * 0.6F + 0.4F; + this.field_70582_as = 1.0F - (float) par9 * 0.5F; + } + + private static final TextureLocation explosion = new TextureLocation("/misc/explosion.png"); + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + int var8 = (int) (((float) this.field_70581_a + par2) * 15.0F / (float) this.field_70584_aq); + + if (var8 <= 15) { + explosion.bindTexture(); + float var9 = (float) (var8 % 4) / 4.0F; + float var10 = var9 + 0.24975F; + float var11 = (float) (var8 / 4) / 4.0F; + float var12 = var11 + 0.24975F; + float var13 = 2.0F * this.field_70582_as; + float var14 = (float) (this.prevPosX + (this.posX - this.prevPosX) * (double) par2 - interpPosX); + float var15 = (float) (this.prevPosY + (this.posY - this.prevPosY) * (double) par2 - interpPosY); + float var16 = (float) (this.prevPosZ + (this.posZ - this.prevPosZ) * (double) par2 - interpPosZ); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + par1Tessellator.startDrawingQuads(); + par1Tessellator.setColorRGBA_F(this.particleRed, this.particleGreen, this.particleBlue, 1.0F); + par1Tessellator.setNormal(0.0F, 1.0F, 0.0F); + par1Tessellator.setBrightness(240); + par1Tessellator.addVertexWithUV((double) (var14 - par3 * var13 - par6 * var13), (double) (var15 - par4 * var13), (double) (var16 - par5 * var13 - par7 * var13), (double) var10, (double) var12); + par1Tessellator.addVertexWithUV((double) (var14 - par3 * var13 + par6 * var13), (double) (var15 + par4 * var13), (double) (var16 - par5 * var13 + par7 * var13), (double) var10, (double) var11); + par1Tessellator.addVertexWithUV((double) (var14 + par3 * var13 + par6 * var13), (double) (var15 + par4 * var13), (double) (var16 + par5 * var13 + par7 * var13), (double) var9, (double) var11); + par1Tessellator.addVertexWithUV((double) (var14 + par3 * var13 - par6 * var13), (double) (var15 - par4 * var13), (double) (var16 + par5 * var13 - par7 * var13), (double) var9, (double) var12); + par1Tessellator.draw(); + EaglerAdapter.glPolygonOffset(0.0F, 0.0F); + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + } + } + + public int getBrightnessForRender(float par1) { + return 61680; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + ++this.field_70581_a; + + if (this.field_70581_a == this.field_70584_aq) { + this.setDead(); + } + } + + public int getFXLayer() { + return 3; + } +} diff --git a/src/main/java/net/minecraft/src/EntityLargeFireball.java b/src/main/java/net/minecraft/src/EntityLargeFireball.java new file mode 100644 index 0000000..ad9d3c1 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityLargeFireball.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + +public class EntityLargeFireball extends EntityFireball { + public int field_92057_e = 1; + + public EntityLargeFireball() { + super(); + } + + public EntityLargeFireball(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + super(par1World, par2, par4, par6, par8, par10, par12); + } + + public EntityLargeFireball(World par1World, EntityLiving par2EntityLiving, double par3, double par5, double par7) { + super(par1World, par2EntityLiving, par3, par5, par7); + } + + /** + * Called when this EntityFireball hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (!this.worldObj.isRemote) { + if (par1MovingObjectPosition.entityHit != null) { + par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeFireballDamage(this, this.shootingEntity), 6); + } + + this.worldObj.newExplosion((Entity) null, this.posX, this.posY, this.posZ, (float) this.field_92057_e, true, this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")); + this.setDead(); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("ExplosionPower", this.field_92057_e); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("ExplosionPower")) { + this.field_92057_e = par1NBTTagCompound.getInteger("ExplosionPower"); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityLavaFX.java b/src/main/java/net/minecraft/src/EntityLavaFX.java new file mode 100644 index 0000000..11d120a --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityLavaFX.java @@ -0,0 +1,82 @@ +package net.minecraft.src; + + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityLavaFX extends EntityFX { + private float lavaParticleScale; + + public EntityLavaFX(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); + this.motionX *= 0.800000011920929D; + this.motionY *= 0.800000011920929D; + this.motionZ *= 0.800000011920929D; + this.motionY = (double) (this.rand.nextFloat() * 0.4F + 0.05F); + this.particleRed = this.particleGreen = this.particleBlue = 1.0F; + this.particleScale *= this.rand.nextFloat() * 2.0F + 0.2F; + this.lavaParticleScale = this.particleScale; + this.particleMaxAge = (int) (16.0D / (Math.random() * 0.8D + 0.2D)); + this.noClip = false; + this.setParticleTextureIndex(49); + } + + public int getBrightnessForRender(float par1) { + float var2 = ((float) this.particleAge + par1) / (float) this.particleMaxAge; + + if (var2 < 0.0F) { + var2 = 0.0F; + } + + if (var2 > 1.0F) { + var2 = 1.0F; + } + + int var3 = super.getBrightnessForRender(par1); + short var4 = 240; + int var5 = var3 >> 16 & 255; + return var4 | var5 << 16; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + return 1.0F; + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = ((float) this.particleAge + par2) / (float) this.particleMaxAge; + this.particleScale = this.lavaParticleScale * (1.0F - var8 * var8); + super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + + float var1 = (float) this.particleAge / (float) this.particleMaxAge; + + if (this.rand.nextFloat() > var1) { + this.worldObj.spawnParticle("smoke", this.posX, this.posY, this.posZ, this.motionX, this.motionY, this.motionZ); + } + + this.motionY -= 0.03D; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9990000128746033D; + this.motionY *= 0.9990000128746033D; + this.motionZ *= 0.9990000128746033D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityLightningBolt.java b/src/main/java/net/minecraft/src/EntityLightningBolt.java new file mode 100644 index 0000000..546c47c --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityLightningBolt.java @@ -0,0 +1,122 @@ +package net.minecraft.src; + +import java.util.List; + +public class EntityLightningBolt extends EntityWeatherEffect { + /** + * Declares which state the lightning bolt is in. Whether it's in the air, hit + * the ground, etc. + */ + private int lightningState; + + /** + * A random long that is used to change the vertex of the lightning rendered in + * RenderLightningBolt + */ + public long boltVertex = 0L; + + /** + * Determines the time before the EntityLightningBolt is destroyed. It is a + * random integer decremented over time. + */ + private int boltLivingTime; + + public EntityLightningBolt(World par1World, double par2, double par4, double par6) { + super(par1World); + this.setLocationAndAngles(par2, par4, par6, 0.0F, 0.0F); + this.lightningState = 2; + this.boltVertex = this.rand.nextLong(); + this.boltLivingTime = this.rand.nextInt(3) + 1; + + if (!par1World.isRemote && par1World.difficultySetting >= 2 && par1World.doChunksNearChunkExist(MathHelper.floor_double(par2), MathHelper.floor_double(par4), MathHelper.floor_double(par6), 10)) { + int var8 = MathHelper.floor_double(par2); + int var9 = MathHelper.floor_double(par4); + int var10 = MathHelper.floor_double(par6); + + if (par1World.getBlockId(var8, var9, var10) == 0 && Block.fire.canPlaceBlockAt(par1World, var8, var9, var10)) { + par1World.setBlock(var8, var9, var10, Block.fire.blockID); + } + + for (var8 = 0; var8 < 4; ++var8) { + var9 = MathHelper.floor_double(par2) + this.rand.nextInt(3) - 1; + var10 = MathHelper.floor_double(par4) + this.rand.nextInt(3) - 1; + int var11 = MathHelper.floor_double(par6) + this.rand.nextInt(3) - 1; + + if (par1World.getBlockId(var9, var10, var11) == 0 && Block.fire.canPlaceBlockAt(par1World, var9, var10, var11)) { + par1World.setBlock(var9, var10, var11, Block.fire.blockID); + } + } + } + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.lightningState == 2) { + this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "ambient.weather.thunder", 10000.0F, 0.8F + this.rand.nextFloat() * 0.2F); + this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "random.explode", 2.0F, 0.5F + this.rand.nextFloat() * 0.2F); + } + + --this.lightningState; + + if (this.lightningState < 0) { + if (this.boltLivingTime == 0) { + this.setDead(); + } else if (this.lightningState < -this.rand.nextInt(10)) { + --this.boltLivingTime; + this.lightningState = 1; + this.boltVertex = this.rand.nextLong(); + + if (!this.worldObj.isRemote && this.worldObj.doChunksNearChunkExist(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ), 10)) { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.posY); + int var3 = MathHelper.floor_double(this.posZ); + + if (this.worldObj.getBlockId(var1, var2, var3) == 0 && Block.fire.canPlaceBlockAt(this.worldObj, var1, var2, var3)) { + this.worldObj.setBlock(var1, var2, var3, Block.fire.blockID); + } + } + } + } + + if (this.lightningState >= 0) { + if (this.worldObj.isRemote) { + this.worldObj.lastLightningBolt = 2; + } else { + double var6 = 3.0D; + List var7 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, AxisAlignedBB.getAABBPool().getAABB(this.posX - var6, this.posY - var6, this.posZ - var6, this.posX + var6, this.posY + 6.0D + var6, this.posZ + var6)); + + for (int var4 = 0; var4 < var7.size(); ++var4) { + Entity var5 = (Entity) var7.get(var4); + var5.onStruckByLightning(this); + } + } + } + } + + protected void entityInit() { + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * Checks using a Vec3d to determine if this entity is within range of that + * vector to be rendered. Args: vec3D + */ + public boolean isInRangeToRenderVec3D(Vec3 par1Vec3) { + return this.lightningState >= 0; + } +} diff --git a/src/main/java/net/minecraft/src/EntityList.java b/src/main/java/net/minecraft/src/EntityList.java new file mode 100644 index 0000000..3ed5dc4 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityList.java @@ -0,0 +1,217 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +public class EntityList { + /** Provides a mapping between entity classes and a string */ + private static Map stringToClassMapping = new HashMap(); + + /** Provides a mapping between a string and an entity classes */ + private static Map classToStringMapping = new HashMap(); + + /** provides a mapping between an entityID and an Entity Class */ + private static Map IDtoClassMapping = new HashMap(); + + /** provides a mapping between an Entity Class and an entity ID */ + private static Map classToIDMapping = new HashMap(); + + /** Maps entity names to their numeric identifiers */ + private static Map stringToIDMapping = new HashMap(); + + /** This is a HashMap of the Creative Entity Eggs/Spawners. */ + public static HashMap entityEggs = new LinkedHashMap(); + + /** + * adds a mapping between Entity classes and both a string representation and an + * ID + */ + private static void addMapping(Class par0Class, String par1Str, int par2) { + stringToClassMapping.put(par1Str, par0Class); + classToStringMapping.put(par0Class, par1Str); + IDtoClassMapping.put(Integer.valueOf(par2), par0Class); + classToIDMapping.put(par0Class, Integer.valueOf(par2)); + stringToIDMapping.put(par1Str, Integer.valueOf(par2)); + } + + /** + * Adds a entity mapping with egg info. + */ + private static void addMapping(Class par0Class, String par1Str, int par2, int par3, int par4) { + addMapping(par0Class, par1Str, par2); + entityEggs.put(Integer.valueOf(par2), new EntityEggInfo(par2, par3, par4)); + } + + /** + * Create a new instance of an entity in the world by using the entity name. + */ + public static Entity createEntityByName(String par0Str, World par1World) { + Entity var2 = null; + + try { + Class var3 = (Class) stringToClassMapping.get(par0Str); + + if (var3 != null) { + var2 = (Entity) var3.getConstructor(new Class[] { World.class }).newInstance(new Object[] { par1World }); + } + } catch (Exception var4) { + var4.printStackTrace(); + } + + return var2; + } + + /** + * create a new instance of an entity from NBT store + */ + public static Entity createEntityFromNBT(NBTTagCompound par0NBTTagCompound, World par1World) { + Entity var2 = null; + + if ("Minecart".equals(par0NBTTagCompound.getString("id"))) { + switch (par0NBTTagCompound.getInteger("Type")) { + case 0: + par0NBTTagCompound.setString("id", "MinecartRideable"); + break; + + case 1: + par0NBTTagCompound.setString("id", "MinecartChest"); + break; + + case 2: + par0NBTTagCompound.setString("id", "MinecartFurnace"); + } + + par0NBTTagCompound.removeTag("Type"); + } + + try { + Class var3 = (Class) stringToClassMapping.get(par0NBTTagCompound.getString("id")); + + if (var3 != null) { + var2 = (Entity) var3.getConstructor(new Class[] { World.class }).newInstance(new Object[] { par1World }); + } + } catch (Exception var4) { + var4.printStackTrace(); + } + + if (var2 != null) { + var2.readFromNBT(par0NBTTagCompound); + } else { + System.err.println("Skipping Entity with id " + par0NBTTagCompound.getString("id")); + } + + return var2; + } + + /** + * Create a new instance of an entity in the world by using an entity ID. + */ + public static Entity createEntityByID(int par0, World par1World) { + Entity var2 = null; + + try { + Class var3 = getClassFromID(par0); + + if (var3 != null) { + var2 = (Entity) var3.newInstance(); + } + } catch (Exception var4) { + var4.printStackTrace(); + } + + if (var2 == null) { + System.err.println("Skipping Entity with id " + par0); + }else { + var2.setWorld(par1World); + } + + return var2; + } + + /** + * gets the entityID of a specific entity + */ + public static int getEntityID(Entity par0Entity) { + Class var1 = par0Entity.getClass(); + return classToIDMapping.containsKey(var1) ? ((Integer) classToIDMapping.get(var1)).intValue() : 0; + } + + /** + * Return the class assigned to this entity ID. + */ + public static Class getClassFromID(int par0) { + return (Class) IDtoClassMapping.get(Integer.valueOf(par0)); + } + + /** + * Gets the string representation of a specific entity. + */ + public static String getEntityString(Entity par0Entity) { + return (String) classToStringMapping.get(par0Entity.getClass()); + } + + /** + * Finds the class using IDtoClassMapping and classToStringMapping + */ + public static String getStringFromID(int par0) { + Class var1 = getClassFromID(par0); + return var1 != null ? (String) classToStringMapping.get(var1) : null; + } + + static { + addMapping(EntityItem.class, "Item", 1); + addMapping(EntityXPOrb.class, "XPOrb", 2); + addMapping(EntityPainting.class, "Painting", 9); + addMapping(EntityArrow.class, "Arrow", 10); + addMapping(EntitySnowball.class, "Snowball", 11); + addMapping(EntityLargeFireball.class, "Fireball", 12); + addMapping(EntitySmallFireball.class, "SmallFireball", 13); + addMapping(EntityEnderPearl.class, "ThrownEnderpearl", 14); + addMapping(EntityEnderEye.class, "EyeOfEnderSignal", 15); + addMapping(EntityPotion.class, "ThrownPotion", 16); + addMapping(EntityExpBottle.class, "ThrownExpBottle", 17); + addMapping(EntityItemFrame.class, "ItemFrame", 18); + addMapping(EntityWitherSkull.class, "WitherSkull", 19); + addMapping(EntityTNTPrimed.class, "PrimedTnt", 20); + addMapping(EntityFallingSand.class, "FallingSand", 21); + addMapping(EntityFireworkRocket.class, "FireworksRocketEntity", 22); + addMapping(EntityBoat.class, "Boat", 41); + addMapping(EntityMinecartEmpty.class, "MinecartRideable", 42); + addMapping(EntityMinecartChest.class, "MinecartChest", 43); + addMapping(EntityMinecartFurnace.class, "MinecartFurnace", 44); + addMapping(EntityMinecartTNT.class, "MinecartTNT", 45); + addMapping(EntityMinecartHopper.class, "MinecartHopper", 46); + addMapping(EntityMinecartMobSpawner.class, "MinecartSpawner", 47); + addMapping(EntityLiving.class, "Mob", 48); + addMapping(EntityMob.class, "Monster", 49); + addMapping(EntityCreeper.class, "Creeper", 50, 894731, 0); + addMapping(EntitySkeleton.class, "Skeleton", 51, 12698049, 4802889); + addMapping(EntitySpider.class, "Spider", 52, 3419431, 11013646); + addMapping(EntityZombie.class, "Zombie", 54, 44975, 7969893); + addMapping(EntitySlime.class, "Slime", 55, 5349438, 8306542); + addMapping(EntityGhast.class, "Ghast", 56, 16382457, 12369084); + addMapping(EntityPigZombie.class, "PigZombie", 57, 15373203, 5009705); + addMapping(EntityEnderman.class, "Enderman", 58, 1447446, 0); + addMapping(EntityCaveSpider.class, "CaveSpider", 59, 803406, 11013646); + addMapping(EntitySilverfish.class, "Silverfish", 60, 7237230, 3158064); + addMapping(EntityBlaze.class, "Blaze", 61, 16167425, 16775294); + addMapping(EntityMagmaCube.class, "LavaSlime", 62, 3407872, 16579584); + addMapping(EntityDragon.class, "EnderDragon", 63); + addMapping(EntityWither.class, "WitherBoss", 64); + addMapping(EntityBat.class, "Bat", 65, 4996656, 986895); + addMapping(EntityWitch.class, "Witch", 66, 3407872, 5349438); + addMapping(EntityPig.class, "Pig", 90, 15771042, 14377823); + addMapping(EntitySheep.class, "Sheep", 91, 15198183, 16758197); + addMapping(EntityCow.class, "Cow", 92, 4470310, 10592673); + addMapping(EntityChicken.class, "Chicken", 93, 10592673, 16711680); + addMapping(EntitySquid.class, "Squid", 94, 2243405, 7375001); + addMapping(EntityWolf.class, "Wolf", 95, 14144467, 13545366); + addMapping(EntityMooshroom.class, "MushroomCow", 96, 10489616, 12040119); + addMapping(EntitySnowman.class, "SnowMan", 97); + addMapping(EntityOcelot.class, "Ozelot", 98, 15720061, 5653556); + addMapping(EntityIronGolem.class, "VillagerGolem", 99); + addMapping(EntityVillager.class, "Villager", 120, 5651507, 12422002); + addMapping(EntityEnderCrystal.class, "EnderCrystal", 200); + } +} diff --git a/src/main/java/net/minecraft/src/EntityLiving.java b/src/main/java/net/minecraft/src/EntityLiving.java new file mode 100644 index 0000000..4237988 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityLiving.java @@ -0,0 +1,2481 @@ +package net.minecraft.src; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + + + +public abstract class EntityLiving extends Entity { + /** + * An array of probabilities that determines whether a random enchantment should + * be added to the held item. Indexed by difficulty. + */ + private static final float[] enchantmentProbability = new float[] { 0.0F, 0.0F, 0.1F, 0.2F }; + + /** Probability to get enchanted armor */ + private static final float[] armorEnchantmentProbability = new float[] { 0.0F, 0.0F, 0.25F, 0.5F }; + + /** Probability to get armor */ + private static final float[] armorProbability = new float[] { 0.0F, 0.0F, 0.05F, 0.07F }; + + /** Probability to pick up loot */ + public static final float[] pickUpLootProability = new float[] { 0.0F, 0.1F, 0.15F, 0.45F }; + public int maxHurtResistantTime = 20; + public float field_70769_ao; + public float field_70770_ap; + public float renderYawOffset = 0.0F; + public float prevRenderYawOffset = 0.0F; + + /** Entity head rotation yaw */ + public float rotationYawHead = 0.0F; + + /** Entity head rotation yaw at previous tick */ + public float prevRotationYawHead = 0.0F; + protected float field_70768_au; + protected float field_70766_av; + protected float field_70764_aw; + protected float field_70763_ax; + protected boolean field_70753_ay = true; + + protected boolean field_70740_aA = true; + protected float field_70741_aB = 0.0F; + + /** + * a string holding the type of entity it is currently only implemented in + * entityPlayer(as 'humanoid') + */ + protected String entityType = null; + protected float field_70743_aD = 1.0F; + + /** The score value of the Mob, the amount of points the mob is worth. */ + protected int scoreValue = 0; + protected float field_70745_aF = 0.0F; + + /** + * A factor used to determine how far this entity will move each tick if it is + * walking on land. Adjusted by speed, and slipperiness of the current block. + */ + public float landMovementFactor = 0.1F; + + /** + * A factor used to determine how far this entity will move each tick if it is + * jumping or falling. + */ + public float jumpMovementFactor = 0.02F; + public float prevSwingProgress; + public float swingProgress; + protected int health = this.getMaxHealth(); + public int prevHealth; + + /** + * in each step in the damage calculations, this is set to the 'carryover' that + * would result if someone was damaged .25 hearts (for example), and added to + * the damage in the next step + */ + protected int carryoverDamage; + + /** Number of ticks since this EntityLiving last produced its sound */ + public int livingSoundTime; + + /** + * The amount of time remaining this entity should act 'hurt'. (Visual + * appearance of red tint) + */ + public int hurtTime; + + /** What the hurt time was max set to last. */ + public int maxHurtTime; + + /** The yaw at which this entity was last attacked from. */ + public float attackedAtYaw = 0.0F; + + /** + * The amount of time remaining this entity should act 'dead', i.e. have a + * corpse in the world. + */ + public int deathTime = 0; + public int attackTime = 0; + public float prevCameraPitch; + public float cameraPitch; + + /** + * This gets set on entity death, but never used. Looks like a duplicate of + * isDead + */ + protected boolean dead = false; + + /** The experience points the Entity gives. */ + protected int experienceValue; + public int field_70731_aW = -1; + public float field_70730_aX = (float) (Math.random() * 0.8999999761581421D + 0.10000000149011612D); + public float prevLimbYaw; + public float limbYaw; + + /** + * Only relevant when limbYaw is not 0(the entity is moving). Influences where + * in its swing legs and arms currently are. + */ + public float limbSwing; + + /** The most recent player that has attacked this entity */ + protected EntityPlayer attackingPlayer = null; + + /** + * Set to 60 when hit by the player or the player's wolf, then decrements. Used + * to determine whether the entity should drop items on death. + */ + protected int recentlyHit = 0; + + /** is only being set, has no uses as of MC 1.1 */ + private EntityLiving entityLivingToAttack = null; + private int revengeTimer = 0; + private EntityLiving lastAttackingEntity = null; + public int arrowHitTimer = 0; + protected HashMap activePotionsMap = new HashMap(); + + /** Whether the DataWatcher needs to be updated with the active potions */ + private boolean potionsNeedUpdate = true; + private int field_70748_f; + private EntityLookHelper lookHelper; + private EntityMoveHelper moveHelper; + + /** Entity jumping helper */ + private EntityJumpHelper jumpHelper; + private EntityBodyHelper bodyHelper; + + /** The active target the Task system uses for tracking */ + private EntityLiving attackTarget; + private EntitySenses senses; + private float AIMoveSpeed; + private ChunkCoordinates homePosition = new ChunkCoordinates(0, 0, 0); + + /** If -1 there is no maximum distance */ + private float maximumHomeDistance = -1.0F; + + /** Equipment (armor and held item) for this entity. */ + private ItemStack[] equipment = new ItemStack[5]; + + /** Chances for each equipment piece from dropping when this entity dies. */ + protected float[] equipmentDropChances = new float[5]; + + /** The equipment this mob was previously wearing, used for syncing. */ + private ItemStack[] previousEquipment = new ItemStack[5]; + + /** Whether an arm swing is currently in progress. */ + public boolean isSwingInProgress = false; + public int swingProgressInt = 0; + + /** Whether this entity can pick up items from the ground. */ + private boolean canPickUpLoot = false; + + /** Whether this entity should NOT despawn. */ + private boolean persistenceRequired = false; + protected final CombatTracker field_94063_bt = new CombatTracker(this); + + /** + * The number of updates over which the new position and rotation are to be + * applied to the entity. + */ + protected int newPosRotationIncrements; + + /** The new X position to be applied to the entity. */ + protected double newPosX; + + /** The new Y position to be applied to the entity. */ + protected double newPosY; + + /** The new Z position to be applied to the entity. */ + protected double newPosZ; + + /** The new yaw rotation to be applied to the entity. */ + protected double newRotationYaw; + + /** The new yaw rotation to be applied to the entity. */ + protected double newRotationPitch; + float field_70706_bo = 0.0F; + + /** Amount of damage taken in last hit, in half-hearts */ + protected int lastDamage = 0; + + /** Holds the living entity age, used to control the despawn. */ + protected int entityAge = 0; + protected float moveStrafing; + protected float moveForward; + protected float randomYawVelocity; + + /** used to check whether entity is jumping. */ + protected boolean isJumping = false; + protected float defaultPitch = 0.0F; + protected float moveSpeed = 0.7F; + + /** Number of ticks since last jump */ + private int jumpTicks = 0; + + /** This entity's current target. */ + private Entity currentTarget; + + /** How long to keep a specific target entity */ + protected int numTicksToChaseTarget = 0; + + public EntityLiving() { + super(); + this.preventEntitySpawning = true; + this.lookHelper = new EntityLookHelper(this); + this.moveHelper = new EntityMoveHelper(this); + this.jumpHelper = new EntityJumpHelper(this); + this.bodyHelper = new EntityBodyHelper(this); + this.senses = new EntitySenses(this); + this.field_70770_ap = (float) (Math.random() + 1.0D) * 0.01F; + this.setPosition(this.posX, this.posY, this.posZ); + this.field_70769_ao = (float) Math.random() * 12398.0F; + this.rotationYaw = (float) (Math.random() * Math.PI * 2.0D); + this.rotationYawHead = this.rotationYaw; + + for (int var2 = 0; var2 < this.equipmentDropChances.length; ++var2) { + this.equipmentDropChances[var2] = 0.085F; + } + + this.stepHeight = 0.5F; + } + + protected int func_96121_ay() { + return 16; + } + + public EntityLookHelper getLookHelper() { + return this.lookHelper; + } + + public EntityMoveHelper getMoveHelper() { + return this.moveHelper; + } + + public EntityJumpHelper getJumpHelper() { + return this.jumpHelper; + } + + /** + * returns the EntitySenses Object for the EntityLiving + */ + public EntitySenses getEntitySenses() { + return this.senses; + } + + public Random getRNG() { + return this.rand; + } + + public EntityLiving getAITarget() { + return this.entityLivingToAttack; + } + + public EntityLiving getLastAttackingEntity() { + return this.lastAttackingEntity; + } + + public void setLastAttackingEntity(Entity par1Entity) { + if (par1Entity instanceof EntityLiving) { + this.lastAttackingEntity = (EntityLiving) par1Entity; + } + } + + public int getAge() { + return this.entityAge; + } + + public float getRotationYawHead() { + return this.rotationYawHead; + } + + /** + * Sets the head's yaw rotation of the entity. + */ + public void setRotationYawHead(float par1) { + this.rotationYawHead = par1; + } + + /** + * the movespeed used for the new AI system + */ + public float getAIMoveSpeed() { + return this.AIMoveSpeed; + } + + /** + * set the movespeed used for the new AI system + */ + public void setAIMoveSpeed(float par1) { + this.AIMoveSpeed = par1; + this.setMoveForward(par1); + } + + public boolean attackEntityAsMob(Entity par1Entity) { + this.setLastAttackingEntity(par1Entity); + return false; + } + + /** + * Gets the active target the Task system uses for tracking + */ + public EntityLiving getAttackTarget() { + return this.attackTarget; + } + + /** + * Sets the active target the Task system uses for tracking + */ + public void setAttackTarget(EntityLiving par1EntityLiving) { + this.attackTarget = par1EntityLiving; + } + + /** + * Returns true if this entity can attack entities of the specified class. + */ + public boolean canAttackClass(Class par1Class) { + return EntityCreeper.class != par1Class && EntityGhast.class != par1Class; + } + + /** + * This function applies the benefits of growing back wool and faster growing up + * to the acting entity. (This function is used in the AIEatGrass) + */ + public void eatGrassBonus() { + } + + /** + * Takes in the distance the entity has fallen this tick and whether its on the + * ground to update the fall distance and deal fall damage if landing on the + * ground. Args: distanceFallenThisTick, onGround + */ + protected void updateFallState(double par1, boolean par3) { + if (!this.isInWater()) { + this.handleWaterMovement(); + } + + if (par3 && this.fallDistance > 0.0F) { + int var4 = MathHelper.floor_double(this.posX); + int var5 = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double) this.yOffset); + int var6 = MathHelper.floor_double(this.posZ); + int var7 = this.worldObj.getBlockId(var4, var5, var6); + + if (var7 == 0) { + int var8 = this.worldObj.blockGetRenderType(var4, var5 - 1, var6); + + if (var8 == 11 || var8 == 32 || var8 == 21) { + var7 = this.worldObj.getBlockId(var4, var5 - 1, var6); + } + } + + if (var7 > 0) { + Block.blocksList[var7].onFallenUpon(this.worldObj, var4, var5, var6, this, this.fallDistance); + } + } + + super.updateFallState(par1, par3); + } + + /** + * Returns true if entity is within home distance from current position + */ + public boolean isWithinHomeDistanceCurrentPosition() { + return this.isWithinHomeDistance(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)); + } + + public boolean isWithinHomeDistance(int par1, int par2, int par3) { + return this.maximumHomeDistance == -1.0F ? true : this.homePosition.getDistanceSquared(par1, par2, par3) < this.maximumHomeDistance * this.maximumHomeDistance; + } + + public void setHomeArea(int par1, int par2, int par3, int par4) { + this.homePosition.set(par1, par2, par3); + this.maximumHomeDistance = (float) par4; + } + + public ChunkCoordinates getHomePosition() { + return this.homePosition; + } + + public float getMaximumHomeDistance() { + return this.maximumHomeDistance; + } + + public void detachHome() { + this.maximumHomeDistance = -1.0F; + } + + public boolean hasHome() { + return this.maximumHomeDistance != -1.0F; + } + + public void setRevengeTarget(EntityLiving par1EntityLiving) { + this.entityLivingToAttack = par1EntityLiving; + this.revengeTimer = this.entityLivingToAttack != null ? 100 : 0; + } + + protected void entityInit() { + this.dataWatcher.addObject(8, Integer.valueOf(this.field_70748_f)); + this.dataWatcher.addObject(9, Byte.valueOf((byte) 0)); + this.dataWatcher.addObject(10, Byte.valueOf((byte) 0)); + this.dataWatcher.addObject(6, Byte.valueOf((byte) 0)); + this.dataWatcher.addObject(5, ""); + } + + /** + * returns true if the entity provided in the argument can be seen. (Raytrace) + */ + public boolean canEntityBeSeen(Entity par1Entity) { + return this.worldObj.rayTraceBlocks(this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY + (double) this.getEyeHeight(), this.posZ), + this.worldObj.getWorldVec3Pool().getVecFromPool(par1Entity.posX, par1Entity.posY + (double) par1Entity.getEyeHeight(), par1Entity.posZ)) == null; + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return !this.isDead; + } + + /** + * Returns true if this entity should push and be pushed by other entities when + * colliding. + */ + public boolean canBePushed() { + return !this.isDead; + } + + public float getEyeHeight() { + return this.height * 0.85F; + } + + /** + * Get number of ticks, at least during which the living entity will be silent. + */ + public int getTalkInterval() { + return 80; + } + + /** + * Plays living's sound at its position + */ + public void playLivingSound() { + String var1 = this.getLivingSound(); + + if (var1 != null) { + this.playSound(var1, this.getSoundVolume(), this.getSoundPitch()); + } + } + + /** + * Gets called every tick from main Entity class + */ + public void onEntityUpdate() { + this.prevSwingProgress = this.swingProgress; + super.onEntityUpdate(); + this.worldObj.theProfiler.startSection("mobBaseTick"); + + if (this.isEntityAlive() && this.rand.nextInt(1000) < this.livingSoundTime++) { + this.livingSoundTime = -this.getTalkInterval(); + this.playLivingSound(); + } + + if (this.isEntityAlive() && this.isEntityInsideOpaqueBlock()) { + this.attackEntityFrom(DamageSource.inWall, 1); + } + + if (this.isImmuneToFire() || this.worldObj.isRemote) { + this.extinguish(); + } + + boolean var1 = this instanceof EntityPlayer && ((EntityPlayer) this).capabilities.disableDamage; + + if (this.isEntityAlive() && this.isInsideOfMaterial(Material.water) && !this.canBreatheUnderwater() && !this.activePotionsMap.containsKey(Integer.valueOf(Potion.waterBreathing.id)) && !var1) { + this.setAir(this.decreaseAirSupply(this.getAir())); + + if (this.getAir() == -20) { + this.setAir(0); + + for (int var2 = 0; var2 < 8; ++var2) { + float var3 = this.rand.nextFloat() - this.rand.nextFloat(); + float var4 = this.rand.nextFloat() - this.rand.nextFloat(); + float var5 = this.rand.nextFloat() - this.rand.nextFloat(); + this.worldObj.spawnParticle("bubble", this.posX + (double) var3, this.posY + (double) var4, this.posZ + (double) var5, this.motionX, this.motionY, this.motionZ); + } + + this.attackEntityFrom(DamageSource.drown, 2); + } + + this.extinguish(); + } else { + this.setAir(300); + } + + this.prevCameraPitch = this.cameraPitch; + + if (this.attackTime > 0) { + --this.attackTime; + } + + if (this.hurtTime > 0) { + --this.hurtTime; + } + + if (this.hurtResistantTime > 0) { + --this.hurtResistantTime; + } + + if (this.health <= 0) { + this.onDeathUpdate(); + } + + if (this.recentlyHit > 0) { + --this.recentlyHit; + } else { + this.attackingPlayer = null; + } + + if (this.lastAttackingEntity != null && !this.lastAttackingEntity.isEntityAlive()) { + this.lastAttackingEntity = null; + } + + if (this.entityLivingToAttack != null) { + if (!this.entityLivingToAttack.isEntityAlive()) { + this.setRevengeTarget((EntityLiving) null); + } else if (this.revengeTimer > 0) { + --this.revengeTimer; + } else { + this.setRevengeTarget((EntityLiving) null); + } + } + + this.updatePotionEffects(); + this.field_70763_ax = this.field_70764_aw; + this.prevRenderYawOffset = this.renderYawOffset; + this.prevRotationYawHead = this.rotationYawHead; + this.prevRotationYaw = this.rotationYaw; + this.prevRotationPitch = this.rotationPitch; + this.worldObj.theProfiler.endSection(); + } + + /** + * handles entity death timer, experience orb and particle creation + */ + protected void onDeathUpdate() { + ++this.deathTime; + + if (this.deathTime == 20) { + int var1; + + if (!this.worldObj.isRemote && (this.recentlyHit > 0 || this.isPlayer()) && !this.isChild() && this.worldObj.getGameRules().getGameRuleBooleanValue("doMobLoot")) { + var1 = this.getExperiencePoints(this.attackingPlayer); + + while (var1 > 0) { + int var2 = EntityXPOrb.getXPSplit(var1); + var1 -= var2; + this.worldObj.spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, var2)); + } + } + + this.setDead(); + + for (var1 = 0; var1 < 20; ++var1) { + double var8 = this.rand.nextGaussian() * 0.02D; + double var4 = this.rand.nextGaussian() * 0.02D; + double var6 = this.rand.nextGaussian() * 0.02D; + this.worldObj.spawnParticle("explode", this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, this.posY + (double) (this.rand.nextFloat() * this.height), + this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, var8, var4, var6); + } + } + } + + /** + * Decrements the entity's air supply when underwater + */ + protected int decreaseAirSupply(int par1) { + int var2 = EnchantmentHelper.getRespiration(this); + return var2 > 0 && this.rand.nextInt(var2 + 1) > 0 ? par1 : par1 - 1; + } + + /** + * Get the experience points the entity currently has. + */ + protected int getExperiencePoints(EntityPlayer par1EntityPlayer) { + if (this.experienceValue > 0) { + int var2 = this.experienceValue; + ItemStack[] var3 = this.getLastActiveItems(); + + for (int var4 = 0; var4 < var3.length; ++var4) { + if (var3[var4] != null && this.equipmentDropChances[var4] <= 1.0F) { + var2 += 1 + this.rand.nextInt(3); + } + } + + return var2; + } else { + return this.experienceValue; + } + } + + /** + * Only use is to identify if class is an instance of player for experience + * dropping + */ + protected boolean isPlayer() { + return false; + } + + /** + * Spawns an explosion particle around the Entity's location + */ + public void spawnExplosionParticle() { + for (int var1 = 0; var1 < 20; ++var1) { + double var2 = this.rand.nextGaussian() * 0.02D; + double var4 = this.rand.nextGaussian() * 0.02D; + double var6 = this.rand.nextGaussian() * 0.02D; + double var8 = 10.0D; + this.worldObj.spawnParticle("explode", this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width - var2 * var8, this.posY + (double) (this.rand.nextFloat() * this.height) - var4 * var8, + this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width - var6 * var8, var2, var4, var6); + } + } + + /** + * Handles updating while being ridden by an entity + */ + public void updateRidden() { + super.updateRidden(); + this.field_70768_au = this.field_70766_av; + this.field_70766_av = 0.0F; + this.fallDistance = 0.0F; + } + + /** + * Sets the position and rotation. Only difference from the other one is no + * bounding on the rotation. Args: posX, posY, posZ, yaw, pitch + */ + public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9) { + this.yOffset = 0.0F; + this.newPosX = par1; + this.newPosY = par3; + this.newPosZ = par5; + this.newRotationYaw = (double) par7; + this.newRotationPitch = (double) par8; + this.newPosRotationIncrements = par9; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + this.onLivingUpdate(); + double var12 = this.posX - this.prevPosX; + double var3 = this.posZ - this.prevPosZ; + float var5 = (float) (var12 * var12 + var3 * var3); + float var6 = this.renderYawOffset; + float var7 = 0.0F; + this.field_70768_au = this.field_70766_av; + float var8 = 0.0F; + + if (var5 > 0.0025000002F) { + var8 = 1.0F; + var7 = (float) Math.sqrt((double) var5) * 3.0F; + var6 = (float) Math.atan2(var3, var12) * 180.0F / (float) Math.PI - 90.0F; + } + + if (this.swingProgress > 0.0F) { + var6 = this.rotationYaw; + } + + if (!this.onGround) { + var8 = 0.0F; + } + + this.field_70766_av += (var8 - this.field_70766_av) * 0.3F; + this.worldObj.theProfiler.startSection("headTurn"); + + if (this.isAIEnabled()) { + this.bodyHelper.func_75664_a(); + } else { + float var9 = MathHelper.wrapAngleTo180_float(var6 - this.renderYawOffset); + this.renderYawOffset += var9 * 0.3F; + float var10 = MathHelper.wrapAngleTo180_float(this.rotationYaw - this.renderYawOffset); + boolean var11 = var10 < -90.0F || var10 >= 90.0F; + + if (var10 < -75.0F) { + var10 = -75.0F; + } + + if (var10 >= 75.0F) { + var10 = 75.0F; + } + + this.renderYawOffset = this.rotationYaw - var10; + + if (var10 * var10 > 2500.0F) { + this.renderYawOffset += var10 * 0.2F; + } + + if (var11) { + var7 *= -1.0F; + } + } + + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("rangeChecks"); + + while (this.rotationYaw - this.prevRotationYaw < -180.0F) { + this.prevRotationYaw -= 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { + this.prevRotationYaw += 360.0F; + } + + while (this.renderYawOffset - this.prevRenderYawOffset < -180.0F) { + this.prevRenderYawOffset -= 360.0F; + } + + while (this.renderYawOffset - this.prevRenderYawOffset >= 180.0F) { + this.prevRenderYawOffset += 360.0F; + } + + while (this.rotationPitch - this.prevRotationPitch < -180.0F) { + this.prevRotationPitch -= 360.0F; + } + + while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { + this.prevRotationPitch += 360.0F; + } + + while (this.rotationYawHead - this.prevRotationYawHead < -180.0F) { + this.prevRotationYawHead -= 360.0F; + } + + while (this.rotationYawHead - this.prevRotationYawHead >= 180.0F) { + this.prevRotationYawHead += 360.0F; + } + + this.worldObj.theProfiler.endSection(); + this.field_70764_aw += var7; + } + + /** + * Heal living entity (param: amount of half-hearts) + */ + public void heal(int par1) { + if (this.health > 0) { + this.setEntityHealth(this.getHealth() + par1); + + if (this.health > this.getMaxHealth()) { + this.setEntityHealth(this.getMaxHealth()); + } + + this.hurtResistantTime = this.maxHurtResistantTime / 2; + } + } + + public abstract int getMaxHealth(); + + public int getHealth() { + return this.health; + } + + public void setEntityHealth(int par1) { + this.health = par1; + + if (par1 > this.getMaxHealth()) { + par1 = this.getMaxHealth(); + } + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else if (this.worldObj.isRemote) { + return false; + } else { + this.entityAge = 0; + + if (this.health <= 0) { + return false; + } else if (par1DamageSource.isFireDamage() && this.isPotionActive(Potion.fireResistance)) { + return false; + } else { + if ((par1DamageSource == DamageSource.anvil || par1DamageSource == DamageSource.fallingBlock) && this.getCurrentItemOrArmor(4) != null) { + this.getCurrentItemOrArmor(4).damageItem(par2 * 4 + this.rand.nextInt(par2 * 2), this); + par2 = (int) ((float) par2 * 0.75F); + } + + this.limbYaw = 1.5F; + boolean var3 = true; + + if ((float) this.hurtResistantTime > (float) this.maxHurtResistantTime / 2.0F) { + if (par2 <= this.lastDamage) { + return false; + } + + this.damageEntity(par1DamageSource, par2 - this.lastDamage); + this.lastDamage = par2; + var3 = false; + } else { + this.lastDamage = par2; + this.prevHealth = this.health; + this.hurtResistantTime = this.maxHurtResistantTime; + this.damageEntity(par1DamageSource, par2); + this.hurtTime = this.maxHurtTime = 10; + } + + this.attackedAtYaw = 0.0F; + Entity var4 = par1DamageSource.getEntity(); + + if (var4 != null) { + if (var4 instanceof EntityLiving) { + this.setRevengeTarget((EntityLiving) var4); + } + + if (var4 instanceof EntityPlayer) { + this.recentlyHit = 100; + this.attackingPlayer = (EntityPlayer) var4; + } else if (var4 instanceof EntityWolf) { + EntityWolf var5 = (EntityWolf) var4; + + if (var5.isTamed()) { + this.recentlyHit = 100; + this.attackingPlayer = null; + } + } + } + + if (var3) { + this.worldObj.setEntityState(this, (byte) 2); + + if (par1DamageSource != DamageSource.drown) { + this.setBeenAttacked(); + } + + if (var4 != null) { + double var9 = var4.posX - this.posX; + double var7; + + for (var7 = var4.posZ - this.posZ; var9 * var9 + var7 * var7 < 1.0E-4D; var7 = (Math.random() - Math.random()) * 0.01D) { + var9 = (Math.random() - Math.random()) * 0.01D; + } + + this.attackedAtYaw = (float) (Math.atan2(var7, var9) * 180.0D / Math.PI) - this.rotationYaw; + this.knockBack(var4, par2, var9, var7); + } else { + this.attackedAtYaw = (float) ((int) (Math.random() * 2.0D) * 180); + } + } + + if (this.health <= 0) { + if (var3) { + this.playSound(this.getDeathSound(), this.getSoundVolume(), this.getSoundPitch()); + } + + this.onDeath(par1DamageSource); + } else if (var3) { + this.playSound(this.getHurtSound(), this.getSoundVolume(), this.getSoundPitch()); + } + + return true; + } + } + } + + /** + * Gets the pitch of living sounds in living entities. + */ + protected float getSoundPitch() { + return this.isChild() ? (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.5F : (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F; + } + + /** + * Setups the entity to do the hurt animation. Only used by packets in + * multiplayer. + */ + public void performHurtAnimation() { + this.hurtTime = this.maxHurtTime = 10; + this.attackedAtYaw = 0.0F; + } + + /** + * Returns the current armor value as determined by a call to + * InventoryPlayer.getTotalArmorValue + */ + public int getTotalArmorValue() { + int var1 = 0; + ItemStack[] var2 = this.getLastActiveItems(); + int var3 = var2.length; + + for (int var4 = 0; var4 < var3; ++var4) { + ItemStack var5 = var2[var4]; + + if (var5 != null && var5.getItem() instanceof ItemArmor) { + int var6 = ((ItemArmor) var5.getItem()).damageReduceAmount; + var1 += var6; + } + } + + return var1; + } + + protected void damageArmor(int par1) { + } + + /** + * Reduces damage, depending on armor + */ + protected int applyArmorCalculations(DamageSource par1DamageSource, int par2) { + if (!par1DamageSource.isUnblockable()) { + int var3 = 25 - this.getTotalArmorValue(); + int var4 = par2 * var3 + this.carryoverDamage; + this.damageArmor(par2); + par2 = var4 / 25; + this.carryoverDamage = var4 % 25; + } + + return par2; + } + + /** + * Reduces damage, depending on potions + */ + protected int applyPotionDamageCalculations(DamageSource par1DamageSource, int par2) { + int var3; + int var4; + int var5; + + if (this.isPotionActive(Potion.resistance)) { + var3 = (this.getActivePotionEffect(Potion.resistance).getAmplifier() + 1) * 5; + var4 = 25 - var3; + var5 = par2 * var4 + this.carryoverDamage; + par2 = var5 / 25; + this.carryoverDamage = var5 % 25; + } + + if (par2 <= 0) { + return 0; + } else { + var3 = EnchantmentHelper.getEnchantmentModifierDamage(this.getLastActiveItems(), par1DamageSource); + + if (var3 > 20) { + var3 = 20; + } + + if (var3 > 0 && var3 <= 20) { + var4 = 25 - var3; + var5 = par2 * var4 + this.carryoverDamage; + par2 = var5 / 25; + this.carryoverDamage = var5 % 25; + } + + return par2; + } + } + + /** + * Deals damage to the entity. If its a EntityPlayer then will take damage from + * the armor first and then health second with the reduced value. Args: + * damageAmount + */ + protected void damageEntity(DamageSource par1DamageSource, int par2) { + if (!this.isEntityInvulnerable()) { + par2 = this.applyArmorCalculations(par1DamageSource, par2); + par2 = this.applyPotionDamageCalculations(par1DamageSource, par2); + int var3 = this.getHealth(); + this.health -= par2; + this.field_94063_bt.func_94547_a(par1DamageSource, var3, par2); + } + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 1.0F; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return null; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "damage.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "damage.hit"; + } + + /** + * knocks back this entity + */ + public void knockBack(Entity par1Entity, int par2, double par3, double par5) { + this.isAirBorne = true; + float var7 = MathHelper.sqrt_double(par3 * par3 + par5 * par5); + float var8 = 0.4F; + this.motionX /= 2.0D; + this.motionY /= 2.0D; + this.motionZ /= 2.0D; + this.motionX -= par3 / (double) var7 * (double) var8; + this.motionY += (double) var8; + this.motionZ -= par5 / (double) var7 * (double) var8; + + if (this.motionY > 0.4000000059604645D) { + this.motionY = 0.4000000059604645D; + } + } + + /** + * Called when the mob's health reaches 0. + */ + public void onDeath(DamageSource par1DamageSource) { + Entity var2 = par1DamageSource.getEntity(); + EntityLiving var3 = this.func_94060_bK(); + + if (this.scoreValue >= 0 && var3 != null) { + var3.addToPlayerScore(this, this.scoreValue); + } + + if (var2 != null) { + var2.onKillEntity(this); + } + + this.dead = true; + + if (!this.worldObj.isRemote) { + int var4 = 0; + + if (var2 instanceof EntityPlayer) { + var4 = EnchantmentHelper.getLootingModifier((EntityLiving) var2); + } + + if (!this.isChild() && this.worldObj.getGameRules().getGameRuleBooleanValue("doMobLoot")) { + this.dropFewItems(this.recentlyHit > 0, var4); + this.dropEquipment(this.recentlyHit > 0, var4); + + if (this.recentlyHit > 0) { + int var5 = this.rand.nextInt(200) - var4; + + if (var5 < 5) { + this.dropRareDrop(var5 <= 0 ? 1 : 0); + } + } + } + } + + this.worldObj.setEntityState(this, (byte) 3); + } + + protected void dropRareDrop(int par1) { + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.getDropItemId(); + + if (var3 > 0) { + int var4 = this.rand.nextInt(3); + + if (par2 > 0) { + var4 += this.rand.nextInt(par2 + 1); + } + + for (int var5 = 0; var5 < var4; ++var5) { + this.dropItem(var3, 1); + } + } + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return 0; + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + super.fall(par1); + int var2 = MathHelper.ceiling_float_int(par1 - 3.0F); + + if (var2 > 0) { + if (var2 > 4) { + this.playSound("damage.fallbig", 1.0F, 1.0F); + } else { + this.playSound("damage.fallsmall", 1.0F, 1.0F); + } + + this.attackEntityFrom(DamageSource.fall, var2); + int var3 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY - 0.20000000298023224D - (double) this.yOffset), MathHelper.floor_double(this.posZ)); + + if (var3 > 0) { + StepSound var4 = Block.blocksList[var3].stepSound; + this.playSound(var4.getStepSound(), var4.getVolume() * 0.5F, var4.getPitch() * 0.75F); + } + } + } + + /** + * Moves the entity based on the specified heading. Args: strafe, forward + */ + public void moveEntityWithHeading(float par1, float par2) { + double var9; + + if (this.isInWater() && (!(this instanceof EntityPlayer) || !((EntityPlayer) this).capabilities.isFlying)) { + var9 = this.posY; + this.moveFlying(par1, par2, this.isAIEnabled() ? 0.04F : 0.02F); + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.800000011920929D; + this.motionY *= 0.800000011920929D; + this.motionZ *= 0.800000011920929D; + this.motionY -= 0.02D; + + if (this.isCollidedHorizontally && this.isOffsetPositionInLiquid(this.motionX, this.motionY + 0.6000000238418579D - this.posY + var9, this.motionZ)) { + this.motionY = 0.30000001192092896D; + } + } else if (this.handleLavaMovement() && (!(this instanceof EntityPlayer) || !((EntityPlayer) this).capabilities.isFlying)) { + var9 = this.posY; + this.moveFlying(par1, par2, 0.02F); + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.5D; + this.motionY *= 0.5D; + this.motionZ *= 0.5D; + this.motionY -= 0.02D; + + if (this.isCollidedHorizontally && this.isOffsetPositionInLiquid(this.motionX, this.motionY + 0.6000000238418579D - this.posY + var9, this.motionZ)) { + this.motionY = 0.30000001192092896D; + } + } else { + float var3 = 0.91F; + + if (this.onGround) { + var3 = 0.54600006F; + int var4 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)); + + if (var4 > 0) { + var3 = Block.blocksList[var4].slipperiness * 0.91F; + } + } + + float var8 = 0.16277136F / (var3 * var3 * var3); + float var5; + + if (this.onGround) { + if (this.isAIEnabled()) { + var5 = this.getAIMoveSpeed(); + } else { + var5 = this.landMovementFactor; + } + + var5 *= var8; + } else { + var5 = this.jumpMovementFactor; + } + + this.moveFlying(par1, par2, var5); + var3 = 0.91F; + + if (this.onGround) { + var3 = 0.54600006F; + int var6 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)); + + if (var6 > 0) { + var3 = Block.blocksList[var6].slipperiness * 0.91F; + } + } + + if (this.isOnLadder()) { + float var10 = 0.15F; + + if (this.motionX < (double) (-var10)) { + this.motionX = (double) (-var10); + } + + if (this.motionX > (double) var10) { + this.motionX = (double) var10; + } + + if (this.motionZ < (double) (-var10)) { + this.motionZ = (double) (-var10); + } + + if (this.motionZ > (double) var10) { + this.motionZ = (double) var10; + } + + this.fallDistance = 0.0F; + + if (this.motionY < -0.15D) { + this.motionY = -0.15D; + } + + boolean var7 = this.isSneaking() && this instanceof EntityPlayer; + + if (var7 && this.motionY < 0.0D) { + this.motionY = 0.0D; + } + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (this.isCollidedHorizontally && this.isOnLadder()) { + this.motionY = 0.2D; + } + + if (this.worldObj.isRemote && (!this.worldObj.blockExists((int) this.posX, 0, (int) this.posZ) || !this.worldObj.getChunkFromBlockCoords((int) this.posX, (int) this.posZ).isChunkLoaded)) { + if (this.posY > 0.0D) { + this.motionY = -0.1D; + } else { + this.motionY = 0.0D; + } + } else { + this.motionY -= 0.08D; + } + + this.motionY *= 0.9800000190734863D; + this.motionX *= (double) var3; + this.motionZ *= (double) var3; + } + + this.prevLimbYaw = this.limbYaw; + var9 = this.posX - this.prevPosX; + double var11 = this.posZ - this.prevPosZ; + float var12 = MathHelper.sqrt_double(var9 * var9 + var11 * var11) * 4.0F; + + if (var12 > 1.0F) { + var12 = 1.0F; + } + + this.limbYaw += (var12 - this.limbYaw) * 0.4F; + this.limbSwing += this.limbYaw; + } + + /** + * returns true if this entity is by a ladder, false otherwise + */ + public boolean isOnLadder() { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.boundingBox.minY); + int var3 = MathHelper.floor_double(this.posZ); + int var4 = this.worldObj.getBlockId(var1, var2, var3); + return var4 == Block.ladder.blockID || var4 == Block.vine.blockID; + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + if (this.health < -32768) { + this.health = -32768; + } + + par1NBTTagCompound.setShort("Health", (short) this.health); + par1NBTTagCompound.setShort("HurtTime", (short) this.hurtTime); + par1NBTTagCompound.setShort("DeathTime", (short) this.deathTime); + par1NBTTagCompound.setShort("AttackTime", (short) this.attackTime); + par1NBTTagCompound.setBoolean("CanPickUpLoot", this.canPickUpLoot()); + par1NBTTagCompound.setBoolean("PersistenceRequired", this.persistenceRequired); + NBTTagList var2 = new NBTTagList(); + + for (int var3 = 0; var3 < this.equipment.length; ++var3) { + NBTTagCompound var4 = new NBTTagCompound(); + + if (this.equipment[var3] != null) { + this.equipment[var3].writeToNBT(var4); + } + + var2.appendTag(var4); + } + + par1NBTTagCompound.setTag("Equipment", var2); + NBTTagList var6; + + if (!this.activePotionsMap.isEmpty()) { + var6 = new NBTTagList(); + Iterator var7 = this.activePotionsMap.values().iterator(); + + while (var7.hasNext()) { + PotionEffect var5 = (PotionEffect) var7.next(); + var6.appendTag(var5.writeCustomPotionEffectToNBT(new NBTTagCompound())); + } + + par1NBTTagCompound.setTag("ActiveEffects", var6); + } + + var6 = new NBTTagList(); + + for (int var8 = 0; var8 < this.equipmentDropChances.length; ++var8) { + var6.appendTag(new NBTTagFloat(var8 + "", this.equipmentDropChances[var8])); + } + + par1NBTTagCompound.setTag("DropChances", var6); + par1NBTTagCompound.setString("CustomName", this.func_94057_bL()); + par1NBTTagCompound.setBoolean("CustomNameVisible", this.func_94062_bN()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.health = par1NBTTagCompound.getShort("Health"); + + if (!par1NBTTagCompound.hasKey("Health")) { + this.health = this.getMaxHealth(); + } + + this.hurtTime = par1NBTTagCompound.getShort("HurtTime"); + this.deathTime = par1NBTTagCompound.getShort("DeathTime"); + this.attackTime = par1NBTTagCompound.getShort("AttackTime"); + this.setCanPickUpLoot(par1NBTTagCompound.getBoolean("CanPickUpLoot")); + this.persistenceRequired = par1NBTTagCompound.getBoolean("PersistenceRequired"); + + if (par1NBTTagCompound.hasKey("CustomName") && par1NBTTagCompound.getString("CustomName").length() > 0) { + this.func_94058_c(par1NBTTagCompound.getString("CustomName")); + } + + this.func_94061_f(par1NBTTagCompound.getBoolean("CustomNameVisible")); + NBTTagList var2; + int var3; + + if (par1NBTTagCompound.hasKey("Equipment")) { + var2 = par1NBTTagCompound.getTagList("Equipment"); + + for (var3 = 0; var3 < this.equipment.length; ++var3) { + this.equipment[var3] = ItemStack.loadItemStackFromNBT((NBTTagCompound) var2.tagAt(var3)); + } + } + + if (par1NBTTagCompound.hasKey("ActiveEffects")) { + var2 = par1NBTTagCompound.getTagList("ActiveEffects"); + + for (var3 = 0; var3 < var2.tagCount(); ++var3) { + NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3); + PotionEffect var5 = PotionEffect.readCustomPotionEffectFromNBT(var4); + this.activePotionsMap.put(Integer.valueOf(var5.getPotionID()), var5); + } + } + + if (par1NBTTagCompound.hasKey("DropChances")) { + var2 = par1NBTTagCompound.getTagList("DropChances"); + + for (var3 = 0; var3 < var2.tagCount(); ++var3) { + this.equipmentDropChances[var3] = ((NBTTagFloat) var2.tagAt(var3)).data; + } + } + } + + /** + * Checks whether target entity is alive. + */ + public boolean isEntityAlive() { + return !this.isDead && this.health > 0; + } + + public boolean canBreatheUnderwater() { + return false; + } + + public void setMoveForward(float par1) { + this.moveForward = par1; + } + + public void setJumping(boolean par1) { + this.isJumping = par1; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (this.jumpTicks > 0) { + --this.jumpTicks; + } + + if (this.newPosRotationIncrements > 0) { + double var1 = this.posX + (this.newPosX - this.posX) / (double) this.newPosRotationIncrements; + double var3 = this.posY + (this.newPosY - this.posY) / (double) this.newPosRotationIncrements; + double var5 = this.posZ + (this.newPosZ - this.posZ) / (double) this.newPosRotationIncrements; + double var7 = MathHelper.wrapAngleTo180_double(this.newRotationYaw - (double) this.rotationYaw); + this.rotationYaw = (float) ((double) this.rotationYaw + var7 / (double) this.newPosRotationIncrements); + this.rotationPitch = (float) ((double) this.rotationPitch + (this.newRotationPitch - (double) this.rotationPitch) / (double) this.newPosRotationIncrements); + --this.newPosRotationIncrements; + this.setPosition(var1, var3, var5); + this.setRotation(this.rotationYaw, this.rotationPitch); + } else if (!this.isClientWorld()) { + this.motionX *= 0.98D; + this.motionY *= 0.98D; + this.motionZ *= 0.98D; + } + + if (Math.abs(this.motionX) < 0.005D) { + this.motionX = 0.0D; + } + + if (Math.abs(this.motionY) < 0.005D) { + this.motionY = 0.0D; + } + + if (Math.abs(this.motionZ) < 0.005D) { + this.motionZ = 0.0D; + } + + this.worldObj.theProfiler.startSection("ai"); + + if (this.isMovementBlocked()) { + this.isJumping = false; + this.moveStrafing = 0.0F; + this.moveForward = 0.0F; + this.randomYawVelocity = 0.0F; + } else if (this.isClientWorld()) { + if (this.isAIEnabled()) { + this.worldObj.theProfiler.startSection("newAi"); + this.updateAITasks(); + this.worldObj.theProfiler.endSection(); + } else { + this.worldObj.theProfiler.startSection("oldAi"); + this.updateEntityActionState(); + this.worldObj.theProfiler.endSection(); + this.rotationYawHead = this.rotationYaw; + } + } + + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("jump"); + + if (this.isJumping) { + if (!this.isInWater() && !this.handleLavaMovement()) { + if (this.onGround && this.jumpTicks == 0) { + this.jump(); + this.jumpTicks = 10; + } + } else { + this.motionY += 0.03999999910593033D; + } + } else { + this.jumpTicks = 0; + } + + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("travel"); + this.moveStrafing *= 0.98F; + this.moveForward *= 0.98F; + this.randomYawVelocity *= 0.9F; + float var11 = this.landMovementFactor; + this.landMovementFactor *= this.getSpeedModifier(); + this.moveEntityWithHeading(this.moveStrafing, this.moveForward); + this.landMovementFactor = var11; + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("push"); + + if (!this.worldObj.isRemote) { + this.func_85033_bc(); + } + + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("looting"); + + if (!this.worldObj.isRemote && this.canPickUpLoot() && !this.dead && this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")) { + List var2 = this.worldObj.getEntitiesWithinAABB(EntityItem.class, this.boundingBox.expand(1.0D, 0.0D, 1.0D)); + Iterator var12 = var2.iterator(); + + while (var12.hasNext()) { + EntityItem var4 = (EntityItem) var12.next(); + + if (!var4.isDead && var4.getEntityItem() != null) { + ItemStack var13 = var4.getEntityItem(); + int var6 = getArmorPosition(var13); + + if (var6 > -1) { + boolean var14 = true; + ItemStack var8 = this.getCurrentItemOrArmor(var6); + + if (var8 != null) { + if (var6 == 0) { + if (var13.getItem() instanceof ItemSword && !(var8.getItem() instanceof ItemSword)) { + var14 = true; + } else if (var13.getItem() instanceof ItemSword && var8.getItem() instanceof ItemSword) { + ItemSword var9 = (ItemSword) var13.getItem(); + ItemSword var10 = (ItemSword) var8.getItem(); + + if (var9.func_82803_g() == var10.func_82803_g()) { + var14 = var13.getItemDamage() > var8.getItemDamage() || var13.hasTagCompound() && !var8.hasTagCompound(); + } else { + var14 = var9.func_82803_g() > var10.func_82803_g(); + } + } else { + var14 = false; + } + } else if (var13.getItem() instanceof ItemArmor && !(var8.getItem() instanceof ItemArmor)) { + var14 = true; + } else if (var13.getItem() instanceof ItemArmor && var8.getItem() instanceof ItemArmor) { + ItemArmor var15 = (ItemArmor) var13.getItem(); + ItemArmor var16 = (ItemArmor) var8.getItem(); + + if (var15.damageReduceAmount == var16.damageReduceAmount) { + var14 = var13.getItemDamage() > var8.getItemDamage() || var13.hasTagCompound() && !var8.hasTagCompound(); + } else { + var14 = var15.damageReduceAmount > var16.damageReduceAmount; + } + } else { + var14 = false; + } + } + + if (var14) { + if (var8 != null && this.rand.nextFloat() - 0.1F < this.equipmentDropChances[var6]) { + this.entityDropItem(var8, 0.0F); + } + + this.setCurrentItemOrArmor(var6, var13); + this.equipmentDropChances[var6] = 2.0F; + this.persistenceRequired = true; + this.onItemPickup(var4, 1); + var4.setDead(); + } + } + } + } + } + + this.worldObj.theProfiler.endSection(); + } + + protected void func_85033_bc() { + List var1 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + + if (var1 != null && !var1.isEmpty()) { + for (int var2 = 0; var2 < var1.size(); ++var2) { + Entity var3 = (Entity) var1.get(var2); + + if (var3.canBePushed()) { + this.collideWithEntity(var3); + } + } + } + } + + protected void collideWithEntity(Entity par1Entity) { + par1Entity.applyEntityCollision(this); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() { + return false; + } + + /** + * Returns whether the entity is in a local (client) world + */ + protected boolean isClientWorld() { + return !this.worldObj.isRemote; + } + + /** + * Dead and sleeping entities cannot move + */ + protected boolean isMovementBlocked() { + return this.health <= 0; + } + + public boolean isBlocking() { + return false; + } + + /** + * Causes this entity to do an upwards motion (jumping). + */ + protected void jump() { + this.motionY = 0.41999998688697815D; + + if (this.isPotionActive(Potion.jump)) { + this.motionY += (double) ((float) (this.getActivePotionEffect(Potion.jump).getAmplifier() + 1) * 0.1F); + } + + if (this.isSprinting()) { + float var1 = this.rotationYaw * 0.017453292F; + this.motionX -= (double) (MathHelper.sin(var1) * 0.2F); + this.motionZ += (double) (MathHelper.cos(var1) * 0.2F); + } + + this.isAirBorne = true; + } + + /** + * Determines if an entity can be despawned, used on idle far away entities + */ + protected boolean canDespawn() { + return true; + } + + /** + * Makes the entity despawn if requirements are reached + */ + protected void despawnEntity() { + if (!this.persistenceRequired) { + EntityPlayer var1 = this.worldObj.getClosestPlayerToEntity(this, -1.0D); + + if (var1 != null) { + double var2 = var1.posX - this.posX; + double var4 = var1.posY - this.posY; + double var6 = var1.posZ - this.posZ; + double var8 = var2 * var2 + var4 * var4 + var6 * var6; + + if (this.canDespawn() && var8 > 16384.0D) { + this.setDead(); + } + + if (this.entityAge > 600 && this.rand.nextInt(800) == 0 && var8 > 1024.0D && this.canDespawn()) { + this.setDead(); + } else if (var8 < 1024.0D) { + this.entityAge = 0; + } + } + } + } + + protected void updateAITasks() { + ++this.entityAge; + this.worldObj.theProfiler.startSection("checkDespawn"); + this.despawnEntity(); + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("sensing"); + this.senses.clearSensingCache(); + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("targetSelector"); + + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("goalSelector"); + + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("mob tick"); + this.updateAITick(); + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("controls"); + this.worldObj.theProfiler.startSection("move"); + this.moveHelper.onUpdateMoveHelper(); + this.worldObj.theProfiler.endStartSection("look"); + this.lookHelper.onUpdateLook(); + this.worldObj.theProfiler.endStartSection("jump"); + this.jumpHelper.doJump(); + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.endSection(); + } + + /** + * main AI tick function, replaces updateEntityActionState + */ + protected void updateAITick() { + } + + protected void updateEntityActionState() { + ++this.entityAge; + this.despawnEntity(); + this.moveStrafing = 0.0F; + this.moveForward = 0.0F; + float var1 = 8.0F; + + if (this.rand.nextFloat() < 0.02F) { + EntityPlayer var2 = this.worldObj.getClosestPlayerToEntity(this, (double) var1); + + if (var2 != null) { + this.currentTarget = var2; + this.numTicksToChaseTarget = 10 + this.rand.nextInt(20); + } else { + this.randomYawVelocity = (this.rand.nextFloat() - 0.5F) * 20.0F; + } + } + + if (this.currentTarget != null) { + this.faceEntity(this.currentTarget, 10.0F, (float) this.getVerticalFaceSpeed()); + + if (this.numTicksToChaseTarget-- <= 0 || this.currentTarget.isDead || this.currentTarget.getDistanceSqToEntity(this) > (double) (var1 * var1)) { + this.currentTarget = null; + } + } else { + if (this.rand.nextFloat() < 0.05F) { + this.randomYawVelocity = (this.rand.nextFloat() - 0.5F) * 20.0F; + } + + this.rotationYaw += this.randomYawVelocity; + this.rotationPitch = this.defaultPitch; + } + + boolean var4 = this.isInWater(); + boolean var3 = this.handleLavaMovement(); + + if (var4 || var3) { + this.isJumping = this.rand.nextFloat() < 0.8F; + } + } + + /** + * Updates the arm swing progress counters and animation progress + */ + protected void updateArmSwingProgress() { + int var1 = this.getArmSwingAnimationEnd(); + + if (this.isSwingInProgress) { + ++this.swingProgressInt; + + if (this.swingProgressInt >= var1) { + this.swingProgressInt = 0; + this.isSwingInProgress = false; + } + } else { + this.swingProgressInt = 0; + } + + this.swingProgress = (float) this.swingProgressInt / (float) var1; + } + + /** + * The speed it takes to move the entityliving's rotationPitch through the + * faceEntity method. This is only currently use in wolves. + */ + public int getVerticalFaceSpeed() { + return 40; + } + + /** + * Changes pitch and yaw so that the entity calling the function is facing the + * entity provided as an argument. + */ + public void faceEntity(Entity par1Entity, float par2, float par3) { + double var4 = par1Entity.posX - this.posX; + double var8 = par1Entity.posZ - this.posZ; + double var6; + + if (par1Entity instanceof EntityLiving) { + EntityLiving var10 = (EntityLiving) par1Entity; + var6 = var10.posY + (double) var10.getEyeHeight() - (this.posY + (double) this.getEyeHeight()); + } else { + var6 = (par1Entity.boundingBox.minY + par1Entity.boundingBox.maxY) / 2.0D - (this.posY + (double) this.getEyeHeight()); + } + + double var14 = (double) MathHelper.sqrt_double(var4 * var4 + var8 * var8); + float var12 = (float) (Math.atan2(var8, var4) * 180.0D / Math.PI) - 90.0F; + float var13 = (float) (-(Math.atan2(var6, var14) * 180.0D / Math.PI)); + this.rotationPitch = this.updateRotation(this.rotationPitch, var13, par3); + this.rotationYaw = this.updateRotation(this.rotationYaw, var12, par2); + } + + /** + * Arguments: current rotation, intended rotation, max increment. + */ + private float updateRotation(float par1, float par2, float par3) { + float var4 = MathHelper.wrapAngleTo180_float(par2 - par1); + + if (var4 > par3) { + var4 = par3; + } + + if (var4 < -par3) { + var4 = -par3; + } + + return par1 + var4; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + return this.worldObj.checkNoEntityCollision(this.boundingBox) && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() && !this.worldObj.isAnyLiquid(this.boundingBox); + } + + /** + * sets the dead flag. Used when you fall off the bottom of the world. + */ + protected void kill() { + this.attackEntityFrom(DamageSource.outOfWorld, 4); + } + + /** + * Returns where in the swing animation the living entity is (from 0 to 1). + * Args: partialTickTime + */ + public float getSwingProgress(float par1) { + float var2 = this.swingProgress - this.prevSwingProgress; + + if (var2 < 0.0F) { + ++var2; + } + + return this.prevSwingProgress + var2 * par1; + } + + /** + * interpolated position vector + */ + public Vec3 getPosition(float par1) { + if (par1 == 1.0F) { + return this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + } else { + double var2 = this.prevPosX + (this.posX - this.prevPosX) * (double) par1; + double var4 = this.prevPosY + (this.posY - this.prevPosY) * (double) par1; + double var6 = this.prevPosZ + (this.posZ - this.prevPosZ) * (double) par1; + return this.worldObj.getWorldVec3Pool().getVecFromPool(var2, var4, var6); + } + } + + /** + * returns a (normalized) vector of where this entity is looking + */ + public Vec3 getLookVec() { + return this.getLook(1.0F); + } + + /** + * interpolated look vector + */ + public Vec3 getLook(float par1) { + float var2; + float var3; + float var4; + float var5; + + if (par1 == 1.0F) { + var2 = MathHelper.cos(-this.rotationYaw * 0.017453292F - (float) Math.PI); + var3 = MathHelper.sin(-this.rotationYaw * 0.017453292F - (float) Math.PI); + var4 = -MathHelper.cos(-this.rotationPitch * 0.017453292F); + var5 = MathHelper.sin(-this.rotationPitch * 0.017453292F); + return this.worldObj.getWorldVec3Pool().getVecFromPool((double) (var3 * var4), (double) var5, (double) (var2 * var4)); + } else { + var2 = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * par1; + var3 = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * par1; + var4 = MathHelper.cos(-var3 * 0.017453292F - (float) Math.PI); + var5 = MathHelper.sin(-var3 * 0.017453292F - (float) Math.PI); + float var6 = -MathHelper.cos(-var2 * 0.017453292F); + float var7 = MathHelper.sin(-var2 * 0.017453292F); + return this.worldObj.getWorldVec3Pool().getVecFromPool((double) (var5 * var6), (double) var7, (double) (var4 * var6)); + } + } + + /** + * Returns render size modifier + */ + public float getRenderSizeModifier() { + return 1.0F; + } + + /** + * Performs a ray trace for the distance specified and using the partial tick + * time. Args: distance, partialTickTime + */ + public MovingObjectPosition rayTrace(double par1, float par3) { + Vec3 var4 = this.getPosition(par3); + Vec3 var5 = this.getLook(par3); + Vec3 var6 = var4.addVector(var5.xCoord * par1, var5.yCoord * par1, var5.zCoord * par1); + return this.worldObj.rayTraceBlocks(var4, var6); + } + + /** + * Will return how many at most can spawn in a chunk at once. + */ + public int getMaxSpawnedInChunk() { + return 4; + } + + public void handleHealthUpdate(byte par1) { + if (par1 == 2) { + this.limbYaw = 1.5F; + this.hurtResistantTime = this.maxHurtResistantTime; + this.hurtTime = this.maxHurtTime = 10; + this.attackedAtYaw = 0.0F; + this.playSound(this.getHurtSound(), this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F); + this.attackEntityFrom(DamageSource.generic, 0); + } else if (par1 == 3) { + this.playSound(this.getDeathSound(), this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F); + this.health = 0; + this.onDeath(DamageSource.generic); + } else { + super.handleHealthUpdate(par1); + } + } + + /** + * Returns whether player is sleeping or not + */ + public boolean isPlayerSleeping() { + return false; + } + + /** + * Gets the Icon Index of the item currently held + */ + public Icon getItemIcon(ItemStack par1ItemStack, int par2) { + return par1ItemStack.getIconIndex(); + } + + protected void updatePotionEffects() { + Iterator var1 = this.activePotionsMap.keySet().iterator(); + + while (var1.hasNext()) { + Integer var2 = (Integer) var1.next(); + PotionEffect var3 = (PotionEffect) this.activePotionsMap.get(var2); + + if (!var3.onUpdate(this)) { + if (!this.worldObj.isRemote) { + var1.remove(); + this.onFinishedPotionEffect(var3); + } + } else if (var3.getDuration() % 600 == 0) { + this.onChangedPotionEffect(var3); + } + } + + int var12; + + if (this.potionsNeedUpdate) { + if (!this.worldObj.isRemote) { + if (this.activePotionsMap.isEmpty()) { + this.dataWatcher.updateObject(9, Byte.valueOf((byte) 0)); + this.dataWatcher.updateObject(8, Integer.valueOf(0)); + this.setInvisible(false); + } else { + var12 = PotionHelper.calcPotionLiquidColor(this.activePotionsMap.values()); + this.dataWatcher.updateObject(9, Byte.valueOf((byte) (PotionHelper.func_82817_b(this.activePotionsMap.values()) ? 1 : 0))); + this.dataWatcher.updateObject(8, Integer.valueOf(var12)); + this.setInvisible(this.isPotionActive(Potion.invisibility.id)); + } + } + + this.potionsNeedUpdate = false; + } + + var12 = this.dataWatcher.getWatchableObjectInt(8); + boolean var13 = this.dataWatcher.getWatchableObjectByte(9) > 0; + + if (var12 > 0) { + boolean var4 = false; + + if (!this.isInvisible()) { + var4 = this.rand.nextBoolean(); + } else { + var4 = this.rand.nextInt(15) == 0; + } + + if (var13) { + var4 &= this.rand.nextInt(5) == 0; + } + + if (var4 && var12 > 0) { + double var14 = (double) (var12 >> 16 & 255) / 255.0D; + double var7 = (double) (var12 >> 8 & 255) / 255.0D; + double var9 = (double) (var12 >> 0 & 255) / 255.0D; + this.worldObj.spawnParticle(var13 ? "mobSpellAmbient" : "mobSpell", this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.width, this.posY + this.rand.nextDouble() * (double) this.height - (double) this.yOffset, + this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.width, var14, var7, var9); + } + } + } + + public void clearActivePotions() { + Iterator var1 = this.activePotionsMap.keySet().iterator(); + + while (var1.hasNext()) { + Integer var2 = (Integer) var1.next(); + PotionEffect var3 = (PotionEffect) this.activePotionsMap.get(var2); + + if (!this.worldObj.isRemote) { + var1.remove(); + this.onFinishedPotionEffect(var3); + } + } + } + + public Collection getActivePotionEffects() { + return this.activePotionsMap.values(); + } + + public boolean isPotionActive(int par1) { + return this.activePotionsMap.containsKey(Integer.valueOf(par1)); + } + + public boolean isPotionActive(Potion par1Potion) { + return this.activePotionsMap.containsKey(Integer.valueOf(par1Potion.id)); + } + + /** + * returns the PotionEffect for the supplied Potion if it is active, null + * otherwise. + */ + public PotionEffect getActivePotionEffect(Potion par1Potion) { + return (PotionEffect) this.activePotionsMap.get(Integer.valueOf(par1Potion.id)); + } + + /** + * adds a PotionEffect to the entity + */ + public void addPotionEffect(PotionEffect par1PotionEffect) { + if (this.isPotionApplicable(par1PotionEffect)) { + if (this.activePotionsMap.containsKey(Integer.valueOf(par1PotionEffect.getPotionID()))) { + ((PotionEffect) this.activePotionsMap.get(Integer.valueOf(par1PotionEffect.getPotionID()))).combine(par1PotionEffect); + this.onChangedPotionEffect((PotionEffect) this.activePotionsMap.get(Integer.valueOf(par1PotionEffect.getPotionID()))); + } else { + this.activePotionsMap.put(Integer.valueOf(par1PotionEffect.getPotionID()), par1PotionEffect); + this.onNewPotionEffect(par1PotionEffect); + } + } + } + + public boolean isPotionApplicable(PotionEffect par1PotionEffect) { + if (this.getCreatureAttribute() == EnumCreatureAttribute.UNDEAD) { + int var2 = par1PotionEffect.getPotionID(); + + if (var2 == Potion.regeneration.id || var2 == Potion.poison.id) { + return false; + } + } + + return true; + } + + /** + * Returns true if this entity is undead. + */ + public boolean isEntityUndead() { + return this.getCreatureAttribute() == EnumCreatureAttribute.UNDEAD; + } + + /** + * Remove the speified potion effect from this entity. + */ + public void removePotionEffectClient(int par1) { + this.activePotionsMap.remove(Integer.valueOf(par1)); + } + + /** + * Remove the specified potion effect from this entity. + */ + public void removePotionEffect(int par1) { + PotionEffect var2 = (PotionEffect) this.activePotionsMap.remove(Integer.valueOf(par1)); + + if (var2 != null) { + this.onFinishedPotionEffect(var2); + } + } + + protected void onNewPotionEffect(PotionEffect par1PotionEffect) { + this.potionsNeedUpdate = true; + } + + protected void onChangedPotionEffect(PotionEffect par1PotionEffect) { + this.potionsNeedUpdate = true; + } + + protected void onFinishedPotionEffect(PotionEffect par1PotionEffect) { + this.potionsNeedUpdate = true; + } + + /** + * This method returns a value to be applied directly to entity speed, this + * factor is less than 1 when a slowdown potion effect is applied, more than 1 + * when a haste potion effect is applied and 2 for fleeing entities. + */ + public float getSpeedModifier() { + float var1 = 1.0F; + + if (this.isPotionActive(Potion.moveSpeed)) { + var1 *= 1.0F + 0.2F * (float) (this.getActivePotionEffect(Potion.moveSpeed).getAmplifier() + 1); + } + + if (this.isPotionActive(Potion.moveSlowdown)) { + var1 *= 1.0F - 0.15F * (float) (this.getActivePotionEffect(Potion.moveSlowdown).getAmplifier() + 1); + } + + if (var1 < 0.0F) { + var1 = 0.0F; + } + + return var1; + } + + /** + * Move the entity to the coordinates informed, but keep yaw/pitch values. + */ + public void setPositionAndUpdate(double par1, double par3, double par5) { + this.setLocationAndAngles(par1, par3, par5, this.rotationYaw, this.rotationPitch); + } + + /** + * If Animal, checks if the age timer is negative + */ + public boolean isChild() { + return false; + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.UNDEFINED; + } + + /** + * Renders broken item particles using the given ItemStack + */ + public void renderBrokenItemStack(ItemStack par1ItemStack) { + this.playSound("random.break", 0.8F, 0.8F + this.worldObj.rand.nextFloat() * 0.4F); + + for (int var2 = 0; var2 < 5; ++var2) { + Vec3 var3 = this.worldObj.getWorldVec3Pool().getVecFromPool(((double) this.rand.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D); + var3.rotateAroundX(-this.rotationPitch * (float) Math.PI / 180.0F); + var3.rotateAroundY(-this.rotationYaw * (float) Math.PI / 180.0F); + Vec3 var4 = this.worldObj.getWorldVec3Pool().getVecFromPool(((double) this.rand.nextFloat() - 0.5D) * 0.3D, (double) (-this.rand.nextFloat()) * 0.6D - 0.3D, 0.6D); + var4.rotateAroundX(-this.rotationPitch * (float) Math.PI / 180.0F); + var4.rotateAroundY(-this.rotationYaw * (float) Math.PI / 180.0F); + var4 = var4.addVector(this.posX, this.posY + (double) this.getEyeHeight(), this.posZ); + this.worldObj.spawnParticle("iconcrack_" + par1ItemStack.getItem().itemID, var4.xCoord, var4.yCoord, var4.zCoord, var3.xCoord, var3.yCoord + 0.05D, var3.zCoord); + } + } + + public int func_82143_as() { + if (this.getAttackTarget() == null) { + return 3; + } else { + int var1 = (int) ((float) this.health - (float) this.getMaxHealth() * 0.33F); + var1 -= (3 - this.worldObj.difficultySetting) * 4; + + if (var1 < 0) { + var1 = 0; + } + + return var1 + 3; + } + } + + /** + * Returns the item that this EntityLiving is holding, if any. + */ + public ItemStack getHeldItem() { + return this.equipment[0]; + } + + /** + * 0 = item, 1-n is armor + */ + public ItemStack getCurrentItemOrArmor(int par1) { + return this.equipment[par1]; + } + + public ItemStack getCurrentArmor(int par1) { + return this.equipment[par1 + 1]; + } + + /** + * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. + * Params: Item, slot + */ + public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack) { + this.equipment[par1] = par2ItemStack; + } + + public ItemStack[] getLastActiveItems() { + return this.equipment; + } + + /** + * Drop the equipment for this entity. + */ + protected void dropEquipment(boolean par1, int par2) { + for (int var3 = 0; var3 < this.getLastActiveItems().length; ++var3) { + ItemStack var4 = this.getCurrentItemOrArmor(var3); + boolean var5 = this.equipmentDropChances[var3] > 1.0F; + + if (var4 != null && (par1 || var5) && this.rand.nextFloat() - (float) par2 * 0.01F < this.equipmentDropChances[var3]) { + if (!var5 && var4.isItemStackDamageable()) { + int var6 = Math.max(var4.getMaxDamage() - 25, 1); + int var7 = var4.getMaxDamage() - this.rand.nextInt(this.rand.nextInt(var6) + 1); + + if (var7 > var6) { + var7 = var6; + } + + if (var7 < 1) { + var7 = 1; + } + + var4.setItemDamage(var7); + } + + this.entityDropItem(var4, 0.0F); + } + } + } + + /** + * Makes entity wear random armor based on difficulty + */ + protected void addRandomArmor() { + if (this.rand.nextFloat() < armorProbability[this.worldObj.difficultySetting]) { + int var1 = this.rand.nextInt(2); + float var2 = this.worldObj.difficultySetting == 3 ? 0.1F : 0.25F; + + if (this.rand.nextFloat() < 0.095F) { + ++var1; + } + + if (this.rand.nextFloat() < 0.095F) { + ++var1; + } + + if (this.rand.nextFloat() < 0.095F) { + ++var1; + } + + for (int var3 = 3; var3 >= 0; --var3) { + ItemStack var4 = this.getCurrentArmor(var3); + + if (var3 < 3 && this.rand.nextFloat() < var2) { + break; + } + + if (var4 == null) { + Item var5 = getArmorItemForSlot(var3 + 1, var1); + + if (var5 != null) { + this.setCurrentItemOrArmor(var3 + 1, new ItemStack(var5)); + } + } + } + } + } + + /** + * Called whenever an item is picked up from walking over it. Args: + * pickedUpEntity, stackSize + */ + public void onItemPickup(Entity par1Entity, int par2) { + + } + + public static int getArmorPosition(ItemStack par0ItemStack) { + if (par0ItemStack.itemID != Block.pumpkin.blockID && par0ItemStack.itemID != Item.skull.itemID) { + if (par0ItemStack.getItem() instanceof ItemArmor) { + switch (((ItemArmor) par0ItemStack.getItem()).armorType) { + case 0: + return 4; + + case 1: + return 3; + + case 2: + return 2; + + case 3: + return 1; + } + } + + return 0; + } else { + return 4; + } + } + + /** + * Params: Armor slot, Item tier + */ + public static Item getArmorItemForSlot(int par0, int par1) { + switch (par0) { + case 4: + if (par1 == 0) { + return Item.helmetLeather; + } else if (par1 == 1) { + return Item.helmetGold; + } else if (par1 == 2) { + return Item.helmetChain; + } else if (par1 == 3) { + return Item.helmetIron; + } else if (par1 == 4) { + return Item.helmetDiamond; + } + + case 3: + if (par1 == 0) { + return Item.plateLeather; + } else if (par1 == 1) { + return Item.plateGold; + } else if (par1 == 2) { + return Item.plateChain; + } else if (par1 == 3) { + return Item.plateIron; + } else if (par1 == 4) { + return Item.plateDiamond; + } + + case 2: + if (par1 == 0) { + return Item.legsLeather; + } else if (par1 == 1) { + return Item.legsGold; + } else if (par1 == 2) { + return Item.legsChain; + } else if (par1 == 3) { + return Item.legsIron; + } else if (par1 == 4) { + return Item.legsDiamond; + } + + case 1: + if (par1 == 0) { + return Item.bootsLeather; + } else if (par1 == 1) { + return Item.bootsGold; + } else if (par1 == 2) { + return Item.bootsChain; + } else if (par1 == 3) { + return Item.bootsIron; + } else if (par1 == 4) { + return Item.bootsDiamond; + } + + default: + return null; + } + } + + protected void func_82162_bC() { + if (this.getHeldItem() != null && this.rand.nextFloat() < enchantmentProbability[this.worldObj.difficultySetting]) { + EnchantmentHelper.addRandomEnchantment(this.rand, this.getHeldItem(), 5 + this.worldObj.difficultySetting * this.rand.nextInt(6)); + } + + for (int var1 = 0; var1 < 4; ++var1) { + ItemStack var2 = this.getCurrentArmor(var1); + + if (var2 != null && this.rand.nextFloat() < armorEnchantmentProbability[this.worldObj.difficultySetting]) { + EnchantmentHelper.addRandomEnchantment(this.rand, var2, 5 + this.worldObj.difficultySetting * this.rand.nextInt(6)); + } + } + } + + /** + * Initialize this creature. + */ + public void initCreature() { + } + + /** + * Returns an integer indicating the end point of the swing animation, used by + * {@link #swingProgress} to provide a progress indicator. Takes dig speed + * enchantments into account. + */ + private int getArmSwingAnimationEnd() { + return this.isPotionActive(Potion.digSpeed) ? 6 - (1 + this.getActivePotionEffect(Potion.digSpeed).getAmplifier()) * 1 + : (this.isPotionActive(Potion.digSlowdown) ? 6 + (1 + this.getActivePotionEffect(Potion.digSlowdown).getAmplifier()) * 2 : 6); + } + + /** + * Swings the item the player is holding. + */ + public void swingItem() { + if (!this.isSwingInProgress || this.swingProgressInt >= this.getArmSwingAnimationEnd() / 2 || this.swingProgressInt < 0) { + this.swingProgressInt = -1; + this.isSwingInProgress = true; + } + } + + /** + * returns true if all the conditions for steering the entity are met. For pigs, + * this is true if it is being ridden by a player and the player is holding a + * carrot-on-a-stick + */ + public boolean canBeSteered() { + return false; + } + + /** + * counts the amount of arrows stuck in the entity. getting hit by arrows + * increases this, used in rendering + */ + public final int getArrowCountInEntity() { + return this.dataWatcher.getWatchableObjectByte(10); + } + + /** + * sets the amount of arrows stuck in the entity. used for rendering those + */ + public final void setArrowCountInEntity(int par1) { + this.dataWatcher.updateObject(10, Byte.valueOf((byte) par1)); + } + + public EntityLiving func_94060_bK() { + return (EntityLiving) (this.field_94063_bt.func_94550_c() != null ? this.field_94063_bt.func_94550_c() + : (this.attackingPlayer != null ? this.attackingPlayer : (this.entityLivingToAttack != null ? this.entityLivingToAttack : null))); + } + + /** + * Gets the username of the entity. + */ + public String getEntityName() { + return this.func_94056_bM() ? this.func_94057_bL() : super.getEntityName(); + } + + public void func_94058_c(String par1Str) { + this.dataWatcher.updateObject(5, par1Str); + } + + public String func_94057_bL() { + return this.dataWatcher.getWatchableObjectString(5); + } + + public boolean func_94056_bM() { + return this.dataWatcher.getWatchableObjectString(5).length() > 0; + } + + public void func_94061_f(boolean par1) { + this.dataWatcher.updateObject(6, Byte.valueOf((byte) (par1 ? 1 : 0))); + } + + public boolean func_94062_bN() { + return this.dataWatcher.getWatchableObjectByte(6) == 1; + } + + public boolean func_94059_bO() { + return this.func_94062_bN(); + } + + public void func_96120_a(int par1, float par2) { + this.equipmentDropChances[par1] = par2; + } + + public boolean canPickUpLoot() { + return this.canPickUpLoot; + } + + public void setCanPickUpLoot(boolean par1) { + this.canPickUpLoot = par1; + } + + public boolean func_104002_bU() { + return this.persistenceRequired; + } +} diff --git a/src/main/java/net/minecraft/src/EntityLookHelper.java b/src/main/java/net/minecraft/src/EntityLookHelper.java new file mode 100644 index 0000000..db4c24d --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityLookHelper.java @@ -0,0 +1,96 @@ +package net.minecraft.src; + + + +public class EntityLookHelper { + private EntityLiving entity; + + /** + * The amount of change that is made each update for an entity facing a + * direction. + */ + private float deltaLookYaw; + + /** + * The amount of change that is made each update for an entity facing a + * direction. + */ + private float deltaLookPitch; + + /** Whether or not the entity is trying to look at something. */ + private boolean isLooking = false; + private double posX; + private double posY; + private double posZ; + + public EntityLookHelper(EntityLiving par1EntityLiving) { + this.entity = par1EntityLiving; + } + + /** + * Sets position to look at using entity + */ + public void setLookPositionWithEntity(Entity par1Entity, float par2, float par3) { + this.posX = par1Entity.posX; + + if (par1Entity instanceof EntityLiving) { + this.posY = par1Entity.posY + (double) par1Entity.getEyeHeight(); + } else { + this.posY = (par1Entity.boundingBox.minY + par1Entity.boundingBox.maxY) / 2.0D; + } + + this.posZ = par1Entity.posZ; + this.deltaLookYaw = par2; + this.deltaLookPitch = par3; + this.isLooking = true; + } + + /** + * Sets position to look at + */ + public void setLookPosition(double par1, double par3, double par5, float par7, float par8) { + this.posX = par1; + this.posY = par3; + this.posZ = par5; + this.deltaLookYaw = par7; + this.deltaLookPitch = par8; + this.isLooking = true; + } + + /** + * Updates look + */ + public void onUpdateLook() { + this.entity.rotationPitch = 0.0F; + + if (this.isLooking) { + this.isLooking = false; + double var1 = this.posX - this.entity.posX; + double var3 = this.posY - (this.entity.posY + (double) this.entity.getEyeHeight()); + double var5 = this.posZ - this.entity.posZ; + double var7 = (double) MathHelper.sqrt_double(var1 * var1 + var5 * var5); + float var9 = (float) (Math.atan2(var5, var1) * 180.0D / Math.PI) - 90.0F; + float var10 = (float) (-(Math.atan2(var3, var7) * 180.0D / Math.PI)); + this.entity.rotationPitch = this.updateRotation(this.entity.rotationPitch, var10, this.deltaLookPitch); + this.entity.rotationYawHead = this.updateRotation(this.entity.rotationYawHead, var9, this.deltaLookYaw); + } else { + this.entity.rotationYawHead = this.updateRotation(this.entity.rotationYawHead, this.entity.renderYawOffset, 10.0F); + } + + float var11 = MathHelper.wrapAngleTo180_float(this.entity.rotationYawHead - this.entity.renderYawOffset); + } + + private float updateRotation(float par1, float par2, float par3) { + float var4 = MathHelper.wrapAngleTo180_float(par2 - par1); + + if (var4 > par3) { + var4 = par3; + } + + if (var4 < -par3) { + var4 = -par3; + } + + return par1 + var4; + } +} diff --git a/src/main/java/net/minecraft/src/EntityMagmaCube.java b/src/main/java/net/minecraft/src/EntityMagmaCube.java new file mode 100644 index 0000000..ea9e45f --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityMagmaCube.java @@ -0,0 +1,162 @@ +package net.minecraft.src; + +public class EntityMagmaCube extends EntitySlime { + public EntityMagmaCube() { + super(); + this.isImmuneToFire = true; + this.landMovementFactor = 0.2F; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + return this.worldObj.difficultySetting > 0 && this.worldObj.checkNoEntityCollision(this.boundingBox) && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() && !this.worldObj.isAnyLiquid(this.boundingBox); + } + + /** + * Returns the current armor value as determined by a call to + * InventoryPlayer.getTotalArmorValue + */ + public int getTotalArmorValue() { + return this.getSlimeSize() * 3; + } + + public int getBrightnessForRender(float par1) { + return 15728880; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + return 1.0F; + } + + /** + * Returns the name of a particle effect that may be randomly created by + * EntitySlime.onUpdate() + */ + protected String getSlimeParticle() { + return "flame"; + } + + protected EntitySlime createInstance() { + EntityMagmaCube c = new EntityMagmaCube(); + c.setWorld(worldObj); + return c; + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.magmaCream.itemID; + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.getDropItemId(); + + if (var3 > 0 && this.getSlimeSize() > 1) { + int var4 = this.rand.nextInt(4) - 2; + + if (par2 > 0) { + var4 += this.rand.nextInt(par2 + 1); + } + + for (int var5 = 0; var5 < var4; ++var5) { + this.dropItem(var3, 1); + } + } + } + + /** + * Returns true if the entity is on fire. Used by render to add the fire effect + * on rendering. + */ + public boolean isBurning() { + return false; + } + + /** + * Gets the amount of time the slime needs to wait between jumps. + */ + protected int getJumpDelay() { + return super.getJumpDelay() * 4; + } + + protected void func_70808_l() { + this.field_70813_a *= 0.9F; + } + + /** + * Causes this entity to do an upwards motion (jumping). + */ + protected void jump() { + this.motionY = (double) (0.42F + (float) this.getSlimeSize() * 0.1F); + this.isAirBorne = true; + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * Indicates weather the slime is able to damage the player (based upon the + * slime's size) + */ + protected boolean canDamagePlayer() { + return true; + } + + /** + * Gets the amount of damage dealt to the player when "attacked" by the slime. + */ + protected int getAttackStrength() { + return super.getAttackStrength() + 2; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.slime." + (this.getSlimeSize() > 1 ? "big" : "small"); + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.slime." + (this.getSlimeSize() > 1 ? "big" : "small"); + } + + /** + * Returns the name of the sound played when the slime jumps. + */ + protected String getJumpSound() { + return this.getSlimeSize() > 1 ? "mob.magmacube.big" : "mob.magmacube.small"; + } + + /** + * Whether or not the current entity is in lava + */ + public boolean handleLavaMovement() { + return false; + } + + /** + * Returns true if the slime makes a sound when it lands after a jump (based + * upon the slime's size) + */ + protected boolean makesSoundOnLand() { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/EntityMinecart.java b/src/main/java/net/minecraft/src/EntityMinecart.java new file mode 100644 index 0000000..0088259 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityMinecart.java @@ -0,0 +1,924 @@ +package net.minecraft.src; + +import java.util.List; + + + +public abstract class EntityMinecart extends Entity { + private boolean isInReverse; + private IUpdatePlayerListBox field_82344_g; + private String entityName; + + /** Minecart rotational logic matrix */ + private static final int[][][] matrix = 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 } } }; + + /** appears to be the progress of the turn */ + private int turnProgress; + private double minecartX; + private double minecartY; + private double minecartZ; + private double minecartYaw; + private double minecartPitch; + private double velocityX; + private double velocityY; + private double velocityZ; + + public EntityMinecart() { + super(); + this.isInReverse = false; + this.preventEntitySpawning = true; + this.setSize(0.98F, 0.7F); + this.yOffset = this.height / 2.0F; + } + + /** + * Creates a new minecart of the specified type in the specified location in the + * given world. par0World - world to create the minecart in, double + * par1,par3,par5 represent x,y,z respectively. int par7 specifies the type: 1 + * for MinecartChest, 2 for MinecartFurnace, 3 for MinecartTNT, 4 for + * MinecartMobSpawner, 5 for MinecartHopper and 0 for a standard empty minecart + */ + public static EntityMinecart createMinecart(World par0World, double par1, double par3, double par5, int par7) { + switch (par7) { + case 1: + return new EntityMinecartChest(par0World, par1, par3, par5); + + case 2: + return new EntityMinecartFurnace(par0World, par1, par3, par5); + + case 3: + return new EntityMinecartTNT(par0World, par1, par3, par5); + + case 4: + return new EntityMinecartMobSpawner(par0World, par1, par3, par5); + + case 5: + return new EntityMinecartHopper(par0World, par1, par3, par5); + + default: + return new EntityMinecartEmpty(par0World, par1, par3, par5); + } + } + + public void setWorld(World w) { + super.setWorld(w); + this.field_82344_g = w.func_82735_a(this); + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + protected void entityInit() { + this.dataWatcher.addObject(17, new Integer(0)); + this.dataWatcher.addObject(18, new Integer(1)); + this.dataWatcher.addObject(19, new Integer(0)); + this.dataWatcher.addObject(20, new Integer(0)); + this.dataWatcher.addObject(21, new Integer(6)); + this.dataWatcher.addObject(22, Byte.valueOf((byte) 0)); + } + + /** + * Returns a boundingBox used to collide the entity with other entities and + * blocks. This enables the entity to be pushable on contact, like boats or + * minecarts. + */ + public AxisAlignedBB getCollisionBox(Entity par1Entity) { + return par1Entity.canBePushed() ? par1Entity.boundingBox : null; + } + + /** + * returns the bounding box for this entity + */ + public AxisAlignedBB getBoundingBox() { + return null; + } + + /** + * Returns true if this entity should push and be pushed by other entities when + * colliding. + */ + public boolean canBePushed() { + return true; + } + + public EntityMinecart(World par1World, double par2, double par4, double par6) { + this(); + this.setWorld(par1World); + this.setPosition(par2, par4 + (double) this.yOffset, par6); + this.motionX = 0.0D; + this.motionY = 0.0D; + this.motionZ = 0.0D; + this.prevPosX = par2; + this.prevPosY = par4; + this.prevPosZ = par6; + } + + /** + * Returns the Y offset from the entity's position for any entity riding this + * one. + */ + public double getMountedYOffset() { + return (double) this.height * 0.0D - 0.30000001192092896D; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (!this.worldObj.isRemote && !this.isDead) { + if (this.isEntityInvulnerable()) { + return false; + } else { + this.setRollingDirection(-this.getRollingDirection()); + this.setRollingAmplitude(10); + this.setBeenAttacked(); + this.setDamage(this.getDamage() + par2 * 10); + boolean var3 = par1DamageSource.getEntity() instanceof EntityPlayer && ((EntityPlayer) par1DamageSource.getEntity()).capabilities.isCreativeMode; + + if (var3 || this.getDamage() > 40) { + if (this.riddenByEntity != null) { + this.riddenByEntity.mountEntity(this); + } + + if (var3 && !this.isInvNameLocalized()) { + this.setDead(); + } else { + this.killMinecart(par1DamageSource); + } + } + + return true; + } + } else { + return true; + } + } + + public void killMinecart(DamageSource par1DamageSource) { + this.setDead(); + ItemStack var2 = new ItemStack(Item.minecartEmpty, 1); + + if (this.entityName != null) { + var2.setItemName(this.entityName); + } + + this.entityDropItem(var2, 0.0F); + } + + /** + * Setups the entity to do the hurt animation. Only used by packets in + * multiplayer. + */ + public void performHurtAnimation() { + this.setRollingDirection(-this.getRollingDirection()); + this.setRollingAmplitude(10); + this.setDamage(this.getDamage() + this.getDamage() * 10); + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return !this.isDead; + } + + /** + * Will get destroyed next tick. + */ + public void setDead() { + super.setDead(); + + if (this.field_82344_g != null) { + this.field_82344_g.update(); + } + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (this.field_82344_g != null) { + this.field_82344_g.update(); + } + + if (this.getRollingAmplitude() > 0) { + this.setRollingAmplitude(this.getRollingAmplitude() - 1); + } + + if (this.getDamage() > 0) { + this.setDamage(this.getDamage() - 1); + } + + if (this.posY < -64.0D) { + this.kill(); + } + + int var2; + + if (this.worldObj.isRemote) { + if (this.turnProgress > 0) { + double var19 = this.posX + (this.minecartX - this.posX) / (double) this.turnProgress; + double var21 = this.posY + (this.minecartY - this.posY) / (double) this.turnProgress; + double var5 = this.posZ + (this.minecartZ - this.posZ) / (double) this.turnProgress; + double var7 = MathHelper.wrapAngleTo180_double(this.minecartYaw - (double) this.rotationYaw); + this.rotationYaw = (float) ((double) this.rotationYaw + var7 / (double) this.turnProgress); + this.rotationPitch = (float) ((double) this.rotationPitch + (this.minecartPitch - (double) this.rotationPitch) / (double) this.turnProgress); + --this.turnProgress; + this.setPosition(var19, var21, var5); + this.setRotation(this.rotationYaw, this.rotationPitch); + } else { + this.setPosition(this.posX, this.posY, this.posZ); + this.setRotation(this.rotationYaw, this.rotationPitch); + } + } else { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.motionY -= 0.03999999910593033D; + int var18 = MathHelper.floor_double(this.posX); + var2 = MathHelper.floor_double(this.posY); + int var20 = MathHelper.floor_double(this.posZ); + + if (BlockRailBase.isRailBlockAt(this.worldObj, var18, var2 - 1, var20)) { + --var2; + } + + double var4 = 0.4D; + double var6 = 0.0078125D; + int var8 = this.worldObj.getBlockId(var18, var2, var20); + + if (BlockRailBase.isRailBlock(var8)) { + int var9 = this.worldObj.getBlockMetadata(var18, var2, var20); + this.updateOnTrack(var18, var2, var20, var4, var6, var8, var9); + + if (var8 == Block.railActivator.blockID) { + this.onActivatorRailPass(var18, var2, var20, (var9 & 8) != 0); + } + } else { + this.func_94088_b(var4); + } + + this.doBlockCollisions(); + this.rotationPitch = 0.0F; + double var22 = this.prevPosX - this.posX; + double var11 = this.prevPosZ - this.posZ; + + if (var22 * var22 + var11 * var11 > 0.001D) { + this.rotationYaw = (float) (Math.atan2(var11, var22) * 180.0D / Math.PI); + + if (this.isInReverse) { + this.rotationYaw += 180.0F; + } + } + + double var13 = (double) MathHelper.wrapAngleTo180_float(this.rotationYaw - this.prevRotationYaw); + + if (var13 < -170.0D || var13 >= 170.0D) { + this.rotationYaw += 180.0F; + this.isInReverse = !this.isInReverse; + } + + this.setRotation(this.rotationYaw, this.rotationPitch); + List var15 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + + if (var15 != null && !var15.isEmpty()) { + for (int var16 = 0; var16 < var15.size(); ++var16) { + Entity var17 = (Entity) var15.get(var16); + + if (var17 != this.riddenByEntity && var17.canBePushed() && var17 instanceof EntityMinecart) { + var17.applyEntityCollision(this); + } + } + } + + if (this.riddenByEntity != null && this.riddenByEntity.isDead) { + if (this.riddenByEntity.ridingEntity == this) { + this.riddenByEntity.ridingEntity = null; + } + + this.riddenByEntity = null; + } + } + } + + /** + * Called every tick the minecart is on an activator rail. + */ + public void onActivatorRailPass(int par1, int par2, int par3, boolean par4) { + } + + protected void func_94088_b(double par1) { + if (this.motionX < -par1) { + this.motionX = -par1; + } + + if (this.motionX > par1) { + this.motionX = par1; + } + + if (this.motionZ < -par1) { + this.motionZ = -par1; + } + + if (this.motionZ > par1) { + this.motionZ = par1; + } + + if (this.onGround) { + this.motionX *= 0.5D; + this.motionY *= 0.5D; + this.motionZ *= 0.5D; + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (!this.onGround) { + this.motionX *= 0.949999988079071D; + this.motionY *= 0.949999988079071D; + this.motionZ *= 0.949999988079071D; + } + } + + protected void updateOnTrack(int par1, int par2, int par3, double par4, double par6, int par8, int par9) { + this.fallDistance = 0.0F; + Vec3 var10 = this.func_70489_a(this.posX, this.posY, this.posZ); + this.posY = (double) par2; + boolean var11 = false; + boolean var12 = false; + + if (par8 == Block.railPowered.blockID) { + var11 = (par9 & 8) != 0; + var12 = !var11; + } + + if (((BlockRailBase) Block.blocksList[par8]).isPowered()) { + par9 &= 7; + } + + if (par9 >= 2 && par9 <= 5) { + this.posY = (double) (par2 + 1); + } + + if (par9 == 2) { + this.motionX -= par6; + } + + if (par9 == 3) { + this.motionX += par6; + } + + if (par9 == 4) { + this.motionZ += par6; + } + + if (par9 == 5) { + this.motionZ -= par6; + } + + int[][] var13 = matrix[par9]; + double var14 = (double) (var13[1][0] - var13[0][0]); + double var16 = (double) (var13[1][2] - var13[0][2]); + double var18 = Math.sqrt(var14 * var14 + var16 * var16); + double var20 = this.motionX * var14 + this.motionZ * var16; + + if (var20 < 0.0D) { + var14 = -var14; + var16 = -var16; + } + + double var22 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + + if (var22 > 2.0D) { + var22 = 2.0D; + } + + this.motionX = var22 * var14 / var18; + this.motionZ = var22 * var16 / var18; + double var24; + double var26; + + if (this.riddenByEntity != null) { + var24 = this.riddenByEntity.motionX * this.riddenByEntity.motionX + this.riddenByEntity.motionZ * this.riddenByEntity.motionZ; + var26 = this.motionX * this.motionX + this.motionZ * this.motionZ; + + if (var24 > 1.0E-4D && var26 < 0.01D) { + this.motionX += this.riddenByEntity.motionX * 0.1D; + this.motionZ += this.riddenByEntity.motionZ * 0.1D; + var12 = false; + } + } + + if (var12) { + var24 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + + if (var24 < 0.03D) { + this.motionX *= 0.0D; + this.motionY *= 0.0D; + this.motionZ *= 0.0D; + } else { + this.motionX *= 0.5D; + this.motionY *= 0.0D; + this.motionZ *= 0.5D; + } + } + + var24 = 0.0D; + var26 = (double) par1 + 0.5D + (double) var13[0][0] * 0.5D; + double var28 = (double) par3 + 0.5D + (double) var13[0][2] * 0.5D; + double var30 = (double) par1 + 0.5D + (double) var13[1][0] * 0.5D; + double var32 = (double) par3 + 0.5D + (double) var13[1][2] * 0.5D; + var14 = var30 - var26; + var16 = var32 - var28; + double var34; + double var36; + + if (var14 == 0.0D) { + this.posX = (double) par1 + 0.5D; + var24 = this.posZ - (double) par3; + } else if (var16 == 0.0D) { + this.posZ = (double) par3 + 0.5D; + var24 = this.posX - (double) par1; + } else { + var34 = this.posX - var26; + var36 = this.posZ - var28; + var24 = (var34 * var14 + var36 * var16) * 2.0D; + } + + this.posX = var26 + var14 * var24; + this.posZ = var28 + var16 * var24; + this.setPosition(this.posX, this.posY + (double) this.yOffset, this.posZ); + var34 = this.motionX; + var36 = this.motionZ; + + if (this.riddenByEntity != null) { + var34 *= 0.75D; + var36 *= 0.75D; + } + + if (var34 < -par4) { + var34 = -par4; + } + + if (var34 > par4) { + var34 = par4; + } + + if (var36 < -par4) { + var36 = -par4; + } + + if (var36 > par4) { + var36 = par4; + } + + this.moveEntity(var34, 0.0D, var36); + + if (var13[0][1] != 0 && MathHelper.floor_double(this.posX) - par1 == var13[0][0] && MathHelper.floor_double(this.posZ) - par3 == var13[0][2]) { + this.setPosition(this.posX, this.posY + (double) var13[0][1], this.posZ); + } else if (var13[1][1] != 0 && MathHelper.floor_double(this.posX) - par1 == var13[1][0] && MathHelper.floor_double(this.posZ) - par3 == var13[1][2]) { + this.setPosition(this.posX, this.posY + (double) var13[1][1], this.posZ); + } + + this.applyDrag(); + Vec3 var38 = this.func_70489_a(this.posX, this.posY, this.posZ); + + if (var38 != null && var10 != null) { + double var39 = (var10.yCoord - var38.yCoord) * 0.05D; + var22 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + + if (var22 > 0.0D) { + this.motionX = this.motionX / var22 * (var22 + var39); + this.motionZ = this.motionZ / var22 * (var22 + var39); + } + + this.setPosition(this.posX, var38.yCoord, this.posZ); + } + + int var45 = MathHelper.floor_double(this.posX); + int var40 = MathHelper.floor_double(this.posZ); + + if (var45 != par1 || var40 != par3) { + var22 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.motionX = var22 * (double) (var45 - par1); + this.motionZ = var22 * (double) (var40 - par3); + } + + if (var11) { + double var41 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + + if (var41 > 0.01D) { + double var43 = 0.06D; + this.motionX += this.motionX / var41 * var43; + this.motionZ += this.motionZ / var41 * var43; + } else if (par9 == 1) { + if (this.worldObj.isBlockNormalCube(par1 - 1, par2, par3)) { + this.motionX = 0.02D; + } else if (this.worldObj.isBlockNormalCube(par1 + 1, par2, par3)) { + this.motionX = -0.02D; + } + } else if (par9 == 0) { + if (this.worldObj.isBlockNormalCube(par1, par2, par3 - 1)) { + this.motionZ = 0.02D; + } else if (this.worldObj.isBlockNormalCube(par1, par2, par3 + 1)) { + this.motionZ = -0.02D; + } + } + } + } + + protected void applyDrag() { + if (this.riddenByEntity != null) { + this.motionX *= 0.996999979019165D; + this.motionY *= 0.0D; + this.motionZ *= 0.996999979019165D; + } else { + this.motionX *= 0.9599999785423279D; + this.motionY *= 0.0D; + this.motionZ *= 0.9599999785423279D; + } + } + + public Vec3 func_70495_a(double par1, double par3, double par5, double par7) { + int var9 = MathHelper.floor_double(par1); + int var10 = MathHelper.floor_double(par3); + int var11 = MathHelper.floor_double(par5); + + if (BlockRailBase.isRailBlockAt(this.worldObj, var9, var10 - 1, var11)) { + --var10; + } + + int var12 = this.worldObj.getBlockId(var9, var10, var11); + + if (!BlockRailBase.isRailBlock(var12)) { + return null; + } else { + int var13 = this.worldObj.getBlockMetadata(var9, var10, var11); + + if (((BlockRailBase) Block.blocksList[var12]).isPowered()) { + var13 &= 7; + } + + par3 = (double) var10; + + if (var13 >= 2 && var13 <= 5) { + par3 = (double) (var10 + 1); + } + + int[][] var14 = matrix[var13]; + double var15 = (double) (var14[1][0] - var14[0][0]); + double var17 = (double) (var14[1][2] - var14[0][2]); + double var19 = Math.sqrt(var15 * var15 + var17 * var17); + var15 /= var19; + var17 /= var19; + par1 += var15 * par7; + par5 += var17 * par7; + + if (var14[0][1] != 0 && MathHelper.floor_double(par1) - var9 == var14[0][0] && MathHelper.floor_double(par5) - var11 == var14[0][2]) { + par3 += (double) var14[0][1]; + } else if (var14[1][1] != 0 && MathHelper.floor_double(par1) - var9 == var14[1][0] && MathHelper.floor_double(par5) - var11 == var14[1][2]) { + par3 += (double) var14[1][1]; + } + + return this.func_70489_a(par1, par3, par5); + } + } + + public Vec3 func_70489_a(double par1, double par3, double par5) { + int var7 = MathHelper.floor_double(par1); + int var8 = MathHelper.floor_double(par3); + int var9 = MathHelper.floor_double(par5); + + if (BlockRailBase.isRailBlockAt(this.worldObj, var7, var8 - 1, var9)) { + --var8; + } + + int var10 = this.worldObj.getBlockId(var7, var8, var9); + + if (BlockRailBase.isRailBlock(var10)) { + int var11 = this.worldObj.getBlockMetadata(var7, var8, var9); + par3 = (double) var8; + + if (((BlockRailBase) Block.blocksList[var10]).isPowered()) { + var11 &= 7; + } + + if (var11 >= 2 && var11 <= 5) { + par3 = (double) (var8 + 1); + } + + int[][] var12 = matrix[var11]; + double var13 = 0.0D; + double var15 = (double) var7 + 0.5D + (double) var12[0][0] * 0.5D; + double var17 = (double) var8 + 0.5D + (double) var12[0][1] * 0.5D; + double var19 = (double) var9 + 0.5D + (double) var12[0][2] * 0.5D; + double var21 = (double) var7 + 0.5D + (double) var12[1][0] * 0.5D; + double var23 = (double) var8 + 0.5D + (double) var12[1][1] * 0.5D; + double var25 = (double) var9 + 0.5D + (double) var12[1][2] * 0.5D; + double var27 = var21 - var15; + double var29 = (var23 - var17) * 2.0D; + double var31 = var25 - var19; + + if (var27 == 0.0D) { + par1 = (double) var7 + 0.5D; + var13 = par5 - (double) var9; + } else if (var31 == 0.0D) { + par5 = (double) var9 + 0.5D; + var13 = par1 - (double) var7; + } else { + double var33 = par1 - var15; + double var35 = par5 - var19; + var13 = (var33 * var27 + var35 * var31) * 2.0D; + } + + par1 = var15 + var27 * var13; + par3 = var17 + var29 * var13; + par5 = var19 + var31 * var13; + + if (var29 < 0.0D) { + ++par3; + } + + if (var29 > 0.0D) { + par3 += 0.5D; + } + + return this.worldObj.getWorldVec3Pool().getVecFromPool(par1, par3, par5); + } else { + return null; + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + if (par1NBTTagCompound.getBoolean("CustomDisplayTile")) { + this.setDisplayTile(par1NBTTagCompound.getInteger("DisplayTile")); + this.setDisplayTileData(par1NBTTagCompound.getInteger("DisplayData")); + this.setDisplayTileOffset(par1NBTTagCompound.getInteger("DisplayOffset")); + } + + if (par1NBTTagCompound.hasKey("CustomName") && par1NBTTagCompound.getString("CustomName").length() > 0) { + this.entityName = par1NBTTagCompound.getString("CustomName"); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + if (this.hasDisplayTile()) { + par1NBTTagCompound.setBoolean("CustomDisplayTile", true); + par1NBTTagCompound.setInteger("DisplayTile", this.getDisplayTile() == null ? 0 : this.getDisplayTile().blockID); + par1NBTTagCompound.setInteger("DisplayData", this.getDisplayTileData()); + par1NBTTagCompound.setInteger("DisplayOffset", this.getDisplayTileOffset()); + } + + if (this.entityName != null && this.entityName.length() > 0) { + par1NBTTagCompound.setString("CustomName", this.entityName); + } + } + + public float getShadowSize() { + return 0.0F; + } + + /** + * Applies a velocity to each of the entities pushing them away from each other. + * Args: entity + */ + public void applyEntityCollision(Entity par1Entity) { + if (!this.worldObj.isRemote) { + if (par1Entity != this.riddenByEntity) { + if (par1Entity instanceof EntityLiving && !(par1Entity instanceof EntityPlayer) && !(par1Entity instanceof EntityIronGolem) && this.getMinecartType() == 0 && this.motionX * this.motionX + this.motionZ * this.motionZ > 0.01D + && this.riddenByEntity == null && par1Entity.ridingEntity == null) { + par1Entity.mountEntity(this); + } + + double var2 = par1Entity.posX - this.posX; + double var4 = par1Entity.posZ - this.posZ; + double var6 = var2 * var2 + var4 * var4; + + if (var6 >= 9.999999747378752E-5D) { + var6 = (double) MathHelper.sqrt_double(var6); + var2 /= var6; + var4 /= var6; + double var8 = 1.0D / var6; + + if (var8 > 1.0D) { + var8 = 1.0D; + } + + var2 *= var8; + var4 *= var8; + var2 *= 0.10000000149011612D; + var4 *= 0.10000000149011612D; + var2 *= (double) (1.0F - this.entityCollisionReduction); + var4 *= (double) (1.0F - this.entityCollisionReduction); + var2 *= 0.5D; + var4 *= 0.5D; + + if (par1Entity instanceof EntityMinecart) { + double var10 = par1Entity.posX - this.posX; + double var12 = par1Entity.posZ - this.posZ; + Vec3 var14 = this.worldObj.getWorldVec3Pool().getVecFromPool(var10, 0.0D, var12).normalize(); + Vec3 var15 = this.worldObj.getWorldVec3Pool().getVecFromPool((double) MathHelper.cos(this.rotationYaw * (float) Math.PI / 180.0F), 0.0D, (double) MathHelper.sin(this.rotationYaw * (float) Math.PI / 180.0F)) + .normalize(); + double var16 = Math.abs(var14.dotProduct(var15)); + + if (var16 < 0.800000011920929D) { + return; + } + + double var18 = par1Entity.motionX + this.motionX; + double var20 = par1Entity.motionZ + this.motionZ; + + if (((EntityMinecart) par1Entity).getMinecartType() == 2 && this.getMinecartType() != 2) { + this.motionX *= 0.20000000298023224D; + this.motionZ *= 0.20000000298023224D; + this.addVelocity(par1Entity.motionX - var2, 0.0D, par1Entity.motionZ - var4); + par1Entity.motionX *= 0.949999988079071D; + par1Entity.motionZ *= 0.949999988079071D; + } else if (((EntityMinecart) par1Entity).getMinecartType() != 2 && this.getMinecartType() == 2) { + par1Entity.motionX *= 0.20000000298023224D; + par1Entity.motionZ *= 0.20000000298023224D; + par1Entity.addVelocity(this.motionX + var2, 0.0D, this.motionZ + var4); + this.motionX *= 0.949999988079071D; + this.motionZ *= 0.949999988079071D; + } else { + var18 /= 2.0D; + var20 /= 2.0D; + this.motionX *= 0.20000000298023224D; + this.motionZ *= 0.20000000298023224D; + this.addVelocity(var18 - var2, 0.0D, var20 - var4); + par1Entity.motionX *= 0.20000000298023224D; + par1Entity.motionZ *= 0.20000000298023224D; + par1Entity.addVelocity(var18 + var2, 0.0D, var20 + var4); + } + } else { + this.addVelocity(-var2, 0.0D, -var4); + par1Entity.addVelocity(var2 / 4.0D, 0.0D, var4 / 4.0D); + } + } + } + } + } + + /** + * Sets the position and rotation. Only difference from the other one is no + * bounding on the rotation. Args: posX, posY, posZ, yaw, pitch + */ + public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9) { + this.minecartX = par1; + this.minecartY = par3; + this.minecartZ = par5; + this.minecartYaw = (double) par7; + this.minecartPitch = (double) par8; + this.turnProgress = par9 + 2; + this.motionX = this.velocityX; + this.motionY = this.velocityY; + this.motionZ = this.velocityZ; + } + + /** + * Sets the velocity to the args. Args: x, y, z + */ + public void setVelocity(double par1, double par3, double par5) { + this.velocityX = this.motionX = par1; + this.velocityY = this.motionY = par3; + this.velocityZ = this.motionZ = par5; + } + + /** + * Sets the current amount of damage the minecart has taken. Decreases over + * time. The cart breaks when this is over 40. + */ + public void setDamage(int par1) { + this.dataWatcher.updateObject(19, Integer.valueOf(par1)); + } + + /** + * Gets the current amount of damage the minecart has taken. Decreases over + * time. The cart breaks when this is over 40. + */ + public int getDamage() { + return this.dataWatcher.getWatchableObjectInt(19); + } + + /** + * Sets the rolling amplitude the cart rolls while being attacked. + */ + public void setRollingAmplitude(int par1) { + this.dataWatcher.updateObject(17, Integer.valueOf(par1)); + } + + /** + * Gets the rolling amplitude the cart rolls while being attacked. + */ + public int getRollingAmplitude() { + return this.dataWatcher.getWatchableObjectInt(17); + } + + /** + * Sets the rolling direction the cart rolls while being attacked. Can be 1 or + * -1. + */ + public void setRollingDirection(int par1) { + this.dataWatcher.updateObject(18, Integer.valueOf(par1)); + } + + /** + * Gets the rolling direction the cart rolls while being attacked. Can be 1 or + * -1. + */ + public int getRollingDirection() { + return this.dataWatcher.getWatchableObjectInt(18); + } + + public abstract int getMinecartType(); + + public Block getDisplayTile() { + if (!this.hasDisplayTile()) { + return this.getDefaultDisplayTile(); + } else { + int var1 = this.getDataWatcher().getWatchableObjectInt(20) & 65535; + return var1 > 0 && var1 < Block.blocksList.length ? Block.blocksList[var1] : null; + } + } + + public Block getDefaultDisplayTile() { + return null; + } + + public int getDisplayTileData() { + return !this.hasDisplayTile() ? this.getDefaultDisplayTileData() : this.getDataWatcher().getWatchableObjectInt(20) >> 16; + } + + public int getDefaultDisplayTileData() { + return 0; + } + + public int getDisplayTileOffset() { + return !this.hasDisplayTile() ? this.getDefaultDisplayTileOffset() : this.getDataWatcher().getWatchableObjectInt(21); + } + + public int getDefaultDisplayTileOffset() { + return 6; + } + + public void setDisplayTile(int par1) { + this.getDataWatcher().updateObject(20, Integer.valueOf(par1 & 65535 | this.getDisplayTileData() << 16)); + this.setHasDisplayTile(true); + } + + public void setDisplayTileData(int par1) { + Block var2 = this.getDisplayTile(); + int var3 = var2 == null ? 0 : var2.blockID; + this.getDataWatcher().updateObject(20, Integer.valueOf(var3 & 65535 | par1 << 16)); + this.setHasDisplayTile(true); + } + + public void setDisplayTileOffset(int par1) { + this.getDataWatcher().updateObject(21, Integer.valueOf(par1)); + this.setHasDisplayTile(true); + } + + public boolean hasDisplayTile() { + return this.getDataWatcher().getWatchableObjectByte(22) == 1; + } + + public void setHasDisplayTile(boolean par1) { + this.getDataWatcher().updateObject(22, Byte.valueOf((byte) (par1 ? 1 : 0))); + } + + public void func_96094_a(String par1Str) { + this.entityName = par1Str; + } + + /** + * Gets the username of the entity. + */ + public String getEntityName() { + return this.entityName != null ? this.entityName : super.getEntityName(); + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return this.entityName != null; + } + + public String func_95999_t() { + return this.entityName; + } +} diff --git a/src/main/java/net/minecraft/src/EntityMinecartChest.java b/src/main/java/net/minecraft/src/EntityMinecartChest.java new file mode 100644 index 0000000..e77eb4d --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityMinecartChest.java @@ -0,0 +1,32 @@ +package net.minecraft.src; + +public class EntityMinecartChest extends EntityMinecartContainer { + + public EntityMinecartChest(World par1, double par2, double par4, double par6) { + super(par1, par2, par4, par6); + } + + public void killMinecart(DamageSource par1DamageSource) { + super.killMinecart(par1DamageSource); + this.dropItemWithOffset(Block.chest.blockID, 1, 0.0F); + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return 27; + } + + public int getMinecartType() { + return 1; + } + + public Block getDefaultDisplayTile() { + return Block.chest; + } + + public int getDefaultDisplayTileOffset() { + return 8; + } +} diff --git a/src/main/java/net/minecraft/src/EntityMinecartContainer.java b/src/main/java/net/minecraft/src/EntityMinecartContainer.java new file mode 100644 index 0000000..02a2612 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityMinecartContainer.java @@ -0,0 +1,257 @@ +package net.minecraft.src; + +public abstract class EntityMinecartContainer extends EntityMinecart implements IInventory { + private ItemStack[] minecartContainerItems = new ItemStack[36]; + + /** + * When set to true, the minecart will drop all items when setDead() is called. + * When false (such as when travelling dimensions) it preserves its contents. + */ + private boolean dropContentsWhenDead = true; + + public EntityMinecartContainer() { + super(); + } + + public EntityMinecartContainer(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + } + + public void killMinecart(DamageSource par1DamageSource) { + super.killMinecart(par1DamageSource); + + for (int var2 = 0; var2 < this.getSizeInventory(); ++var2) { + ItemStack var3 = this.getStackInSlot(var2); + + if (var3 != null) { + float var4 = this.rand.nextFloat() * 0.8F + 0.1F; + float var5 = this.rand.nextFloat() * 0.8F + 0.1F; + float var6 = this.rand.nextFloat() * 0.8F + 0.1F; + + while (var3.stackSize > 0) { + int var7 = this.rand.nextInt(21) + 10; + + if (var7 > var3.stackSize) { + var7 = var3.stackSize; + } + + var3.stackSize -= var7; + EntityItem var8 = new EntityItem(this.worldObj, this.posX + (double) var4, this.posY + (double) var5, this.posZ + (double) var6, new ItemStack(var3.itemID, var7, var3.getItemDamage())); + float var9 = 0.05F; + var8.motionX = (double) ((float) this.rand.nextGaussian() * var9); + var8.motionY = (double) ((float) this.rand.nextGaussian() * var9 + 0.2F); + var8.motionZ = (double) ((float) this.rand.nextGaussian() * var9); + this.worldObj.spawnEntityInWorld(var8); + } + } + } + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return this.minecartContainerItems[par1]; + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (this.minecartContainerItems[par1] != null) { + ItemStack var3; + + if (this.minecartContainerItems[par1].stackSize <= par2) { + var3 = this.minecartContainerItems[par1]; + this.minecartContainerItems[par1] = null; + return var3; + } else { + var3 = this.minecartContainerItems[par1].splitStack(par2); + + if (this.minecartContainerItems[par1].stackSize == 0) { + this.minecartContainerItems[par1] = null; + } + + return var3; + } + } else { + return null; + } + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (this.minecartContainerItems[par1] != null) { + ItemStack var2 = this.minecartContainerItems[par1]; + this.minecartContainerItems[par1] = null; + return var2; + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + this.minecartContainerItems[par1] = par2ItemStack; + + if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) { + par2ItemStack.stackSize = this.getInventoryStackLimit(); + } + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.isDead ? false : par1EntityPlayer.getDistanceSqToEntity(this) <= 64.0D; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return this.isInvNameLocalized() ? this.func_95999_t() : "container.minecart"; + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Teleports the entity to another dimension. Params: Dimension number to + * teleport to + */ + public void travelToDimension(int par1) { + this.dropContentsWhenDead = false; + super.travelToDimension(par1); + } + + /** + * Will get destroyed next tick. + */ + public void setDead() { + if (this.dropContentsWhenDead) { + for (int var1 = 0; var1 < this.getSizeInventory(); ++var1) { + ItemStack var2 = this.getStackInSlot(var1); + + if (var2 != null) { + float var3 = this.rand.nextFloat() * 0.8F + 0.1F; + float var4 = this.rand.nextFloat() * 0.8F + 0.1F; + float var5 = this.rand.nextFloat() * 0.8F + 0.1F; + + while (var2.stackSize > 0) { + int var6 = this.rand.nextInt(21) + 10; + + if (var6 > var2.stackSize) { + var6 = var2.stackSize; + } + + var2.stackSize -= var6; + EntityItem var7 = new EntityItem(this.worldObj, this.posX + (double) var3, this.posY + (double) var4, this.posZ + (double) var5, new ItemStack(var2.itemID, var6, var2.getItemDamage())); + + if (var2.hasTagCompound()) { + var7.getEntityItem().setTagCompound((NBTTagCompound) var2.getTagCompound().copy()); + } + + float var8 = 0.05F; + var7.motionX = (double) ((float) this.rand.nextGaussian() * var8); + var7.motionY = (double) ((float) this.rand.nextGaussian() * var8 + 0.2F); + var7.motionZ = (double) ((float) this.rand.nextGaussian() * var8); + this.worldObj.spawnEntityInWorld(var7); + } + } + } + } + + super.setDead(); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + NBTTagList var2 = new NBTTagList(); + + for (int var3 = 0; var3 < this.minecartContainerItems.length; ++var3) { + if (this.minecartContainerItems[var3] != null) { + NBTTagCompound var4 = new NBTTagCompound(); + var4.setByte("Slot", (byte) var3); + this.minecartContainerItems[var3].writeToNBT(var4); + var2.appendTag(var4); + } + } + + par1NBTTagCompound.setTag("Items", var2); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + NBTTagList var2 = par1NBTTagCompound.getTagList("Items"); + this.minecartContainerItems = new ItemStack[this.getSizeInventory()]; + + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3); + int var5 = var4.getByte("Slot") & 255; + + if (var5 >= 0 && var5 < this.minecartContainerItems.length) { + this.minecartContainerItems[var5] = ItemStack.loadItemStackFromNBT(var4); + } + } + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + if (!this.worldObj.isRemote) { + par1EntityPlayer.displayGUIChest(this); + } + + return true; + } + + protected void applyDrag() { + int var1 = 15 - Container.calcRedstoneFromInventory(this); + float var2 = 0.98F + (float) var1 * 0.001F; + this.motionX *= (double) var2; + this.motionY *= 0.0D; + this.motionZ *= (double) var2; + } +} diff --git a/src/main/java/net/minecraft/src/EntityMinecartEmpty.java b/src/main/java/net/minecraft/src/EntityMinecartEmpty.java new file mode 100644 index 0000000..db40762 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityMinecartEmpty.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +public class EntityMinecartEmpty extends EntityMinecart { + + public EntityMinecartEmpty(World par1, double par2, double par4, double par6) { + super(par1, par2, par4, par6); + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityPlayer && this.riddenByEntity != par1EntityPlayer) { + return true; + } else if (this.riddenByEntity != null && this.riddenByEntity != par1EntityPlayer) { + return false; + } else { + if (!this.worldObj.isRemote) { + par1EntityPlayer.mountEntity(this); + } + + return true; + } + } + + public int getMinecartType() { + return 0; + } +} diff --git a/src/main/java/net/minecraft/src/EntityMinecartFurnace.java b/src/main/java/net/minecraft/src/EntityMinecartFurnace.java new file mode 100644 index 0000000..8429b71 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityMinecartFurnace.java @@ -0,0 +1,150 @@ +package net.minecraft.src; + +public class EntityMinecartFurnace extends EntityMinecart { + private int fuel = 0; + public double pushX; + public double pushZ; + + public EntityMinecartFurnace(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + } + + public int getMinecartType() { + return 2; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte) 0)); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.fuel > 0) { + --this.fuel; + } + + if (this.fuel <= 0) { + this.pushX = this.pushZ = 0.0D; + } + + this.setMinecartPowered(this.fuel > 0); + + if (this.isMinecartPowered() && this.rand.nextInt(4) == 0) { + this.worldObj.spawnParticle("largesmoke", this.posX, this.posY + 0.8D, this.posZ, 0.0D, 0.0D, 0.0D); + } + } + + public void killMinecart(DamageSource par1DamageSource) { + super.killMinecart(par1DamageSource); + + if (!par1DamageSource.isExplosion()) { + this.entityDropItem(new ItemStack(Block.furnaceIdle, 1), 0.0F); + } + } + + protected void updateOnTrack(int par1, int par2, int par3, double par4, double par6, int par8, int par9) { + super.updateOnTrack(par1, par2, par3, par4, par6, par8, par9); + double var10 = this.pushX * this.pushX + this.pushZ * this.pushZ; + + if (var10 > 1.0E-4D && this.motionX * this.motionX + this.motionZ * this.motionZ > 0.001D) { + var10 = (double) MathHelper.sqrt_double(var10); + this.pushX /= var10; + this.pushZ /= var10; + + if (this.pushX * this.motionX + this.pushZ * this.motionZ < 0.0D) { + this.pushX = 0.0D; + this.pushZ = 0.0D; + } else { + this.pushX = this.motionX; + this.pushZ = this.motionZ; + } + } + } + + protected void applyDrag() { + double var1 = this.pushX * this.pushX + this.pushZ * this.pushZ; + + if (var1 > 1.0E-4D) { + var1 = (double) MathHelper.sqrt_double(var1); + this.pushX /= var1; + this.pushZ /= var1; + double var3 = 0.05D; + this.motionX *= 0.800000011920929D; + this.motionY *= 0.0D; + this.motionZ *= 0.800000011920929D; + this.motionX += this.pushX * var3; + this.motionZ += this.pushZ * var3; + } else { + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.0D; + this.motionZ *= 0.9800000190734863D; + } + + super.applyDrag(); + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + + if (var2 != null && var2.itemID == Item.coal.itemID) { + if (--var2.stackSize == 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null); + } + + this.fuel += 3600; + } + + this.pushX = this.posX - par1EntityPlayer.posX; + this.pushZ = this.posZ - par1EntityPlayer.posZ; + return true; + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setDouble("PushX", this.pushX); + par1NBTTagCompound.setDouble("PushZ", this.pushZ); + par1NBTTagCompound.setShort("Fuel", (short) this.fuel); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.pushX = par1NBTTagCompound.getDouble("PushX"); + this.pushZ = par1NBTTagCompound.getDouble("PushZ"); + this.fuel = par1NBTTagCompound.getShort("Fuel"); + } + + protected boolean isMinecartPowered() { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + protected void setMinecartPowered(boolean par1) { + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (this.dataWatcher.getWatchableObjectByte(16) | 1))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (this.dataWatcher.getWatchableObjectByte(16) & -2))); + } + } + + public Block getDefaultDisplayTile() { + return Block.furnaceBurning; + } + + public int getDefaultDisplayTileData() { + return 2; + } +} diff --git a/src/main/java/net/minecraft/src/EntityMinecartHopper.java b/src/main/java/net/minecraft/src/EntityMinecartHopper.java new file mode 100644 index 0000000..04e7b1a --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityMinecartHopper.java @@ -0,0 +1,166 @@ +package net.minecraft.src; + +import java.util.List; + +public class EntityMinecartHopper extends EntityMinecartContainer implements Hopper { + /** Whether this hopper minecart is being blocked by an activator rail. */ + private boolean isBlocked = true; + private int transferTicker = -1; + + public EntityMinecartHopper(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + } + + public int getMinecartType() { + return 5; + } + + public Block getDefaultDisplayTile() { + return Block.hopperBlock; + } + + public int getDefaultDisplayTileOffset() { + return 1; + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return 5; + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + if (!this.worldObj.isRemote) { + par1EntityPlayer.displayGUIHopperMinecart(this); + } + + return true; + } + + /** + * Called every tick the minecart is on an activator rail. + */ + public void onActivatorRailPass(int par1, int par2, int par3, boolean par4) { + boolean var5 = !par4; + + if (var5 != this.getBlocked()) { + this.setBlocked(var5); + } + } + + /** + * Get whether this hopper minecart is being blocked by an activator rail. + */ + public boolean getBlocked() { + return this.isBlocked; + } + + /** + * Set whether this hopper minecart is being blocked by an activator rail. + */ + public void setBlocked(boolean par1) { + this.isBlocked = par1; + } + + /** + * Returns the worldObj for this tileEntity. + */ + public World getWorldObj() { + return this.worldObj; + } + + /** + * Gets the world X position for this hopper entity. + */ + public double getXPos() { + return this.posX; + } + + /** + * Gets the world Y position for this hopper entity. + */ + public double getYPos() { + return this.posY; + } + + /** + * Gets the world Z position for this hopper entity. + */ + public double getZPos() { + return this.posZ; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (!this.worldObj.isRemote && this.isEntityAlive() && this.getBlocked()) { + --this.transferTicker; + + if (!this.canTransfer()) { + this.setTransferTicker(0); + + if (this.func_96112_aD()) { + this.setTransferTicker(4); + this.onInventoryChanged(); + } + } + } + } + + public boolean func_96112_aD() { + if (TileEntityHopper.suckItemsIntoHopper(this)) { + return true; + } else { + List var1 = this.worldObj.selectEntitiesWithinAABB(EntityItem.class, this.boundingBox.expand(0.25D, 0.0D, 0.25D), IEntitySelector.selectAnything); + + if (var1.size() > 0) { + TileEntityHopper.func_96114_a(this, (EntityItem) var1.get(0)); + } + + return false; + } + } + + public void killMinecart(DamageSource par1DamageSource) { + super.killMinecart(par1DamageSource); + this.dropItemWithOffset(Block.hopperBlock.blockID, 1, 0.0F); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("TransferCooldown", this.transferTicker); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.transferTicker = par1NBTTagCompound.getInteger("TransferCooldown"); + } + + /** + * Sets the transfer ticker, used to determine the delay between transfers. + */ + public void setTransferTicker(int par1) { + this.transferTicker = par1; + } + + /** + * Returns whether the hopper cart can currently transfer an item. + */ + public boolean canTransfer() { + return this.transferTicker > 0; + } +} diff --git a/src/main/java/net/minecraft/src/EntityMinecartMobSpawner.java b/src/main/java/net/minecraft/src/EntityMinecartMobSpawner.java new file mode 100644 index 0000000..01225d7 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityMinecartMobSpawner.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + +public class EntityMinecartMobSpawner extends EntityMinecart { + /** Mob spawner logic for this spawner minecart. */ + + public EntityMinecartMobSpawner(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + } + + public int getMinecartType() { + return 4; + } + + public Block getDefaultDisplayTile() { + return Block.mobSpawner; + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + } +} diff --git a/src/main/java/net/minecraft/src/EntityMinecartTNT.java b/src/main/java/net/minecraft/src/EntityMinecartTNT.java new file mode 100644 index 0000000..e50fa37 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityMinecartTNT.java @@ -0,0 +1,149 @@ +package net.minecraft.src; + + + +public class EntityMinecartTNT extends EntityMinecart { + private int minecartTNTFuse = -1; + + public EntityMinecartTNT(World par1, double par2, double par4, double par6) { + super(par1, par2, par4, par6); + } + + public int getMinecartType() { + return 3; + } + + public Block getDefaultDisplayTile() { + return Block.tnt; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.minecartTNTFuse > 0) { + --this.minecartTNTFuse; + this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D); + } else if (this.minecartTNTFuse == 0) { + this.explodeCart(this.motionX * this.motionX + this.motionZ * this.motionZ); + } + + if (this.isCollidedHorizontally) { + double var1 = this.motionX * this.motionX + this.motionZ * this.motionZ; + + if (var1 >= 0.009999999776482582D) { + this.explodeCart(var1); + } + } + } + + public void killMinecart(DamageSource par1DamageSource) { + super.killMinecart(par1DamageSource); + double var2 = this.motionX * this.motionX + this.motionZ * this.motionZ; + + if (!par1DamageSource.isExplosion()) { + this.entityDropItem(new ItemStack(Block.tnt, 1), 0.0F); + } + + if (par1DamageSource.isFireDamage() || par1DamageSource.isExplosion() || var2 >= 0.009999999776482582D) { + this.explodeCart(var2); + } + } + + /** + * Makes the minecart explode. + */ + protected void explodeCart(double par1) { + if (!this.worldObj.isRemote) { + double var3 = Math.sqrt(par1); + + if (var3 > 5.0D) { + var3 = 5.0D; + } + + this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float) (4.0D + this.rand.nextDouble() * 1.5D * var3), true); + this.setDead(); + } + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + if (par1 >= 3.0F) { + float var2 = par1 / 10.0F; + this.explodeCart((double) (var2 * var2)); + } + + super.fall(par1); + } + + /** + * Called every tick the minecart is on an activator rail. + */ + public void onActivatorRailPass(int par1, int par2, int par3, boolean par4) { + if (par4 && this.minecartTNTFuse < 0) { + this.ignite(); + } + } + + public void handleHealthUpdate(byte par1) { + if (par1 == 10) { + this.ignite(); + } else { + super.handleHealthUpdate(par1); + } + } + + /** + * Ignites this TNT cart. + */ + public void ignite() { + this.minecartTNTFuse = 80; + + if (!this.worldObj.isRemote) { + this.worldObj.setEntityState(this, (byte) 10); + this.worldObj.playSoundAtEntity(this, "random.fuse", 1.0F, 1.0F); + } + } + + public int func_94104_d() { + return this.minecartTNTFuse; + } + + /** + * Returns true if the TNT minecart is ignited. + */ + public boolean isIgnited() { + return this.minecartTNTFuse > -1; + } + + public float func_82146_a(Explosion par1Explosion, World par2World, int par3, int par4, int par5, Block par6Block) { + return this.isIgnited() && (BlockRailBase.isRailBlock(par6Block.blockID) || BlockRailBase.isRailBlockAt(par2World, par3, par4 + 1, par5)) ? 0.0F : super.func_82146_a(par1Explosion, par2World, par3, par4, par5, par6Block); + } + + public boolean func_96091_a(Explosion par1Explosion, World par2World, int par3, int par4, int par5, int par6, float par7) { + return this.isIgnited() && (BlockRailBase.isRailBlock(par6) || BlockRailBase.isRailBlockAt(par2World, par3, par4 + 1, par5)) ? false : super.func_96091_a(par1Explosion, par2World, par3, par4, par5, par6, par7); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("TNTFuse")) { + this.minecartTNTFuse = par1NBTTagCompound.getInteger("TNTFuse"); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("TNTFuse", this.minecartTNTFuse); + } +} diff --git a/src/main/java/net/minecraft/src/EntityMob.java b/src/main/java/net/minecraft/src/EntityMob.java new file mode 100644 index 0000000..ad3c500 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityMob.java @@ -0,0 +1,168 @@ +package net.minecraft.src; + + + +public abstract class EntityMob extends EntityCreature implements IMob { + public EntityMob() { + super(); + this.experienceValue = 5; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + this.updateArmSwingProgress(); + float var1 = this.getBrightness(1.0F); + + if (var1 > 0.5F) { + this.entityAge += 2; + } + + super.onLivingUpdate(); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (!this.worldObj.isRemote && this.worldObj.difficultySetting == 0) { + this.setDead(); + } + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity + * isn't interested in attacking (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() { + EntityPlayer var1 = this.worldObj.getClosestVulnerablePlayerToEntity(this, 16.0D); + return var1 != null && this.canEntityBeSeen(var1) ? var1 : null; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else if (super.attackEntityFrom(par1DamageSource, par2)) { + Entity var3 = par1DamageSource.getEntity(); + + if (this.riddenByEntity != var3 && this.ridingEntity != var3) { + if (var3 != this) { + this.entityToAttack = var3; + } + + return true; + } else { + return true; + } + } else { + return false; + } + } + + public boolean attackEntityAsMob(Entity par1Entity) { + int var2 = this.getAttackStrength(par1Entity); + + if (this.isPotionActive(Potion.damageBoost)) { + var2 += 3 << this.getActivePotionEffect(Potion.damageBoost).getAmplifier(); + } + + if (this.isPotionActive(Potion.weakness)) { + var2 -= 2 << this.getActivePotionEffect(Potion.weakness).getAmplifier(); + } + + int var3 = 0; + + if (par1Entity instanceof EntityLiving) { + var2 += EnchantmentHelper.getEnchantmentModifierLiving(this, (EntityLiving) par1Entity); + var3 += EnchantmentHelper.getKnockbackModifier(this, (EntityLiving) par1Entity); + } + + boolean var4 = par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), var2); + + if (var4) { + if (var3 > 0) { + par1Entity.addVelocity((double) (-MathHelper.sin(this.rotationYaw * (float) Math.PI / 180.0F) * (float) var3 * 0.5F), 0.1D, (double) (MathHelper.cos(this.rotationYaw * (float) Math.PI / 180.0F) * (float) var3 * 0.5F)); + this.motionX *= 0.6D; + this.motionZ *= 0.6D; + } + + int var5 = EnchantmentHelper.getFireAspectModifier(this); + + if (var5 > 0) { + par1Entity.setFire(var5 * 4); + } + + if (par1Entity instanceof EntityLiving) { + EnchantmentThorns.func_92096_a(this, (EntityLiving) par1Entity, this.rand); + } + } + + return var4; + } + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by + * each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) { + if (this.attackTime <= 0 && par2 < 2.0F && par1Entity.boundingBox.maxY > this.boundingBox.minY && par1Entity.boundingBox.minY < this.boundingBox.maxY) { + this.attackTime = 20; + this.attackEntityAsMob(par1Entity); + } + } + + /** + * Takes a coordinate in and returns a weight to determine how likely this + * creature will try to path to the block. Args: x, y, z + */ + public float getBlockPathWeight(int par1, int par2, int par3) { + return 0.5F - this.worldObj.getLightBrightness(par1, par2, par3); + } + + /** + * Checks to make sure the light is not too bright where the mob is spawning + */ + protected boolean isValidLightLevel() { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.boundingBox.minY); + int var3 = MathHelper.floor_double(this.posZ); + + if (this.worldObj.getSavedLightValue(EnumSkyBlock.Sky, var1, var2, var3) > this.rand.nextInt(32)) { + return false; + } else { + int var4 = this.worldObj.getBlockLightValue(var1, var2, var3); + + if (this.worldObj.isThundering()) { + int var5 = this.worldObj.skylightSubtracted; + this.worldObj.skylightSubtracted = 10; + var4 = this.worldObj.getBlockLightValue(var1, var2, var3); + this.worldObj.skylightSubtracted = var5; + } + + return var4 <= this.rand.nextInt(8); + } + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + return this.isValidLightLevel() && super.getCanSpawnHere(); + } + + /** + * Returns the amount of damage a mob should deal. + */ + public int getAttackStrength(Entity par1Entity) { + return 2; + } +} diff --git a/src/main/java/net/minecraft/src/EntityMooshroom.java b/src/main/java/net/minecraft/src/EntityMooshroom.java new file mode 100644 index 0000000..365523e --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityMooshroom.java @@ -0,0 +1,54 @@ +package net.minecraft.src; + +public class EntityMooshroom extends EntityCow { + public EntityMooshroom() { + super(); + this.setSize(0.9F, 1.3F); + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + + if (var2 != null && var2.itemID == Item.bowlEmpty.itemID && this.getGrowingAge() >= 0) { + if (var2.stackSize == 1) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, new ItemStack(Item.bowlSoup)); + return true; + } + + if (par1EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Item.bowlSoup)) && !par1EntityPlayer.capabilities.isCreativeMode) { + par1EntityPlayer.inventory.decrStackSize(par1EntityPlayer.inventory.currentItem, 1); + return true; + } + } + + if (var2 != null && var2.itemID == Item.shears.itemID && this.getGrowingAge() >= 0) { + this.setDead(); + this.worldObj.spawnParticle("largeexplode", this.posX, this.posY + (double) (this.height / 2.0F), this.posZ, 0.0D, 0.0D, 0.0D); + return true; + } else { + return super.interact(par1EntityPlayer); + } + } + + public EntityMooshroom func_94900_c(EntityAgeable par1EntityAgeable) { + EntityMooshroom m = new EntityMooshroom(); + m.setWorld(worldObj); + return m; + } + + /** + * This function is used when two same-species animals in 'love mode' breed to + * generate the new baby animal. + */ + public EntityCow spawnBabyAnimal(EntityAgeable par1EntityAgeable) { + return this.func_94900_c(par1EntityAgeable); + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.func_94900_c(par1EntityAgeable); + } +} diff --git a/src/main/java/net/minecraft/src/EntityMoveHelper.java b/src/main/java/net/minecraft/src/EntityMoveHelper.java new file mode 100644 index 0000000..03e2256 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityMoveHelper.java @@ -0,0 +1,81 @@ +package net.minecraft.src; + + + +public class EntityMoveHelper { + /** The EntityLiving that is being moved */ + private EntityLiving entity; + private double posX; + private double posY; + private double posZ; + + /** The speed at which the entity should move */ + private float speed; + private boolean update = false; + + public EntityMoveHelper(EntityLiving par1EntityLiving) { + this.entity = par1EntityLiving; + this.posX = par1EntityLiving.posX; + this.posY = par1EntityLiving.posY; + this.posZ = par1EntityLiving.posZ; + } + + public boolean isUpdating() { + return this.update; + } + + public float getSpeed() { + return this.speed; + } + + /** + * Sets the speed and location to move to + */ + public void setMoveTo(double par1, double par3, double par5, float par7) { + this.posX = par1; + this.posY = par3; + this.posZ = par5; + this.speed = par7; + this.update = true; + } + + public void onUpdateMoveHelper() { + this.entity.setMoveForward(0.0F); + + if (this.update) { + this.update = false; + int var1 = MathHelper.floor_double(this.entity.boundingBox.minY + 0.5D); + double var2 = this.posX - this.entity.posX; + double var4 = this.posZ - this.entity.posZ; + double var6 = this.posY - (double) var1; + double var8 = var2 * var2 + var6 * var6 + var4 * var4; + + if (var8 >= 2.500000277905201E-7D) { + float var10 = (float) (Math.atan2(var4, var2) * 180.0D / Math.PI) - 90.0F; + this.entity.rotationYaw = this.limitAngle(this.entity.rotationYaw, var10, 30.0F); + this.entity.setAIMoveSpeed(this.speed * this.entity.getSpeedModifier()); + + if (var6 > 0.0D && var2 * var2 + var4 * var4 < 1.0D) { + this.entity.getJumpHelper().setJumping(); + } + } + } + } + + /** + * Limits the given angle to a upper and lower limit. + */ + private float limitAngle(float par1, float par2, float par3) { + float var4 = MathHelper.wrapAngleTo180_float(par2 - par1); + + if (var4 > par3) { + var4 = par3; + } + + if (var4 < -par3) { + var4 = -par3; + } + + return par1 + var4; + } +} diff --git a/src/main/java/net/minecraft/src/EntityNoteFX.java b/src/main/java/net/minecraft/src/EntityNoteFX.java new file mode 100644 index 0000000..f296db8 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityNoteFX.java @@ -0,0 +1,73 @@ +package net.minecraft.src; + + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityNoteFX extends EntityFX { + float noteParticleScale; + + public EntityNoteFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + this(par1World, par2, par4, par6, par8, par10, par12, 2.0F); + } + + public EntityNoteFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float par14) { + super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); + this.motionX *= 0.009999999776482582D; + this.motionY *= 0.009999999776482582D; + this.motionZ *= 0.009999999776482582D; + this.motionY += 0.2D; + this.particleRed = MathHelper.sin(((float) par8 + 0.0F) * (float) Math.PI * 2.0F) * 0.65F + 0.35F; + this.particleGreen = MathHelper.sin(((float) par8 + 0.33333334F) * (float) Math.PI * 2.0F) * 0.65F + 0.35F; + this.particleBlue = MathHelper.sin(((float) par8 + 0.6666667F) * (float) Math.PI * 2.0F) * 0.65F + 0.35F; + this.particleScale *= 0.75F; + this.particleScale *= par14; + this.noteParticleScale = this.particleScale; + this.particleMaxAge = 6; + this.noClip = false; + this.setParticleTextureIndex(64); + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = ((float) this.particleAge + par2) / (float) this.particleMaxAge * 32.0F; + + if (var8 < 0.0F) { + var8 = 0.0F; + } + + if (var8 > 1.0F) { + var8 = 1.0F; + } + + this.particleScale = this.noteParticleScale * var8; + super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (this.posY == this.prevPosY) { + this.motionX *= 1.1D; + this.motionZ *= 1.1D; + } + + this.motionX *= 0.6600000262260437D; + this.motionY *= 0.6600000262260437D; + this.motionZ *= 0.6600000262260437D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityOcelot.java b/src/main/java/net/minecraft/src/EntityOcelot.java new file mode 100644 index 0000000..b7f0759 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityOcelot.java @@ -0,0 +1,227 @@ +package net.minecraft.src; + +public class EntityOcelot extends EntityTameable { + + public EntityOcelot() { + super(); + this.setSize(0.6F, 0.8F); + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(18, Byte.valueOf((byte) 0)); + } + + /** + * main AI tick function, replaces updateEntityActionState + */ + public void updateAITick() { + if (this.getMoveHelper().isUpdating()) { + float var1 = this.getMoveHelper().getSpeed(); + + if (var1 == 0.18F) { + this.setSneaking(true); + this.setSprinting(false); + } else if (var1 == 0.4F) { + this.setSneaking(false); + this.setSprinting(true); + } else { + this.setSneaking(false); + this.setSprinting(false); + } + } else { + this.setSneaking(false); + this.setSprinting(false); + } + } + + /** + * Determines if an entity can be despawned, used on idle far away entities + */ + protected boolean canDespawn() { + return !this.isTamed(); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + public int getMaxHealth() { + return 10; + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("CatType", this.getTameSkin()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setTameSkin(par1NBTTagCompound.getInteger("CatType")); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return this.isTamed() ? (this.isInLove() ? "mob.cat.purr" : (this.rand.nextInt(4) == 0 ? "mob.cat.purreow" : "mob.cat.meow")) : ""; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.cat.hitt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.cat.hitt"; + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 0.4F; + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.leather.itemID; + } + + public boolean attackEntityAsMob(Entity par1Entity) { + return par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), 3); + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + } + + /** + * This function is used when two same-species animals in 'love mode' breed to + * generate the new baby animal. + */ + public EntityOcelot spawnBabyAnimal(EntityAgeable par1EntityAgeable) { + EntityOcelot var2 = new EntityOcelot(); + var2.setWorld(worldObj); + + if (this.isTamed()) { + var2.setOwner(this.getOwnerName()); + var2.setTamed(true); + var2.setTameSkin(this.getTameSkin()); + } + + return var2; + } + + /** + * Checks if the parameter is an item which this animal can be fed to breed it + * (wheat, carrots or seeds depending on the animal type) + */ + public boolean isBreedingItem(ItemStack par1ItemStack) { + return par1ItemStack != null && par1ItemStack.itemID == Item.fishRaw.itemID; + } + + /** + * Returns true if the mob is currently able to mate with the specified mob. + */ + public boolean canMateWith(EntityAnimal par1EntityAnimal) { + if (par1EntityAnimal == this) { + return false; + } else if (!this.isTamed()) { + return false; + } else if (!(par1EntityAnimal instanceof EntityOcelot)) { + return false; + } else { + EntityOcelot var2 = (EntityOcelot) par1EntityAnimal; + return !var2.isTamed() ? false : this.isInLove() && var2.isInLove(); + } + } + + public int getTameSkin() { + return this.dataWatcher.getWatchableObjectByte(18); + } + + public void setTameSkin(int par1) { + this.dataWatcher.updateObject(18, Byte.valueOf((byte) par1)); + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + if (this.worldObj.rand.nextInt(3) == 0) { + return false; + } else { + if (this.worldObj.checkNoEntityCollision(this.boundingBox) && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() && !this.worldObj.isAnyLiquid(this.boundingBox)) { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.boundingBox.minY); + int var3 = MathHelper.floor_double(this.posZ); + + if (var2 < 63) { + return false; + } + + int var4 = this.worldObj.getBlockId(var1, var2 - 1, var3); + + if (var4 == Block.grass.blockID || var4 == Block.leaves.blockID) { + return true; + } + } + + return false; + } + } + + /** + * Gets the username of the entity. + */ + public String getEntityName() { + return this.func_94056_bM() ? this.func_94057_bL() : (this.isTamed() ? "entity.Cat.name" : super.getEntityName()); + } + + /** + * Initialize this creature. + */ + public void initCreature() { + if (this.worldObj.rand.nextInt(7) == 0) { + for (int var1 = 0; var1 < 2; ++var1) { + EntityOcelot var2 = new EntityOcelot(); + var2.setWorld(worldObj); + var2.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F); + var2.setGrowingAge(-24000); + this.worldObj.spawnEntityInWorld(var2); + } + } + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.spawnBabyAnimal(par1EntityAgeable); + } +} diff --git a/src/main/java/net/minecraft/src/EntityOtherPlayerMP.java b/src/main/java/net/minecraft/src/EntityOtherPlayerMP.java new file mode 100644 index 0000000..9d36746 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityOtherPlayerMP.java @@ -0,0 +1,175 @@ +package net.minecraft.src; + + +import net.minecraft.client.Minecraft; + +public class EntityOtherPlayerMP extends EntityPlayer { + private boolean isItemInUse = false; + private int otherPlayerMPPosRotationIncrements; + private double otherPlayerMPX; + private double otherPlayerMPY; + private double otherPlayerMPZ; + private double otherPlayerMPYaw; + private double otherPlayerMPPitch; + + public byte[] skinPacket; + + public EntityOtherPlayerMP(World par1World, String par2Str) { + super(); + this.setWorld(par1World); + this.username = par2Str; + this.yOffset = 0.0F; + this.stepHeight = 0.0F; + this.noClip = true; + this.field_71082_cx = 0.25F; + this.renderDistanceWeight = 10.0D; + this.skinPacket = null; + } + + /** + * sets the players height back to normal after doing things like sleeping and + * dieing + */ + protected void resetHeight() { + this.yOffset = 0.0F; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + return true; + } + + /** + * Sets the position and rotation. Only difference from the other one is no + * bounding on the rotation. Args: posX, posY, posZ, yaw, pitch + */ + public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9) { + this.otherPlayerMPX = par1; + this.otherPlayerMPY = par3; + this.otherPlayerMPZ = par5; + this.otherPlayerMPYaw = (double) par7; + this.otherPlayerMPPitch = (double) par8; + this.otherPlayerMPPosRotationIncrements = par9; + } + + public void updateCloak() { + + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.field_71082_cx = 0.0F; + super.onUpdate(); + this.prevLimbYaw = this.limbYaw; + double var1 = this.posX - this.prevPosX; + double var3 = this.posZ - this.prevPosZ; + float var5 = MathHelper.sqrt_double(var1 * var1 + var3 * var3) * 4.0F; + + if (var5 > 1.0F) { + var5 = 1.0F; + } + + this.limbYaw += (var5 - this.limbYaw) * 0.4F; + this.limbSwing += this.limbYaw; + + if (!this.isItemInUse && this.isEating() && this.inventory.mainInventory[this.inventory.currentItem] != null) { + ItemStack var6 = this.inventory.mainInventory[this.inventory.currentItem]; + this.setItemInUse(this.inventory.mainInventory[this.inventory.currentItem], Item.itemsList[var6.itemID].getMaxItemUseDuration(var6)); + this.isItemInUse = true; + } else if (this.isItemInUse && !this.isEating()) { + this.clearItemInUse(); + this.isItemInUse = false; + } + } + + public float getShadowSize() { + return 0.0F; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + super.updateEntityActionState(); + + if (this.otherPlayerMPPosRotationIncrements > 0) { + double var1 = this.posX + (this.otherPlayerMPX - this.posX) / (double) this.otherPlayerMPPosRotationIncrements; + double var3 = this.posY + (this.otherPlayerMPY - this.posY) / (double) this.otherPlayerMPPosRotationIncrements; + double var5 = this.posZ + (this.otherPlayerMPZ - this.posZ) / (double) this.otherPlayerMPPosRotationIncrements; + double var7; + + for (var7 = this.otherPlayerMPYaw - (double) this.rotationYaw; var7 < -180.0D; var7 += 360.0D) { + ; + } + + while (var7 >= 180.0D) { + var7 -= 360.0D; + } + + this.rotationYaw = (float) ((double) this.rotationYaw + var7 / (double) this.otherPlayerMPPosRotationIncrements); + this.rotationPitch = (float) ((double) this.rotationPitch + (this.otherPlayerMPPitch - (double) this.rotationPitch) / (double) this.otherPlayerMPPosRotationIncrements); + --this.otherPlayerMPPosRotationIncrements; + this.setPosition(var1, var3, var5); + this.setRotation(this.rotationYaw, this.rotationPitch); + } + + this.prevCameraYaw = this.cameraYaw; + float var9 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + float var2 = (float) Math.atan(-this.motionY * 0.20000000298023224D) * 15.0F; + + if (var9 > 0.1F) { + var9 = 0.1F; + } + + if (!this.onGround || this.getHealth() <= 0) { + var9 = 0.0F; + } + + if (this.onGround || this.getHealth() <= 0) { + var2 = 0.0F; + } + + this.cameraYaw += (var9 - this.cameraYaw) * 0.4F; + this.cameraPitch += (var2 - this.cameraPitch) * 0.8F; + } + + /** + * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. + * Params: Item, slot + */ + public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack) { + if (par1 == 0) { + this.inventory.mainInventory[this.inventory.currentItem] = par2ItemStack; + } else { + this.inventory.armorInventory[par1 - 1] = par2ItemStack; + } + } + + public float getEyeHeight() { + return 1.82F; + } + + public void sendChatToPlayer(String par1Str) { + Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(par1Str); + } + + /** + * Returns true if the command sender is allowed to use the given command. + */ + public boolean canCommandSenderUseCommand(int par1, String par2Str) { + return false; + } + + /** + * Return the position for this command sender. + */ + public ChunkCoordinates getPlayerCoordinates() { + return new ChunkCoordinates(MathHelper.floor_double(this.posX + 0.5D), MathHelper.floor_double(this.posY + 0.5D), MathHelper.floor_double(this.posZ + 0.5D)); + } +} diff --git a/src/main/java/net/minecraft/src/EntityPainting.java b/src/main/java/net/minecraft/src/EntityPainting.java new file mode 100644 index 0000000..b685284 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityPainting.java @@ -0,0 +1,93 @@ +package net.minecraft.src; + +import java.util.ArrayList; + +public class EntityPainting extends EntityHanging { + public EnumArt art; + + public EntityPainting(World par1World, int par2, int par3, int par4, int par5) { + super(par1World, par2, par3, par4, par5); + ArrayList var6 = new ArrayList(); + EnumArt[] var7 = EnumArt.values(); + int var8 = var7.length; + + for (int var9 = 0; var9 < var8; ++var9) { + EnumArt var10 = var7[var9]; + this.art = var10; + this.setDirection(par5); + + if (this.onValidSurface()) { + var6.add(var10); + } + } + + if (!var6.isEmpty()) { + this.art = (EnumArt) var6.get(this.rand.nextInt(var6.size())); + } + + this.setDirection(par5); + } + + public EntityPainting(World par1World, int par2, int par3, int par4, int par5, String par6Str) { + this(par1World, par2, par3, par4, par5); + EnumArt[] var7 = EnumArt.values(); + int var8 = var7.length; + + for (int var9 = 0; var9 < var8; ++var9) { + EnumArt var10 = var7[var9]; + + if (var10.title.equals(par6Str)) { + this.art = var10; + break; + } + } + + this.setDirection(par5); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setString("Motive", this.art.title); + super.writeEntityToNBT(par1NBTTagCompound); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + String var2 = par1NBTTagCompound.getString("Motive"); + EnumArt[] var3 = EnumArt.values(); + int var4 = var3.length; + + for (int var5 = 0; var5 < var4; ++var5) { + EnumArt var6 = var3[var5]; + + if (var6.title.equals(var2)) { + this.art = var6; + } + } + + if (this.art == null) { + this.art = EnumArt.Kebab; + } + + super.readEntityFromNBT(par1NBTTagCompound); + } + + public int func_82329_d() { + return this.art.sizeX; + } + + public int func_82330_g() { + return this.art.sizeY; + } + + /** + * Drop the item currently on this item frame. + */ + public void dropItemStack() { + this.entityDropItem(new ItemStack(Item.painting), 0.0F); + } +} diff --git a/src/main/java/net/minecraft/src/EntityPickupFX.java b/src/main/java/net/minecraft/src/EntityPickupFX.java new file mode 100644 index 0000000..4649de3 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityPickupFX.java @@ -0,0 +1,63 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityPickupFX extends EntityFX { + private Entity entityToPickUp; + private Entity entityPickingUp; + private int age = 0; + private int maxAge = 0; + + /** renamed from yOffset to fix shadowing Entity.yOffset */ + private float yOffs; + + public EntityPickupFX(World par1World, Entity par2Entity, Entity par3Entity, float par4) { + super(par1World, par2Entity.posX, par2Entity.posY, par2Entity.posZ, par2Entity.motionX, par2Entity.motionY, par2Entity.motionZ); + this.entityToPickUp = par2Entity; + this.entityPickingUp = par3Entity; + this.maxAge = 3; + this.yOffs = par4; + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = ((float) this.age + par2) / (float) this.maxAge; + var8 *= var8; + double var9 = this.entityToPickUp.posX; + double var11 = this.entityToPickUp.posY; + double var13 = this.entityToPickUp.posZ; + double var15 = this.entityPickingUp.lastTickPosX + (this.entityPickingUp.posX - this.entityPickingUp.lastTickPosX) * (double) par2; + double var17 = this.entityPickingUp.lastTickPosY + (this.entityPickingUp.posY - this.entityPickingUp.lastTickPosY) * (double) par2 + (double) this.yOffs; + double var19 = this.entityPickingUp.lastTickPosZ + (this.entityPickingUp.posZ - this.entityPickingUp.lastTickPosZ) * (double) par2; + double var21 = var9 + (var15 - var9) * (double) var8; + double var23 = var11 + (var17 - var11) * (double) var8; + double var25 = var13 + (var19 - var13) * (double) var8; + int var27 = MathHelper.floor_double(var21); + int var28 = MathHelper.floor_double(var23 + (double) (this.yOffset / 2.0F)); + int var29 = MathHelper.floor_double(var25); + int var30 = this.getBrightnessForRender(par2); + int var31 = var30 % 65536; + int var32 = var30 / 65536; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) var31 / 1.0F, (float) var32 / 1.0F); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + var21 -= interpPosX; + var23 -= interpPosY; + var25 -= interpPosZ; + RenderManager.instance.renderEntityWithPosYaw(this.entityToPickUp, (double) ((float) var21), (double) ((float) var23), (double) ((float) var25), this.entityToPickUp.rotationYaw, par2); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + ++this.age; + + if (this.age == this.maxAge) { + this.setDead(); + } + } + + public int getFXLayer() { + return 3; + } +} diff --git a/src/main/java/net/minecraft/src/EntityPig.java b/src/main/java/net/minecraft/src/EntityPig.java new file mode 100644 index 0000000..559a2fa --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityPig.java @@ -0,0 +1,185 @@ +package net.minecraft.src; + +public class EntityPig extends EntityAnimal { + + public EntityPig() { + super(); + this.setSize(0.9F, 0.9F); + float var2 = 0.25F; + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + public int getMaxHealth() { + return 10; + } + + protected void updateAITasks() { + super.updateAITasks(); + } + + /** + * returns true if all the conditions for steering the entity are met. For pigs, + * this is true if it is being ridden by a player and the player is holding a + * carrot-on-a-stick + */ + public boolean canBeSteered() { + ItemStack var1 = ((EntityPlayer) this.riddenByEntity).getHeldItem(); + return var1 != null && var1.itemID == Item.carrotOnAStick.itemID; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, Byte.valueOf((byte) 0)); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setBoolean("Saddle", this.getSaddled()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setSaddled(par1NBTTagCompound.getBoolean("Saddle")); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.pig.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.pig.say"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.pig.death"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.pig.step", 0.15F, 1.0F); + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + if (super.interact(par1EntityPlayer)) { + return true; + } else if (this.getSaddled() && !this.worldObj.isRemote && (this.riddenByEntity == null || this.riddenByEntity == par1EntityPlayer)) { + par1EntityPlayer.mountEntity(this); + return true; + } else { + return false; + } + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return this.isBurning() ? Item.porkCooked.itemID : Item.porkRaw.itemID; + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(3) + 1 + this.rand.nextInt(1 + par2); + + for (int var4 = 0; var4 < var3; ++var4) { + if (this.isBurning()) { + this.dropItem(Item.porkCooked.itemID, 1); + } else { + this.dropItem(Item.porkRaw.itemID, 1); + } + } + + if (this.getSaddled()) { + this.dropItem(Item.saddle.itemID, 1); + } + } + + /** + * Returns true if the pig is saddled. + */ + public boolean getSaddled() { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + /** + * Set or remove the saddle of the pig. + */ + public void setSaddled(boolean par1) { + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) 1)); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) 0)); + } + } + + /** + * Called when a lightning bolt hits the entity. + */ + public void onStruckByLightning(EntityLightningBolt par1EntityLightningBolt) { + + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + super.fall(par1); + + if (par1 > 5.0F && this.riddenByEntity instanceof EntityPlayer) { + ((EntityPlayer) this.riddenByEntity).triggerAchievement(AchievementList.flyPig); + } + } + + /** + * This function is used when two same-species animals in 'love mode' breed to + * generate the new baby animal. + */ + public EntityPig spawnBabyAnimal(EntityAgeable par1EntityAgeable) { + EntityPig p = new EntityPig(); + p.setWorld(worldObj); + return p; + } + + /** + * Checks if the parameter is an item which this animal can be fed to breed it + * (wheat, carrots or seeds depending on the animal type) + */ + public boolean isBreedingItem(ItemStack par1ItemStack) { + return par1ItemStack != null && par1ItemStack.itemID == Item.carrot.itemID; + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.spawnBabyAnimal(par1EntityAgeable); + } +} diff --git a/src/main/java/net/minecraft/src/EntityPigZombie.java b/src/main/java/net/minecraft/src/EntityPigZombie.java new file mode 100644 index 0000000..8cb155c --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityPigZombie.java @@ -0,0 +1,203 @@ +package net.minecraft.src; + +import java.util.List; + +public class EntityPigZombie extends EntityZombie { + /** Above zero if this PigZombie is Angry. */ + private int angerLevel = 0; + + /** A random delay until this PigZombie next makes a sound. */ + private int randomSoundDelay = 0; + + public EntityPigZombie() { + super(); + this.moveSpeed = 0.5F; + this.isImmuneToFire = true; + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() { + return false; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.moveSpeed = this.entityToAttack != null ? 0.95F : 0.5F; + + if (this.randomSoundDelay > 0 && --this.randomSoundDelay == 0) { + this.playSound("mob.zombiepig.zpigangry", this.getSoundVolume() * 2.0F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F) * 1.8F); + } + + super.onUpdate(); + } + + /** + * Returns the texture's file path as a String. + */ + public String getTexture() { + return "/mob/pigzombie.png"; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + return this.worldObj.difficultySetting > 0 && this.worldObj.checkNoEntityCollision(this.boundingBox) && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() && !this.worldObj.isAnyLiquid(this.boundingBox); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setShort("Anger", (short) this.angerLevel); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.angerLevel = par1NBTTagCompound.getShort("Anger"); + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity + * isn't interested in attacking (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() { + return this.angerLevel == 0 ? null : super.findPlayerToAttack(); + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + Entity var3 = par1DamageSource.getEntity(); + + if (var3 instanceof EntityPlayer) { + List var4 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(32.0D, 32.0D, 32.0D)); + + for (int var5 = 0; var5 < var4.size(); ++var5) { + Entity var6 = (Entity) var4.get(var5); + + if (var6 instanceof EntityPigZombie) { + EntityPigZombie var7 = (EntityPigZombie) var6; + var7.becomeAngryAt(var3); + } + } + + this.becomeAngryAt(var3); + } + + return super.attackEntityFrom(par1DamageSource, par2); + } + } + + /** + * Causes this PigZombie to become angry at the supplied Entity (which will be a + * player). + */ + private void becomeAngryAt(Entity par1Entity) { + this.entityToAttack = par1Entity; + this.angerLevel = 400 + this.rand.nextInt(400); + this.randomSoundDelay = this.rand.nextInt(40); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.zombiepig.zpig"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.zombiepig.zpighurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.zombiepig.zpigdeath"; + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(2 + par2); + int var4; + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.rottenFlesh.itemID, 1); + } + + var3 = this.rand.nextInt(2 + par2); + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.goldNugget.itemID, 1); + } + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + return false; + } + + protected void dropRareDrop(int par1) { + this.dropItem(Item.ingotGold.itemID, 1); + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.rottenFlesh.itemID; + } + + /** + * Makes entity wear random armor based on difficulty + */ + protected void addRandomArmor() { + this.setCurrentItemOrArmor(0, new ItemStack(Item.swordGold)); + } + + /** + * Initialize this creature. + */ + public void initCreature() { + super.initCreature(); + this.setVillager(false); + } + + /** + * Returns the amount of damage a mob should deal. + */ + public int getAttackStrength(Entity par1Entity) { + ItemStack var2 = this.getHeldItem(); + int var3 = 5; + + if (var2 != null) { + var3 += var2.getDamageVsEntity(this); + } + + return var3; + } +} diff --git a/src/main/java/net/minecraft/src/EntityPlayer.java b/src/main/java/net/minecraft/src/EntityPlayer.java new file mode 100644 index 0000000..45dbb5d --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityPlayer.java @@ -0,0 +1,1868 @@ +package net.minecraft.src; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import net.lax1dude.eaglercraft.DefaultSkinRenderer; + +import net.minecraft.client.Minecraft; + +public abstract class EntityPlayer extends EntityLiving implements ICommandSender { + /** Inventory of the player */ + public InventoryPlayer inventory = new InventoryPlayer(this); + private InventoryEnderChest theInventoryEnderChest = new InventoryEnderChest(); + + /** + * The Container for the player's inventory (which opens when they press E) + */ + public Container inventoryContainer; + + /** The Container the player has open. */ + public Container openContainer; + + /** The player's food stats. (See class FoodStats) */ + protected FoodStats foodStats = new FoodStats(); + + /** + * Used to tell if the player pressed jump twice. If this is at 0 and it's + * pressed (And they are allowed to fly, as defined in the player's + * movementInput) it sets this to 7. If it's pressed and it's greater than 0 + * enable fly. + */ + protected int flyToggleTimer = 0; + public byte field_71098_bD = 0; + public float prevCameraYaw; + public float cameraYaw; + public String username; + + /** + * Used by EntityPlayer to prevent too many xp orbs from getting absorbed at + * once. + */ + public int xpCooldown = 0; + public double field_71091_bM; + public double field_71096_bN; + public double field_71097_bO; + public double field_71094_bP; + public double field_71095_bQ; + public double field_71085_bR; + + /** Boolean value indicating weather a player is sleeping or not */ + protected boolean sleeping; + + /** + * The chunk coordinates of the bed the player is in (null if player isn't in a + * bed). + */ + public ChunkCoordinates playerLocation; + private int sleepTimer; + public float field_71079_bU; + public float field_71082_cx; + public float field_71089_bV; + + /** + * Holds the last coordinate to spawn based on last bed that the player sleep. + */ + private ChunkCoordinates spawnChunk; + + /** + * Whether this player's spawn point is forced, preventing execution of bed + * checks. + */ + private boolean spawnForced; + + /** Holds the coordinate of the player when enter a minecraft to ride. */ + private ChunkCoordinates startMinecartRidingCoordinate; + + /** The player's capabilities. (See class PlayerCapabilities) */ + public PlayerCapabilities capabilities = new PlayerCapabilities(); + + /** The current experience level the player is on. */ + public int experienceLevel; + + /** + * The total amount of experience the player has. This also includes the amount + * of experience within their Experience Bar. + */ + public int experienceTotal; + + /** + * The current amount of experience the player has within their Experience Bar. + */ + public float experience; + + /** + * This is the item that is in use when the player is holding down the + * useItemButton (e.g., bow, food, sword) + */ + private ItemStack itemInUse; + + /** + * This field starts off equal to getMaxItemUseDuration and is decremented on + * each tick + */ + private int itemInUseCount; + protected float speedOnGround = 0.1F; + protected float speedInAir = 0.02F; + private int field_82249_h = 0; + + /** + * An instance of a fishing rod's hook. If this isn't null, the icon image of + * the fishing rod is slightly different + */ + public EntityFishHook fishEntity = null; + + public EntityPlayer() { + super(); + this.inventoryContainer = new ContainerPlayer(this.inventory, false, this); + this.openContainer = this.inventoryContainer; + this.yOffset = 1.62F; + //ChunkCoordinates var2 = par1World.getSpawnPoint(); + //this.setLocationAndAngles((double) var2.posX + 0.5D, (double) (var2.posY + 1), (double) var2.posZ + 0.5D, 0.0F, 0.0F); + this.entityType = "humanoid"; + this.field_70741_aB = 180.0F; + this.fireResistance = 20; + } + + public int getBrightnessForRender(float par1) { + return DefaultSkinRenderer.getPlayerRenderer(this) == 21 ? 15728880 : super.getBrightnessForRender(par1); + } + + public int getMaxHealth() { + return 20; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, Byte.valueOf((byte) 0)); + this.dataWatcher.addObject(17, Byte.valueOf((byte) 0)); + this.dataWatcher.addObject(18, Integer.valueOf(0)); + } + + /** + * returns the ItemStack containing the itemInUse + */ + public ItemStack getItemInUse() { + return this.itemInUse; + } + + /** + * Returns the item in use count + */ + public int getItemInUseCount() { + return this.itemInUseCount; + } + + /** + * Checks if the entity is currently using an item (e.g., bow, food, sword) by + * holding down the useItemButton + */ + public boolean isUsingItem() { + return this.itemInUse != null; + } + + /** + * gets the duration for how long the current itemInUse has been in use + */ + public int getItemInUseDuration() { + return this.isUsingItem() ? this.itemInUse.getMaxItemUseDuration() - this.itemInUseCount : 0; + } + + public void stopUsingItem() { + if (this.itemInUse != null) { + this.itemInUse.onPlayerStoppedUsing(this.worldObj, this, this.itemInUseCount); + } + + this.clearItemInUse(); + } + + public void clearItemInUse() { + this.itemInUse = null; + this.itemInUseCount = 0; + + if (!this.worldObj.isRemote) { + this.setEating(false); + } + } + + public boolean isBlocking() { + return this.isUsingItem() && Item.itemsList[this.itemInUse.itemID].getItemUseAction(this.itemInUse) == EnumAction.block; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (this.itemInUse != null) { + ItemStack var1 = this.inventory.getCurrentItem(); + + if (var1 == this.itemInUse) { + if (this.itemInUseCount <= 25 && this.itemInUseCount % 4 == 0) { + this.updateItemUse(var1, 5); + } + + if (--this.itemInUseCount == 0 && !this.worldObj.isRemote) { + this.onItemUseFinish(); + } + } else { + this.clearItemInUse(); + } + } + + if (this.xpCooldown > 0) { + --this.xpCooldown; + } + + if (this.isPlayerSleeping()) { + ++this.sleepTimer; + + if (this.sleepTimer > 100) { + this.sleepTimer = 100; + } + + if (!this.worldObj.isRemote) { + if (!this.isInBed()) { + this.wakeUpPlayer(true, true, false); + } else if (this.worldObj.isDaytime()) { + this.wakeUpPlayer(false, true, true); + } + } + } else if (this.sleepTimer > 0) { + ++this.sleepTimer; + + if (this.sleepTimer >= 110) { + this.sleepTimer = 0; + } + } + + super.onUpdate(); + + if (!this.worldObj.isRemote && this.openContainer != null && !this.openContainer.canInteractWith(this)) { + this.closeScreen(); + this.openContainer = this.inventoryContainer; + } + + if (this.isBurning() && this.capabilities.disableDamage) { + this.extinguish(); + } + + if(!(this.equals(Minecraft.getMinecraft().renderViewEntity) && Minecraft.getMinecraft().gameSettings.thirdPersonView == 0)) { + int i = DefaultSkinRenderer.getPlayerRenderer(this); + if(i == 21) { + this.worldObj.spawnParticle("largesmoke", this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.width, this.posY - this.yOffset + this.rand.nextDouble() * (double) this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.width, 0.0D, 0.0D, 0.0D); + }else if(i == 19) { + for (int j = 0; j < 2; ++j) { + this.worldObj.spawnParticle("portal", this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.width, this.posY - this.yOffset + this.rand.nextDouble() * (double) 2.5D, this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.width, (this.rand.nextDouble() - 0.5D) * 2.0D, -this.rand.nextDouble(), (this.rand.nextDouble() - 0.5D) * 2.0D); + } + } + } + + this.field_71091_bM = this.field_71094_bP; + this.field_71096_bN = this.field_71095_bQ; + this.field_71097_bO = this.field_71085_bR; + double var9 = this.posX - this.field_71094_bP; + double var3 = this.posY - this.field_71095_bQ; + double var5 = this.posZ - this.field_71085_bR; + double var7 = 10.0D; + + if (var9 > var7) { + this.field_71091_bM = this.field_71094_bP = this.posX; + } + + if (var5 > var7) { + this.field_71097_bO = this.field_71085_bR = this.posZ; + } + + if (var3 > var7) { + this.field_71096_bN = this.field_71095_bQ = this.posY; + } + + if (var9 < -var7) { + this.field_71091_bM = this.field_71094_bP = this.posX; + } + + if (var5 < -var7) { + this.field_71097_bO = this.field_71085_bR = this.posZ; + } + + if (var3 < -var7) { + this.field_71096_bN = this.field_71095_bQ = this.posY; + } + + this.field_71094_bP += var9 * 0.25D; + this.field_71085_bR += var5 * 0.25D; + this.field_71095_bQ += var3 * 0.25D; + + if (this.ridingEntity == null) { + this.startMinecartRidingCoordinate = null; + } + + if (!this.worldObj.isRemote) { + this.foodStats.onUpdate(this); + } + } + + /** + * Return the amount of time this entity should stay in a portal before being + * transported. + */ + public int getMaxInPortalTime() { + return this.capabilities.disableDamage ? 0 : 80; + } + + /** + * Return the amount of cooldown before this entity can use a portal again. + */ + public int getPortalCooldown() { + return 10; + } + + public void playSound(String par1Str, float par2, float par3) { + this.worldObj.playSoundToNearExcept(this, par1Str, par2, par3); + } + + /** + * Plays sounds and makes particles for item in use state + */ + protected void updateItemUse(ItemStack par1ItemStack, int par2) { + if (par1ItemStack.getItemUseAction() == EnumAction.drink) { + this.playSound("random.drink", 0.5F, this.worldObj.rand.nextFloat() * 0.1F + 0.9F); + } + + if (par1ItemStack.getItemUseAction() == EnumAction.eat) { + for (int var3 = 0; var3 < par2; ++var3) { + Vec3 var4 = this.worldObj.getWorldVec3Pool().getVecFromPool(((double) this.rand.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D); + var4.rotateAroundX(-this.rotationPitch * (float) Math.PI / 180.0F); + var4.rotateAroundY(-this.rotationYaw * (float) Math.PI / 180.0F); + Vec3 var5 = this.worldObj.getWorldVec3Pool().getVecFromPool(((double) this.rand.nextFloat() - 0.5D) * 0.3D, (double) (-this.rand.nextFloat()) * 0.6D - 0.3D, 0.6D); + var5.rotateAroundX(-this.rotationPitch * (float) Math.PI / 180.0F); + var5.rotateAroundY(-this.rotationYaw * (float) Math.PI / 180.0F); + var5 = var5.addVector(this.posX, this.posY + (double) this.getEyeHeight(), this.posZ); + this.worldObj.spawnParticle("iconcrack_" + par1ItemStack.getItem().itemID, var5.xCoord, var5.yCoord, var5.zCoord, var4.xCoord, var4.yCoord + 0.05D, var4.zCoord); + } + + this.playSound("random.eat", 0.5F + 0.5F * (float) this.rand.nextInt(2), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F); + } + } + + /** + * Used for when item use count runs out, ie: eating completed + */ + protected void onItemUseFinish() { + if (this.itemInUse != null) { + this.updateItemUse(this.itemInUse, 16); + int var1 = this.itemInUse.stackSize; + ItemStack var2 = this.itemInUse.onFoodEaten(this.worldObj, this); + + if (var2 != this.itemInUse || var2 != null && var2.stackSize != var1) { + this.inventory.mainInventory[this.inventory.currentItem] = var2; + + if (var2.stackSize == 0) { + this.inventory.mainInventory[this.inventory.currentItem] = null; + } + } + + this.clearItemInUse(); + } + } + + public void handleHealthUpdate(byte par1) { + if (par1 == 9) { + this.onItemUseFinish(); + } else { + super.handleHealthUpdate(par1); + } + } + + /** + * Dead and sleeping entities cannot move + */ + protected boolean isMovementBlocked() { + return this.getHealth() <= 0 || this.isPlayerSleeping(); + } + + /** + * sets current screen to null (used on escape buttons of GUIs) + */ + protected void closeScreen() { + this.openContainer = this.inventoryContainer; + } + + /** + * Called when a player mounts an entity. e.g. mounts a pig, mounts a boat. + */ + public void mountEntity(Entity par1Entity) { + if (this.ridingEntity == par1Entity) { + this.unmountEntity(par1Entity); + + if (this.ridingEntity != null) { + this.ridingEntity.riddenByEntity = null; + } + + this.ridingEntity = null; + } else { + super.mountEntity(par1Entity); + } + } + + /** + * Handles updating while being ridden by an entity + */ + public void updateRidden() { + double var1 = this.posX; + double var3 = this.posY; + double var5 = this.posZ; + float var7 = this.rotationYaw; + float var8 = this.rotationPitch; + super.updateRidden(); + this.prevCameraYaw = this.cameraYaw; + this.cameraYaw = 0.0F; + this.addMountedMovementStat(this.posX - var1, this.posY - var3, this.posZ - var5); + + if (this.ridingEntity instanceof EntityPig) { + this.rotationPitch = var8; + this.rotationYaw = var7; + this.renderYawOffset = ((EntityPig) this.ridingEntity).renderYawOffset; + } + } + + /** + * Keeps moving the entity up so it isn't colliding with blocks and other + * requirements for this entity to be spawned (only actually used on players + * though its also on Entity) + */ + public void preparePlayerToSpawn() { + this.yOffset = 1.62F; + this.setSize(0.6F, 1.8F); + super.preparePlayerToSpawn(); + this.setEntityHealth(this.getMaxHealth()); + this.deathTime = 0; + } + + protected void updateEntityActionState() { + this.updateArmSwingProgress(); + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (this.flyToggleTimer > 0) { + --this.flyToggleTimer; + } + + if (this.worldObj.difficultySetting == 0 && this.getHealth() < this.getMaxHealth() && this.ticksExisted % 20 * 12 == 0) { + this.heal(1); + } + + this.inventory.decrementAnimations(); + this.prevCameraYaw = this.cameraYaw; + super.onLivingUpdate(); + this.landMovementFactor = this.capabilities.getWalkSpeed(); + this.jumpMovementFactor = this.speedInAir; + + if (this.isSprinting()) { + this.landMovementFactor = (float) ((double) this.landMovementFactor + (double) this.capabilities.getWalkSpeed() * 0.3D); + this.jumpMovementFactor = (float) ((double) this.jumpMovementFactor + (double) this.speedInAir * 0.3D); + } + + float var1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + float var2 = (float) Math.atan(-this.motionY * 0.20000000298023224D) * 15.0F; + + if (var1 > 0.1F) { + var1 = 0.1F; + } + + if (!this.onGround || this.getHealth() <= 0) { + var1 = 0.0F; + } + + if (this.onGround || this.getHealth() <= 0) { + var2 = 0.0F; + } + + this.cameraYaw += (var1 - this.cameraYaw) * 0.4F; + this.cameraPitch += (var2 - this.cameraPitch) * 0.8F; + + if (this.getHealth() > 0) { + List var3 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(1.0D, 0.5D, 1.0D)); + + if (var3 != null) { + for (int var4 = 0; var4 < var3.size(); ++var4) { + Entity var5 = (Entity) var3.get(var4); + + if (!var5.isDead) { + this.collideWithPlayer(var5); + } + } + } + } + } + + private void collideWithPlayer(Entity par1Entity) { + par1Entity.onCollideWithPlayer(this); + } + + public int getScore() { + return this.dataWatcher.getWatchableObjectInt(18); + } + + /** + * Set player's score + */ + public void setScore(int par1) { + this.dataWatcher.updateObject(18, Integer.valueOf(par1)); + } + + /** + * Add to player's score + */ + public void addScore(int par1) { + int var2 = this.getScore(); + this.dataWatcher.updateObject(18, Integer.valueOf(var2 + par1)); + } + + /** + * Called when the mob's health reaches 0. + */ + public void onDeath(DamageSource par1DamageSource) { + super.onDeath(par1DamageSource); + this.setSize(0.2F, 0.2F); + this.setPosition(this.posX, this.posY, this.posZ); + this.motionY = 0.10000000149011612D; + + if (this.username.equals("Notch")) { + this.dropPlayerItemWithRandomChoice(new ItemStack(Item.appleRed, 1), true); + } + + if (!this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory")) { + this.inventory.dropAllItems(); + } + + if (par1DamageSource != null) { + this.motionX = (double) (-MathHelper.cos((this.attackedAtYaw + this.rotationYaw) * (float) Math.PI / 180.0F) * 0.1F); + this.motionZ = (double) (-MathHelper.sin((this.attackedAtYaw + this.rotationYaw) * (float) Math.PI / 180.0F) * 0.1F); + } else { + this.motionX = this.motionZ = 0.0D; + } + + this.yOffset = 0.1F; + } + + /** + * Adds a value to the player score. Currently not actually used and the entity + * passed in does nothing. Args: entity, scoreToAdd + */ + public void addToPlayerScore(Entity par1Entity, int par2) { + this.addScore(par2); + Collection var3 = this.getWorldScoreboard().func_96520_a(ScoreObjectiveCriteria.field_96640_e); + + if (par1Entity instanceof EntityPlayer) { + var3.addAll(this.getWorldScoreboard().func_96520_a(ScoreObjectiveCriteria.field_96639_d)); + } else { + } + + Iterator var4 = var3.iterator(); + + while (var4.hasNext()) { + ScoreObjective var5 = (ScoreObjective) var4.next(); + Score var6 = this.getWorldScoreboard().func_96529_a(this.getEntityName(), var5); + var6.func_96648_a(); + } + } + + /** + * Called when player presses the drop item key + */ + public EntityItem dropOneItem(boolean par1) { + return this.dropPlayerItemWithRandomChoice(this.inventory.decrStackSize(this.inventory.currentItem, par1 && this.inventory.getCurrentItem() != null ? this.inventory.getCurrentItem().stackSize : 1), false); + } + + /** + * Args: itemstack - called when player drops an item stack that's not in his + * inventory (like items still placed in a workbench while the workbench'es GUI + * gets closed) + */ + public EntityItem dropPlayerItem(ItemStack par1ItemStack) { + return this.dropPlayerItemWithRandomChoice(par1ItemStack, false); + } + + /** + * Args: itemstack, flag + */ + public EntityItem dropPlayerItemWithRandomChoice(ItemStack par1ItemStack, boolean par2) { + if (par1ItemStack == null) { + return null; + } else { + EntityItem var3 = new EntityItem(this.worldObj, this.posX, this.posY - 0.30000001192092896D + (double) this.getEyeHeight(), this.posZ, par1ItemStack); + var3.delayBeforeCanPickup = 40; + float var4 = 0.1F; + float var5; + + if (par2) { + var5 = this.rand.nextFloat() * 0.5F; + float var6 = this.rand.nextFloat() * (float) Math.PI * 2.0F; + var3.motionX = (double) (-MathHelper.sin(var6) * var5); + var3.motionZ = (double) (MathHelper.cos(var6) * var5); + var3.motionY = 0.20000000298023224D; + } else { + var4 = 0.3F; + var3.motionX = (double) (-MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI) * var4); + var3.motionZ = (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI) * var4); + var3.motionY = (double) (-MathHelper.sin(this.rotationPitch / 180.0F * (float) Math.PI) * var4 + 0.1F); + var4 = 0.02F; + var5 = this.rand.nextFloat() * (float) Math.PI * 2.0F; + var4 *= this.rand.nextFloat(); + var3.motionX += Math.cos((double) var5) * (double) var4; + var3.motionY += (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.1F); + var3.motionZ += Math.sin((double) var5) * (double) var4; + } + + this.joinEntityItemWithWorld(var3); + return var3; + } + } + + /** + * Joins the passed in entity item with the world. Args: entityItem + */ + protected void joinEntityItemWithWorld(EntityItem par1EntityItem) { + this.worldObj.spawnEntityInWorld(par1EntityItem); + } + + /** + * Returns how strong the player is against the specified block at this moment + */ + public float getCurrentPlayerStrVsBlock(Block par1Block, boolean par2) { + float var3 = this.inventory.getStrVsBlock(par1Block); + + if (var3 > 1.0F) { + int var4 = EnchantmentHelper.getEfficiencyModifier(this); + ItemStack var5 = this.inventory.getCurrentItem(); + + if (var4 > 0 && var5 != null) { + float var6 = (float) (var4 * var4 + 1); + + if (!var5.canHarvestBlock(par1Block) && var3 <= 1.0F) { + var3 += var6 * 0.08F; + } else { + var3 += var6; + } + } + } + + if (this.isPotionActive(Potion.digSpeed)) { + var3 *= 1.0F + (float) (this.getActivePotionEffect(Potion.digSpeed).getAmplifier() + 1) * 0.2F; + } + + if (this.isPotionActive(Potion.digSlowdown)) { + var3 *= 1.0F - (float) (this.getActivePotionEffect(Potion.digSlowdown).getAmplifier() + 1) * 0.2F; + } + + if (this.isInsideOfMaterial(Material.water) && !EnchantmentHelper.getAquaAffinityModifier(this)) { + var3 /= 5.0F; + } + + if (!this.onGround) { + var3 /= 5.0F; + } + + return var3; + } + + /** + * Checks if the player has the ability to harvest a block (checks current + * inventory item for a tool if necessary) + */ + public boolean canHarvestBlock(Block par1Block) { + return this.inventory.canHarvestBlock(par1Block); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + NBTTagList var2 = par1NBTTagCompound.getTagList("Inventory"); + this.inventory.readFromNBT(var2); + this.inventory.currentItem = par1NBTTagCompound.getInteger("SelectedItemSlot"); + this.sleeping = par1NBTTagCompound.getBoolean("Sleeping"); + this.sleepTimer = par1NBTTagCompound.getShort("SleepTimer"); + this.experience = par1NBTTagCompound.getFloat("XpP"); + this.experienceLevel = par1NBTTagCompound.getInteger("XpLevel"); + this.experienceTotal = par1NBTTagCompound.getInteger("XpTotal"); + this.setScore(par1NBTTagCompound.getInteger("Score")); + + if (this.sleeping) { + this.playerLocation = new ChunkCoordinates(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)); + this.wakeUpPlayer(true, true, false); + } + + if (par1NBTTagCompound.hasKey("SpawnX") && par1NBTTagCompound.hasKey("SpawnY") && par1NBTTagCompound.hasKey("SpawnZ")) { + this.spawnChunk = new ChunkCoordinates(par1NBTTagCompound.getInteger("SpawnX"), par1NBTTagCompound.getInteger("SpawnY"), par1NBTTagCompound.getInteger("SpawnZ")); + this.spawnForced = par1NBTTagCompound.getBoolean("SpawnForced"); + } + + this.foodStats.readNBT(par1NBTTagCompound); + this.capabilities.readCapabilitiesFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("EnderItems")) { + NBTTagList var3 = par1NBTTagCompound.getTagList("EnderItems"); + this.theInventoryEnderChest.loadInventoryFromNBT(var3); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setTag("Inventory", this.inventory.writeToNBT(new NBTTagList())); + par1NBTTagCompound.setInteger("SelectedItemSlot", this.inventory.currentItem); + par1NBTTagCompound.setBoolean("Sleeping", this.sleeping); + par1NBTTagCompound.setShort("SleepTimer", (short) this.sleepTimer); + par1NBTTagCompound.setFloat("XpP", this.experience); + par1NBTTagCompound.setInteger("XpLevel", this.experienceLevel); + par1NBTTagCompound.setInteger("XpTotal", this.experienceTotal); + par1NBTTagCompound.setInteger("Score", this.getScore()); + + if (this.spawnChunk != null) { + par1NBTTagCompound.setInteger("SpawnX", this.spawnChunk.posX); + par1NBTTagCompound.setInteger("SpawnY", this.spawnChunk.posY); + par1NBTTagCompound.setInteger("SpawnZ", this.spawnChunk.posZ); + par1NBTTagCompound.setBoolean("SpawnForced", this.spawnForced); + } + + this.foodStats.writeNBT(par1NBTTagCompound); + this.capabilities.writeCapabilitiesToNBT(par1NBTTagCompound); + par1NBTTagCompound.setTag("EnderItems", this.theInventoryEnderChest.saveInventoryToNBT()); + } + + /** + * Displays the GUI for interacting with a chest inventory. Args: chestInventory + */ + public void displayGUIChest(IInventory par1IInventory) { + } + + public void displayGUIHopper(TileEntityHopper par1TileEntityHopper) { + } + + public void displayGUIHopperMinecart(EntityMinecartHopper par1EntityMinecartHopper) { + } + + public void displayGUIEnchantment(int par1, int par2, int par3, String par4Str) { + } + + /** + * Displays the GUI for interacting with an anvil. + */ + public void displayGUIAnvil(int par1, int par2, int par3) { + } + + /** + * Displays the crafting GUI for a workbench. + */ + public void displayGUIWorkbench(int par1, int par2, int par3) { + } + + public float getEyeHeight() { + return 0.12F; + } + + /** + * sets the players height back to normal after doing things like sleeping and + * dieing + */ + protected void resetHeight() { + this.yOffset = 1.62F; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else if (this.capabilities.disableDamage && !par1DamageSource.canHarmInCreative()) { + return false; + } else { + this.entityAge = 0; + + if (this.getHealth() <= 0) { + return false; + } else { + if (this.isPlayerSleeping() && !this.worldObj.isRemote) { + this.wakeUpPlayer(true, true, false); + } + + if (par1DamageSource.isDifficultyScaled()) { + if (this.worldObj.difficultySetting == 0) { + par2 = 0; + } + + if (this.worldObj.difficultySetting == 1) { + par2 = par2 / 2 + 1; + } + + if (this.worldObj.difficultySetting == 3) { + par2 = par2 * 3 / 2; + } + } + + if (par2 == 0) { + return false; + } else { + Entity var3 = par1DamageSource.getEntity(); + + if (var3 instanceof EntityArrow && ((EntityArrow) var3).shootingEntity != null) { + var3 = ((EntityArrow) var3).shootingEntity; + } + + if (var3 instanceof EntityLiving) { + this.alertWolves((EntityLiving) var3, false); + } + + return super.attackEntityFrom(par1DamageSource, par2); + } + } + } + } + + public boolean func_96122_a(EntityPlayer par1EntityPlayer) { + ScorePlayerTeam var2 = this.getTeam(); + ScorePlayerTeam var3 = par1EntityPlayer.getTeam(); + return var2 != var3 ? true : (var2 != null ? var2.func_96665_g() : true); + } + + /** + * Called when the player attack or gets attacked, it's alert all wolves in the + * area that are owned by the player to join the attack or defend the player. + */ + protected void alertWolves(EntityLiving par1EntityLiving, boolean par2) { + if (!(par1EntityLiving instanceof EntityCreeper) && !(par1EntityLiving instanceof EntityGhast)) { + if (par1EntityLiving instanceof EntityWolf) { + EntityWolf var3 = (EntityWolf) par1EntityLiving; + + if (var3.isTamed() && this.username.equals(var3.getOwnerName())) { + return; + } + } + + if (!(par1EntityLiving instanceof EntityPlayer) || this.func_96122_a((EntityPlayer) par1EntityLiving)) { + List var6 = this.worldObj.getEntitiesWithinAABB(EntityWolf.class, AxisAlignedBB.getAABBPool().getAABB(this.posX, this.posY, this.posZ, this.posX + 1.0D, this.posY + 1.0D, this.posZ + 1.0D).expand(16.0D, 4.0D, 16.0D)); + Iterator var4 = var6.iterator(); + + while (var4.hasNext()) { + EntityWolf var5 = (EntityWolf) var4.next(); + + if (var5.isTamed() && var5.getEntityToAttack() == null && this.username.equals(var5.getOwnerName()) && (!par2 || !var5.isSitting())) { + var5.setSitting(false); + var5.setTarget(par1EntityLiving); + } + } + } + } + } + + protected void damageArmor(int par1) { + this.inventory.damageArmor(par1); + } + + /** + * Returns the current armor value as determined by a call to + * InventoryPlayer.getTotalArmorValue + */ + public int getTotalArmorValue() { + return this.inventory.getTotalArmorValue(); + } + + public float func_82243_bO() { + int var1 = 0; + ItemStack[] var2 = this.inventory.armorInventory; + int var3 = var2.length; + + for (int var4 = 0; var4 < var3; ++var4) { + ItemStack var5 = var2[var4]; + + if (var5 != null) { + ++var1; + } + } + + return (float) var1 / (float) this.inventory.armorInventory.length; + } + + /** + * Deals damage to the entity. If its a EntityPlayer then will take damage from + * the armor first and then health second with the reduced value. Args: + * damageAmount + */ + protected void damageEntity(DamageSource par1DamageSource, int par2) { + if (!this.isEntityInvulnerable()) { + if (!par1DamageSource.isUnblockable() && this.isBlocking()) { + par2 = 1 + par2 >> 1; + } + + par2 = this.applyArmorCalculations(par1DamageSource, par2); + par2 = this.applyPotionDamageCalculations(par1DamageSource, par2); + this.addExhaustion(par1DamageSource.getHungerDamage()); + int var3 = this.getHealth(); + this.setEntityHealth(this.getHealth() - par2); + this.field_94063_bt.func_94547_a(par1DamageSource, var3, par2); + } + } + + /** + * Displays the furnace GUI for the passed in furnace entity. Args: + * tileEntityFurnace + */ + public void displayGUIFurnace(TileEntityFurnace par1TileEntityFurnace) { + } + + /** + * Displays the dipsenser GUI for the passed in dispenser entity. Args: + * TileEntityDispenser + */ + public void displayGUIDispenser(TileEntityDispenser par1TileEntityDispenser) { + } + + /** + * Displays the GUI for editing a sign. Args: tileEntitySign + */ + public void displayGUIEditSign(TileEntity par1TileEntity) { + } + + /** + * Displays the GUI for interacting with a brewing stand. + */ + public void displayGUIBrewingStand(TileEntityBrewingStand par1TileEntityBrewingStand) { + } + + /** + * Displays the GUI for interacting with a beacon. + */ + public void displayGUIBeacon(TileEntityBeacon par1TileEntityBeacon) { + } + + public void displayGUIMerchant(IMerchant par1IMerchant, String par2Str) { + } + + /** + * Displays the GUI for interacting with a book. + */ + public void displayGUIBook(ItemStack par1ItemStack) { + } + + public boolean interactWith(Entity par1Entity) { + if (par1Entity.interact(this)) { + return true; + } else { + ItemStack var2 = this.getCurrentEquippedItem(); + + if (var2 != null && par1Entity instanceof EntityLiving) { + if (this.capabilities.isCreativeMode) { + var2 = var2.copy(); + } + + if (var2.interactWith((EntityLiving) par1Entity)) { + if (var2.stackSize <= 0 && !this.capabilities.isCreativeMode) { + this.destroyCurrentEquippedItem(); + } + + return true; + } + } + + return false; + } + } + + /** + * Returns the currently being used item by the player. + */ + public ItemStack getCurrentEquippedItem() { + return this.inventory.getCurrentItem(); + } + + /** + * Destroys the currently equipped item from the player's inventory. + */ + public void destroyCurrentEquippedItem() { + this.inventory.setInventorySlotContents(this.inventory.currentItem, (ItemStack) null); + } + + /** + * Returns the Y Offset of this entity. + */ + public double getYOffset() { + return (double) (this.yOffset - 0.5F); + } + + /** + * Attacks for the player the targeted entity with the currently equipped item. + * The equipped item has hitEntity called on it. Args: targetEntity + */ + public void attackTargetEntityWithCurrentItem(Entity par1Entity) { + if (par1Entity.canAttackWithItem()) { + if (!par1Entity.func_85031_j(this)) { + int var2 = this.inventory.getDamageVsEntity(par1Entity); + + if (this.isPotionActive(Potion.damageBoost)) { + var2 += 3 << this.getActivePotionEffect(Potion.damageBoost).getAmplifier(); + } + + if (this.isPotionActive(Potion.weakness)) { + var2 -= 2 << this.getActivePotionEffect(Potion.weakness).getAmplifier(); + } + + int var3 = 0; + int var4 = 0; + + if (par1Entity instanceof EntityLiving) { + var4 = EnchantmentHelper.getEnchantmentModifierLiving(this, (EntityLiving) par1Entity); + var3 += EnchantmentHelper.getKnockbackModifier(this, (EntityLiving) par1Entity); + } + + if (this.isSprinting()) { + ++var3; + } + + if (var2 > 0 || var4 > 0) { + boolean var5 = this.fallDistance > 0.0F && !this.onGround && !this.isOnLadder() && !this.isInWater() && !this.isPotionActive(Potion.blindness) && this.ridingEntity == null && par1Entity instanceof EntityLiving; + + if (var5 && var2 > 0) { + var2 += this.rand.nextInt(var2 / 2 + 2); + } + + var2 += var4; + boolean var6 = false; + int var7 = EnchantmentHelper.getFireAspectModifier(this); + + if (par1Entity instanceof EntityLiving && var7 > 0 && !par1Entity.isBurning()) { + var6 = true; + par1Entity.setFire(1); + } + + boolean var8 = par1Entity.attackEntityFrom(DamageSource.causePlayerDamage(this), var2); + + if (var8) { + if (var3 > 0) { + par1Entity.addVelocity((double) (-MathHelper.sin(this.rotationYaw * (float) Math.PI / 180.0F) * (float) var3 * 0.5F), 0.1D, + (double) (MathHelper.cos(this.rotationYaw * (float) Math.PI / 180.0F) * (float) var3 * 0.5F)); + this.motionX *= 0.6D; + this.motionZ *= 0.6D; + this.setSprinting(false); + } + + if (var5) { + this.onCriticalHit(par1Entity); + } + + if (var4 > 0) { + this.onEnchantmentCritical(par1Entity); + } + + if (var2 >= 18) { + this.triggerAchievement(AchievementList.overkill); + } + + this.setLastAttackingEntity(par1Entity); + + if (par1Entity instanceof EntityLiving) { + EnchantmentThorns.func_92096_a(this, (EntityLiving) par1Entity, this.rand); + } + } + + ItemStack var9 = this.getCurrentEquippedItem(); + Object var10 = par1Entity; + + if (par1Entity instanceof EntityDragonPart) { + IEntityMultiPart var11 = ((EntityDragonPart) par1Entity).entityDragonObj; + + if (var11 != null && var11 instanceof EntityLiving) { + var10 = (EntityLiving) var11; + } + } + + if (var9 != null && var10 instanceof EntityLiving) { + var9.hitEntity((EntityLiving) var10, this); + + if (var9.stackSize <= 0) { + this.destroyCurrentEquippedItem(); + } + } + + if (par1Entity instanceof EntityLiving) { + if (par1Entity.isEntityAlive()) { + this.alertWolves((EntityLiving) par1Entity, true); + } + + if (var7 > 0 && var8) { + par1Entity.setFire(var7 * 4); + } else if (var6) { + par1Entity.extinguish(); + } + } + + this.addExhaustion(0.3F); + } + } + } + } + + /** + * Called when the player performs a critical hit on the Entity. Args: entity + * that was hit critically + */ + public void onCriticalHit(Entity par1Entity) { + } + + public void onEnchantmentCritical(Entity par1Entity) { + } + + public void respawnPlayer() { + } + + /** + * Will get destroyed next tick. + */ + public void setDead() { + super.setDead(); + this.inventoryContainer.onCraftGuiClosed(this); + + if (this.openContainer != null) { + this.openContainer.onCraftGuiClosed(this); + } + } + + /** + * Checks if this entity is inside of an opaque block + */ + public boolean isEntityInsideOpaqueBlock() { + return !this.sleeping && super.isEntityInsideOpaqueBlock(); + } + + public boolean func_71066_bF() { + return false; + } + + /** + * Attempts to have the player sleep in a bed at the specified location. + */ + public EnumStatus sleepInBedAt(int par1, int par2, int par3) { + if (!this.worldObj.isRemote) { + if (this.isPlayerSleeping() || !this.isEntityAlive()) { + return EnumStatus.OTHER_PROBLEM; + } + + if (!this.worldObj.provider.isSurfaceWorld()) { + return EnumStatus.NOT_POSSIBLE_HERE; + } + + if (this.worldObj.isDaytime()) { + return EnumStatus.NOT_POSSIBLE_NOW; + } + + if (Math.abs(this.posX - (double) par1) > 3.0D || Math.abs(this.posY - (double) par2) > 2.0D || Math.abs(this.posZ - (double) par3) > 3.0D) { + return EnumStatus.TOO_FAR_AWAY; + } + + double var4 = 8.0D; + double var6 = 5.0D; + List var8 = this.worldObj.getEntitiesWithinAABB(EntityMob.class, + AxisAlignedBB.getAABBPool().getAABB((double) par1 - var4, (double) par2 - var6, (double) par3 - var4, (double) par1 + var4, (double) par2 + var6, (double) par3 + var4)); + + if (!var8.isEmpty()) { + return EnumStatus.NOT_SAFE; + } + } + + this.setSize(0.2F, 0.2F); + this.yOffset = 0.2F; + + if (this.worldObj.blockExists(par1, par2, par3)) { + int var9 = this.worldObj.getBlockMetadata(par1, par2, par3); + int var5 = BlockBed.getDirection(var9); + float var10 = 0.5F; + float var7 = 0.5F; + + switch (var5) { + case 0: + var7 = 0.9F; + break; + + case 1: + var10 = 0.1F; + break; + + case 2: + var7 = 0.1F; + break; + + case 3: + var10 = 0.9F; + } + + this.func_71013_b(var5); + this.setPosition((double) ((float) par1 + var10), (double) ((float) par2 + 0.9375F), (double) ((float) par3 + var7)); + } else { + this.setPosition((double) ((float) par1 + 0.5F), (double) ((float) par2 + 0.9375F), (double) ((float) par3 + 0.5F)); + } + + this.sleeping = true; + this.sleepTimer = 0; + this.playerLocation = new ChunkCoordinates(par1, par2, par3); + this.motionX = this.motionZ = this.motionY = 0.0D; + + if (!this.worldObj.isRemote) { + this.worldObj.updateAllPlayersSleepingFlag(); + } + + return EnumStatus.OK; + } + + private void func_71013_b(int par1) { + this.field_71079_bU = 0.0F; + this.field_71089_bV = 0.0F; + + switch (par1) { + case 0: + this.field_71089_bV = -1.8F; + break; + + case 1: + this.field_71079_bU = 1.8F; + break; + + case 2: + this.field_71089_bV = 1.8F; + break; + + case 3: + this.field_71079_bU = -1.8F; + } + } + + /** + * Wake up the player if they're sleeping. + */ + public void wakeUpPlayer(boolean par1, boolean par2, boolean par3) { + this.setSize(0.6F, 1.8F); + this.resetHeight(); + ChunkCoordinates var4 = this.playerLocation; + ChunkCoordinates var5 = this.playerLocation; + + if (var4 != null && this.worldObj.getBlockId(var4.posX, var4.posY, var4.posZ) == Block.bed.blockID) { + BlockBed.setBedOccupied(this.worldObj, var4.posX, var4.posY, var4.posZ, false); + var5 = BlockBed.getNearestEmptyChunkCoordinates(this.worldObj, var4.posX, var4.posY, var4.posZ, 0); + + if (var5 == null) { + var5 = new ChunkCoordinates(var4.posX, var4.posY + 1, var4.posZ); + } + + this.setPosition((double) ((float) var5.posX + 0.5F), (double) ((float) var5.posY + this.yOffset + 0.1F), (double) ((float) var5.posZ + 0.5F)); + } + + this.sleeping = false; + + if (!this.worldObj.isRemote && par2) { + this.worldObj.updateAllPlayersSleepingFlag(); + } + + if (par1) { + this.sleepTimer = 0; + } else { + this.sleepTimer = 100; + } + + if (par3) { + this.setSpawnChunk(this.playerLocation, false); + } + } + + /** + * Checks if the player is currently in a bed + */ + private boolean isInBed() { + return this.worldObj.getBlockId(this.playerLocation.posX, this.playerLocation.posY, this.playerLocation.posZ) == Block.bed.blockID; + } + + /** + * Ensure that a block enabling respawning exists at the specified coordinates + * and find an empty space nearby to spawn. + */ + public static ChunkCoordinates verifyRespawnCoordinates(World par0World, ChunkCoordinates par1ChunkCoordinates, boolean par2) { + IChunkProvider var3 = par0World.getChunkProvider(); + var3.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ - 3 >> 4); + var3.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ - 3 >> 4); + var3.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4); + var3.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4); + + if (par0World.getBlockId(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY, par1ChunkCoordinates.posZ) == Block.bed.blockID) { + ChunkCoordinates var8 = BlockBed.getNearestEmptyChunkCoordinates(par0World, par1ChunkCoordinates.posX, par1ChunkCoordinates.posY, par1ChunkCoordinates.posZ, 0); + return var8; + } else { + Material var4 = par0World.getBlockMaterial(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY, par1ChunkCoordinates.posZ); + Material var5 = par0World.getBlockMaterial(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY + 1, par1ChunkCoordinates.posZ); + boolean var6 = !var4.isSolid() && !var4.isLiquid(); + boolean var7 = !var5.isSolid() && !var5.isLiquid(); + return par2 && var6 && var7 ? par1ChunkCoordinates : null; + } + } + + /** + * Returns the orientation of the bed in degrees. + */ + public float getBedOrientationInDegrees() { + if (this.playerLocation != null) { + int var1 = this.worldObj.getBlockMetadata(this.playerLocation.posX, this.playerLocation.posY, this.playerLocation.posZ); + int var2 = BlockBed.getDirection(var1); + + switch (var2) { + case 0: + return 90.0F; + + case 1: + return 0.0F; + + case 2: + return 270.0F; + + case 3: + return 180.0F; + } + } + + return 0.0F; + } + + /** + * Returns whether player is sleeping or not + */ + public boolean isPlayerSleeping() { + return this.sleeping; + } + + /** + * Returns whether or not the player is asleep and the screen has fully faded. + */ + public boolean isPlayerFullyAsleep() { + return this.sleeping && this.sleepTimer >= 100; + } + + public int getSleepTimer() { + return this.sleepTimer; + } + + protected boolean getHideCape(int par1) { + return (this.dataWatcher.getWatchableObjectByte(16) & 1 << par1) != 0; + } + + protected void setHideCape(int par1, boolean par2) { + byte var3 = this.dataWatcher.getWatchableObjectByte(16); + + if (par2) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var3 | 1 << par1))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var3 & ~(1 << par1)))); + } + } + + /** + * Add a chat message to the player + */ + public void addChatMessage(String par1Str) { + } + + /** + * Returns the location of the bed the player will respawn at, or null if the + * player has not slept in a bed. + */ + public ChunkCoordinates getBedLocation() { + return this.spawnChunk; + } + + public boolean isSpawnForced() { + return this.spawnForced; + } + + /** + * Defines a spawn coordinate to player spawn. Used by bed after the player + * sleep on it. + */ + public void setSpawnChunk(ChunkCoordinates par1ChunkCoordinates, boolean par2) { + if (par1ChunkCoordinates != null) { + this.spawnChunk = new ChunkCoordinates(par1ChunkCoordinates); + this.spawnForced = par2; + } else { + this.spawnChunk = null; + this.spawnForced = false; + } + } + + /** + * Will trigger the specified trigger. + */ + public void triggerAchievement(StatBase par1StatBase) { + this.addStat(par1StatBase, 1); + } + + /** + * Adds a value to a statistic field. + */ + public void addStat(StatBase par1StatBase, int par2) { + } + + /** + * Causes this entity to do an upwards motion (jumping). + */ + protected void jump() { + super.jump(); + + if (this.isSprinting()) { + this.addExhaustion(0.8F); + } else { + this.addExhaustion(0.2F); + } + } + + /** + * Moves the entity based on the specified heading. Args: strafe, forward + */ + public void moveEntityWithHeading(float par1, float par2) { + double var3 = this.posX; + double var5 = this.posY; + double var7 = this.posZ; + + if (this.capabilities.isFlying && this.ridingEntity == null) { + double var9 = this.motionY; + float var11 = this.jumpMovementFactor; + this.jumpMovementFactor = this.capabilities.getFlySpeed(); + super.moveEntityWithHeading(par1, par2); + this.motionY = var9 * 0.6D; + this.jumpMovementFactor = var11; + } else { + super.moveEntityWithHeading(par1, par2); + } + + this.addMovementStat(this.posX - var3, this.posY - var5, this.posZ - var7); + } + + /** + * Adds a value to a movement statistic field - like run, walk, swin or climb. + */ + public void addMovementStat(double par1, double par3, double par5) { + if (this.ridingEntity == null) { + int var7; + + if (this.isInsideOfMaterial(Material.water)) { + var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5) * 100.0F); + + if (var7 > 0) { + this.addExhaustion(0.015F * (float) var7 * 0.01F); + } + } else if (this.isInWater()) { + var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F); + + if (var7 > 0) { + this.addExhaustion(0.015F * (float) var7 * 0.01F); + } + } else if (this.isOnLadder()) { + if (par3 > 0.0D) { + } + } else if (this.onGround) { + var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F); + + if (var7 > 0) { + + if (this.isSprinting()) { + this.addExhaustion(0.099999994F * (float) var7 * 0.01F); + } else { + this.addExhaustion(0.01F * (float) var7 * 0.01F); + } + } + } else { + var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F); + + if (var7 > 25) { + } + } + } + } + + /** + * Adds a value to a mounted movement statistic field - by minecart, boat, or + * pig. + */ + private void addMountedMovementStat(double par1, double par3, double par5) { + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + if (!this.capabilities.allowFlying) { + + super.fall(par1); + } + } + + /** + * This method gets called when the entity kills another one. + */ + public void onKillEntity(EntityLiving par1EntityLiving) { + if (par1EntityLiving instanceof IMob) { + this.triggerAchievement(AchievementList.killEnemy); + } + } + + /** + * Sets the Entity inside a web block. + */ + public void setInWeb() { + if (!this.capabilities.isFlying) { + super.setInWeb(); + } + } + + /** + * Gets the Icon Index of the item currently held + */ + public Icon getItemIcon(ItemStack par1ItemStack, int par2) { + Icon var3 = super.getItemIcon(par1ItemStack, par2); + + if (par1ItemStack.itemID == Item.fishingRod.itemID && this.fishEntity != null) { + var3 = Item.fishingRod.func_94597_g(); + } else { + if (par1ItemStack.getItem().requiresMultipleRenderPasses()) { + return par1ItemStack.getItem().getIconFromDamageForRenderPass(par1ItemStack.getItemDamage(), par2); + } + + if (this.itemInUse != null && par1ItemStack.itemID == Item.bow.itemID) { + int var4 = par1ItemStack.getMaxItemUseDuration() - this.itemInUseCount; + + if (var4 >= 18) { + return Item.bow.getItemIconForUseDuration(2); + } + + if (var4 > 13) { + return Item.bow.getItemIconForUseDuration(1); + } + + if (var4 > 0) { + return Item.bow.getItemIconForUseDuration(0); + } + } + } + + return var3; + } + + public ItemStack getCurrentArmor(int par1) { + return this.inventory.armorItemInSlot(par1); + } + + /** + * Makes entity wear random armor based on difficulty + */ + protected void addRandomArmor() { + } + + protected void func_82162_bC() { + } + + /** + * This method increases the player's current amount of experience. + */ + public void addExperience(int par1) { + this.addScore(par1); + int var2 = Integer.MAX_VALUE - this.experienceTotal; + + if (par1 > var2) { + par1 = var2; + } + + this.experience += (float) par1 / (float) this.xpBarCap(); + + for (this.experienceTotal += par1; this.experience >= 1.0F; this.experience /= (float) this.xpBarCap()) { + this.experience = (this.experience - 1.0F) * (float) this.xpBarCap(); + this.addExperienceLevel(1); + } + } + + /** + * Add experience levels to this player. + */ + public void addExperienceLevel(int par1) { + this.experienceLevel += par1; + + if (this.experienceLevel < 0) { + this.experienceLevel = 0; + this.experience = 0.0F; + this.experienceTotal = 0; + } + + if (par1 > 0 && this.experienceLevel % 5 == 0 && (float) this.field_82249_h < (float) this.ticksExisted - 100.0F) { + float var2 = this.experienceLevel > 30 ? 1.0F : (float) this.experienceLevel / 30.0F; + this.worldObj.playSoundAtEntity(this, "random.levelup", var2 * 0.75F, 1.0F); + this.field_82249_h = this.ticksExisted; + } + } + + /** + * This method returns the cap amount of experience that the experience bar can + * hold. With each level, the experience cap on the player's experience bar is + * raised by 10. + */ + public int xpBarCap() { + return this.experienceLevel >= 30 ? 62 + (this.experienceLevel - 30) * 7 : (this.experienceLevel >= 15 ? 17 + (this.experienceLevel - 15) * 3 : 17); + } + + /** + * increases exhaustion level by supplied amount + */ + public void addExhaustion(float par1) { + if (!this.capabilities.disableDamage) { + if (!this.worldObj.isRemote) { + this.foodStats.addExhaustion(par1); + } + } + } + + /** + * Returns the player's FoodStats object. + */ + public FoodStats getFoodStats() { + return this.foodStats; + } + + public boolean canEat(boolean par1) { + return (par1 || this.foodStats.needFood()) && !this.capabilities.disableDamage; + } + + /** + * Checks if the player's health is not full and not zero. + */ + public boolean shouldHeal() { + return this.getHealth() > 0 && this.getHealth() < this.getMaxHealth(); + } + + /** + * sets the itemInUse when the use item button is clicked. Args: itemstack, int + * maxItemUseDuration + */ + public void setItemInUse(ItemStack par1ItemStack, int par2) { + if (par1ItemStack != this.itemInUse) { + this.itemInUse = par1ItemStack; + this.itemInUseCount = par2; + + if (!this.worldObj.isRemote) { + this.setEating(true); + } + } + } + + /** + * Returns true if the item the player is holding can harvest the block at the + * given coords. Args: x, y, z. + */ + public boolean canCurrentToolHarvestBlock(int par1, int par2, int par3) { + if (this.capabilities.allowEdit) { + return true; + } else { + int var4 = this.worldObj.getBlockId(par1, par2, par3); + + if (var4 > 0) { + Block var5 = Block.blocksList[var4]; + + if (var5.blockMaterial.isAlwaysHarvested()) { + return true; + } + + if (this.getCurrentEquippedItem() != null) { + ItemStack var6 = this.getCurrentEquippedItem(); + + if (var6.canHarvestBlock(var5) || var6.getStrVsBlock(var5) > 1.0F) { + return true; + } + } + } + + return false; + } + } + + public boolean canPlayerEdit(int par1, int par2, int par3, int par4, ItemStack par5ItemStack) { + return this.capabilities.allowEdit ? true : (par5ItemStack != null ? par5ItemStack.func_82835_x() : false); + } + + /** + * Get the experience points the entity currently has. + */ + protected int getExperiencePoints(EntityPlayer par1EntityPlayer) { + if (this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory")) { + return 0; + } else { + int var2 = this.experienceLevel * 7; + return var2 > 100 ? 100 : var2; + } + } + + /** + * Only use is to identify if class is an instance of player for experience + * dropping + */ + protected boolean isPlayer() { + return true; + } + + /** + * Gets the username of the entity. + */ + public String getEntityName() { + return this.username; + } + + public boolean func_94062_bN() { + return super.func_94062_bN(); + } + + public boolean func_94059_bO() { + return true; + } + + public boolean canPickUpLoot() { + return false; + } + + /** + * Copies the values from the given player into this player if boolean par2 is + * true. Always clones Ender Chest Inventory. + */ + public void clonePlayer(EntityPlayer par1EntityPlayer, boolean par2) { + if (par2) { + this.inventory.copyInventory(par1EntityPlayer.inventory); + this.health = par1EntityPlayer.health; + this.foodStats = par1EntityPlayer.foodStats; + this.experienceLevel = par1EntityPlayer.experienceLevel; + this.experienceTotal = par1EntityPlayer.experienceTotal; + this.experience = par1EntityPlayer.experience; + this.setScore(par1EntityPlayer.getScore()); + this.teleportDirection = par1EntityPlayer.teleportDirection; + } else if (this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory")) { + this.inventory.copyInventory(par1EntityPlayer.inventory); + this.experienceLevel = par1EntityPlayer.experienceLevel; + this.experienceTotal = par1EntityPlayer.experienceTotal; + this.experience = par1EntityPlayer.experience; + this.setScore(par1EntityPlayer.getScore()); + } + + this.theInventoryEnderChest = par1EntityPlayer.theInventoryEnderChest; + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return !this.capabilities.isFlying; + } + + /** + * Sends the player's abilities to the server (if there is one). + */ + public void sendPlayerAbilities() { + } + + /** + * Sets the player's game mode and sends it to them. + */ + public void setGameType(EnumGameType par1EnumGameType) { + } + + /** + * Gets the name of this command sender (usually username, but possibly "Rcon") + */ + public String getCommandSenderName() { + return this.username; + } + + public StringTranslate getTranslator() { + return StringTranslate.getInstance(); + } + + /** + * Translates and formats the given string key with the given arguments. + */ + public String translateString(String par1Str, Object... par2ArrayOfObj) { + return this.getTranslator().translateKeyFormat(par1Str, par2ArrayOfObj); + } + + /** + * Returns the InventoryEnderChest of this player. + */ + public InventoryEnderChest getInventoryEnderChest() { + return this.theInventoryEnderChest; + } + + /** + * 0 = item, 1-n is armor + */ + public ItemStack getCurrentItemOrArmor(int par1) { + return par1 == 0 ? this.inventory.getCurrentItem() : this.inventory.armorInventory[par1 - 1]; + } + + /** + * Returns the item that this EntityLiving is holding, if any. + */ + public ItemStack getHeldItem() { + return this.inventory.getCurrentItem(); + } + + /** + * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. + * Params: Item, slot + */ + public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack) { + this.inventory.armorInventory[par1] = par2ItemStack; + } + + public boolean func_98034_c(EntityPlayer par1EntityPlayer) { + if (!this.isInvisible()) { + return false; + } else { + ScorePlayerTeam var2 = this.getTeam(); + return var2 == null || par1EntityPlayer == null || par1EntityPlayer.getTeam() != var2 || !var2.func_98297_h(); + } + } + + public ItemStack[] getLastActiveItems() { + return this.inventory.armorInventory; + } + + public boolean getHideCape() { + return this.getHideCape(1); + } + + public boolean func_96092_aw() { + return !this.capabilities.isFlying; + } + + public Scoreboard getWorldScoreboard() { + return this.worldObj.getScoreboard(); + } + + public ScorePlayerTeam getTeam() { + return this.getWorldScoreboard().getPlayersTeam(this.username); + } + + /** + * Returns the translated name of the entity. + */ + public String getTranslatedEntityName() { + return ScorePlayerTeam.func_96667_a(this.getTeam(), this.username); + } +} diff --git a/src/main/java/net/minecraft/src/EntityPlayerSP.java b/src/main/java/net/minecraft/src/EntityPlayerSP.java new file mode 100644 index 0000000..8fa700f --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityPlayerSP.java @@ -0,0 +1,510 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.LocalStorageManager; +import net.minecraft.client.Minecraft; + +public class EntityPlayerSP extends EntityPlayer { + public MovementInput movementInput; + protected Minecraft mc; + + /** + * Used to tell if the player pressed forward twice. If this is at 0 and it's + * pressed (And they are allowed to sprint, aka enough food on the ground etc) + * it sets this to 7. If it's pressed and it's greater than 0 enable sprinting. + */ + protected int sprintToggleTimer = 0; + + /** Ticks left before sprinting is disabled. */ + public int sprintingTicksLeft = 0; + public float renderArmYaw; + public float renderArmPitch; + public float prevRenderArmYaw; + public float prevRenderArmPitch; + private MouseFilter field_71162_ch = new MouseFilter(); + private MouseFilter field_71160_ci = new MouseFilter(); + private MouseFilter field_71161_cj = new MouseFilter(); + + /** The amount of time an entity has been in a Portal */ + public float timeInPortal; + + /** The amount of time an entity has been in a Portal the previous tick */ + public float prevTimeInPortal; + + public EntityPlayerSP(Minecraft par1Minecraft, World par2World, String par3Session, int par4) { + super(); + this.setWorld(par2World); + this.mc = par1Minecraft; + this.dimension = par4; + this.username = par3Session; + } + + /** + * Tries to moves the entity by the passed in displacement. Args: x, y, z + */ + public void moveEntity(double par1, double par3, double par5) { + super.moveEntity(par1, par3, par5); + } + + public void updateEntityActionState() { + super.updateEntityActionState(); + this.moveStrafing = this.movementInput.moveStrafe; + this.moveForward = this.movementInput.moveForward; + this.isJumping = this.movementInput.jump; + this.prevRenderArmYaw = this.renderArmYaw; + this.prevRenderArmPitch = this.renderArmPitch; + this.renderArmPitch = (float) ((double) this.renderArmPitch + (double) (this.rotationPitch - this.renderArmPitch) * 0.5D); + this.renderArmYaw = (float) ((double) this.renderArmYaw + (double) (this.rotationYaw - this.renderArmYaw) * 0.5D); + } + + /** + * Returns whether the entity is in a local (client) world + */ + protected boolean isClientWorld() { + return true; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (this.sprintingTicksLeft > 0) { + --this.sprintingTicksLeft; + + if (this.sprintingTicksLeft == 0) { + this.setSprinting(false); + } + } + + if (this.sprintToggleTimer > 0) { + --this.sprintToggleTimer; + } + + if (this.mc.playerController.enableEverythingIsScrewedUpMode()) { + this.posX = this.posZ = 0.5D; + this.posX = 0.0D; + this.posZ = 0.0D; + this.rotationYaw = (float) this.ticksExisted / 12.0F; + this.rotationPitch = 10.0F; + this.posY = 68.5D; + } else { + + this.prevTimeInPortal = this.timeInPortal; + + if (this.inPortal) { + if (this.mc.currentScreen != null) { + this.mc.displayGuiScreen((GuiScreen) null); + } + + if (this.timeInPortal == 0.0F) { + this.mc.sndManager.playSoundFX("portal.trigger", 1.0F, this.rand.nextFloat() * 0.4F + 0.8F); + } + + this.timeInPortal += 0.0125F; + + if (this.timeInPortal >= 1.0F) { + this.timeInPortal = 1.0F; + } + + this.inPortal = false; + } else if (this.isPotionActive(Potion.confusion) && this.getActivePotionEffect(Potion.confusion).getDuration() > 60) { + this.timeInPortal += 0.006666667F; + + if (this.timeInPortal > 1.0F) { + this.timeInPortal = 1.0F; + } + } else { + if (this.timeInPortal > 0.0F) { + this.timeInPortal -= 0.05F; + } + + if (this.timeInPortal < 0.0F) { + this.timeInPortal = 0.0F; + } + } + + if (this.timeUntilPortal > 0) { + --this.timeUntilPortal; + } + + boolean var1 = this.movementInput.jump; + float var2 = 0.8F; + boolean var3 = this.movementInput.moveForward >= var2; + this.movementInput.updatePlayerMoveState(); + + if (this.isUsingItem()) { + this.movementInput.moveStrafe *= 0.2F; + this.movementInput.moveForward *= 0.2F; + this.sprintToggleTimer = 0; + } + + if (this.movementInput.sneak && this.ySize < 0.2F) { + this.ySize = 0.2F; + } + + this.pushOutOfBlocks(this.posX - (double) this.width * 0.35D, this.boundingBox.minY + 0.5D, this.posZ + (double) this.width * 0.35D); + this.pushOutOfBlocks(this.posX - (double) this.width * 0.35D, this.boundingBox.minY + 0.5D, this.posZ - (double) this.width * 0.35D); + this.pushOutOfBlocks(this.posX + (double) this.width * 0.35D, this.boundingBox.minY + 0.5D, this.posZ - (double) this.width * 0.35D); + this.pushOutOfBlocks(this.posX + (double) this.width * 0.35D, this.boundingBox.minY + 0.5D, this.posZ + (double) this.width * 0.35D); + boolean var4 = this.canSprint(); + + if (this.onGround && !var3 && this.movementInput.moveForward >= var2 && !this.isSprinting() && var4 && !this.isUsingItem() && !this.isPotionActive(Potion.blindness)) { + if (this.sprintToggleTimer == 0) { + this.sprintToggleTimer = 7; + } else { + this.setSprinting(true); + this.sprintToggleTimer = 0; + } + } + + if (this.isSneaking()) { + this.sprintToggleTimer = 0; + } + + if (this.isSprinting() && (this.movementInput.moveForward < var2 || this.isCollidedHorizontally || !var4)) { + this.setSprinting(false); + } + + if (this.capabilities.allowFlying && !var1 && this.movementInput.jump) { + if (this.flyToggleTimer == 0) { + this.flyToggleTimer = 7; + } else { + this.capabilities.isFlying = !this.capabilities.isFlying; + this.sendPlayerAbilities(); + this.flyToggleTimer = 0; + } + } + + if (this.capabilities.isFlying) { + if (this.movementInput.sneak) { + this.motionY -= 0.15D; + } + + if (this.movementInput.jump) { + this.motionY += 0.15D; + } + } + + super.onLivingUpdate(); + + if (this.onGround && this.capabilities.isFlying) { + this.capabilities.isFlying = false; + this.sendPlayerAbilities(); + } + } + } + + public boolean canSprint() { + return (float) this.getFoodStats().getFoodLevel() > 6.0F || this.capabilities.allowFlying; + } + + /** + * Gets the player's field of view multiplier. (ex. when flying) + */ + public float getFOVMultiplier() { + float var1 = 1.0F; + + if (this.capabilities.isFlying) { + var1 *= 1.1F; + } + + var1 *= (this.landMovementFactor * this.getSpeedModifier() / this.speedOnGround + 1.0F) / 2.0F; + + if (this.isUsingItem() && this.getItemInUse().itemID == Item.bow.itemID) { + int var2 = this.getItemInUseDuration(); + float var3 = (float) var2 / 20.0F; + + if (var3 > 1.0F) { + var3 = 1.0F; + } else { + var3 *= var3; + } + + var1 *= 1.0F - var3 * 0.15F; + } + + return var1; + } + + public void updateCloak() { + + } + + /** + * sets current screen to null (used on escape buttons of GUIs) + */ + public void closeScreen() { + super.closeScreen(); + this.mc.displayGuiScreen((GuiScreen) null); + } + + /** + * Displays the GUI for editing a sign. Args: tileEntitySign + */ + public void displayGUIEditSign(TileEntity par1TileEntity) { + if (par1TileEntity instanceof TileEntitySign) { + this.mc.displayGuiScreen(new GuiEditSign((TileEntitySign) par1TileEntity)); + } else if (par1TileEntity instanceof TileEntityCommandBlock) { + this.mc.displayGuiScreen(new GuiCommandBlock((TileEntityCommandBlock) par1TileEntity)); + } + } + + /** + * Displays the GUI for interacting with a book. + */ + public void displayGUIBook(ItemStack par1ItemStack) { + Item var2 = par1ItemStack.getItem(); + + if (var2 == Item.writtenBook) { + this.mc.displayGuiScreen(new GuiScreenBook(this, par1ItemStack, false)); + } else if (var2 == Item.writableBook) { + this.mc.displayGuiScreen(new GuiScreenBook(this, par1ItemStack, true)); + } + } + + /** + * Displays the GUI for interacting with a chest inventory. Args: chestInventory + */ + public void displayGUIChest(IInventory par1IInventory) { + this.mc.displayGuiScreen(new GuiChest(this.inventory, par1IInventory)); + } + + public void displayGUIHopper(TileEntityHopper par1TileEntityHopper) { + this.mc.displayGuiScreen(new GuiHopper(this.inventory, par1TileEntityHopper)); + } + + public void displayGUIHopperMinecart(EntityMinecartHopper par1EntityMinecartHopper) { + this.mc.displayGuiScreen(new GuiHopper(this.inventory, par1EntityMinecartHopper)); + } + + /** + * Displays the crafting GUI for a workbench. + */ + public void displayGUIWorkbench(int par1, int par2, int par3) { + this.mc.displayGuiScreen(new GuiCrafting(this.inventory, this.worldObj, par1, par2, par3)); + } + + public void displayGUIEnchantment(int par1, int par2, int par3, String par4Str) { + this.mc.displayGuiScreen(new GuiEnchantment(this.inventory, this.worldObj, par1, par2, par3, par4Str)); + } + + /** + * Displays the GUI for interacting with an anvil. + */ + public void displayGUIAnvil(int par1, int par2, int par3) { + this.mc.displayGuiScreen(new GuiRepair(this.inventory, this.worldObj, par1, par2, par3)); + } + + /** + * Displays the furnace GUI for the passed in furnace entity. Args: + * tileEntityFurnace + */ + public void displayGUIFurnace(TileEntityFurnace par1TileEntityFurnace) { + this.mc.displayGuiScreen(new GuiFurnace(this.inventory, par1TileEntityFurnace)); + } + + /** + * Displays the GUI for interacting with a brewing stand. + */ + public void displayGUIBrewingStand(TileEntityBrewingStand par1TileEntityBrewingStand) { + this.mc.displayGuiScreen(new GuiBrewingStand(this.inventory, par1TileEntityBrewingStand)); + } + + /** + * Displays the GUI for interacting with a beacon. + */ + public void displayGUIBeacon(TileEntityBeacon par1TileEntityBeacon) { + this.mc.displayGuiScreen(new GuiBeacon(this.inventory, par1TileEntityBeacon)); + } + + /** + * Displays the dipsenser GUI for the passed in dispenser entity. Args: + * TileEntityDispenser + */ + public void displayGUIDispenser(TileEntityDispenser par1TileEntityDispenser) { + this.mc.displayGuiScreen(new GuiDispenser(this.inventory, par1TileEntityDispenser)); + } + + public void displayGUIMerchant(IMerchant par1IMerchant, String par2Str) { + this.mc.displayGuiScreen(new GuiMerchant(this.inventory, par1IMerchant, this.worldObj, par2Str)); + } + + /** + * Called when the player performs a critical hit on the Entity. Args: entity + * that was hit critically + */ + public void onCriticalHit(Entity par1Entity) { + this.mc.effectRenderer.addEffect(new EntityCrit2FX(this.mc.theWorld, par1Entity)); + } + + public void onEnchantmentCritical(Entity par1Entity) { + EntityCrit2FX var2 = new EntityCrit2FX(this.mc.theWorld, par1Entity, "magicCrit"); + this.mc.effectRenderer.addEffect(var2); + } + + /** + * Called whenever an item is picked up from walking over it. Args: + * pickedUpEntity, stackSize + */ + public void onItemPickup(Entity par1Entity, int par2) { + this.mc.effectRenderer.addEffect(new EntityPickupFX(this.mc.theWorld, par1Entity, this, -0.5F)); + } + + /** + * Returns if this entity is sneaking. + */ + public boolean isSneaking() { + return this.movementInput.sneak && !this.sleeping; + } + + /** + * Updates health locally. + */ + public void setHealth(int par1) { + int var2 = this.getHealth() - par1; + + if (var2 <= 0) { + this.setEntityHealth(par1); + + if (var2 < 0) { + this.hurtResistantTime = this.maxHurtResistantTime / 2; + } + } else { + this.lastDamage = var2; + this.setEntityHealth(this.getHealth()); + this.hurtResistantTime = this.maxHurtResistantTime; + this.damageEntity(DamageSource.generic, var2); + this.hurtTime = this.maxHurtTime = 10; + } + } + + /** + * Add a chat message to the player + */ + public void addChatMessage(String par1Str) { + this.mc.ingameGUI.getChatGUI().addTranslatedMessage(par1Str, new Object[0]); + } + + /** + * Adds a value to a statistic field. + */ + public void addStat(StatBase par1StatBase, int par2) { + if (par1StatBase != null) { + if(par1StatBase.isAchievement() && LocalStorageManager.hasMadeAchievement((Achievement)par1StatBase)) { + this.mc.guiAchievement.queueTakenAchievement((Achievement)par1StatBase); + } + } + } + + private boolean isBlockTranslucent(int par1, int par2, int par3) { + return this.worldObj.isBlockNormalCube(par1, par2, par3); + } + + /** + * Adds velocity to push the entity out of blocks at the specified x, y, z + * position Args: x, y, z + */ + protected boolean pushOutOfBlocks(double par1, double par3, double par5) { + int var7 = MathHelper.floor_double(par1); + int var8 = MathHelper.floor_double(par3); + int var9 = MathHelper.floor_double(par5); + double var10 = par1 - (double) var7; + double var12 = par5 - (double) var9; + + if (this.isBlockTranslucent(var7, var8, var9) || this.isBlockTranslucent(var7, var8 + 1, var9)) { + boolean var14 = !this.isBlockTranslucent(var7 - 1, var8, var9) && !this.isBlockTranslucent(var7 - 1, var8 + 1, var9); + boolean var15 = !this.isBlockTranslucent(var7 + 1, var8, var9) && !this.isBlockTranslucent(var7 + 1, var8 + 1, var9); + boolean var16 = !this.isBlockTranslucent(var7, var8, var9 - 1) && !this.isBlockTranslucent(var7, var8 + 1, var9 - 1); + boolean var17 = !this.isBlockTranslucent(var7, var8, var9 + 1) && !this.isBlockTranslucent(var7, var8 + 1, var9 + 1); + byte var18 = -1; + double var19 = 9999.0D; + + if (var14 && var10 < var19) { + var19 = var10; + var18 = 0; + } + + if (var15 && 1.0D - var10 < var19) { + var19 = 1.0D - var10; + var18 = 1; + } + + if (var16 && var12 < var19) { + var19 = var12; + var18 = 4; + } + + if (var17 && 1.0D - var12 < var19) { + var19 = 1.0D - var12; + var18 = 5; + } + + float var21 = 0.1F; + + if (var18 == 0) { + this.motionX = (double) (-var21); + } + + if (var18 == 1) { + this.motionX = (double) var21; + } + + if (var18 == 4) { + this.motionZ = (double) (-var21); + } + + if (var18 == 5) { + this.motionZ = (double) var21; + } + } + + return false; + } + + /** + * Set sprinting switch for Entity. + */ + public void setSprinting(boolean par1) { + super.setSprinting(par1); + this.sprintingTicksLeft = par1 ? 600 : 0; + } + + /** + * Sets the current XP, total XP, and level number. + */ + public void setXPStats(float par1, int par2, int par3) { + this.experience = par1; + this.experienceTotal = par2; + this.experienceLevel = par3; + } + + public void sendChatToPlayer(String par1Str) { + this.mc.ingameGUI.getChatGUI().printChatMessage(par1Str); + } + + /** + * Returns true if the command sender is allowed to use the given command. + */ + public boolean canCommandSenderUseCommand(int par1, String par2Str) { + return par1 <= 0; + } + + /** + * Return the position for this command sender. + */ + public ChunkCoordinates getPlayerCoordinates() { + return new ChunkCoordinates(MathHelper.floor_double(this.posX + 0.5D), MathHelper.floor_double(this.posY + 0.5D), MathHelper.floor_double(this.posZ + 0.5D)); + } + + /** + * Returns the item that this EntityLiving is holding, if any. + */ + public ItemStack getHeldItem() { + return this.inventory.getCurrentItem(); + } + + public void playSound(String par1Str, float par2, float par3) { + this.worldObj.playSound(this.posX, this.posY - (double) this.yOffset, this.posZ, par1Str, par2, par3, false); + } +} diff --git a/src/main/java/net/minecraft/src/EntityPortalFX.java b/src/main/java/net/minecraft/src/EntityPortalFX.java new file mode 100644 index 0000000..c7bd738 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityPortalFX.java @@ -0,0 +1,84 @@ +package net.minecraft.src; + + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityPortalFX extends EntityFX { + private float portalParticleScale; + private double portalPosX; + private double portalPosY; + private double portalPosZ; + + public EntityPortalFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + super(par1World, par2, par4, par6, par8, par10, par12); + this.motionX = par8; + this.motionY = par10; + this.motionZ = par12; + this.portalPosX = this.posX = par2; + this.portalPosY = this.posY = par4; + this.portalPosZ = this.posZ = par6; + float var14 = this.rand.nextFloat() * 0.6F + 0.4F; + this.portalParticleScale = this.particleScale = this.rand.nextFloat() * 0.2F + 0.5F; + this.particleRed = this.particleGreen = this.particleBlue = 1.0F * var14; + this.particleGreen *= 0.3F; + this.particleRed *= 0.9F; + this.particleMaxAge = (int) (Math.random() * 10.0D) + 40; + this.noClip = true; + this.setParticleTextureIndex((int) (Math.random() * 8.0D)); + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = ((float) this.particleAge + par2) / (float) this.particleMaxAge; + var8 = 1.0F - var8; + var8 *= var8; + var8 = 1.0F - var8; + this.particleScale = this.portalParticleScale * var8; + super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); + } + + public int getBrightnessForRender(float par1) { + int var2 = super.getBrightnessForRender(par1); + float var3 = (float) this.particleAge / (float) this.particleMaxAge; + var3 *= var3; + var3 *= var3; + int var4 = var2 & 255; + int var5 = var2 >> 16 & 255; + var5 += (int) (var3 * 15.0F * 16.0F); + + if (var5 > 240) { + var5 = 240; + } + + return var4 | var5 << 16; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + float var2 = super.getBrightness(par1); + float var3 = (float) this.particleAge / (float) this.particleMaxAge; + var3 = var3 * var3 * var3 * var3; + return var2 * (1.0F - var3) + var3; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + float var1 = (float) this.particleAge / (float) this.particleMaxAge; + float var2 = var1; + var1 = -var1 + var1 * var1 * 2.0F; + var1 = 1.0F - var1; + this.posX = this.portalPosX + this.motionX * (double) var1; + this.posY = this.portalPosY + this.motionY * (double) var1 + (double) (1.0F - var2); + this.posZ = this.portalPosZ + this.motionZ * (double) var1; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityPotion.java b/src/main/java/net/minecraft/src/EntityPotion.java new file mode 100644 index 0000000..e157083 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityPotion.java @@ -0,0 +1,149 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + + + +public class EntityPotion extends EntityThrowable { + /** + * The damage value of the thrown potion that this EntityPotion represents. + */ + private ItemStack potionDamage; + + public EntityPotion() { + super(); + } + + public EntityPotion(World par1World, EntityLiving par2EntityLiving, int par3) { + this(par1World, par2EntityLiving, new ItemStack(Item.potion, 1, par3)); + } + + public EntityPotion(World par1World, EntityLiving par2EntityLiving, ItemStack par3ItemStack) { + super(par1World, par2EntityLiving); + this.potionDamage = par3ItemStack; + } + + public EntityPotion(World par1World, double par2, double par4, double par6, int par8) { + this(par1World, par2, par4, par6, new ItemStack(Item.potion, 1, par8)); + } + + public EntityPotion(World par1World, double par2, double par4, double par6, ItemStack par8ItemStack) { + super(par1World, par2, par4, par6); + this.potionDamage = par8ItemStack; + } + + /** + * Gets the amount of gravity to apply to the thrown entity with each tick. + */ + protected float getGravityVelocity() { + return 0.05F; + } + + protected float func_70182_d() { + return 0.5F; + } + + protected float func_70183_g() { + return -20.0F; + } + + public void setPotionDamage(int par1) { + if (this.potionDamage == null) { + this.potionDamage = new ItemStack(Item.potion, 1, 0); + } + + this.potionDamage.setItemDamage(par1); + } + + /** + * Returns the damage value of the thrown potion that this EntityPotion + * represents. + */ + public int getPotionDamage() { + if (this.potionDamage == null) { + this.potionDamage = new ItemStack(Item.potion, 1, 0); + } + + return this.potionDamage.getItemDamage(); + } + + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (!this.worldObj.isRemote) { + List var2 = Item.potion.getEffects(this.potionDamage); + + if (var2 != null && !var2.isEmpty()) { + AxisAlignedBB var3 = this.boundingBox.expand(4.0D, 2.0D, 4.0D); + List var4 = this.worldObj.getEntitiesWithinAABB(EntityLiving.class, var3); + + if (var4 != null && !var4.isEmpty()) { + Iterator var5 = var4.iterator(); + + while (var5.hasNext()) { + EntityLiving var6 = (EntityLiving) var5.next(); + double var7 = this.getDistanceSqToEntity(var6); + + if (var7 < 16.0D) { + double var9 = 1.0D - Math.sqrt(var7) / 4.0D; + + if (var6 == par1MovingObjectPosition.entityHit) { + var9 = 1.0D; + } + + Iterator var11 = var2.iterator(); + + while (var11.hasNext()) { + PotionEffect var12 = (PotionEffect) var11.next(); + int var13 = var12.getPotionID(); + + if (Potion.potionTypes[var13].isInstant()) { + Potion.potionTypes[var13].affectEntity(this.getThrower(), var6, var12.getAmplifier(), var9); + } else { + int var14 = (int) (var9 * (double) var12.getDuration() + 0.5D); + + if (var14 > 20) { + var6.addPotionEffect(new PotionEffect(var13, var14, var12.getAmplifier())); + } + } + } + } + } + } + } + + this.worldObj.playAuxSFX(2002, (int) Math.round(this.posX), (int) Math.round(this.posY), (int) Math.round(this.posZ), this.getPotionDamage()); + this.setDead(); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("Potion")) { + this.potionDamage = ItemStack.loadItemStackFromNBT(par1NBTTagCompound.getCompoundTag("Potion")); + } else { + this.setPotionDamage(par1NBTTagCompound.getInteger("potionValue")); + } + + if (this.potionDamage == null) { + this.setDead(); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + + if (this.potionDamage != null) { + par1NBTTagCompound.setCompoundTag("Potion", this.potionDamage.writeToNBT(new NBTTagCompound())); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityRainFX.java b/src/main/java/net/minecraft/src/EntityRainFX.java new file mode 100644 index 0000000..60f45e4 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityRainFX.java @@ -0,0 +1,58 @@ +package net.minecraft.src; + + + +public class EntityRainFX extends EntityFX { + public EntityRainFX(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); + this.motionX *= 0.30000001192092896D; + this.motionY = (double) ((float) Math.random() * 0.2F + 0.1F); + this.motionZ *= 0.30000001192092896D; + this.particleRed = 1.0F; + this.particleGreen = 1.0F; + this.particleBlue = 1.0F; + this.particleAlpha = 0.4f; + this.setParticleTextureIndex(19 + this.rand.nextInt(4)); + this.setSize(0.01F, 0.01F); + this.particleGravity = 0.06F; + this.particleMaxAge = (int) (8.0D / (Math.random() * 0.8D + 0.2D)); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.motionY -= (double) this.particleGravity; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.9800000190734863D; + this.motionZ *= 0.9800000190734863D; + + if (this.particleMaxAge-- <= 0) { + this.setDead(); + } + + if (this.onGround) { + if (Math.random() < 0.5D) { + this.setDead(); + } + + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + + Material var1 = this.worldObj.getBlockMaterial(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)); + + if (var1.isLiquid() || var1.isSolid()) { + double var2 = (double) ((float) (MathHelper.floor_double(this.posY) + 1) + - BlockFluid.getFluidHeightPercent(this.worldObj.getBlockMetadata(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)))); + + if (this.posY < var2) { + this.setDead(); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityReddustFX.java b/src/main/java/net/minecraft/src/EntityReddustFX.java new file mode 100644 index 0000000..5c34602 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityReddustFX.java @@ -0,0 +1,79 @@ +package net.minecraft.src; + + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntityReddustFX extends EntityFX { + float reddustParticleScale; + + public EntityReddustFX(World par1World, double par2, double par4, double par6, float par8, float par9, float par10) { + this(par1World, par2, par4, par6, 1.0F, par8, par9, par10); + } + + public EntityReddustFX(World par1World, double par2, double par4, double par6, float par8, float par9, float par10, float par11) { + super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); + this.motionX *= 0.10000000149011612D; + this.motionY *= 0.10000000149011612D; + this.motionZ *= 0.10000000149011612D; + + if (par9 == 0.0F) { + par9 = 1.0F; + } + + float var12 = (float) Math.random() * 0.4F + 0.6F; + this.particleRed = ((float) (Math.random() * 0.20000000298023224D) + 0.8F) * par9 * var12; + this.particleGreen = ((float) (Math.random() * 0.20000000298023224D) + 0.8F) * par10 * var12; + this.particleBlue = ((float) (Math.random() * 0.20000000298023224D) + 0.8F) * par11 * var12; + this.particleScale *= 0.75F; + this.particleScale *= par8; + this.reddustParticleScale = this.particleScale; + this.particleMaxAge = (int) (8.0D / (Math.random() * 0.8D + 0.2D)); + this.particleMaxAge = (int) ((float) this.particleMaxAge * par8); + this.noClip = false; + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = ((float) this.particleAge + par2) / (float) this.particleMaxAge * 32.0F; + + if (var8 < 0.0F) { + var8 = 0.0F; + } + + if (var8 > 1.0F) { + var8 = 1.0F; + } + + this.particleScale = this.reddustParticleScale * var8; + super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + + this.setParticleTextureIndex(7 - this.particleAge * 8 / this.particleMaxAge); + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (this.posY == this.prevPosY) { + this.motionX *= 1.1D; + this.motionZ *= 1.1D; + } + + this.motionX *= 0.9599999785423279D; + this.motionY *= 0.9599999785423279D; + this.motionZ *= 0.9599999785423279D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityRenderer.java b/src/main/java/net/minecraft/src/EntityRenderer.java new file mode 100644 index 0000000..f62a705 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityRenderer.java @@ -0,0 +1,1683 @@ +package net.minecraft.src; + +import java.nio.FloatBuffer; +import java.util.List; +import java.util.Random; + +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.EaglerImage; + +import net.lax1dude.eaglercraft.GuiScreenVoiceChannel; +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; +import net.lax1dude.eaglercraft.glemu.EffectPipeline; +import net.lax1dude.eaglercraft.glemu.EffectPipelineFXAA; + +public class EntityRenderer { + public static boolean anaglyphEnable = false; + + /** Anaglyph field (0=R, 1=GB) */ + public static int anaglyphField; + + /** A reference to the Minecraft object. */ + private Minecraft mc; + private float farPlaneDistance = 0.0F; + public ItemRenderer itemRenderer; + + /** Entity renderer update count */ + private int rendererUpdateCount; + + /** Pointed entity */ + private Entity pointedEntity = null; + private MouseFilter mouseFilterXAxis = new MouseFilter(); + private MouseFilter mouseFilterYAxis = new MouseFilter(); + + /** Mouse filter dummy 1 */ + private MouseFilter mouseFilterDummy1 = new MouseFilter(); + + /** Mouse filter dummy 2 */ + private MouseFilter mouseFilterDummy2 = new MouseFilter(); + + /** Mouse filter dummy 3 */ + private MouseFilter mouseFilterDummy3 = new MouseFilter(); + + /** Mouse filter dummy 4 */ + private MouseFilter mouseFilterDummy4 = new MouseFilter(); + private float thirdPersonDistance = 4.0F; + + /** Third person distance temp */ + private float thirdPersonDistanceTemp = 4.0F; + private float debugCamYaw = 0.0F; + private float prevDebugCamYaw = 0.0F; + private float debugCamPitch = 0.0F; + private float prevDebugCamPitch = 0.0F; + + /** Smooth cam yaw */ + private float smoothCamYaw; + + /** Smooth cam pitch */ + private float smoothCamPitch; + + /** Smooth cam filter X */ + private float smoothCamFilterX; + + /** Smooth cam filter Y */ + private float smoothCamFilterY; + + /** Smooth cam partial ticks */ + private float smoothCamPartialTicks; + private float debugCamFOV = 0.0F; + private float prevDebugCamFOV = 0.0F; + private float camRoll = 0.0F; + private float prevCamRoll = 0.0F; + + /** + * The texture id of the blocklight/skylight texture used for lighting effects + */ + public int lightmapTexture; + + /** + * Colors computed in updateLightmap() and loaded into the lightmap emptyTexture + */ + private int[] lightmapColors; + + /** FOV modifier hand */ + private float fovModifierHand; + + /** FOV modifier hand prev */ + private float fovModifierHandPrev; + + /** FOV multiplier temp */ + private float fovMultiplierTemp; + private float field_82831_U; + private float field_82832_V; + + /** Cloud fog mode */ + private boolean cloudFog = false; + private double cameraZoom = 1.0D; + private double cameraYaw = 0.0D; + private double cameraPitch = 0.0D; + + /** Previous frame time in milliseconds */ + private long prevFrameTime = Minecraft.getSystemTime(); + + /** End time of last render (ns) */ + private long renderEndNanoTime = 0L; + + /** + * Is set, updateCameraAndRender() calls updateLightmap(); set by + * updateTorchFlicker() + */ + private boolean lightmapUpdateNeeded = false; + + /** Torch flicker X */ + float torchFlickerX = 0.0F; + + /** Torch flicker DX */ + float torchFlickerDX = 0.0F; + + /** Torch flicker Y */ + float torchFlickerY = 0.0F; + + /** Torch flicker DY */ + float torchFlickerDY = 0.0F; + private Random random = new Random(); + + /** Rain sound counter */ + private int rainSoundCounter = 0; + + /** Rain X coords */ + float[] rainXCoords; + + /** Rain Y coords */ + float[] rainYCoords; + volatile int field_78523_k = 0; + volatile int field_78520_l = 0; + + /** Fog color buffer */ + FloatBuffer fogColorBuffer = GLAllocation.createDirectFloatBuffer(16); + + /** red component of the fog color */ + float fogColorRed; + + /** green component of the fog color */ + float fogColorGreen; + + /** blue component of the fog color */ + float fogColorBlue; + + /** Fog color 2 */ + private float fogColor2; + + /** Fog color 1 */ + private float fogColor1; + + /** + * Debug view direction (0=OFF, 1=Front, 2=Right, 3=Back, 4=Left, 5=TiltLeft, + * 6=TiltRight) + */ + public int debugViewDirection; + + public EntityRenderer(Minecraft par1Minecraft) { + this.mc = par1Minecraft; + this.itemRenderer = new ItemRenderer(par1Minecraft); + this.lightmapTexture = par1Minecraft.renderEngine.allocateAndSetupTexture(new EaglerImage(16, 16, true)); + this.lightmapColors = new int[256]; + } + + /** + * Updates the entity renderer + */ + public void updateRenderer() { + this.updateFovModifierHand(); + this.updateTorchFlicker(); + this.fogColor2 = this.fogColor1; + this.thirdPersonDistanceTemp = this.thirdPersonDistance; + this.prevDebugCamYaw = this.debugCamYaw; + this.prevDebugCamPitch = this.debugCamPitch; + this.prevDebugCamFOV = this.debugCamFOV; + this.prevCamRoll = this.camRoll; + float var1; + float var2; + + if (this.mc.gameSettings.smoothCamera) { + var1 = this.mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; + var2 = var1 * var1 * var1 * 8.0F; + this.smoothCamFilterX = this.mouseFilterXAxis.smooth(this.smoothCamYaw, 0.05F * var2); + this.smoothCamFilterY = this.mouseFilterYAxis.smooth(this.smoothCamPitch, 0.05F * var2); + this.smoothCamPartialTicks = 0.0F; + this.smoothCamYaw = 0.0F; + this.smoothCamPitch = 0.0F; + } + + if (this.mc.renderViewEntity == null) { + this.mc.renderViewEntity = this.mc.thePlayer; + } + + var1 = this.mc.theWorld.getLightBrightness(MathHelper.floor_double(this.mc.renderViewEntity.posX), MathHelper.floor_double(this.mc.renderViewEntity.posY), MathHelper.floor_double(this.mc.renderViewEntity.posZ)); + var2 = (float) (3 - this.mc.gameSettings.renderDistance) / 3.0F; + float var3 = var1 * (1.0F - var2) + var2; + this.fogColor1 += (var3 - this.fogColor1) * 0.1F; + ++this.rendererUpdateCount; + this.itemRenderer.updateEquippedItem(); + this.addRainParticles(); + this.field_82832_V = this.field_82831_U; + + if (BossStatus.field_82825_d) { + this.field_82831_U += 0.05F; + + if (this.field_82831_U > 1.0F) { + this.field_82831_U = 1.0F; + } + + BossStatus.field_82825_d = false; + } else if (this.field_82831_U > 0.0F) { + this.field_82831_U -= 0.0125F; + } + } + + /** + * Finds what block or object the mouse is over at the specified partial tick + * time. Args: partialTickTime + */ + public void getMouseOver(float par1) { + if (this.mc.renderViewEntity != null) { + if (this.mc.theWorld != null) { + this.mc.pointedEntityLiving = null; + double var2 = (double) this.mc.playerController.getBlockReachDistance(); + this.mc.objectMouseOver = this.mc.renderViewEntity.rayTrace(var2, par1); + double var4 = var2; + Vec3 var6 = this.mc.renderViewEntity.getPosition(par1); + + if (this.mc.playerController.extendedReach()) { + var2 = 6.0D; + var4 = 6.0D; + } else { + if (var2 > 3.0D) { + var4 = 3.0D; + } + + var2 = var4; + } + + if (this.mc.objectMouseOver != null) { + var4 = this.mc.objectMouseOver.hitVec.distanceTo(var6); + } + + Vec3 var7 = this.mc.renderViewEntity.getLook(par1); + Vec3 var8 = var6.addVector(var7.xCoord * var2, var7.yCoord * var2, var7.zCoord * var2); + this.pointedEntity = null; + float var9 = 1.0F; + List var10 = this.mc.theWorld.getEntitiesWithinAABBExcludingEntity(this.mc.renderViewEntity, + this.mc.renderViewEntity.boundingBox.addCoord(var7.xCoord * var2, var7.yCoord * var2, var7.zCoord * var2).expand((double) var9, (double) var9, (double) var9)); + double var11 = var4; + + for (int var13 = 0; var13 < var10.size(); ++var13) { + Entity var14 = (Entity) var10.get(var13); + + if (var14.canBeCollidedWith()) { + float var15 = var14.getCollisionBorderSize(); + AxisAlignedBB var16 = var14.boundingBox.expand((double) var15, (double) var15, (double) var15); + MovingObjectPosition var17 = var16.calculateIntercept(var6, var8); + + if (var16.isVecInside(var6)) { + if (0.0D < var11 || var11 == 0.0D) { + this.pointedEntity = var14; + var11 = 0.0D; + } + } else if (var17 != null) { + double var18 = var6.distanceTo(var17.hitVec); + + if (var18 < var11 || var11 == 0.0D) { + this.pointedEntity = var14; + var11 = var18; + } + } + } + } + + if (this.pointedEntity != null && (var11 < var4 || this.mc.objectMouseOver == null)) { + this.mc.objectMouseOver = new MovingObjectPosition(this.pointedEntity); + + if (this.pointedEntity instanceof EntityLiving) { + this.mc.pointedEntityLiving = (EntityLiving) this.pointedEntity; + } + } + } + } + } + + /** + * Update FOV modifier hand + */ + private void updateFovModifierHand() { + EntityPlayerSP var1 = (EntityPlayerSP) this.mc.renderViewEntity; + this.fovMultiplierTemp = var1.getFOVMultiplier(); + this.fovModifierHandPrev = this.fovModifierHand; + this.fovModifierHand += (this.fovMultiplierTemp - this.fovModifierHand) * 0.5F; + + if (this.fovModifierHand > 1.5F) { + this.fovModifierHand = 1.5F; + } + + if (this.fovModifierHand < 0.1F) { + this.fovModifierHand = 0.1F; + } + } + + /** + * Changes the field of view of the player depending on if they are underwater + * or not + */ + private float getFOVModifier(float par1, boolean par2) { + if(this.mc.gameSettings.keyBindZoom.pressed) { + return 12.0F; + } else if (this.debugViewDirection > 0) { + return 90.0F; + } else { + EntityPlayer var3 = (EntityPlayer) this.mc.renderViewEntity; + float var4 = 70.0F; + + if (par2) { + var4 += this.mc.gameSettings.fovSetting * 40.0F; + var4 *= this.fovModifierHandPrev + (this.fovModifierHand - this.fovModifierHandPrev) * par1; + } + + if (var3.getHealth() <= 0) { + float var5 = (float) var3.deathTime + par1; + var4 /= (1.0F - 500.0F / (var5 + 500.0F)) * 2.0F + 1.0F; + } + + int var6 = ActiveRenderInfo.getBlockIdAtEntityViewpoint(this.mc.theWorld, var3, par1); + + if (var6 != 0 && Block.blocksList[var6].blockMaterial == Material.water) { + var4 = var4 * 60.0F / 70.0F; + } + + return var4 + this.prevDebugCamFOV + (this.debugCamFOV - this.prevDebugCamFOV) * par1; + } + } + + private void hurtCameraEffect(float par1) { + EntityLiving var2 = this.mc.renderViewEntity; + float var3 = (float) var2.hurtTime - par1; + float var4; + + if (var2.getHealth() <= 0) { + var4 = (float) var2.deathTime + par1; + EaglerAdapter.glRotatef(40.0F - 8000.0F / (var4 + 200.0F), 0.0F, 0.0F, 1.0F); + } + + if (var3 >= 0.0F) { + var3 /= (float) var2.maxHurtTime; + var3 = MathHelper.sin(var3 * var3 * var3 * var3 * (float) Math.PI); + var4 = var2.attackedAtYaw; + EaglerAdapter.glRotatef(-var4, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(-var3 * 14.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glRotatef(var4, 0.0F, 1.0F, 0.0F); + } + } + + /** + * Setups all the GL settings for view bobbing. Args: partialTickTime + */ + private void setupViewBobbing(float par1) { + if (this.mc.renderViewEntity instanceof EntityPlayer) { + EntityPlayer var2 = (EntityPlayer) this.mc.renderViewEntity; + float var3 = var2.distanceWalkedModified - var2.prevDistanceWalkedModified; + float var4 = -(var2.distanceWalkedModified + var3 * par1); + float var5 = var2.prevCameraYaw + (var2.cameraYaw - var2.prevCameraYaw) * par1; + float var6 = var2.prevCameraPitch + (var2.cameraPitch - var2.prevCameraPitch) * par1; + EaglerAdapter.glTranslatef(MathHelper.sin(var4 * (float) Math.PI) * var5 * 0.5F, -Math.abs(MathHelper.cos(var4 * (float) Math.PI) * var5), 0.0F); + EaglerAdapter.glRotatef(MathHelper.sin(var4 * (float) Math.PI) * var5 * 3.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glRotatef(Math.abs(MathHelper.cos(var4 * (float) Math.PI - 0.2F) * var5) * 5.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(var6, 1.0F, 0.0F, 0.0F); + } + } + + /** + * sets up player's eye (or camera in third person mode) + */ + private void orientCamera(float par1) { + EntityLiving var2 = this.mc.renderViewEntity; + float var3 = var2.yOffset - 1.62F; + double var4 = var2.prevPosX + (var2.posX - var2.prevPosX) * (double) par1; + double var6 = var2.prevPosY + (var2.posY - var2.prevPosY) * (double) par1 - (double) var3; + double var8 = var2.prevPosZ + (var2.posZ - var2.prevPosZ) * (double) par1; + EaglerAdapter.glRotatef(this.prevCamRoll + (this.camRoll - this.prevCamRoll) * par1, 0.0F, 0.0F, 1.0F); + + if (var2.isPlayerSleeping()) { + var3 = (float) ((double) var3 + 1.0D); + EaglerAdapter.glTranslatef(0.0F, 0.3F, 0.0F); + + if (!this.mc.gameSettings.debugCamEnable) { + int var10 = this.mc.theWorld.getBlockId(MathHelper.floor_double(var2.posX), MathHelper.floor_double(var2.posY), MathHelper.floor_double(var2.posZ)); + + if (var10 == Block.bed.blockID) { + int var11 = this.mc.theWorld.getBlockMetadata(MathHelper.floor_double(var2.posX), MathHelper.floor_double(var2.posY), MathHelper.floor_double(var2.posZ)); + int var12 = var11 & 3; + EaglerAdapter.glRotatef((float) (var12 * 90), 0.0F, 1.0F, 0.0F); + } + + EaglerAdapter.glRotatef(var2.prevRotationYaw + (var2.rotationYaw - var2.prevRotationYaw) * par1 + 180.0F, 0.0F, -1.0F, 0.0F); + EaglerAdapter.glRotatef(var2.prevRotationPitch + (var2.rotationPitch - var2.prevRotationPitch) * par1, -1.0F, 0.0F, 0.0F); + } + } else if (this.mc.gameSettings.thirdPersonView > 0) { + double var27 = (double) (this.thirdPersonDistanceTemp + (this.thirdPersonDistance - this.thirdPersonDistanceTemp) * par1); + float var13; + float var28; + + if (this.mc.gameSettings.debugCamEnable) { + var28 = this.prevDebugCamYaw + (this.debugCamYaw - this.prevDebugCamYaw) * par1; + var13 = this.prevDebugCamPitch + (this.debugCamPitch - this.prevDebugCamPitch) * par1; + EaglerAdapter.glTranslatef(0.0F, 0.0F, (float) (-var27)); + EaglerAdapter.glRotatef(var13, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(var28, 0.0F, 1.0F, 0.0F); + } else { + var28 = var2.rotationYaw; + var13 = var2.rotationPitch; + + if (this.mc.gameSettings.thirdPersonView == 2) { + var13 += 180.0F; + } + + double var14 = (double) (-MathHelper.sin(var28 / 180.0F * (float) Math.PI) * MathHelper.cos(var13 / 180.0F * (float) Math.PI)) * var27; + double var16 = (double) (MathHelper.cos(var28 / 180.0F * (float) Math.PI) * MathHelper.cos(var13 / 180.0F * (float) Math.PI)) * var27; + double var18 = (double) (-MathHelper.sin(var13 / 180.0F * (float) Math.PI)) * var27; + + for (int var20 = 0; var20 < 8; ++var20) { + float var21 = (float) ((var20 & 1) * 2 - 1); + float var22 = (float) ((var20 >> 1 & 1) * 2 - 1); + float var23 = (float) ((var20 >> 2 & 1) * 2 - 1); + var21 *= 0.1F; + var22 *= 0.1F; + var23 *= 0.1F; + MovingObjectPosition var24 = this.mc.theWorld.rayTraceBlocks(this.mc.theWorld.getWorldVec3Pool().getVecFromPool(var4 + (double) var21, var6 + (double) var22, var8 + (double) var23), + this.mc.theWorld.getWorldVec3Pool().getVecFromPool(var4 - var14 + (double) var21 + (double) var23, var6 - var18 + (double) var22, var8 - var16 + (double) var23)); + + if (var24 != null) { + double var25 = var24.hitVec.distanceTo(this.mc.theWorld.getWorldVec3Pool().getVecFromPool(var4, var6, var8)); + + if (var25 < var27) { + var27 = var25; + } + } + } + + if (this.mc.gameSettings.thirdPersonView == 2) { + EaglerAdapter.glRotatef(180.0F, 0.0F, 1.0F, 0.0F); + } + + EaglerAdapter.glRotatef(var2.rotationPitch - var13, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(var2.rotationYaw - var28, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glTranslatef(0.0F, 0.0F, (float) (-var27)); + EaglerAdapter.glRotatef(var28 - var2.rotationYaw, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(var13 - var2.rotationPitch, 1.0F, 0.0F, 0.0F); + } + } else { + EaglerAdapter.glTranslatef(0.0F, 0.0F, -0.1F); + } + + if (!this.mc.gameSettings.debugCamEnable) { + EaglerAdapter.glRotatef(var2.prevRotationPitch + (var2.rotationPitch - var2.prevRotationPitch) * par1, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(var2.prevRotationYaw + (var2.rotationYaw - var2.prevRotationYaw) * par1 + 180.0F, 0.0F, 1.0F, 0.0F); + } + + EaglerAdapter.glTranslatef(0.0F, var3, 0.0F); + var4 = var2.prevPosX + (var2.posX - var2.prevPosX) * (double) par1; + var6 = var2.prevPosY + (var2.posY - var2.prevPosY) * (double) par1 - (double) var3; + var8 = var2.prevPosZ + (var2.posZ - var2.prevPosZ) * (double) par1; + this.cloudFog = this.mc.renderGlobal.hasCloudFog(var4, var6, var8, par1); + } + + /** + * sets up projection, view effects, camera position/rotation + */ + private void setupCameraTransform(float par1, int par2) { + this.farPlaneDistance = (float) (256 >> this.mc.gameSettings.renderDistance); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glLoadIdentity(); + float var3 = 0.07F; + + if (this.mc.gameSettings.anaglyph) { + EaglerAdapter.glTranslatef((float) (-(par2 * 2 - 1)) * var3, 0.0F, 0.0F); + } + + if (this.cameraZoom != 1.0D) { + EaglerAdapter.glTranslatef((float) this.cameraYaw, (float) (-this.cameraPitch), 0.0F); + EaglerAdapter.glScalef((float)this.cameraZoom, (float)this.cameraZoom, 1.0F); + } + + EaglerAdapter.gluPerspective(this.getFOVModifier(par1, true), (float) this.mc.displayWidth / (float) this.mc.displayHeight, 0.05F, this.farPlaneDistance * 2.0F); + float var4; + + if (this.mc.playerController.enableEverythingIsScrewedUpMode()) { + var4 = 0.6666667F; + EaglerAdapter.glScalef(1.0F, var4, 1.0F); + } + + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glLoadIdentity(); + + if (this.mc.gameSettings.anaglyph) { + EaglerAdapter.glTranslatef((float) (par2 * 2 - 1) * 0.1F, 0.0F, 0.0F); + } + + this.hurtCameraEffect(par1); + + if (this.mc.gameSettings.viewBobbing) { + this.setupViewBobbing(par1); + } + + var4 = this.mc.thePlayer.prevTimeInPortal + (this.mc.thePlayer.timeInPortal - this.mc.thePlayer.prevTimeInPortal) * par1; + + if (var4 > 0.0F) { + byte var5 = 20; + + if (this.mc.thePlayer.isPotionActive(Potion.confusion)) { + var5 = 7; + } + + float var6 = 5.0F / (var4 * var4 + 5.0F) - var4 * 0.04F; + var6 *= var6; + EaglerAdapter.glRotatef(((float) this.rendererUpdateCount + par1) * (float) var5, 0.0F, 1.0F, 1.0F); + EaglerAdapter.glScalef(1.0F / var6, 1.0F, 1.0F); + EaglerAdapter.glRotatef(-((float) this.rendererUpdateCount + par1) * (float) var5, 0.0F, 1.0F, 1.0F); + } + + this.orientCamera(par1); + + if (this.debugViewDirection > 0) { + int var7 = this.debugViewDirection - 1; + + if (var7 == 1) { + EaglerAdapter.glRotatef(90.0F, 0.0F, 1.0F, 0.0F); + } + + if (var7 == 2) { + EaglerAdapter.glRotatef(180.0F, 0.0F, 1.0F, 0.0F); + } + + if (var7 == 3) { + EaglerAdapter.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F); + } + + if (var7 == 4) { + EaglerAdapter.glRotatef(90.0F, 1.0F, 0.0F, 0.0F); + } + + if (var7 == 5) { + EaglerAdapter.glRotatef(-90.0F, 1.0F, 0.0F, 0.0F); + } + } + } + + /** + * Render player hand + */ + private void renderHand(float par1, int par2) { + if (this.debugViewDirection <= 0) { + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glLoadIdentity(); + float var3 = 0.07F; + + EaglerAdapter.gluPerspectiveFlat(this.getFOVModifier(par1, false), (float) this.mc.displayWidth / (float) this.mc.displayHeight, 0.05F, 10f); + + if (this.mc.gameSettings.anaglyph) { + EaglerAdapter.glTranslatef((float) (-(par2 * 2 - 1)) * var3, 0.0F, 0.0F); + } + + if (this.cameraZoom != 1.0D) { + EaglerAdapter.glTranslatef((float) this.cameraYaw, (float) (-this.cameraPitch), 0.0F); + EaglerAdapter.glScalef((float)this.cameraZoom, (float)this.cameraZoom, 1.0F); + } + + if (this.mc.playerController.enableEverythingIsScrewedUpMode()) { + float var4 = 0.6666667F; + EaglerAdapter.glScalef(1.0F, var4, 1.0F); + } + + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glLoadIdentity(); + + if (this.mc.gameSettings.anaglyph) { + EaglerAdapter.glTranslatef((float) (par2 * 2 - 1) * 0.1F, 0.0F, 0.0F); + } + + EaglerAdapter.glPushMatrix(); + this.hurtCameraEffect(par1); + + if (this.mc.gameSettings.viewBobbing) { + this.setupViewBobbing(par1); + } + + if (this.mc.gameSettings.thirdPersonView == 0 && !this.mc.renderViewEntity.isPlayerSleeping() && !this.mc.gameSettings.hideGUI && !this.mc.playerController.enableEverythingIsScrewedUpMode()) { + this.enableLightmap((double) par1); + this.itemRenderer.renderItemInFirstPerson(par1); + this.disableLightmap((double) par1); + } + + EaglerAdapter.glPopMatrix(); + + if (this.mc.gameSettings.thirdPersonView == 0 && !this.mc.renderViewEntity.isPlayerSleeping()) { + this.itemRenderer.renderOverlays(par1); + this.hurtCameraEffect(par1); + } + + if (this.mc.gameSettings.viewBobbing) { + this.setupViewBobbing(par1); + } + } + } + + /** + * Disable secondary texture unit used by lightmap + */ + public void disableLightmap(double par1) { + OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + } + + /** + * Enable lightmap in secondary texture unit + */ + public void enableLightmap(double par1) { + OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); + //EaglerAdapter.glMatrixMode(EaglerAdapter.GL_TEXTURE); + //EaglerAdapter.glLoadIdentity(); + //float var3 = 0.00390625F; + //EaglerAdapter.glScalef(var3, var3, var3); + //EaglerAdapter.glTranslatef(8.0F, 8.0F, 8.0F); + //EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glBindTexture(EaglerAdapter.GL_TEXTURE_2D, this.lightmapTexture); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MIN_FILTER, EaglerAdapter.GL_LINEAR); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MAG_FILTER, EaglerAdapter.GL_LINEAR); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_WRAP_S, EaglerAdapter.GL_CLAMP); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_WRAP_T, EaglerAdapter.GL_CLAMP); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + this.mc.renderEngine.resetBoundTexture(); + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + } + + /** + * Recompute a random value that is applied to block color in updateLightmap() + */ + private void updateTorchFlicker() { + this.torchFlickerDX = (float) ((double) this.torchFlickerDX + (Math.random() - Math.random()) * Math.random() * Math.random()); + this.torchFlickerDY = (float) ((double) this.torchFlickerDY + (Math.random() - Math.random()) * Math.random() * Math.random()); + this.torchFlickerDX = (float) ((double) this.torchFlickerDX * 0.9D); + this.torchFlickerDY = (float) ((double) this.torchFlickerDY * 0.9D); + this.torchFlickerX += (this.torchFlickerDX - this.torchFlickerX) * 1.0F; + this.torchFlickerY += (this.torchFlickerDY - this.torchFlickerY) * 1.0F; + this.lightmapUpdateNeeded = true; + } + + private void updateLightmap(float par1) { + WorldClient var2 = this.mc.theWorld; + + if (var2 != null) { + for (int var3 = 0; var3 < 256; ++var3) { + float var4 = var2.getSunBrightness(1.0F) * 0.95F + 0.05F; + float var5 = var2.provider.lightBrightnessTable[var3 / 16] * var4; + float var6 = var2.provider.lightBrightnessTable[var3 % 16] * (this.torchFlickerX * 0.15F + 1.45F); + + if (var2.lastLightningBolt > 0) { + var5 = var2.provider.lightBrightnessTable[var3 / 16]; + } + + float var7 = var5 * (var2.getSunBrightness(1.0F) * 0.65F + 0.35F); + float var8 = var7; + float var11 = var6 * ((var6 * 0.6F + 0.4F) * 0.6F + 0.4F); + float var12 = var6 * (var6 * var6 * 0.6F + 0.4F); + float var13 = var7 + var6; + float var14 = var8 + var11; + float var15 = var5 + var12; + var13 = var13 * 0.96F + 0.03F; + var14 = var14 * 0.96F + 0.03F; + var15 = var15 * 0.96F + 0.03F; + float var16; + + if (this.field_82831_U > 0.0F) { + var16 = this.field_82832_V + (this.field_82831_U - this.field_82832_V) * par1; + var13 = var13 * (1.0F - var16) + var13 * 0.7F * var16; + var14 = var14 * (1.0F - var16) + var14 * 0.6F * var16; + var15 = var15 * (1.0F - var16) + var15 * 0.6F * var16; + } + + if (var2.provider.dimensionId == 1) { + var13 = 0.22F + var6 * 0.75F; + var14 = 0.28F + var11 * 0.75F; + var15 = 0.25F + var12 * 0.75F; + } + + float var17; + + if (this.mc.thePlayer.isPotionActive(Potion.nightVision)) { + var16 = this.getNightVisionBrightness(this.mc.thePlayer, par1); + var17 = 1.0F / var13; + + if (var17 > 1.0F / var14) { + var17 = 1.0F / var14; + } + + if (var17 > 1.0F / var15) { + var17 = 1.0F / var15; + } + + var13 = var13 * (1.0F - var16) + var13 * var17 * var16; + var14 = var14 * (1.0F - var16) + var14 * var17 * var16; + var15 = var15 * (1.0F - var16) + var15 * var17 * var16; + } + + if (var13 > 1.0F) { + var13 = 1.0F; + } + + if (var14 > 1.0F) { + var14 = 1.0F; + } + + if (var15 > 1.0F) { + var15 = 1.0F; + } + + var16 = this.mc.gameSettings.gammaSetting; + var17 = 1.0F - var13; + float var18 = 1.0F - var14; + float var19 = 1.0F - var15; + var17 = 1.0F - var17 * var17 * var17 * var17; + var18 = 1.0F - var18 * var18 * var18 * var18; + var19 = 1.0F - var19 * var19 * var19 * var19; + var13 = var13 * (1.0F - var16) + var17 * var16; + var14 = var14 * (1.0F - var16) + var18 * var16; + var15 = var15 * (1.0F - var16) + var19 * var16; + var13 = var13 * 0.96F + 0.03F; + var14 = var14 * 0.96F + 0.03F; + var15 = var15 * 0.96F + 0.03F; + + if (var13 > 1.0F) { + var13 = 1.0F; + } + + if (var14 > 1.0F) { + var14 = 1.0F; + } + + if (var15 > 1.0F) { + var15 = 1.0F; + } + + if (var13 < 0.0F) { + var13 = 0.0F; + } + + if (var14 < 0.0F) { + var14 = 0.0F; + } + + if (var15 < 0.0F) { + var15 = 0.0F; + } + + int var20 = 255; + int var21 = (int) (var13 * 255.0F); + int var22 = (int) (var14 * 255.0F); + int var23 = (int) (var15 * 255.0F); + this.lightmapColors[var3] = var20 << 24 | var21 << 16 | var22 << 8 | var23; + } + + this.mc.renderEngine.createTextureFromBytes(this.lightmapColors, 16, 16, this.lightmapTexture); + } + } + + /** + * Gets the night vision brightness + */ + private float getNightVisionBrightness(EntityPlayer par1EntityPlayer, float par2) { + int var3 = par1EntityPlayer.getActivePotionEffect(Potion.nightVision).getDuration(); + return var3 > 200 ? 1.0F : 0.7F + MathHelper.sin(((float) var3 - par2) * (float) Math.PI * 0.2F) * 0.3F; + } + + /** + * Will update any inputs that effect the camera angle (mouse) and then render + * the world and GUI + */ + public void updateCameraAndRender(float par1) { + this.mc.mcProfiler.startSection("lightTex"); + + if (this.lightmapUpdateNeeded) { + this.updateLightmap(par1); + } + + this.mc.mcProfiler.endSection(); + boolean var2 = EaglerAdapter.isFocused(); + + if (!var2 && this.mc.gameSettings.pauseOnLostFocus) { + this.mc.displayInGameMenu(); + } else { + this.prevFrameTime = Minecraft.getSystemTime(); + } + + this.mc.mcProfiler.startSection("mouse"); + + if (this.mc.inGameHasFocus && var2) { + this.mc.mouseHelper.mouseXYChange(); + float var3 = this.mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; + if(this.mc.gameSettings.keyBindZoom.pressed) var3 *= 0.5f; + float var4 = var3 * var3 * var3 * 8.0F; + float var5 = (float) this.mc.mouseHelper.deltaX * var4; + float var6 = (float) this.mc.mouseHelper.deltaY * var4; + byte var7 = 1; + + if (this.mc.gameSettings.invertMouse) { + var7 = -1; + } + + if (this.mc.gameSettings.smoothCamera) { + this.smoothCamYaw += var5; + this.smoothCamPitch += var6; + float var8 = par1 - this.smoothCamPartialTicks; + this.smoothCamPartialTicks = par1; + var5 = this.smoothCamFilterX * var8; + var6 = this.smoothCamFilterY * var8; + this.mc.thePlayer.setAngles(var5, var6 * (float) var7); + } else { + this.mc.thePlayer.setAngles(var5, var6 * (float) var7); + } + } + + this.mc.mcProfiler.endSection(); + + if (!this.mc.skipRenderWorld) { + anaglyphEnable = this.mc.gameSettings.anaglyph; + ScaledResolution var13 = new ScaledResolution(this.mc.gameSettings, this.mc.displayWidth, this.mc.displayHeight); + int var14 = var13.getScaledWidth(); + int var15 = var13.getScaledHeight(); + int var16 = EaglerAdapter.mouseGetX() * var14 / this.mc.displayWidth; + int var17 = var15 - EaglerAdapter.mouseGetY() * var15 / this.mc.displayHeight - 1; + int var18 = performanceToFps(this.mc.gameSettings.limitFramerate); + + if (this.mc.theWorld != null) { + this.mc.mcProfiler.startSection("level"); + + if (this.mc.gameSettings.limitFramerate == 0) { + this.renderWorld(par1, 0L); + } else { + this.renderWorld(par1, this.renderEndNanoTime + (long) (1000000000 / var18)); + } + + this.renderEndNanoTime = System.nanoTime(); + this.mc.mcProfiler.endStartSection("gui"); + + if (!this.mc.gameSettings.hideGUI || this.mc.currentScreen != null) { + this.mc.ingameGUI.renderGameOverlay(par1, this.mc.currentScreen != null, var16, var17); + } + + this.mc.mcProfiler.endSection(); + } else { + EaglerAdapter.glViewport(0, 0, this.mc.displayWidth, this.mc.displayHeight); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glLoadIdentity(); + this.setupOverlayRendering(); + this.renderEndNanoTime = System.nanoTime(); + } + + EaglerAdapter.glClear(EaglerAdapter.GL_DEPTH_BUFFER_BIT); + + if (this.mc.currentScreen != null) { + this.mc.currentScreen.drawScreen(var16, var17, par1); + + if (this.mc.currentScreen != null && this.mc.currentScreen.guiParticles != null) { + this.mc.currentScreen.guiParticles.draw(par1); + } + } + + GuiScreenVoiceChannel.drawOverlay(); + } + + } + + public static final TextureLocation terrain = new TextureLocation("/terrain.png"); + + public void renderWorld(float par1, long par2) { + this.mc.mcProfiler.startSection("lightTex"); + + if (this.lightmapUpdateNeeded) { + this.updateLightmap(par1); + } + + EaglerAdapter.glEnable(EaglerAdapter.GL_CULL_FACE); + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + + if (this.mc.renderViewEntity == null) { + this.mc.renderViewEntity = this.mc.thePlayer; + } + + this.mc.mcProfiler.endStartSection("pick"); + this.getMouseOver(par1); + EntityLiving var4 = this.mc.renderViewEntity; + RenderGlobal var5 = this.mc.renderGlobal; + EffectRenderer var6 = this.mc.effectRenderer; + double var7 = var4.lastTickPosX + (var4.posX - var4.lastTickPosX) * (double) par1; + double var9 = var4.lastTickPosY + (var4.posY - var4.lastTickPosY) * (double) par1; + double var11 = var4.lastTickPosZ + (var4.posZ - var4.lastTickPosZ) * (double) par1; + this.mc.mcProfiler.endStartSection("center"); + + for (int var13 = 0; var13 < 2; ++var13) { + if (this.mc.gameSettings.anaglyph) { + anaglyphField = var13; + + if (anaglyphField == 0) { + EaglerAdapter.glColorMask(false, true, true, false); + } else { + EaglerAdapter.glColorMask(true, false, false, false); + } + } + + EaglerAdapter.glViewport(0, 0, this.mc.displayWidth, this.mc.displayHeight); + EffectPipelineFXAA.beginPipelineRender(); + this.mc.mcProfiler.endStartSection("clear"); + EaglerAdapter.glClear(EaglerAdapter.GL_COLOR_BUFFER_BIT | EaglerAdapter.GL_DEPTH_BUFFER_BIT); + this.updateFogColor(par1); + EaglerAdapter.glEnable(EaglerAdapter.GL_CULL_FACE); + this.mc.mcProfiler.endStartSection("camera"); + this.setupCameraTransform(par1, var13); + ActiveRenderInfo.updateRenderInfo(this.mc.thePlayer, this.mc.gameSettings.thirdPersonView == 2); + this.mc.mcProfiler.endStartSection("frustrum"); + ClippingHelperImpl.getInstance(); + + EaglerAdapter.glEnable(EaglerAdapter.GL_FOG); + + if (this.mc.gameSettings.renderDistance < 2) { + this.setupFog(-1, par1); + this.mc.mcProfiler.endStartSection("sky"); + var5.renderSky(par1); + } + + this.setupFog(1, par1); + + if (this.mc.gameSettings.ambientOcclusion != 0) { + EaglerAdapter.glShadeModel(EaglerAdapter.GL_SMOOTH); + } + + this.mc.mcProfiler.endStartSection("culling"); + Frustrum var14 = new Frustrum(); + var14.setPosition(var7, var9, var11); + this.mc.renderGlobal.clipRenderersByFrustum(var14, par1); + + if (var13 == 0) { + this.mc.mcProfiler.endStartSection("updatechunks"); + + while (!this.mc.renderGlobal.updateRenderers(var4, false) && par2 != 0L) { + long var15 = par2 - System.nanoTime(); + + if (var15 < 0L || var15 > 1000000000L) { + break; + } + } + } + + if (var4.posY < 128.0D) { + this.renderCloudsCheck(var5, par1); + } + + this.mc.mcProfiler.endStartSection("prepareterrain"); + EaglerAdapter.glEnable(EaglerAdapter.GL_FOG); + this.setupFog(0, par1); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + RenderHelper.disableStandardItemLighting(); + terrain.bindTexture(); + EaglerAdapter.glTexParameterf(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MAX_ANISOTROPY, 16.0f); + //EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MIN_FILTER, mc.gameSettings.fancyGraphics ? EaglerAdapter.GL_LINEAR_MIPMAP_LINEAR : EaglerAdapter.GL_NEAREST_MIPMAP_LINEAR); + EaglerAdapter.glAlphaFunc(EaglerAdapter.GL_GREATER, 0.6f); + this.mc.mcProfiler.endStartSection("terrain"); + var5.sortAndRender(var4, 0, (double) par1); + EaglerAdapter.glShadeModel(EaglerAdapter.GL_FLAT); + EntityPlayer var17; + + if (this.debugViewDirection == 0) { + RenderHelper.enableStandardItemLighting(); + this.mc.mcProfiler.endStartSection("entities"); + var5.renderEntities(var4.getPosition(par1), var14, par1); + this.enableLightmap((double) par1); + this.mc.mcProfiler.endStartSection("litParticles"); + var6.renderLitParticles(var4, par1); + RenderHelper.disableStandardItemLighting(); + this.setupFog(0, par1); + this.mc.mcProfiler.endStartSection("particles"); + var6.renderParticles(var4, par1); + this.disableLightmap((double) par1); + + if (this.mc.objectMouseOver != null && var4.isInsideOfMaterial(Material.water) && var4 instanceof EntityPlayer && !this.mc.gameSettings.hideGUI) { + var17 = (EntityPlayer) var4; + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + this.mc.mcProfiler.endStartSection("outline"); + var5.drawBlockBreaking(var17, this.mc.objectMouseOver, 0, var17.inventory.getCurrentItem(), par1); + var5.drawSelectionBox(var17, this.mc.objectMouseOver, 0, var17.inventory.getCurrentItem(), par1); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + } + } + + EaglerAdapter.glEnable(EaglerAdapter.GL_CULL_FACE); + EaglerAdapter.glDepthMask(true); + this.setupFog(0, par1); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glAlphaFunc(EaglerAdapter.GL_GREATER, 0.03f); + EaglerAdapter.glDisable(EaglerAdapter.GL_CULL_FACE); + EaglerAdapter.glColor4f(1f, 1f, 1f, 1f); + terrain.bindTexture(); + + //if (this.mc.gameSettings.fancyGraphics) { + this.mc.mcProfiler.endStartSection("water"); + + EaglerAdapter.glColorMask(false, false, false, false); + int var18 = var5.sortAndRender(var4, 1, (double) par1); + + if (this.mc.gameSettings.anaglyph) { + if (anaglyphField == 0) { + EaglerAdapter.glColorMask(false, true, true, true); + } else { + EaglerAdapter.glColorMask(true, false, false, true); + } + } else { + EaglerAdapter.glColorMask(true, true, true, true); + } + + if (var18 > 0) { + EaglerAdapter.glDepthFunc(EaglerAdapter.GL_EQUAL); + var5.renderSortedRenderers(0, var5.sortedWorldRenderers.length, 1, (double) par1); + EaglerAdapter.glDepthFunc(EaglerAdapter.GL_LEQUAL); + } + + //} else { + // this.mc.mcProfiler.endStartSection("water"); + // var5.sortAndRender(var4, 1, (double) par1); + //} + + EaglerAdapter.glTexParameterf(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MAX_ANISOTROPY, 1.0f); + //EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MIN_FILTER, EaglerAdapter.GL_NEAREST_MIPMAP_LINEAR); + + var6.renderTransparentParticles(var4, par1); + + EaglerAdapter.glDepthMask(true); + EaglerAdapter.glEnable(EaglerAdapter.GL_CULL_FACE); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + + if (this.cameraZoom == 1.0D && var4 instanceof EntityPlayer && !this.mc.gameSettings.hideGUI && this.mc.objectMouseOver != null && !var4.isInsideOfMaterial(Material.water)) { + var17 = (EntityPlayer) var4; + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + this.mc.mcProfiler.endStartSection("outline"); + var5.drawBlockBreaking(var17, this.mc.objectMouseOver, 0, var17.inventory.getCurrentItem(), par1); + var5.drawSelectionBox(var17, this.mc.objectMouseOver, 0, var17.inventory.getCurrentItem(), par1); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + } + + this.mc.mcProfiler.endStartSection("destroyProgress"); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE); + var5.drawBlockDamageTexture(Tessellator.instance, (EntityPlayer) var4, par1); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + this.mc.mcProfiler.endStartSection("weather"); + EaglerAdapter.glDisable(EaglerAdapter.GL_FOG); + + if (var4.posY >= 128.0D) { + this.renderCloudsCheck(var5, par1); + } + + this.renderRainSnow(par1); + + this.mc.mcProfiler.endStartSection("hand"); + + //EaglerAdapter.glClear(EaglerAdapter.GL_DEPTH_BUFFER_BIT); + + if (!this.mc.gameSettings.keyBindZoom.pressed) { + this.renderHand(par1, var13); + } + + + if (!this.mc.gameSettings.anaglyph) { + break; + } + } + + this.mc.mcProfiler.endStartSection("postprocess"); + EaglerAdapter.glColorMask(true, true, true, false); + EffectPipelineFXAA.endPipelineRender(); + this.mc.mcProfiler.endSection(); + } + + /** + * Render clouds if enabled + */ + private void renderCloudsCheck(RenderGlobal par1RenderGlobal, float par2) { + if (this.mc.gameSettings.shouldRenderClouds()) { + this.mc.mcProfiler.endStartSection("clouds"); + EaglerAdapter.glPushMatrix(); + this.setupFog(0, par2); + EaglerAdapter.glEnable(EaglerAdapter.GL_FOG); + par1RenderGlobal.renderClouds(par2); + EaglerAdapter.glDisable(EaglerAdapter.GL_FOG); + this.setupFog(1, par2); + EaglerAdapter.glPopMatrix(); + } + } + + private void addRainParticles() { + float var1 = this.mc.theWorld.getRainStrength(1.0F); + + if (!this.mc.gameSettings.fancyGraphics) { + var1 /= 2.0F; + } + + if (var1 != 0.0F) { + this.random.setSeed((long) this.rendererUpdateCount * 312987231L); + EntityLiving var2 = this.mc.renderViewEntity; + WorldClient var3 = this.mc.theWorld; + int var4 = MathHelper.floor_double(var2.posX); + int var5 = MathHelper.floor_double(var2.posY); + int var6 = MathHelper.floor_double(var2.posZ); + byte var7 = 10; + double var8 = 0.0D; + double var10 = 0.0D; + double var12 = 0.0D; + int var14 = 0; + int var15 = (int) (100.0F * var1 * var1); + + if (this.mc.gameSettings.particleSetting == 1) { + var15 >>= 1; + } else if (this.mc.gameSettings.particleSetting == 2) { + var15 = 0; + } + + for (int var16 = 0; var16 < var15; ++var16) { + int var17 = var4 + this.random.nextInt(var7) - this.random.nextInt(var7); + int var18 = var6 + this.random.nextInt(var7) - this.random.nextInt(var7); + int var19 = var3.getPrecipitationHeight(var17, var18); + int var20 = var3.getBlockId(var17, var19 - 1, var18); + BiomeGenBase var21 = var3.getBiomeGenForCoords(var17, var18); + + if (var19 <= var5 + var7 && var19 >= var5 - var7 && var21.canSpawnLightningBolt() && var21.getFloatTemperature() >= 0.2F) { + float var22 = this.random.nextFloat(); + float var23 = this.random.nextFloat(); + + if (var20 > 0) { + if (Block.blocksList[var20].blockMaterial == Material.lava) { + this.mc.effectRenderer + .addEffect(new EntitySmokeFX(var3, (double) ((float) var17 + var22), (double) ((float) var19 + 0.1F) - Block.blocksList[var20].getBlockBoundsMinY(), (double) ((float) var18 + var23), 0.0D, 0.0D, 0.0D)); + } else { + ++var14; + + if (this.random.nextInt(var14) == 0) { + var8 = (double) ((float) var17 + var22); + var10 = (double) ((float) var19 + 0.1F) - Block.blocksList[var20].getBlockBoundsMinY(); + var12 = (double) ((float) var18 + var23); + } + + this.mc.effectRenderer.addEffect(new EntityRainFX(var3, (double) ((float) var17 + var22), (double) ((float) var19 + 0.1F) - Block.blocksList[var20].getBlockBoundsMinY(), (double) ((float) var18 + var23))); + } + } + } + } + + if (var14 > 0 && this.random.nextInt(3) < this.rainSoundCounter++) { + this.rainSoundCounter = 0; + + if (var10 > var2.posY + 1.0D && var3.getPrecipitationHeight(MathHelper.floor_double(var2.posX), MathHelper.floor_double(var2.posZ)) > MathHelper.floor_double(var2.posY)) { + this.mc.theWorld.playSound(var8, var10, var12, "ambient.weather.rain", 0.03F, 0.5F, false); + } else { + this.mc.theWorld.playSound(var8, var10, var12, "ambient.weather.rain", 0.06F, 1.0F, false); + } + } + } + } + + private static final TextureLocation rain = new TextureLocation("/environment/rain.png"); + private static final TextureLocation snow = new TextureLocation("/environment/snow.png"); + + /** + * Render rain and snow + */ + protected void renderRainSnow(float par1) { + float var2 = this.mc.theWorld.getRainStrength(par1) * 0.5f; + + if (var2 > 0.0F) { + this.enableLightmap((double) par1); + + if (this.rainXCoords == null) { + this.rainXCoords = new float[1024]; + this.rainYCoords = new float[1024]; + + for (int var3 = 0; var3 < 32; ++var3) { + for (int var4 = 0; var4 < 32; ++var4) { + float var5 = (float) (var4 - 16); + float var6 = (float) (var3 - 16); + float var7 = MathHelper.sqrt_float(var5 * var5 + var6 * var6); + this.rainXCoords[var3 << 5 | var4] = -var6 / var7; + this.rainYCoords[var3 << 5 | var4] = var5 / var7; + } + } + } + + EntityLiving var41 = this.mc.renderViewEntity; + WorldClient var42 = this.mc.theWorld; + int var43 = MathHelper.floor_double(var41.posX); + int var44 = MathHelper.floor_double(var41.posY); + int var45 = MathHelper.floor_double(var41.posZ); + Tessellator var8 = Tessellator.instance; + EaglerAdapter.glDisable(EaglerAdapter.GL_CULL_FACE); + EaglerAdapter.glNormal3f(0.0F, 1.0F, 0.0F); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glAlphaFunc(EaglerAdapter.GL_GREATER, 0.01F); + snow.bindTexture(); + double var9 = var41.lastTickPosX + (var41.posX - var41.lastTickPosX) * (double) par1; + double var11 = var41.lastTickPosY + (var41.posY - var41.lastTickPosY) * (double) par1; + double var13 = var41.lastTickPosZ + (var41.posZ - var41.lastTickPosZ) * (double) par1; + int var15 = MathHelper.floor_double(var11); + byte var16 = 5; + + if (this.mc.gameSettings.fancyGraphics) { + var16 = 10; + } + + boolean var17 = false; + byte var18 = -1; + int ticks = (this.rendererUpdateCount % 100000); + float var19 = ticks + par1; + + if (this.mc.gameSettings.fancyGraphics) { + var16 = 10; + } + + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + var17 = false; + + for (int var20 = var45 - var16; var20 <= var45 + var16; ++var20) { + for (int var21 = var43 - var16; var21 <= var43 + var16; ++var21) { + int var22 = (var20 - var45 + 16) * 32 + var21 - var43 + 16; + float var23 = this.rainXCoords[var22] * 0.5F; + float var24 = this.rainYCoords[var22] * 0.5F; + BiomeGenBase var25 = var42.getBiomeGenForCoords(var21, var20); + + if (var25.canSpawnLightningBolt() || var25.getEnableSnow()) { + int var26 = var42.getPrecipitationHeight(var21, var20); + int var27 = var44 - var16; + int var28 = var44 + var16; + + if (var27 < var26) { + var27 = var26; + } + + if (var28 < var26) { + var28 = var26; + } + + float var29 = 1.0F; + int var30 = var26; + + if (var26 < var15) { + var30 = var15; + } + + if (var27 != var28) { + this.random.setSeed((long) (var21 * var21 * 3121 + var21 * 45238971 ^ var20 * var20 * 418711 + var20 * 13761)); + float var31 = var25.getFloatTemperature(); + float var32; + double var35; + + if (var31 >= 0.15F) { + if (var18 != 0) { + if (var18 >= 0) { + var8.draw(); + } + + var18 = 0; + rain.bindTexture(); + var8.startDrawingQuads(); + } + + var32 = ((float) (ticks + var21 * var21 * 3121 + var21 * 45238971 + var20 * var20 * 418711 + var20 * 13761 & 31) + par1) / 32.0F * (3.0F + this.random.nextFloat()); + var32 = var32 % 100000.0f; + double var33 = (double) ((float) var21 + 0.5F) - var41.posX; + var35 = (double) ((float) var20 + 0.5F) - var41.posZ; + float var37 = MathHelper.sqrt_double(var33 * var33 + var35 * var35) / (float) var16; + float var38 = 1.0F; + var8.setBrightness(var42.getLightBrightnessForSkyBlocks(var21, var30, var20, 0)); + var8.setColorRGBA_F(var38, var38, var38, ((1.0F - var37 * var37) * 0.5F + 0.5F) * var2); + var8.setTranslation(-var9 * 1.0D, -var11 * 1.0D, -var13 * 1.0D); + var8.addVertexWithUV((double) ((float) var21 - var23) + 0.5D, (double) var27, (double) ((float) var20 - var24) + 0.5D, (double) (0.0F * var29), (double) ((float) var27 * var29 / 4.0F + var32 * var29)); + var8.addVertexWithUV((double) ((float) var21 + var23) + 0.5D, (double) var27, (double) ((float) var20 + var24) + 0.5D, (double) (1.0F * var29), (double) ((float) var27 * var29 / 4.0F + var32 * var29)); + var8.addVertexWithUV((double) ((float) var21 + var23) + 0.5D, (double) var28, (double) ((float) var20 + var24) + 0.5D, (double) (1.0F * var29), (double) ((float) var28 * var29 / 4.0F + var32 * var29)); + var8.addVertexWithUV((double) ((float) var21 - var23) + 0.5D, (double) var28, (double) ((float) var20 - var24) + 0.5D, (double) (0.0F * var29), (double) ((float) var28 * var29 / 4.0F + var32 * var29)); + var8.setTranslation(0.0D, 0.0D, 0.0D); + } else { + if (var18 != 1) { + if (var18 >= 0) { + var8.draw(); + } + + var18 = 1; + snow.bindTexture(); + var8.startDrawingQuads(); + } + + var32 = (((float) (ticks & 511) + par1) / 512.0F); + float var46 = this.random.nextFloat() + var19 * 0.01F * (float) this.random.nextGaussian(); + float var34 = this.random.nextFloat() + var19 * (float) this.random.nextGaussian() * 0.001F; + var35 = (double) ((float) var21 + 0.5F) - var41.posX; + double var47 = (double) ((float) var20 + 0.5F) - var41.posZ; + float var39 = MathHelper.sqrt_double(var35 * var35 + var47 * var47) / (float) var16; + float var40 = 1.0F; + var8.setBrightness((var42.getLightBrightnessForSkyBlocks(var21, var30, var20, 0) * 3 + 15728880) / 4); + var8.setColorRGBA_F(var40, var40, var40, ((1.0F - var39 * var39) * 0.3F + 0.5F) * var2); + var8.setTranslation(-var9 * 1.0D, -var11 * 1.0D, -var13 * 1.0D); + var8.addVertexWithUV((double) ((float) var21 - var23) + 0.5D, (double) var27, (double) ((float) var20 - var24) + 0.5D, (double) (0.0F * var29 + var46), (double) ((float) var27 * var29 / 4.0F + var32 * var29 + var34)); + var8.addVertexWithUV((double) ((float) var21 + var23) + 0.5D, (double) var27, (double) ((float) var20 + var24) + 0.5D, (double) (1.0F * var29 + var46), (double) ((float) var27 * var29 / 4.0F + var32 * var29 + var34)); + var8.addVertexWithUV((double) ((float) var21 + var23) + 0.5D, (double) var28, (double) ((float) var20 + var24) + 0.5D, (double) (1.0F * var29 + var46), (double) ((float) var28 * var29 / 4.0F + var32 * var29 + var34)); + var8.addVertexWithUV((double) ((float) var21 - var23) + 0.5D, (double) var28, (double) ((float) var20 - var24) + 0.5D, (double) (0.0F * var29 + var46), (double) ((float) var28 * var29 / 4.0F + var32 * var29 + var34)); + var8.setTranslation(0.0D, 0.0D, 0.0D); + } + } + } + } + } + + if (var18 >= 0) { + var8.draw(); + } + + EaglerAdapter.glEnable(EaglerAdapter.GL_CULL_FACE); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glAlphaFunc(EaglerAdapter.GL_GREATER, 0.1F); + this.disableLightmap((double) par1); + } + } + + /** + * Setup orthogonal projection for rendering GUI screen overlays + */ + public void setupOverlayRendering() { + ScaledResolution var1 = new ScaledResolution(this.mc.gameSettings, this.mc.displayWidth, this.mc.displayHeight); + EaglerAdapter.glClear(EaglerAdapter.GL_DEPTH_BUFFER_BIT); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glOrtho(0.0F, var1.getScaledWidth(), var1.getScaledHeight(), 0.0F, 1000.0F, 3000.0F); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glTranslatef(0.0F, 0.0F, -2000.0F); + } + + /** + * calculates fog and calls glClearColor + */ + private void updateFogColor(float par1) { + WorldClient var2 = this.mc.theWorld; + EntityLiving var3 = this.mc.renderViewEntity; + float var4 = 1.0F / (float) (4 - this.mc.gameSettings.renderDistance); + var4 = 1.0F - (float) Math.pow((double) var4, 0.25D); + Vec3 var5 = var2.getSkyColor(this.mc.renderViewEntity, par1); + float var6 = (float) var5.xCoord; + float var7 = (float) var5.yCoord; + float var8 = (float) var5.zCoord; + Vec3 var9 = var2.getFogColor(par1); + this.fogColorRed = (float) var9.xCoord; + this.fogColorGreen = (float) var9.yCoord; + this.fogColorBlue = (float) var9.zCoord; + float var11; + + if (this.mc.gameSettings.renderDistance < 2) { + Vec3 var10 = MathHelper.sin(var2.getCelestialAngleRadians(par1)) > 0.0F ? var2.getWorldVec3Pool().getVecFromPool(-1.0D, 0.0D, 0.0D) : var2.getWorldVec3Pool().getVecFromPool(1.0D, 0.0D, 0.0D); + var11 = (float) var3.getLook(par1).dotProduct(var10); + + if (var11 < 0.0F) { + var11 = 0.0F; + } + + if (var11 > 0.0F) { + float[] var12 = var2.provider.calcSunriseSunsetColors(var2.getCelestialAngle(par1), par1); + + if (var12 != null) { + var11 *= var12[3]; + this.fogColorRed = this.fogColorRed * (1.0F - var11) + var12[0] * var11; + this.fogColorGreen = this.fogColorGreen * (1.0F - var11) + var12[1] * var11; + this.fogColorBlue = this.fogColorBlue * (1.0F - var11) + var12[2] * var11; + } + } + } + + this.fogColorRed += (var6 - this.fogColorRed) * var4; + this.fogColorGreen += (var7 - this.fogColorGreen) * var4; + this.fogColorBlue += (var8 - this.fogColorBlue) * var4; + float var19 = var2.getRainStrength(par1); + float var20; + + if (var19 > 0.0F) { + var11 = 1.0F - var19 * 0.5F; + var20 = 1.0F - var19 * 0.4F; + this.fogColorRed *= var11; + this.fogColorGreen *= var11; + this.fogColorBlue *= var20; + } + + var11 = var2.getWeightedThunderStrength(par1); + + if (var11 > 0.0F) { + var20 = 1.0F - var11 * 0.5F; + this.fogColorRed *= var20; + this.fogColorGreen *= var20; + this.fogColorBlue *= var20; + } + + int var21 = ActiveRenderInfo.getBlockIdAtEntityViewpoint(this.mc.theWorld, var3, par1); + + if (this.cloudFog) { + Vec3 var13 = var2.getCloudColour(par1); + this.fogColorRed = (float) var13.xCoord; + this.fogColorGreen = (float) var13.yCoord; + this.fogColorBlue = (float) var13.zCoord; + } else if (var21 != 0 && Block.blocksList[var21].blockMaterial == Material.water) { + this.fogColorRed = 0.02F; + this.fogColorGreen = 0.02F; + this.fogColorBlue = 0.2F; + } else if (var21 != 0 && Block.blocksList[var21].blockMaterial == Material.lava) { + this.fogColorRed = 0.6F; + this.fogColorGreen = 0.1F; + this.fogColorBlue = 0.0F; + } + + float var22 = this.fogColor2 + (this.fogColor1 - this.fogColor2) * par1; + this.fogColorRed *= var22; + this.fogColorGreen *= var22; + this.fogColorBlue *= var22; + double var14 = (var3.lastTickPosY + (var3.posY - var3.lastTickPosY) * (double) par1) * var2.provider.getVoidFogYFactor(); + + if (var3.isPotionActive(Potion.blindness)) { + int var16 = var3.getActivePotionEffect(Potion.blindness).getDuration(); + + if (var16 < 20) { + var14 *= (double) (1.0F - (float) var16 / 20.0F); + } else { + var14 = 0.0D; + } + } + + if (var14 < 1.0D) { + if (var14 < 0.0D) { + var14 = 0.0D; + } + + var14 *= var14; + this.fogColorRed = (float) ((double) this.fogColorRed * var14); + this.fogColorGreen = (float) ((double) this.fogColorGreen * var14); + this.fogColorBlue = (float) ((double) this.fogColorBlue * var14); + } + + float var23; + + if (this.field_82831_U > 0.0F) { + var23 = this.field_82832_V + (this.field_82831_U - this.field_82832_V) * par1; + this.fogColorRed = this.fogColorRed * (1.0F - var23) + this.fogColorRed * 0.7F * var23; + this.fogColorGreen = this.fogColorGreen * (1.0F - var23) + this.fogColorGreen * 0.6F * var23; + this.fogColorBlue = this.fogColorBlue * (1.0F - var23) + this.fogColorBlue * 0.6F * var23; + } + + float var17; + + if (var3.isPotionActive(Potion.nightVision)) { + var23 = this.getNightVisionBrightness(this.mc.thePlayer, par1); + var17 = 1.0F / this.fogColorRed; + + if (var17 > 1.0F / this.fogColorGreen) { + var17 = 1.0F / this.fogColorGreen; + } + + if (var17 > 1.0F / this.fogColorBlue) { + var17 = 1.0F / this.fogColorBlue; + } + + this.fogColorRed = this.fogColorRed * (1.0F - var23) + this.fogColorRed * var17 * var23; + this.fogColorGreen = this.fogColorGreen * (1.0F - var23) + this.fogColorGreen * var17 * var23; + this.fogColorBlue = this.fogColorBlue * (1.0F - var23) + this.fogColorBlue * var17 * var23; + } + + if (this.mc.gameSettings.anaglyph) { + var23 = (this.fogColorRed * 30.0F + this.fogColorGreen * 59.0F + this.fogColorBlue * 11.0F) / 100.0F; + var17 = (this.fogColorRed * 30.0F + this.fogColorGreen * 70.0F) / 100.0F; + float var18 = (this.fogColorRed * 30.0F + this.fogColorBlue * 70.0F) / 100.0F; + this.fogColorRed = var23; + this.fogColorGreen = var17; + this.fogColorBlue = var18; + } + + EaglerAdapter.glClearColor(this.fogColorRed, this.fogColorGreen, this.fogColorBlue, 0.0F); + } + + /** + * Sets up the fog to be rendered. If the arg passed in is -1 the fog starts at + * 0 and goes to 80% of far plane distance and is used for sky rendering. + */ + private void setupFog(int par1, float par2) { + EntityLiving var3 = this.mc.renderViewEntity; + + if (par1 == 999) { + EaglerAdapter.glFog(EaglerAdapter.GL_FOG_COLOR, this.setFogColorBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + EaglerAdapter.glFogi(EaglerAdapter.GL_FOG_MODE, EaglerAdapter.GL_LINEAR); + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_START, 0.0F); + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_END, 8.0F); + + //if (EaglerAdapter.NVFogDistanceInstalled) { + // EaglerAdapter.glFogi(EaglerAdapter.GL_FOG_DISTANCE_MODE, EaglerAdapter.GL_EYE_RADIAL); + //} + + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_START, 0.0F); + } else { + EaglerAdapter.glFog(EaglerAdapter.GL_FOG_COLOR, this.setFogColorBuffer(this.fogColorRed, this.fogColorGreen, this.fogColorBlue, 1.0F)); + EaglerAdapter.glNormal3f(0.0F, -1.0F, 0.0F); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + int var5 = ActiveRenderInfo.getBlockIdAtEntityViewpoint(this.mc.theWorld, var3, par2); + float var6; + + if (var3.isPotionActive(Potion.blindness)) { + var6 = 5.0F; + int var7 = var3.getActivePotionEffect(Potion.blindness).getDuration(); + + if (var7 < 20) { + var6 = 5.0F + (this.farPlaneDistance - 5.0F) * (1.0F - (float) var7 / 20.0F); + } + + EaglerAdapter.glFogi(EaglerAdapter.GL_FOG_MODE, EaglerAdapter.GL_LINEAR); + + if (par1 < 0) { + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_START, 0.0F); + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_END, var6 * 0.8F); + } else { + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_START, var6 * 0.25F); + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_END, var6); + } + + //if (EaglerAdapter.NVFogDistanceInstalled) { + // EaglerAdapter.glFogi(EaglerAdapter.GL_FOG_DISTANCE_MODE, EaglerAdapter.GL_EYE_RADIAL); + //} + } else { + float var8; + float var9; + float var10; + float var11; + float var12; + + if (this.cloudFog) { + EaglerAdapter.glFogi(EaglerAdapter.GL_FOG_MODE, EaglerAdapter.GL_EXP); + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_DENSITY, 0.1F); + var6 = 1.0F; + var12 = 1.0F; + var8 = 1.0F; + + if (this.mc.gameSettings.anaglyph) { + var9 = (var6 * 30.0F + var12 * 59.0F + var8 * 11.0F) / 100.0F; + var10 = (var6 * 30.0F + var12 * 70.0F) / 100.0F; + var11 = (var6 * 30.0F + var8 * 70.0F) / 100.0F; + } + } else if (var5 > 0 && Block.blocksList[var5].blockMaterial == Material.water) { + EaglerAdapter.glFogi(EaglerAdapter.GL_FOG_MODE, EaglerAdapter.GL_EXP); + + if (var3.isPotionActive(Potion.waterBreathing)) { + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_DENSITY, 0.05F); + } else { + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_DENSITY, 0.1F); + } + + var6 = 0.4F; + var12 = 0.4F; + var8 = 0.9F; + + if (this.mc.gameSettings.anaglyph) { + var9 = (var6 * 30.0F + var12 * 59.0F + var8 * 11.0F) / 100.0F; + var10 = (var6 * 30.0F + var12 * 70.0F) / 100.0F; + var11 = (var6 * 30.0F + var8 * 70.0F) / 100.0F; + } + } else if (var5 > 0 && Block.blocksList[var5].blockMaterial == Material.lava) { + EaglerAdapter.glFogi(EaglerAdapter.GL_FOG_MODE, EaglerAdapter.GL_EXP); + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_DENSITY, 2.0F); + var6 = 0.4F; + var12 = 0.3F; + var8 = 0.3F; + + if (this.mc.gameSettings.anaglyph) { + var9 = (var6 * 30.0F + var12 * 59.0F + var8 * 11.0F) / 100.0F; + var10 = (var6 * 30.0F + var12 * 70.0F) / 100.0F; + var11 = (var6 * 30.0F + var8 * 70.0F) / 100.0F; + } + } else { + if(this.mc.gameSettings.enableFog) { + var6 = this.farPlaneDistance; + + if (this.mc.theWorld.provider.getWorldHasVoidParticles()) { + double var13 = (double) ((var3.getBrightnessForRender(par2) & 15728640) >> 20) / 16.0D + (var3.lastTickPosY + (var3.posY - var3.lastTickPosY) * (double) par2 + 4.0D) / 32.0D; + + if (var13 < 1.0D) { + if (var13 < 0.0D) { + var13 = 0.0D; + } + + var13 *= var13; + var9 = 100.0F * (float) var13; + + if (var9 < 5.0F) { + var9 = 5.0F; + } + + if (var6 > var9) { + var6 = var9; + } + } + } + + EaglerAdapter.glFogi(EaglerAdapter.GL_FOG_MODE, EaglerAdapter.GL_LINEAR); + + if (par1 < 0) { + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_START, 0.0F); + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_END, var6 * 0.8F); + } else { + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_START, var6 * 0.25F); + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_END, var6 * 0.9F); + } + + //if (EaglerAdapter.NVFogDistanceInstalled) { + // EaglerAdapter.glFogi(EaglerAdapter.GL_FOG_DISTANCE_MODE, EaglerAdapter.GL_EYE_RADIAL); + //} + + if (this.mc.theWorld.provider.doesXZShowFog((int) var3.posX, (int) var3.posZ)) { + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_START, var6 * 0.05F); + EaglerAdapter.glFogf(EaglerAdapter.GL_FOG_END, Math.min(var6, 192.0F) * 0.5F); + } + }else { + EaglerAdapter.glDisable(EaglerAdapter.GL_FOG); + } + } + } + + EaglerAdapter.glEnable(EaglerAdapter.GL_COLOR_MATERIAL); + EaglerAdapter.glColorMaterial(EaglerAdapter.GL_FRONT, EaglerAdapter.GL_AMBIENT); + } + } + + /** + * Update and return fogColorBuffer with the RGBA values passed as arguments + */ + private FloatBuffer setFogColorBuffer(float par1, float par2, float par3, float par4) { + this.fogColorBuffer.clear(); + this.fogColorBuffer.put(par1).put(par2).put(par3).put(par4); + this.fogColorBuffer.flip(); + return this.fogColorBuffer; + } + + /** + * Converts performance value (0-2) to FPS (35-200) + */ + public static int performanceToFps(int par0) { + short var1 = 240; + + if (par0 == 1) { + var1 = 90; + } + + if (par0 == 2) { + var1 = 35; + } + + return var1; + } + + /** + * Get minecraft reference from the EntityRenderer + */ + static Minecraft getRendererMinecraft(EntityRenderer par0EntityRenderer) { + return par0EntityRenderer.mc; + } +} diff --git a/src/main/java/net/minecraft/src/EntitySelectorAlive.java b/src/main/java/net/minecraft/src/EntitySelectorAlive.java new file mode 100644 index 0000000..c7f4751 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySelectorAlive.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +final class EntitySelectorAlive implements IEntitySelector { + /** + * Return whether the specified entity is applicable to this filter. + */ + public boolean isEntityApplicable(Entity par1Entity) { + return par1Entity.isEntityAlive(); + } +} diff --git a/src/main/java/net/minecraft/src/EntitySelectorArmoredMob.java b/src/main/java/net/minecraft/src/EntitySelectorArmoredMob.java new file mode 100644 index 0000000..22fbe6a --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySelectorArmoredMob.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +public class EntitySelectorArmoredMob implements IEntitySelector { + private final ItemStack field_96567_c; + + public EntitySelectorArmoredMob(ItemStack par1ItemStack) { + this.field_96567_c = par1ItemStack; + } + + /** + * Return whether the specified entity is applicable to this filter. + */ + public boolean isEntityApplicable(Entity par1Entity) { + if (!par1Entity.isEntityAlive()) { + return false; + } else if (!(par1Entity instanceof EntityLiving)) { + return false; + } else { + EntityLiving var2 = (EntityLiving) par1Entity; + return var2.getCurrentItemOrArmor(EntityLiving.getArmorPosition(this.field_96567_c)) != null ? false : var2.canPickUpLoot() || var2 instanceof EntityPlayer; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntitySelectorInventory.java b/src/main/java/net/minecraft/src/EntitySelectorInventory.java new file mode 100644 index 0000000..cce2672 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySelectorInventory.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +final class EntitySelectorInventory implements IEntitySelector { + /** + * Return whether the specified entity is applicable to this filter. + */ + public boolean isEntityApplicable(Entity par1Entity) { + return par1Entity instanceof IInventory && par1Entity.isEntityAlive(); + } +} diff --git a/src/main/java/net/minecraft/src/EntitySenses.java b/src/main/java/net/minecraft/src/EntitySenses.java new file mode 100644 index 0000000..7fd353d --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySenses.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +public class EntitySenses { + EntityLiving entityObj; + + /** Cache of entities which we can see */ + List seenEntities = new ArrayList(); + + /** Cache of entities which we cannot see */ + List unseenEntities = new ArrayList(); + + public EntitySenses(EntityLiving par1EntityLiving) { + this.entityObj = par1EntityLiving; + } + + /** + * Clears canSeeCachePositive and canSeeCacheNegative. + */ + public void clearSensingCache() { + this.seenEntities.clear(); + this.unseenEntities.clear(); + } + + /** + * Checks, whether 'our' entity can see the entity given as argument (true) or + * not (false), caching the result. + */ + public boolean canSee(Entity par1Entity) { + if (this.seenEntities.contains(par1Entity)) { + return true; + } else if (this.unseenEntities.contains(par1Entity)) { + return false; + } else { + this.entityObj.worldObj.theProfiler.startSection("canSee"); + boolean var2 = this.entityObj.canEntityBeSeen(par1Entity); + this.entityObj.worldObj.theProfiler.endSection(); + + if (var2) { + this.seenEntities.add(par1Entity); + } else { + this.unseenEntities.add(par1Entity); + } + + return var2; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntitySheep.java b/src/main/java/net/minecraft/src/EntitySheep.java new file mode 100644 index 0000000..2657cb0 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySheep.java @@ -0,0 +1,272 @@ +package net.minecraft.src; + +import java.util.Random; + + + +public class EntitySheep extends EntityAnimal { + private final InventoryCrafting field_90016_e = new InventoryCrafting(new ContainerSheep(this), 2, 1); + + /** + * Holds the RGB table of the sheep colors - in OpenGL glColor3f values - used + * to render the sheep colored fleece. + */ + public static final float[][] fleeceColorTable = new float[][] { { 1.0F, 1.0F, 1.0F }, { 0.85F, 0.5F, 0.2F }, { 0.7F, 0.3F, 0.85F }, { 0.4F, 0.6F, 0.85F }, { 0.9F, 0.9F, 0.2F }, { 0.5F, 0.8F, 0.1F }, { 0.95F, 0.5F, 0.65F }, + { 0.3F, 0.3F, 0.3F }, { 0.6F, 0.6F, 0.6F }, { 0.3F, 0.5F, 0.6F }, { 0.5F, 0.25F, 0.7F }, { 0.2F, 0.3F, 0.7F }, { 0.4F, 0.3F, 0.2F }, { 0.4F, 0.5F, 0.2F }, { 0.6F, 0.2F, 0.2F }, { 0.1F, 0.1F, 0.1F } }; + + /** + * Used to control movement as well as wool regrowth. Set to 40 on + * handleHealthUpdate and counts down with each tick. + */ + private int sheepTimer; + + public EntitySheep() { + super(); + this.setSize(0.9F, 1.3F); + float var2 = 0.23F; + this.field_90016_e.setInventorySlotContents(0, new ItemStack(Item.dyePowder, 1, 0)); + this.field_90016_e.setInventorySlotContents(1, new ItemStack(Item.dyePowder, 1, 0)); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() { + return true; + } + + protected void updateAITasks() { + super.updateAITasks(); + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (this.worldObj.isRemote) { + this.sheepTimer = Math.max(0, this.sheepTimer - 1); + } + + super.onLivingUpdate(); + } + + public int getMaxHealth() { + return 8; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte) 0)); + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + if (!this.getSheared()) { + this.entityDropItem(new ItemStack(Block.cloth.blockID, 1, this.getFleeceColor()), 0.0F); + } + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Block.cloth.blockID; + } + + public void handleHealthUpdate(byte par1) { + if (par1 == 10) { + this.sheepTimer = 40; + } else { + super.handleHealthUpdate(par1); + } + } + + public float func_70894_j(float par1) { + return this.sheepTimer <= 0 ? 0.0F : (this.sheepTimer >= 4 && this.sheepTimer <= 36 ? 1.0F : (this.sheepTimer < 4 ? ((float) this.sheepTimer - par1) / 4.0F : -((float) (this.sheepTimer - 40) - par1) / 4.0F)); + } + + public float func_70890_k(float par1) { + if (this.sheepTimer > 4 && this.sheepTimer <= 36) { + float var2 = ((float) (this.sheepTimer - 4) - par1) / 32.0F; + return ((float) Math.PI / 5F) + ((float) Math.PI * 7F / 100F) * MathHelper.sin(var2 * 28.7F); + } else { + return this.sheepTimer > 0 ? ((float) Math.PI / 5F) : this.rotationPitch / (180F / (float) Math.PI); + } + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + + if (var2 != null && var2.itemID == Item.shears.itemID && !this.getSheared() && !this.isChild()) { + if (!this.worldObj.isRemote) { + this.setSheared(true); + int var3 = 1 + this.rand.nextInt(3); + + for (int var4 = 0; var4 < var3; ++var4) { + EntityItem var5 = this.entityDropItem(new ItemStack(Block.cloth.blockID, 1, this.getFleeceColor()), 1.0F); + var5.motionY += (double) (this.rand.nextFloat() * 0.05F); + var5.motionX += (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.1F); + var5.motionZ += (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.1F); + } + } + + var2.damageItem(1, par1EntityPlayer); + this.playSound("mob.sheep.shear", 1.0F, 1.0F); + } + + return super.interact(par1EntityPlayer); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setBoolean("Sheared", this.getSheared()); + par1NBTTagCompound.setByte("Color", (byte) this.getFleeceColor()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setSheared(par1NBTTagCompound.getBoolean("Sheared")); + this.setFleeceColor(par1NBTTagCompound.getByte("Color")); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.sheep.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.sheep.say"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.sheep.say"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.sheep.step", 0.15F, 1.0F); + } + + public int getFleeceColor() { + return this.dataWatcher.getWatchableObjectByte(16) & 15; + } + + public void setFleeceColor(int par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & 240 | par1 & 15))); + } + + /** + * returns true if a sheeps wool has been sheared + */ + public boolean getSheared() { + return (this.dataWatcher.getWatchableObjectByte(16) & 16) != 0; + } + + /** + * make a sheep sheared if set to true + */ + public void setSheared(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 16))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -17))); + } + } + + /** + * This method is called when a sheep spawns in the world to select the color of + * sheep fleece. + */ + public static int getRandomFleeceColor(Random par0Random) { + int var1 = par0Random.nextInt(100); + return var1 < 5 ? 15 : (var1 < 10 ? 7 : (var1 < 15 ? 8 : (var1 < 18 ? 12 : (par0Random.nextInt(500) == 0 ? 6 : 0)))); + } + + public EntitySheep func_90015_b(EntityAgeable par1EntityAgeable) { + EntitySheep var2 = (EntitySheep) par1EntityAgeable; + EntitySheep var3 = new EntitySheep(); + var3.setWorld(worldObj); + int var4 = this.func_90014_a(this, var2); + var3.setFleeceColor(15 - var4); + return var3; + } + + /** + * This function applies the benefits of growing back wool and faster growing up + * to the acting entity. (This function is used in the AIEatGrass) + */ + public void eatGrassBonus() { + this.setSheared(false); + + if (this.isChild()) { + int var1 = this.getGrowingAge() + 1200; + + if (var1 > 0) { + var1 = 0; + } + + this.setGrowingAge(var1); + } + } + + /** + * Initialize this creature. + */ + public void initCreature() { + this.setFleeceColor(getRandomFleeceColor(this.worldObj.rand)); + } + + private int func_90014_a(EntityAnimal par1EntityAnimal, EntityAnimal par2EntityAnimal) { + int var3 = this.func_90013_b(par1EntityAnimal); + int var4 = this.func_90013_b(par2EntityAnimal); + this.field_90016_e.getStackInSlot(0).setItemDamage(var3); + this.field_90016_e.getStackInSlot(1).setItemDamage(var4); + ItemStack var5 = CraftingManager.getInstance().findMatchingRecipe(this.field_90016_e, ((EntitySheep) par1EntityAnimal).worldObj); + int var6; + + if (var5 != null && var5.getItem().itemID == Item.dyePowder.itemID) { + var6 = var5.getItemDamage(); + } else { + var6 = this.worldObj.rand.nextBoolean() ? var3 : var4; + } + + return var6; + } + + private int func_90013_b(EntityAnimal par1EntityAnimal) { + return 15 - ((EntitySheep) par1EntityAnimal).getFleeceColor(); + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.func_90015_b(par1EntityAgeable); + } +} diff --git a/src/main/java/net/minecraft/src/EntitySilverfish.java b/src/main/java/net/minecraft/src/EntitySilverfish.java new file mode 100644 index 0000000..ada150a --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySilverfish.java @@ -0,0 +1,205 @@ +package net.minecraft.src; + +public class EntitySilverfish extends EntityMob { + /** + * A cooldown before this entity will search for another Silverfish to join them + * in battle. + */ + private int allySummonCooldown; + + public EntitySilverfish() { + super(); + this.setSize(0.3F, 0.7F); + this.moveSpeed = 0.6F; + } + + public int getMaxHealth() { + return 8; + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity + * isn't interested in attacking (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() { + double var1 = 8.0D; + return this.worldObj.getClosestVulnerablePlayerToEntity(this, var1); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.silverfish.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.silverfish.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.silverfish.kill"; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + if (this.allySummonCooldown <= 0 && (par1DamageSource instanceof EntityDamageSource || par1DamageSource == DamageSource.magic)) { + this.allySummonCooldown = 20; + } + + return super.attackEntityFrom(par1DamageSource, par2); + } + } + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by + * each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) { + if (this.attackTime <= 0 && par2 < 1.2F && par1Entity.boundingBox.maxY > this.boundingBox.minY && par1Entity.boundingBox.minY < this.boundingBox.maxY) { + this.attackTime = 20; + this.attackEntityAsMob(par1Entity); + } + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.silverfish.step", 0.15F, 1.0F); + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return 0; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.renderYawOffset = this.rotationYaw; + super.onUpdate(); + } + + protected void updateEntityActionState() { + super.updateEntityActionState(); + + if (!this.worldObj.isRemote) { + int var1; + int var2; + int var3; + int var5; + + if (this.allySummonCooldown > 0) { + --this.allySummonCooldown; + + if (this.allySummonCooldown == 0) { + var1 = MathHelper.floor_double(this.posX); + var2 = MathHelper.floor_double(this.posY); + var3 = MathHelper.floor_double(this.posZ); + boolean var4 = false; + + for (var5 = 0; !var4 && var5 <= 5 && var5 >= -5; var5 = var5 <= 0 ? 1 - var5 : 0 - var5) { + for (int var6 = 0; !var4 && var6 <= 10 && var6 >= -10; var6 = var6 <= 0 ? 1 - var6 : 0 - var6) { + for (int var7 = 0; !var4 && var7 <= 10 && var7 >= -10; var7 = var7 <= 0 ? 1 - var7 : 0 - var7) { + int var8 = this.worldObj.getBlockId(var1 + var6, var2 + var5, var3 + var7); + + if (var8 == Block.silverfish.blockID) { + this.worldObj.destroyBlock(var1 + var6, var2 + var5, var3 + var7, false); + Block.silverfish.onBlockDestroyedByPlayer(this.worldObj, var1 + var6, var2 + var5, var3 + var7, 0); + + if (this.rand.nextBoolean()) { + var4 = true; + break; + } + } + } + } + } + } + } + + if (this.entityToAttack == null && !this.hasPath()) { + var1 = MathHelper.floor_double(this.posX); + var2 = MathHelper.floor_double(this.posY + 0.5D); + var3 = MathHelper.floor_double(this.posZ); + int var9 = this.rand.nextInt(6); + var5 = this.worldObj.getBlockId(var1 + Facing.offsetsXForSide[var9], var2 + Facing.offsetsYForSide[var9], var3 + Facing.offsetsZForSide[var9]); + + if (BlockSilverfish.getPosingIdByMetadata(var5)) { + this.worldObj.setBlock(var1 + Facing.offsetsXForSide[var9], var2 + Facing.offsetsYForSide[var9], var3 + Facing.offsetsZForSide[var9], Block.silverfish.blockID, BlockSilverfish.getMetadataForBlockType(var5), 3); + this.spawnExplosionParticle(); + this.setDead(); + } else { + this.updateWanderPath(); + } + } else if (this.entityToAttack != null && !this.hasPath()) { + this.entityToAttack = null; + } + } + } + + /** + * Takes a coordinate in and returns a weight to determine how likely this + * creature will try to path to the block. Args: x, y, z + */ + public float getBlockPathWeight(int par1, int par2, int par3) { + return this.worldObj.getBlockId(par1, par2 - 1, par3) == Block.stone.blockID ? 10.0F : super.getBlockPathWeight(par1, par2, par3); + } + + /** + * Checks to make sure the light is not too bright where the mob is spawning + */ + protected boolean isValidLightLevel() { + return true; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + if (super.getCanSpawnHere()) { + EntityPlayer var1 = this.worldObj.getClosestPlayerToEntity(this, 5.0D); + return var1 == null; + } else { + return false; + } + } + + /** + * Returns the amount of damage a mob should deal. + */ + public int getAttackStrength(Entity par1Entity) { + return 1; + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.ARTHROPOD; + } +} diff --git a/src/main/java/net/minecraft/src/EntitySkeleton.java b/src/main/java/net/minecraft/src/EntitySkeleton.java new file mode 100644 index 0000000..96dd9ef --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySkeleton.java @@ -0,0 +1,291 @@ +package net.minecraft.src; + +public class EntitySkeleton extends EntityMob implements IRangedAttackMob { + + public EntitySkeleton() { + super(); + this.moveSpeed = 0.25F; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(13, new Byte((byte) 0)); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + public int getMaxHealth() { + return 20; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.skeleton.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.skeleton.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.skeleton.death"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.skeleton.step", 0.15F, 1.0F); + } + + public boolean attackEntityAsMob(Entity par1Entity) { + if (super.attackEntityAsMob(par1Entity)) { + if (this.getSkeletonType() == 1 && par1Entity instanceof EntityLiving) { + ((EntityLiving) par1Entity).addPotionEffect(new PotionEffect(Potion.wither.id, 200)); + } + + return true; + } else { + return false; + } + } + + /** + * Returns the amount of damage a mob should deal. + */ + public int getAttackStrength(Entity par1Entity) { + if (this.getSkeletonType() == 1) { + ItemStack var2 = this.getHeldItem(); + int var3 = 4; + + if (var2 != null) { + var3 += var2.getDamageVsEntity(this); + } + + return var3; + } else { + return super.getAttackStrength(par1Entity); + } + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.UNDEAD; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (this.worldObj.isDaytime() && !this.worldObj.isRemote) { + float var1 = this.getBrightness(1.0F); + + if (var1 > 0.5F && this.rand.nextFloat() * 30.0F < (var1 - 0.4F) * 2.0F && this.worldObj.canBlockSeeTheSky(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ))) { + boolean var2 = true; + ItemStack var3 = this.getCurrentItemOrArmor(4); + + if (var3 != null) { + if (var3.isItemStackDamageable()) { + var3.setItemDamage(var3.getItemDamageForDisplay() + this.rand.nextInt(2)); + + if (var3.getItemDamageForDisplay() >= var3.getMaxDamage()) { + this.renderBrokenItemStack(var3); + this.setCurrentItemOrArmor(4, (ItemStack) null); + } + } + + var2 = false; + } + + if (var2) { + this.setFire(8); + } + } + } + + if (this.worldObj.isRemote && this.getSkeletonType() == 1) { + this.setSize(0.72F, 2.34F); + } + + super.onLivingUpdate(); + } + + /** + * Called when the mob's health reaches 0. + */ + public void onDeath(DamageSource par1DamageSource) { + super.onDeath(par1DamageSource); + + if (par1DamageSource.getSourceOfDamage() instanceof EntityArrow && par1DamageSource.getEntity() instanceof EntityPlayer) { + EntityPlayer var2 = (EntityPlayer) par1DamageSource.getEntity(); + double var3 = var2.posX - this.posX; + double var5 = var2.posZ - this.posZ; + + if (var3 * var3 + var5 * var5 >= 2500.0D) { + var2.triggerAchievement(AchievementList.snipeSkeleton); + } + } + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.arrow.itemID; + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + int var3; + int var4; + + if (this.getSkeletonType() == 1) { + var3 = this.rand.nextInt(3 + par2) - 1; + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.coal.itemID, 1); + } + } else { + var3 = this.rand.nextInt(3 + par2); + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.arrow.itemID, 1); + } + } + + var3 = this.rand.nextInt(3 + par2); + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.bone.itemID, 1); + } + } + + protected void dropRareDrop(int par1) { + if (this.getSkeletonType() == 1) { + this.entityDropItem(new ItemStack(Item.skull.itemID, 1, 1), 0.0F); + } + } + + /** + * Makes entity wear random armor based on difficulty + */ + protected void addRandomArmor() { + super.addRandomArmor(); + this.setCurrentItemOrArmor(0, new ItemStack(Item.bow)); + } + + /** + * Initialize this creature. + */ + public void initCreature() { + + } + + /** + * sets this entity's combat AI. + */ + public void setCombatTask() { + + } + + /** + * Attack the specified entity using a ranged attack. + */ + public void attackEntityWithRangedAttack(EntityLiving par1EntityLiving, float par2) { + EntityArrow var3 = new EntityArrow(this.worldObj, this, par1EntityLiving, 1.6F, (float) (14 - this.worldObj.difficultySetting * 4)); + int var4 = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, this.getHeldItem()); + int var5 = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, this.getHeldItem()); + var3.setDamage((double) (par2 * 2.0F) + this.rand.nextGaussian() * 0.25D + (double) ((float) this.worldObj.difficultySetting * 0.11F)); + + if (var4 > 0) { + var3.setDamage(var3.getDamage() + (double) var4 * 0.5D + 0.5D); + } + + if (var5 > 0) { + var3.setKnockbackStrength(var5); + } + + if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, this.getHeldItem()) > 0 || this.getSkeletonType() == 1) { + var3.setFire(100); + } + + this.playSound("random.bow", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); + this.worldObj.spawnEntityInWorld(var3); + } + + /** + * Return this skeleton's type. + */ + public int getSkeletonType() { + return this.dataWatcher.getWatchableObjectByte(13); + } + + /** + * Set this skeleton's type. + */ + public void setSkeletonType(int par1) { + this.dataWatcher.updateObject(13, Byte.valueOf((byte) par1)); + this.isImmuneToFire = par1 == 1; + + if (par1 == 1) { + this.setSize(0.72F, 2.34F); + } else { + this.setSize(0.6F, 1.8F); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("SkeletonType")) { + byte var2 = par1NBTTagCompound.getByte("SkeletonType"); + this.setSkeletonType(var2); + } + + this.setCombatTask(); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setByte("SkeletonType", (byte) this.getSkeletonType()); + } + + /** + * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. + * Params: Item, slot + */ + public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack) { + super.setCurrentItemOrArmor(par1, par2ItemStack); + + if (!this.worldObj.isRemote && par1 == 0) { + this.setCombatTask(); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntitySlime.java b/src/main/java/net/minecraft/src/EntitySlime.java new file mode 100644 index 0000000..2a0b620 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySlime.java @@ -0,0 +1,299 @@ +package net.minecraft.src; + + + +public class EntitySlime extends EntityLiving implements IMob { + /** Chances for slimes to spawn in swamps for every moon phase. */ + private static final float[] spawnChances = new float[] { 1.0F, 0.75F, 0.5F, 0.25F, 0.0F, 0.25F, 0.5F, 0.75F }; + public float field_70813_a; + public float field_70811_b; + public float field_70812_c; + + /** the time between each jump of the slime */ + private int slimeJumpDelay = 0; + + public EntitySlime() { + super(); + int var2 = 1 << this.rand.nextInt(3); + this.yOffset = 0.0F; + this.slimeJumpDelay = this.rand.nextInt(20) + 10; + this.setSlimeSize(var2); + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte) 1)); + } + + protected void setSlimeSize(int par1) { + this.dataWatcher.updateObject(16, new Byte((byte) par1)); + this.setSize(0.6F * (float) par1, 0.6F * (float) par1); + this.setPosition(this.posX, this.posY, this.posZ); + this.setEntityHealth(this.getMaxHealth()); + this.experienceValue = par1; + } + + public int getMaxHealth() { + int var1 = this.getSlimeSize(); + return var1 * var1; + } + + /** + * Returns the size of the slime. + */ + public int getSlimeSize() { + return this.dataWatcher.getWatchableObjectByte(16); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("Size", this.getSlimeSize() - 1); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setSlimeSize(par1NBTTagCompound.getInteger("Size") + 1); + } + + /** + * Returns the name of a particle effect that may be randomly created by + * EntitySlime.onUpdate() + */ + protected String getSlimeParticle() { + return "slime"; + } + + /** + * Returns the name of the sound played when the slime jumps. + */ + protected String getJumpSound() { + return "mob.slime." + (this.getSlimeSize() > 1 ? "big" : "small"); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (!this.worldObj.isRemote && this.worldObj.difficultySetting == 0 && this.getSlimeSize() > 0) { + this.isDead = true; + } + + this.field_70811_b += (this.field_70813_a - this.field_70811_b) * 0.5F; + this.field_70812_c = this.field_70811_b; + boolean var1 = this.onGround; + super.onUpdate(); + int var2; + + if (this.onGround && !var1) { + var2 = this.getSlimeSize(); + + for (int var3 = 0; var3 < var2 * 8; ++var3) { + float var4 = this.rand.nextFloat() * (float) Math.PI * 2.0F; + float var5 = this.rand.nextFloat() * 0.5F + 0.5F; + float var6 = MathHelper.sin(var4) * (float) var2 * 0.5F * var5; + float var7 = MathHelper.cos(var4) * (float) var2 * 0.5F * var5; + this.worldObj.spawnParticle(this.getSlimeParticle(), this.posX + (double) var6, this.boundingBox.minY, this.posZ + (double) var7, 0.0D, 0.0D, 0.0D); + } + + if (this.makesSoundOnLand()) { + this.playSound(this.getJumpSound(), this.getSoundVolume(), ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F) / 0.8F); + } + + this.field_70813_a = -0.5F; + } else if (!this.onGround && var1) { + this.field_70813_a = 1.0F; + } + + this.func_70808_l(); + + if (this.worldObj.isRemote) { + var2 = this.getSlimeSize(); + this.setSize(0.6F * (float) var2, 0.6F * (float) var2); + } + } + + protected void updateEntityActionState() { + this.despawnEntity(); + EntityPlayer var1 = this.worldObj.getClosestVulnerablePlayerToEntity(this, 16.0D); + + if (var1 != null) { + this.faceEntity(var1, 10.0F, 20.0F); + } + + if (this.onGround && this.slimeJumpDelay-- <= 0) { + this.slimeJumpDelay = this.getJumpDelay(); + + if (var1 != null) { + this.slimeJumpDelay /= 3; + } + + this.isJumping = true; + + if (this.makesSoundOnJump()) { + this.playSound(this.getJumpSound(), this.getSoundVolume(), ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F) * 0.8F); + } + + this.moveStrafing = 1.0F - this.rand.nextFloat() * 2.0F; + this.moveForward = (float) (1 * this.getSlimeSize()); + } else { + this.isJumping = false; + + if (this.onGround) { + this.moveStrafing = this.moveForward = 0.0F; + } + } + } + + protected void func_70808_l() { + this.field_70813_a *= 0.6F; + } + + /** + * Gets the amount of time the slime needs to wait between jumps. + */ + protected int getJumpDelay() { + return this.rand.nextInt(20) + 10; + } + + protected EntitySlime createInstance() { + EntitySlime s = new EntitySlime(); + s.setWorld(worldObj); + return s; + } + + /** + * Will get destroyed next tick. + */ + public void setDead() { + int var1 = this.getSlimeSize(); + + if (!this.worldObj.isRemote && var1 > 1 && this.getHealth() <= 0) { + int var2 = 2 + this.rand.nextInt(3); + + for (int var3 = 0; var3 < var2; ++var3) { + float var4 = ((float) (var3 % 2) - 0.5F) * (float) var1 / 4.0F; + float var5 = ((float) (var3 / 2) - 0.5F) * (float) var1 / 4.0F; + EntitySlime var6 = this.createInstance(); + var6.setSlimeSize(var1 / 2); + var6.setLocationAndAngles(this.posX + (double) var4, this.posY + 0.5D, this.posZ + (double) var5, this.rand.nextFloat() * 360.0F, 0.0F); + this.worldObj.spawnEntityInWorld(var6); + } + } + + super.setDead(); + } + + /** + * Called by a player entity when they collide with an entity + */ + public void onCollideWithPlayer(EntityPlayer par1EntityPlayer) { + if (this.canDamagePlayer()) { + int var2 = this.getSlimeSize(); + + if (this.canEntityBeSeen(par1EntityPlayer) && this.getDistanceSqToEntity(par1EntityPlayer) < 0.6D * (double) var2 * 0.6D * (double) var2 + && par1EntityPlayer.attackEntityFrom(DamageSource.causeMobDamage(this), this.getAttackStrength())) { + this.playSound("mob.attack", 1.0F, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F); + } + } + } + + /** + * Indicates weather the slime is able to damage the player (based upon the + * slime's size) + */ + protected boolean canDamagePlayer() { + return this.getSlimeSize() > 1; + } + + /** + * Gets the amount of damage dealt to the player when "attacked" by the slime. + */ + protected int getAttackStrength() { + return this.getSlimeSize(); + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.slime." + (this.getSlimeSize() > 1 ? "big" : "small"); + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.slime." + (this.getSlimeSize() > 1 ? "big" : "small"); + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return this.getSlimeSize() == 1 ? Item.slimeBall.itemID : 0; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + Chunk var1 = this.worldObj.getChunkFromBlockCoords(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posZ)); + + if (this.worldObj.getWorldInfo().getTerrainType() == WorldType.FLAT && this.rand.nextInt(4) != 1) { + return false; + } else { + if (this.getSlimeSize() == 1 || this.worldObj.difficultySetting > 0) { + BiomeGenBase var2 = this.worldObj.getBiomeGenForCoords(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posZ)); + + if (var2 == BiomeGenBase.swampland && this.posY > 50.0D && this.posY < 70.0D && this.rand.nextFloat() < 0.5F && this.rand.nextFloat() < spawnChances[this.worldObj.getMoonPhase()] + && this.worldObj.getBlockLightValue(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) <= this.rand.nextInt(8)) { + return super.getCanSpawnHere(); + } + + if (this.rand.nextInt(10) == 0 && var1.getRandomWithSeed(987234911L).nextInt(10) == 0 && this.posY < 40.0D) { + return super.getCanSpawnHere(); + } + } + + return false; + } + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 0.4F * (float) this.getSlimeSize(); + } + + /** + * The speed it takes to move the entityliving's rotationPitch through the + * faceEntity method. This is only currently use in wolves. + */ + public int getVerticalFaceSpeed() { + return 0; + } + + /** + * Returns true if the slime makes a sound when it jumps (based upon the slime's + * size) + */ + protected boolean makesSoundOnJump() { + return this.getSlimeSize() > 0; + } + + /** + * Returns true if the slime makes a sound when it lands after a jump (based + * upon the slime's size) + */ + protected boolean makesSoundOnLand() { + return this.getSlimeSize() > 2; + } +} diff --git a/src/main/java/net/minecraft/src/EntitySmallFireball.java b/src/main/java/net/minecraft/src/EntitySmallFireball.java new file mode 100644 index 0000000..4d8c1ab --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySmallFireball.java @@ -0,0 +1,81 @@ +package net.minecraft.src; + +public class EntitySmallFireball extends EntityFireball { + public EntitySmallFireball() { + super(); + this.setSize(0.3125F, 0.3125F); + } + + public EntitySmallFireball(World par1World, EntityLiving par2EntityLiving, double par3, double par5, double par7) { + super(par1World, par2EntityLiving, par3, par5, par7); + this.setSize(0.3125F, 0.3125F); + } + + public EntitySmallFireball(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + super(par1World, par2, par4, par6, par8, par10, par12); + this.setSize(0.3125F, 0.3125F); + } + + /** + * Called when this EntityFireball hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (!this.worldObj.isRemote) { + if (par1MovingObjectPosition.entityHit != null) { + if (!par1MovingObjectPosition.entityHit.isImmuneToFire() && par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeFireballDamage(this, this.shootingEntity), 5)) { + par1MovingObjectPosition.entityHit.setFire(5); + } + } else { + int var2 = par1MovingObjectPosition.blockX; + int var3 = par1MovingObjectPosition.blockY; + int var4 = par1MovingObjectPosition.blockZ; + + switch (par1MovingObjectPosition.sideHit) { + case 0: + --var3; + break; + + case 1: + ++var3; + break; + + case 2: + --var4; + break; + + case 3: + ++var4; + break; + + case 4: + --var2; + break; + + case 5: + ++var2; + } + + if (this.worldObj.isAirBlock(var2, var3, var4)) { + this.worldObj.setBlock(var2, var3, var4, Block.fire.blockID); + } + } + + this.setDead(); + } + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return false; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/EntitySmokeFX.java b/src/main/java/net/minecraft/src/EntitySmokeFX.java new file mode 100644 index 0000000..315aa2a --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySmokeFX.java @@ -0,0 +1,75 @@ +package net.minecraft.src; + + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntitySmokeFX extends EntityFX { + float smokeParticleScale; + + public EntitySmokeFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + this(par1World, par2, par4, par6, par8, par10, par12, 1.0F); + } + + public EntitySmokeFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float par14) { + super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); + this.motionX *= 0.10000000149011612D; + this.motionY *= 0.10000000149011612D; + this.motionZ *= 0.10000000149011612D; + this.motionX += par8; + this.motionY += par10; + this.motionZ += par12; + this.particleRed = this.particleGreen = this.particleBlue = (float) (Math.random() * 0.30000001192092896D); + this.particleScale *= 0.75F; + this.particleScale *= par14; + this.smokeParticleScale = this.particleScale; + this.particleMaxAge = (int) (8.0D / (Math.random() * 0.8D + 0.2D)); + this.particleMaxAge = (int) ((float) this.particleMaxAge * par14); + this.noClip = false; + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = ((float) this.particleAge + par2) / (float) this.particleMaxAge * 32.0F; + + if (var8 < 0.0F) { + var8 = 0.0F; + } + + if (var8 > 1.0F) { + var8 = 1.0F; + } + + this.particleScale = this.smokeParticleScale * var8; + super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + + this.setParticleTextureIndex(7 - this.particleAge * 8 / this.particleMaxAge); + this.motionY += 0.004D; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (this.posY == this.prevPosY) { + this.motionX *= 1.1D; + this.motionZ *= 1.1D; + } + + this.motionX *= 0.9599999785423279D; + this.motionY *= 0.9599999785423279D; + this.motionZ *= 0.9599999785423279D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntitySnowShovelFX.java b/src/main/java/net/minecraft/src/EntitySnowShovelFX.java new file mode 100644 index 0000000..7d5a032 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySnowShovelFX.java @@ -0,0 +1,69 @@ +package net.minecraft.src; + + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntitySnowShovelFX extends EntityFX { + float snowDigParticleScale; + + public EntitySnowShovelFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + this(par1World, par2, par4, par6, par8, par10, par12, 1.0F); + } + + public EntitySnowShovelFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float par14) { + super(par1World, par2, par4, par6, par8, par10, par12); + this.motionX *= 0.10000000149011612D; + this.motionY *= 0.10000000149011612D; + this.motionZ *= 0.10000000149011612D; + this.motionX += par8; + this.motionY += par10; + this.motionZ += par12; + this.particleRed = this.particleGreen = this.particleBlue = 1.0F - (float) (Math.random() * 0.30000001192092896D); + this.particleScale *= 0.75F; + this.particleScale *= par14; + this.snowDigParticleScale = this.particleScale; + this.particleMaxAge = (int) (8.0D / (Math.random() * 0.8D + 0.2D)); + this.particleMaxAge = (int) ((float) this.particleMaxAge * par14); + this.noClip = false; + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = ((float) this.particleAge + par2) / (float) this.particleMaxAge * 32.0F; + + if (var8 < 0.0F) { + var8 = 0.0F; + } + + if (var8 > 1.0F) { + var8 = 1.0F; + } + + this.particleScale = this.snowDigParticleScale * var8; + super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + + this.setParticleTextureIndex(7 - this.particleAge * 8 / this.particleMaxAge); + this.motionY -= 0.03D; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9900000095367432D; + this.motionY *= 0.9900000095367432D; + this.motionZ *= 0.9900000095367432D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntitySnowball.java b/src/main/java/net/minecraft/src/EntitySnowball.java new file mode 100644 index 0000000..fdf2215 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySnowball.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + +public class EntitySnowball extends EntityThrowable { + public EntitySnowball() { + super(); + } + + public EntitySnowball(World par1World, EntityLiving par2EntityLiving) { + super(par1World, par2EntityLiving); + } + + public EntitySnowball(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + } + + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (par1MovingObjectPosition.entityHit != null) { + byte var2 = 0; + + if (par1MovingObjectPosition.entityHit instanceof EntityBlaze) { + var2 = 3; + } + + par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), var2); + } + + for (int var3 = 0; var3 < 8; ++var3) { + this.worldObj.spawnParticle("snowballpoof", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D); + } + + if (!this.worldObj.isRemote) { + this.setDead(); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntitySnowman.java b/src/main/java/net/minecraft/src/EntitySnowman.java new file mode 100644 index 0000000..04b2b95 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySnowman.java @@ -0,0 +1,83 @@ +package net.minecraft.src; + +public class EntitySnowman extends EntityGolem implements IRangedAttackMob { + public EntitySnowman() { + super(); + this.setSize(0.4F, 1.8F); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + public int getMaxHealth() { + return 4; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (this.isWet()) { + this.attackEntityFrom(DamageSource.drown, 1); + } + + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.posZ); + + if (this.worldObj.getBiomeGenForCoords(var1, var2).getFloatTemperature() > 1.0F) { + this.attackEntityFrom(DamageSource.onFire, 1); + } + + for (var1 = 0; var1 < 4; ++var1) { + var2 = MathHelper.floor_double(this.posX + (double) ((float) (var1 % 2 * 2 - 1) * 0.25F)); + int var3 = MathHelper.floor_double(this.posY); + int var4 = MathHelper.floor_double(this.posZ + (double) ((float) (var1 / 2 % 2 * 2 - 1) * 0.25F)); + + if (this.worldObj.getBlockId(var2, var3, var4) == 0 && this.worldObj.getBiomeGenForCoords(var2, var4).getFloatTemperature() < 0.8F && Block.snow.canPlaceBlockAt(this.worldObj, var2, var3, var4)) { + this.worldObj.setBlock(var2, var3, var4, Block.snow.blockID); + } + } + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.snowball.itemID; + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(16); + + for (int var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.snowball.itemID, 1); + } + } + + /** + * Attack the specified entity using a ranged attack. + */ + public void attackEntityWithRangedAttack(EntityLiving par1EntityLiving, float par2) { + EntitySnowball var3 = new EntitySnowball(this.worldObj, this); + double var4 = par1EntityLiving.posX - this.posX; + double var6 = par1EntityLiving.posY + (double) par1EntityLiving.getEyeHeight() - 1.100000023841858D - var3.posY; + double var8 = par1EntityLiving.posZ - this.posZ; + float var10 = MathHelper.sqrt_double(var4 * var4 + var8 * var8) * 0.2F; + var3.setThrowableHeading(var4, var6 + (double) var10, var8, 1.6F, 12.0F); + this.playSound("random.bow", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); + this.worldObj.spawnEntityInWorld(var3); + } +} diff --git a/src/main/java/net/minecraft/src/EntitySorter.java b/src/main/java/net/minecraft/src/EntitySorter.java new file mode 100644 index 0000000..c96daae --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySorter.java @@ -0,0 +1,47 @@ +package net.minecraft.src; + +import java.util.Comparator; + +public class EntitySorter implements Comparator { + /** Entity position X */ + private double entityPosX; + + /** Entity position Y */ + private double entityPosY; + + /** Entity position Z */ + private double entityPosZ; + + private boolean reverse; + + public EntitySorter(Entity par1Entity) { + this.entityPosX = -par1Entity.posX; + this.entityPosY = -par1Entity.posY; + this.entityPosZ = -par1Entity.posZ; + this.reverse = false; + } + + public EntitySorter(Entity par1Entity, boolean reverse) { + this.entityPosX = -par1Entity.posX; + this.entityPosY = -par1Entity.posY; + this.entityPosZ = -par1Entity.posZ; + this.reverse = reverse; + } + + /** + * Sorts the two world renderers according to their distance to a given entity. + */ + public int sortByDistanceToEntity(WorldRenderer par1WorldRenderer, WorldRenderer par2WorldRenderer) { + double var3 = (double) par1WorldRenderer.posXPlus + this.entityPosX; + double var5 = (double) par1WorldRenderer.posYPlus + this.entityPosY; + double var7 = (double) par1WorldRenderer.posZPlus + this.entityPosZ; + double var9 = (double) par2WorldRenderer.posXPlus + this.entityPosX; + double var11 = (double) par2WorldRenderer.posYPlus + this.entityPosY; + double var13 = (double) par2WorldRenderer.posZPlus + this.entityPosZ; + return (int) ((var3 * var3 + var5 * var5 + var7 * var7 - (var9 * var9 + var11 * var11 + var13 * var13)) * 1024.0D); + } + + public int compare(Object par1Obj, Object par2Obj) { + return (reverse ? -1 : 1) * this.sortByDistanceToEntity((WorldRenderer) par1Obj, (WorldRenderer) par2Obj); + } +} diff --git a/src/main/java/net/minecraft/src/EntitySpellParticleFX.java b/src/main/java/net/minecraft/src/EntitySpellParticleFX.java new file mode 100644 index 0000000..e482e3b --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySpellParticleFX.java @@ -0,0 +1,75 @@ +package net.minecraft.src; + + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class EntitySpellParticleFX extends EntityFX { + /** Base spell texture index */ + private int baseSpellTextureIndex = 128; + + public EntitySpellParticleFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + super(par1World, par2, par4, par6, par8, par10, par12); + this.motionY *= 0.20000000298023224D; + + if (par8 == 0.0D && par12 == 0.0D) { + this.motionX *= 0.10000000149011612D; + this.motionZ *= 0.10000000149011612D; + } + + this.particleScale *= 0.75F; + this.particleMaxAge = (int) (8.0D / (Math.random() * 0.8D + 0.2D)); + this.noClip = false; + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { + float var8 = ((float) this.particleAge + par2) / (float) this.particleMaxAge * 32.0F; + + if (var8 < 0.0F) { + var8 = 0.0F; + } + + if (var8 > 1.0F) { + var8 = 1.0F; + } + + super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setDead(); + } + + this.setParticleTextureIndex(this.baseSpellTextureIndex + (7 - this.particleAge * 8 / this.particleMaxAge)); + this.motionY += 0.004D; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (this.posY == this.prevPosY) { + this.motionX *= 1.1D; + this.motionZ *= 1.1D; + } + + this.motionX *= 0.9599999785423279D; + this.motionY *= 0.9599999785423279D; + this.motionZ *= 0.9599999785423279D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } + + /** + * Sets the base spell texture index + */ + public void setBaseSpellTextureIndex(int par1) { + this.baseSpellTextureIndex = par1; + } +} diff --git a/src/main/java/net/minecraft/src/EntitySpider.java b/src/main/java/net/minecraft/src/EntitySpider.java new file mode 100644 index 0000000..6da6d3e --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySpider.java @@ -0,0 +1,194 @@ +package net.minecraft.src; + +public class EntitySpider extends EntityMob { + public EntitySpider() { + super(); + this.setSize(1.4F, 0.9F); + this.moveSpeed = 0.8F; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte) 0)); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (!this.worldObj.isRemote) { + this.setBesideClimbableBlock(this.isCollidedHorizontally); + } + } + + public int getMaxHealth() { + return 16; + } + + /** + * Returns the Y offset from the entity's position for any entity riding this + * one. + */ + public double getMountedYOffset() { + return (double) this.height * 0.75D - 0.5D; + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity + * isn't interested in attacking (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() { + float var1 = this.getBrightness(1.0F); + + if (var1 < 0.5F) { + double var2 = 16.0D; + return this.worldObj.getClosestVulnerablePlayerToEntity(this, var2); + } else { + return null; + } + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.spider.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.spider.say"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.spider.death"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.spider.step", 0.15F, 1.0F); + } + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by + * each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) { + float var3 = this.getBrightness(1.0F); + + if (var3 > 0.5F && this.rand.nextInt(100) == 0) { + this.entityToAttack = null; + } else { + if (par2 > 2.0F && par2 < 6.0F && this.rand.nextInt(10) == 0) { + if (this.onGround) { + double var4 = par1Entity.posX - this.posX; + double var6 = par1Entity.posZ - this.posZ; + float var8 = MathHelper.sqrt_double(var4 * var4 + var6 * var6); + this.motionX = var4 / (double) var8 * 0.5D * 0.800000011920929D + this.motionX * 0.20000000298023224D; + this.motionZ = var6 / (double) var8 * 0.5D * 0.800000011920929D + this.motionZ * 0.20000000298023224D; + this.motionY = 0.4000000059604645D; + } + } else { + super.attackEntity(par1Entity, par2); + } + } + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.silk.itemID; + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + super.dropFewItems(par1, par2); + + if (par1 && (this.rand.nextInt(3) == 0 || this.rand.nextInt(1 + par2) > 0)) { + this.dropItem(Item.spiderEye.itemID, 1); + } + } + + /** + * returns true if this entity is by a ladder, false otherwise + */ + public boolean isOnLadder() { + return this.isBesideClimbableBlock(); + } + + /** + * Sets the Entity inside a web block. + */ + public void setInWeb() { + } + + /** + * How large the spider should be scaled. + */ + public float spiderScaleAmount() { + return 1.0F; + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.ARTHROPOD; + } + + public boolean isPotionApplicable(PotionEffect par1PotionEffect) { + return par1PotionEffect.getPotionID() == Potion.poison.id ? false : super.isPotionApplicable(par1PotionEffect); + } + + /** + * Returns true if the WatchableObject (Byte) is 0x01 otherwise returns false. + * The WatchableObject is updated using setBesideClimableBlock. + */ + public boolean isBesideClimbableBlock() { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + /** + * Updates the WatchableObject (Byte) created in entityInit(), setting it to + * 0x01 if par1 is true or 0x00 if it is false. + */ + public void setBesideClimbableBlock(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + var2 = (byte) (var2 | 1); + } else { + var2 &= -2; + } + + this.dataWatcher.updateObject(16, Byte.valueOf(var2)); + } + + /** + * Initialize this creature. + */ + public void initCreature() { + if (this.worldObj.rand.nextInt(100) == 0) { + EntitySkeleton var1 = new EntitySkeleton(); + var1.setWorld(worldObj); + var1.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F); + var1.initCreature(); + this.worldObj.spawnEntityInWorld(var1); + var1.mountEntity(this); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntitySplashFX.java b/src/main/java/net/minecraft/src/EntitySplashFX.java new file mode 100644 index 0000000..5752a97 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySplashFX.java @@ -0,0 +1,15 @@ +package net.minecraft.src; + +public class EntitySplashFX extends EntityRainFX { + public EntitySplashFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + super(par1World, par2, par4, par6); + this.particleGravity = 0.04F; + this.nextTextureIndexX(); + + if (par10 == 0.0D && (par8 != 0.0D || par12 != 0.0D)) { + this.motionX = par8; + this.motionY = par10 + 0.1D; + this.motionZ = par12; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntitySquid.java b/src/main/java/net/minecraft/src/EntitySquid.java new file mode 100644 index 0000000..1bdb8fc --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySquid.java @@ -0,0 +1,185 @@ +package net.minecraft.src; + + + +public class EntitySquid extends EntityWaterMob { + public float squidPitch = 0.0F; + public float prevSquidPitch = 0.0F; + public float squidYaw = 0.0F; + public float prevSquidYaw = 0.0F; + public float field_70867_h = 0.0F; + public float field_70868_i = 0.0F; + + /** angle of the tentacles in radians */ + public float tentacleAngle = 0.0F; + + /** the last calculated angle of the tentacles in radians */ + public float prevTentacleAngle = 0.0F; + private float randomMotionSpeed = 0.0F; + private float field_70864_bA = 0.0F; + private float field_70871_bB = 0.0F; + private float randomMotionVecX = 0.0F; + private float randomMotionVecY = 0.0F; + private float randomMotionVecZ = 0.0F; + + public EntitySquid() { + super(); + this.setSize(0.95F, 0.95F); + this.field_70864_bA = 1.0F / (this.rand.nextFloat() + 1.0F) * 0.2F; + } + + public int getMaxHealth() { + return 10; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return null; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return null; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return null; + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 0.4F; + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return 0; + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(3 + par2) + 1; + + for (int var4 = 0; var4 < var3; ++var4) { + this.entityDropItem(new ItemStack(Item.dyePowder, 1, 0), 0.0F); + } + } + + /** + * Checks if this entity is inside water (if inWater field is true as a result + * of handleWaterMovement() returning true) + */ + public boolean isInWater() { + return this.worldObj.handleMaterialAcceleration(this.boundingBox.expand(0.0D, -0.6000000238418579D, 0.0D), Material.water, this); + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + super.onLivingUpdate(); + this.prevSquidPitch = this.squidPitch; + this.prevSquidYaw = this.squidYaw; + this.field_70868_i = this.field_70867_h; + this.prevTentacleAngle = this.tentacleAngle; + this.field_70867_h += this.field_70864_bA; + + if (this.field_70867_h > ((float) Math.PI * 2F)) { + this.field_70867_h -= ((float) Math.PI * 2F); + + if (this.rand.nextInt(10) == 0) { + this.field_70864_bA = 1.0F / (this.rand.nextFloat() + 1.0F) * 0.2F; + } + } + + if (this.isInWater()) { + float var1; + + if (this.field_70867_h < (float) Math.PI) { + var1 = this.field_70867_h / (float) Math.PI; + this.tentacleAngle = MathHelper.sin(var1 * var1 * (float) Math.PI) * (float) Math.PI * 0.25F; + + if ((double) var1 > 0.75D) { + this.randomMotionSpeed = 1.0F; + this.field_70871_bB = 1.0F; + } else { + this.field_70871_bB *= 0.8F; + } + } else { + this.tentacleAngle = 0.0F; + this.randomMotionSpeed *= 0.9F; + this.field_70871_bB *= 0.99F; + } + + if (!this.worldObj.isRemote) { + this.motionX = (double) (this.randomMotionVecX * this.randomMotionSpeed); + this.motionY = (double) (this.randomMotionVecY * this.randomMotionSpeed); + this.motionZ = (double) (this.randomMotionVecZ * this.randomMotionSpeed); + } + + var1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.renderYawOffset += (-((float) Math.atan2(this.motionX, this.motionZ)) * 180.0F / (float) Math.PI - this.renderYawOffset) * 0.1F; + this.rotationYaw = this.renderYawOffset; + this.squidYaw += (float) Math.PI * this.field_70871_bB * 1.5F; + this.squidPitch += (-((float) Math.atan2((double) var1, this.motionY)) * 180.0F / (float) Math.PI - this.squidPitch) * 0.1F; + } else { + this.tentacleAngle = MathHelper.abs(MathHelper.sin(this.field_70867_h)) * (float) Math.PI * 0.25F; + + if (!this.worldObj.isRemote) { + this.motionX = 0.0D; + this.motionY -= 0.08D; + this.motionY *= 0.9800000190734863D; + this.motionZ = 0.0D; + } + + this.squidPitch = (float) ((double) this.squidPitch + (double) (-90.0F - this.squidPitch) * 0.02D); + } + } + + /** + * Moves the entity based on the specified heading. Args: strafe, forward + */ + public void moveEntityWithHeading(float par1, float par2) { + this.moveEntity(this.motionX, this.motionY, this.motionZ); + } + + protected void updateEntityActionState() { + ++this.entityAge; + + if (this.entityAge > 100) { + this.randomMotionVecX = this.randomMotionVecY = this.randomMotionVecZ = 0.0F; + } else if (this.rand.nextInt(50) == 0 || !this.inWater || this.randomMotionVecX == 0.0F && this.randomMotionVecY == 0.0F && this.randomMotionVecZ == 0.0F) { + float var1 = this.rand.nextFloat() * (float) Math.PI * 2.0F; + this.randomMotionVecX = MathHelper.cos(var1) * 0.2F; + this.randomMotionVecY = -0.1F + this.rand.nextFloat() * 0.2F; + this.randomMotionVecZ = MathHelper.sin(var1) * 0.2F; + } + + this.despawnEntity(); + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + return this.posY > 45.0D && this.posY < 63.0D && super.getCanSpawnHere(); + } +} diff --git a/src/main/java/net/minecraft/src/EntitySuspendFX.java b/src/main/java/net/minecraft/src/EntitySuspendFX.java new file mode 100644 index 0000000..88168a7 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySuspendFX.java @@ -0,0 +1,37 @@ +package net.minecraft.src; + + + +public class EntitySuspendFX extends EntityFX { + public EntitySuspendFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + super(par1World, par2, par4 - 0.125D, par6, par8, par10, par12); + this.particleRed = 0.4F; + this.particleGreen = 0.4F; + this.particleBlue = 0.7F; + this.setParticleTextureIndex(0); + this.setSize(0.01F, 0.01F); + this.particleScale *= this.rand.nextFloat() * 0.6F + 0.2F; + this.motionX = par8 * 0.0D; + this.motionY = par10 * 0.0D; + this.motionZ = par12 * 0.0D; + this.particleMaxAge = (int) (16.0D / (Math.random() * 0.8D + 0.2D)); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (this.worldObj.getBlockMaterial(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) != Material.water) { + this.setDead(); + } + + if (this.particleMaxAge-- <= 0) { + this.setDead(); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityTNTPrimed.java b/src/main/java/net/minecraft/src/EntityTNTPrimed.java new file mode 100644 index 0000000..875b3f4 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityTNTPrimed.java @@ -0,0 +1,111 @@ +package net.minecraft.src; + + + +public class EntityTNTPrimed extends Entity { + /** How long the fuse is */ + public int fuse; + private EntityLiving tntPlacedBy; + + public EntityTNTPrimed() { + super(); + this.fuse = 0; + this.preventEntitySpawning = true; + this.setSize(0.98F, 0.98F); + this.yOffset = this.height / 2.0F; + } + + public EntityTNTPrimed(World par1World, double par2, double par4, double par6, EntityLiving par8EntityLiving) { + this(); + this.setWorld(par1World); + this.setPosition(par2, par4, par6); + float var9 = (float) (Math.random() * Math.PI * 2.0D); + this.motionX = (double) (-((float) Math.sin((double) var9)) * 0.02F); + this.motionY = 0.20000000298023224D; + this.motionZ = (double) (-((float) Math.cos((double) var9)) * 0.02F); + this.fuse = 80; + this.prevPosX = par2; + this.prevPosY = par4; + this.prevPosZ = par6; + this.tntPlacedBy = par8EntityLiving; + } + + protected void entityInit() { + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return !this.isDead; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.motionY -= 0.03999999910593033D; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.9800000190734863D; + this.motionZ *= 0.9800000190734863D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + this.motionY *= -0.5D; + } + + if (this.fuse-- <= 0) { + this.setDead(); + + if (!this.worldObj.isRemote) { + this.explode(); + } + } else { + this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D); + } + } + + private void explode() { + float var1 = 4.0F; + this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, var1, true); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setByte("Fuse", (byte) this.fuse); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.fuse = par1NBTTagCompound.getByte("Fuse"); + } + + public float getShadowSize() { + return 0.0F; + } + + /** + * returns null or the entityliving it was placed or ignited by + */ + public EntityLiving getTntPlacedBy() { + return this.tntPlacedBy; + } +} diff --git a/src/main/java/net/minecraft/src/EntityTameable.java b/src/main/java/net/minecraft/src/EntityTameable.java new file mode 100644 index 0000000..ba19d12 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityTameable.java @@ -0,0 +1,109 @@ +package net.minecraft.src; + +public abstract class EntityTameable extends EntityAnimal { + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, Byte.valueOf((byte) 0)); + this.dataWatcher.addObject(17, ""); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + + if (this.getOwnerName() == null) { + par1NBTTagCompound.setString("Owner", ""); + } else { + par1NBTTagCompound.setString("Owner", this.getOwnerName()); + } + + par1NBTTagCompound.setBoolean("Sitting", this.isSitting()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + String var2 = par1NBTTagCompound.getString("Owner"); + + if (var2.length() > 0) { + this.setOwner(var2); + this.setTamed(true); + } + + this.setSitting(par1NBTTagCompound.getBoolean("Sitting")); + } + + /** + * Play the taming effect, will either be hearts or smoke depending on status + */ + protected void playTameEffect(boolean par1) { + String var2 = "heart"; + + if (!par1) { + var2 = "smoke"; + } + + for (int var3 = 0; var3 < 7; ++var3) { + double var4 = this.rand.nextGaussian() * 0.02D; + double var6 = this.rand.nextGaussian() * 0.02D; + double var8 = this.rand.nextGaussian() * 0.02D; + this.worldObj.spawnParticle(var2, this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, this.posY + 0.5D + (double) (this.rand.nextFloat() * this.height), + this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, var4, var6, var8); + } + } + + public void handleHealthUpdate(byte par1) { + if (par1 == 7) { + this.playTameEffect(true); + } else if (par1 == 6) { + this.playTameEffect(false); + } else { + super.handleHealthUpdate(par1); + } + } + + public boolean isTamed() { + return (this.dataWatcher.getWatchableObjectByte(16) & 4) != 0; + } + + public void setTamed(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 4))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -5))); + } + } + + public boolean isSitting() { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + public void setSitting(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 1))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -2))); + } + } + + public String getOwnerName() { + return this.dataWatcher.getWatchableObjectString(17); + } + + public void setOwner(String par1Str) { + this.dataWatcher.updateObject(17, par1Str); + } + + public EntityLiving getOwner() { + return this.worldObj.getPlayerEntityByName(this.getOwnerName()); + } +} diff --git a/src/main/java/net/minecraft/src/EntityThrowable.java b/src/main/java/net/minecraft/src/EntityThrowable.java new file mode 100644 index 0000000..e5685dc --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityThrowable.java @@ -0,0 +1,302 @@ +package net.minecraft.src; + +import java.util.List; + + + +public abstract class EntityThrowable extends Entity implements IProjectile { + private int xTile = -1; + private int yTile = -1; + private int zTile = -1; + private int inTile = 0; + protected boolean inGround = false; + public int throwableShake = 0; + + /** + * Is the entity that throws this 'thing' (snowball, ender pearl, eye of ender + * or potion) + */ + private EntityLiving thrower; + private String throwerName = null; + private int ticksInGround; + private int ticksInAir = 0; + + public EntityThrowable() { + super(); + this.setSize(0.25F, 0.25F); + } + + protected void entityInit() { + } + + /** + * Checks if the entity is in range to render by using the past in distance and + * comparing it to its average edge length * 64 * renderDistanceWeight Args: + * distance + */ + public boolean isInRangeToRenderDist(double par1) { + double var3 = this.boundingBox.getAverageEdgeLength() * 4.0D; + var3 *= 64.0D; + return par1 < var3 * var3; + } + + public EntityThrowable(World par1World, EntityLiving par2EntityLiving) { + super(); + this.setWorld(par1World); + this.thrower = par2EntityLiving; + this.setSize(0.25F, 0.25F); + this.setLocationAndAngles(par2EntityLiving.posX, par2EntityLiving.posY + (double) par2EntityLiving.getEyeHeight(), par2EntityLiving.posZ, par2EntityLiving.rotationYaw, par2EntityLiving.rotationPitch); + this.posX -= (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * 0.16F); + this.posY -= 0.10000000149011612D; + this.posZ -= (double) (MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * 0.16F); + this.setPosition(this.posX, this.posY, this.posZ); + this.yOffset = 0.0F; + float var3 = 0.4F; + this.motionX = (double) (-MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI) * var3); + this.motionZ = (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI) * var3); + this.motionY = (double) (-MathHelper.sin((this.rotationPitch + this.func_70183_g()) / 180.0F * (float) Math.PI) * var3); + this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, this.func_70182_d(), 1.0F); + } + + public EntityThrowable(World par1World, double par2, double par4, double par6) { + super(); + this.setWorld(par1World); + this.ticksInGround = 0; + this.setSize(0.25F, 0.25F); + this.setPosition(par2, par4, par6); + this.yOffset = 0.0F; + } + + protected float func_70182_d() { + return 1.5F; + } + + protected float func_70183_g() { + return 0.0F; + } + + /** + * Similar to setArrowHeading, it's point the throwable entity to a x, y, z + * direction. + */ + public void setThrowableHeading(double par1, double par3, double par5, float par7, float par8) { + float var9 = MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5); + par1 /= (double) var9; + par3 /= (double) var9; + par5 /= (double) var9; + par1 += this.rand.nextGaussian() * 0.007499999832361937D * (double) par8; + par3 += this.rand.nextGaussian() * 0.007499999832361937D * (double) par8; + par5 += this.rand.nextGaussian() * 0.007499999832361937D * (double) par8; + par1 *= (double) par7; + par3 *= (double) par7; + par5 *= (double) par7; + this.motionX = par1; + this.motionY = par3; + this.motionZ = par5; + float var10 = MathHelper.sqrt_double(par1 * par1 + par5 * par5); + this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(par1, par5) * 180.0D / Math.PI); + this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(par3, (double) var10) * 180.0D / Math.PI); + this.ticksInGround = 0; + } + + /** + * Sets the velocity to the args. Args: x, y, z + */ + public void setVelocity(double par1, double par3, double par5) { + this.motionX = par1; + this.motionY = par3; + this.motionZ = par5; + + if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) { + float var7 = MathHelper.sqrt_double(par1 * par1 + par5 * par5); + this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(par1, par5) * 180.0D / Math.PI); + this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(par3, (double) var7) * 180.0D / Math.PI); + } + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.lastTickPosX = this.posX; + this.lastTickPosY = this.posY; + this.lastTickPosZ = this.posZ; + super.onUpdate(); + + if (this.throwableShake > 0) { + --this.throwableShake; + } + + if (this.inGround) { + int var1 = this.worldObj.getBlockId(this.xTile, this.yTile, this.zTile); + + if (var1 == this.inTile) { + ++this.ticksInGround; + + if (this.ticksInGround == 1200) { + this.setDead(); + } + + return; + } + + this.inGround = false; + this.motionX *= (double) (this.rand.nextFloat() * 0.2F); + this.motionY *= (double) (this.rand.nextFloat() * 0.2F); + this.motionZ *= (double) (this.rand.nextFloat() * 0.2F); + this.ticksInGround = 0; + this.ticksInAir = 0; + } else { + ++this.ticksInAir; + } + + Vec3 var16 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + Vec3 var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); + MovingObjectPosition var3 = this.worldObj.rayTraceBlocks(var16, var2); + var16 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); + + if (var3 != null) { + var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(var3.hitVec.xCoord, var3.hitVec.yCoord, var3.hitVec.zCoord); + } + + if (!this.worldObj.isRemote) { + Entity var4 = null; + List var5 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D)); + double var6 = 0.0D; + EntityLiving var8 = this.getThrower(); + + for (int var9 = 0; var9 < var5.size(); ++var9) { + Entity var10 = (Entity) var5.get(var9); + + if (var10.canBeCollidedWith() && (var10 != var8 || this.ticksInAir >= 5)) { + float var11 = 0.3F; + AxisAlignedBB var12 = var10.boundingBox.expand((double) var11, (double) var11, (double) var11); + MovingObjectPosition var13 = var12.calculateIntercept(var16, var2); + + if (var13 != null) { + double var14 = var16.distanceTo(var13.hitVec); + + if (var14 < var6 || var6 == 0.0D) { + var4 = var10; + var6 = var14; + } + } + } + } + + if (var4 != null) { + var3 = new MovingObjectPosition(var4); + } + } + + if (var3 != null) { + if (var3.typeOfHit == EnumMovingObjectType.TILE && this.worldObj.getBlockId(var3.blockX, var3.blockY, var3.blockZ) == Block.portal.blockID) { + this.setInPortal(); + } else { + this.onImpact(var3); + } + } + + this.posX += this.motionX; + this.posY += this.motionY; + this.posZ += this.motionZ; + float var17 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); + + for (this.rotationPitch = (float) (Math.atan2(this.motionY, (double) var17) * 180.0D / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) { + ; + } + + while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { + this.prevRotationPitch += 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw < -180.0F) { + this.prevRotationYaw -= 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { + this.prevRotationYaw += 360.0F; + } + + this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; + this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; + float var18 = 0.99F; + float var19 = this.getGravityVelocity(); + + if (this.isInWater()) { + for (int var7 = 0; var7 < 4; ++var7) { + float var20 = 0.25F; + this.worldObj.spawnParticle("bubble", this.posX - this.motionX * (double) var20, this.posY - this.motionY * (double) var20, this.posZ - this.motionZ * (double) var20, this.motionX, this.motionY, this.motionZ); + } + + var18 = 0.8F; + } + + this.motionX *= (double) var18; + this.motionY *= (double) var18; + this.motionZ *= (double) var18; + this.motionY -= (double) var19; + this.setPosition(this.posX, this.posY, this.posZ); + } + + /** + * Gets the amount of gravity to apply to the thrown entity with each tick. + */ + protected float getGravityVelocity() { + return 0.03F; + } + + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected abstract void onImpact(MovingObjectPosition var1); + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setShort("xTile", (short) this.xTile); + par1NBTTagCompound.setShort("yTile", (short) this.yTile); + par1NBTTagCompound.setShort("zTile", (short) this.zTile); + par1NBTTagCompound.setByte("inTile", (byte) this.inTile); + par1NBTTagCompound.setByte("shake", (byte) this.throwableShake); + par1NBTTagCompound.setByte("inGround", (byte) (this.inGround ? 1 : 0)); + + if ((this.throwerName == null || this.throwerName.length() == 0) && this.thrower != null && this.thrower instanceof EntityPlayer) { + this.throwerName = this.thrower.getEntityName(); + } + + par1NBTTagCompound.setString("ownerName", this.throwerName == null ? "" : this.throwerName); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.xTile = par1NBTTagCompound.getShort("xTile"); + this.yTile = par1NBTTagCompound.getShort("yTile"); + this.zTile = par1NBTTagCompound.getShort("zTile"); + this.inTile = par1NBTTagCompound.getByte("inTile") & 255; + this.throwableShake = par1NBTTagCompound.getByte("shake") & 255; + this.inGround = par1NBTTagCompound.getByte("inGround") == 1; + this.throwerName = par1NBTTagCompound.getString("ownerName"); + + if (this.throwerName != null && this.throwerName.length() == 0) { + this.throwerName = null; + } + } + + public float getShadowSize() { + return 0.0F; + } + + public EntityLiving getThrower() { + if (this.thrower == null && this.throwerName != null && this.throwerName.length() > 0) { + this.thrower = this.worldObj.getPlayerEntityByName(this.throwerName); + } + + return this.thrower; + } +} diff --git a/src/main/java/net/minecraft/src/EntityVillager.java b/src/main/java/net/minecraft/src/EntityVillager.java new file mode 100644 index 0000000..e8e8fb9 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityVillager.java @@ -0,0 +1,562 @@ +package net.minecraft.src; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Random; + +public class EntityVillager extends EntityAgeable implements INpc, IMerchant { + private int randomTickDivider; + private boolean isMating; + private boolean isPlaying; + + /** This villager's current customer. */ + private EntityPlayer buyingPlayer; + + /** Initialises the MerchantRecipeList.java */ + private MerchantRecipeList buyingList; + private int timeUntilReset; + + /** addDefaultEquipmentAndRecipies is called if this is true */ + private boolean needsInitilization; + private int wealth; + + /** Last player to trade with this villager, used for aggressivity. */ + private String lastBuyingPlayer; + private boolean field_82190_bM; + private float field_82191_bN; + + /** + * a villagers recipe list is intialized off this list ; the 2 params are + * min/max amount they will trade for 1 emerald + */ + private static final Map villagerStockList = new HashMap(); + + /** + * Selling list of Blacksmith items. negative numbers mean 1 emerald for n + * items, positive numbers are n emeralds for 1 item + */ + private static final Map blacksmithSellingList = new HashMap(); + + public EntityVillager() { + this(0); + } + + public EntityVillager(int par2) { + super(); + this.randomTickDivider = 0; + this.isMating = false; + this.isPlaying = false; + this.setProfession(par2); + this.moveSpeed = 0.5F; + this.setSize(0.6F, 1.8F); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + /** + * main AI tick function, replaces updateEntityActionState + */ + protected void updateAITick() { + + if (!this.isTrading() && this.timeUntilReset > 0) { + --this.timeUntilReset; + + if (this.timeUntilReset <= 0) { + if (this.needsInitilization) { + if (this.buyingList.size() > 1) { + Iterator var3 = this.buyingList.iterator(); + + while (var3.hasNext()) { + MerchantRecipe var2 = (MerchantRecipe) var3.next(); + + if (var2.func_82784_g()) { + var2.func_82783_a(this.rand.nextInt(6) + this.rand.nextInt(6) + 2); + } + } + } + + this.addDefaultEquipmentAndRecipies(1); + this.needsInitilization = false; + } + + this.addPotionEffect(new PotionEffect(Potion.regeneration.id, 200, 0)); + } + } + + super.updateAITick(); + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + boolean var3 = var2 != null && var2.itemID == Item.monsterPlacer.itemID; + + if (!var3 && this.isEntityAlive() && !this.isTrading() && !this.isChild()) { + if (!this.worldObj.isRemote) { + this.setCustomer(par1EntityPlayer); + par1EntityPlayer.displayGUIMerchant(this, this.func_94057_bL()); + } + + return true; + } else { + return super.interact(par1EntityPlayer); + } + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, Integer.valueOf(0)); + } + + public int getMaxHealth() { + return 20; + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("Profession", this.getProfession()); + par1NBTTagCompound.setInteger("Riches", this.wealth); + + if (this.buyingList != null) { + par1NBTTagCompound.setCompoundTag("Offers", this.buyingList.getRecipiesAsTags()); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setProfession(par1NBTTagCompound.getInteger("Profession")); + this.wealth = par1NBTTagCompound.getInteger("Riches"); + + if (par1NBTTagCompound.hasKey("Offers")) { + NBTTagCompound var2 = par1NBTTagCompound.getCompoundTag("Offers"); + this.buyingList = new MerchantRecipeList(var2); + } + } + + /** + * Determines if an entity can be despawned, used on idle far away entities + */ + protected boolean canDespawn() { + return false; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.villager.default"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.villager.defaulthurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.villager.defaultdeath"; + } + + public void setProfession(int par1) { + this.dataWatcher.updateObject(16, Integer.valueOf(par1)); + } + + public int getProfession() { + return this.dataWatcher.getWatchableObjectInt(16); + } + + public boolean isMating() { + return this.isMating; + } + + public void setMating(boolean par1) { + this.isMating = par1; + } + + public void setPlaying(boolean par1) { + this.isPlaying = par1; + } + + public boolean isPlaying() { + return this.isPlaying; + } + + public void setRevengeTarget(EntityLiving par1EntityLiving) { + super.setRevengeTarget(par1EntityLiving); + } + + /** + * Called when the mob's health reaches 0. + */ + public void onDeath(DamageSource par1DamageSource) { + super.onDeath(par1DamageSource); + } + + public void setCustomer(EntityPlayer par1EntityPlayer) { + this.buyingPlayer = par1EntityPlayer; + } + + public EntityPlayer getCustomer() { + return this.buyingPlayer; + } + + public boolean isTrading() { + return this.buyingPlayer != null; + } + + public void useRecipe(MerchantRecipe par1MerchantRecipe) { + par1MerchantRecipe.incrementToolUses(); + + if (par1MerchantRecipe.hasSameIDsAs((MerchantRecipe) this.buyingList.get(this.buyingList.size() - 1))) { + this.timeUntilReset = 40; + this.needsInitilization = true; + + if (this.buyingPlayer != null) { + this.lastBuyingPlayer = this.buyingPlayer.getCommandSenderName(); + } else { + this.lastBuyingPlayer = null; + } + } + + if (par1MerchantRecipe.getItemToBuy().itemID == Item.emerald.itemID) { + this.wealth += par1MerchantRecipe.getItemToBuy().stackSize; + } + } + + public MerchantRecipeList getRecipes(EntityPlayer par1EntityPlayer) { + if (this.buyingList == null) { + this.addDefaultEquipmentAndRecipies(1); + } + + return this.buyingList; + } + + private float func_82188_j(float par1) { + float var2 = par1 + this.field_82191_bN; + return var2 > 0.9F ? 0.9F - (var2 - 0.9F) : var2; + } + + /** + * based on the villagers profession add items, equipment, and recipies adds + * par1 random items to the list of things that the villager wants to buy. (at + * most 1 of each wanted type is added) + */ + private void addDefaultEquipmentAndRecipies(int par1) { + if (this.buyingList != null) { + this.field_82191_bN = MathHelper.sqrt_float((float) this.buyingList.size()) * 0.2F; + } else { + this.field_82191_bN = 0.0F; + } + + MerchantRecipeList var2; + var2 = new MerchantRecipeList(); + int var6; + label50: + + switch (this.getProfession()) { + case 0: + addMerchantItem(var2, Item.wheat.itemID, this.rand, this.func_82188_j(0.9F)); + addMerchantItem(var2, Block.cloth.blockID, this.rand, this.func_82188_j(0.5F)); + addMerchantItem(var2, Item.chickenRaw.itemID, this.rand, this.func_82188_j(0.5F)); + addMerchantItem(var2, Item.fishCooked.itemID, this.rand, this.func_82188_j(0.4F)); + addBlacksmithItem(var2, Item.bread.itemID, this.rand, this.func_82188_j(0.9F)); + addBlacksmithItem(var2, Item.melon.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.appleRed.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.cookie.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.shears.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.flintAndSteel.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.chickenCooked.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.arrow.itemID, this.rand, this.func_82188_j(0.5F)); + + if (this.rand.nextFloat() < this.func_82188_j(0.5F)) { + var2.add(new MerchantRecipe(new ItemStack(Block.gravel, 10), new ItemStack(Item.emerald), new ItemStack(Item.flint.itemID, 4 + this.rand.nextInt(2), 0))); + } + + break; + + case 1: + addMerchantItem(var2, Item.paper.itemID, this.rand, this.func_82188_j(0.8F)); + addMerchantItem(var2, Item.book.itemID, this.rand, this.func_82188_j(0.8F)); + addMerchantItem(var2, Item.writtenBook.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Block.bookShelf.blockID, this.rand, this.func_82188_j(0.8F)); + addBlacksmithItem(var2, Block.glass.blockID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.compass.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.pocketSundial.itemID, this.rand, this.func_82188_j(0.2F)); + + if (this.rand.nextFloat() < this.func_82188_j(0.07F)) { + Enchantment var8 = Enchantment.field_92090_c[this.rand.nextInt(Enchantment.field_92090_c.length)]; + int var10 = MathHelper.getRandomIntegerInRange(this.rand, var8.getMinLevel(), var8.getMaxLevel()); + ItemStack var11 = Item.enchantedBook.func_92111_a(new EnchantmentData(var8, var10)); + var6 = 2 + this.rand.nextInt(5 + var10 * 10) + 3 * var10; + var2.add(new MerchantRecipe(new ItemStack(Item.book), new ItemStack(Item.emerald, var6), var11)); + } + + break; + + case 2: + addBlacksmithItem(var2, Item.eyeOfEnder.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.expBottle.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.redstone.itemID, this.rand, this.func_82188_j(0.4F)); + addBlacksmithItem(var2, Block.glowStone.blockID, this.rand, this.func_82188_j(0.3F)); + int[] var3 = new int[] { Item.swordIron.itemID, Item.swordDiamond.itemID, Item.plateIron.itemID, Item.plateDiamond.itemID, Item.axeIron.itemID, Item.axeDiamond.itemID, Item.pickaxeIron.itemID, Item.pickaxeDiamond.itemID }; + int[] var4 = var3; + int var5 = var3.length; + var6 = 0; + + while (true) { + if (var6 >= var5) { + break label50; + } + + int var7 = var4[var6]; + + if (this.rand.nextFloat() < this.func_82188_j(0.05F)) { + var2.add(new MerchantRecipe(new ItemStack(var7, 1, 0), new ItemStack(Item.emerald, 2 + this.rand.nextInt(3), 0), EnchantmentHelper.addRandomEnchantment(this.rand, new ItemStack(var7, 1, 0), 5 + this.rand.nextInt(15)))); + } + + ++var6; + } + + case 3: + addMerchantItem(var2, Item.coal.itemID, this.rand, this.func_82188_j(0.7F)); + addMerchantItem(var2, Item.ingotIron.itemID, this.rand, this.func_82188_j(0.5F)); + addMerchantItem(var2, Item.ingotGold.itemID, this.rand, this.func_82188_j(0.5F)); + addMerchantItem(var2, Item.diamond.itemID, this.rand, this.func_82188_j(0.5F)); + addBlacksmithItem(var2, Item.swordIron.itemID, this.rand, this.func_82188_j(0.5F)); + addBlacksmithItem(var2, Item.swordDiamond.itemID, this.rand, this.func_82188_j(0.5F)); + addBlacksmithItem(var2, Item.axeIron.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.axeDiamond.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.pickaxeIron.itemID, this.rand, this.func_82188_j(0.5F)); + addBlacksmithItem(var2, Item.pickaxeDiamond.itemID, this.rand, this.func_82188_j(0.5F)); + addBlacksmithItem(var2, Item.shovelIron.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.shovelDiamond.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.hoeIron.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.hoeDiamond.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.bootsIron.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.bootsDiamond.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.helmetIron.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.helmetDiamond.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.plateIron.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.plateDiamond.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.legsIron.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.legsDiamond.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.bootsChain.itemID, this.rand, this.func_82188_j(0.1F)); + addBlacksmithItem(var2, Item.helmetChain.itemID, this.rand, this.func_82188_j(0.1F)); + addBlacksmithItem(var2, Item.plateChain.itemID, this.rand, this.func_82188_j(0.1F)); + addBlacksmithItem(var2, Item.legsChain.itemID, this.rand, this.func_82188_j(0.1F)); + break; + + case 4: + addMerchantItem(var2, Item.coal.itemID, this.rand, this.func_82188_j(0.7F)); + addMerchantItem(var2, Item.porkRaw.itemID, this.rand, this.func_82188_j(0.5F)); + addMerchantItem(var2, Item.beefRaw.itemID, this.rand, this.func_82188_j(0.5F)); + addBlacksmithItem(var2, Item.saddle.itemID, this.rand, this.func_82188_j(0.1F)); + addBlacksmithItem(var2, Item.plateLeather.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.bootsLeather.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.helmetLeather.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.legsLeather.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.porkCooked.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.beefCooked.itemID, this.rand, this.func_82188_j(0.3F)); + } + + if (var2.isEmpty()) { + addMerchantItem(var2, Item.ingotGold.itemID, this.rand, 1.0F); + } + + Collections.shuffle(var2); + + if (this.buyingList == null) { + this.buyingList = new MerchantRecipeList(); + } + + for (int var9 = 0; var9 < par1 && var9 < var2.size(); ++var9) { + this.buyingList.addToListWithCheck((MerchantRecipe) var2.get(var9)); + } + } + + public void setRecipes(MerchantRecipeList par1MerchantRecipeList) { + } + + /** + * each recipie takes a random stack from villagerStockList and offers it for 1 + * emerald + */ + private static void addMerchantItem(MerchantRecipeList par0MerchantRecipeList, int par1, Random par2Random, float par3) { + if (par2Random.nextFloat() < par3) { + par0MerchantRecipeList.add(new MerchantRecipe(getRandomSizedStack(par1, par2Random), Item.emerald)); + } + } + + private static ItemStack getRandomSizedStack(int par0, Random par1Random) { + return new ItemStack(par0, getRandomCountForItem(par0, par1Random), 0); + } + + /** + * default to 1, and villagerStockList contains a min/max amount for each index + */ + private static int getRandomCountForItem(int par0, Random par1Random) { + Tuple var2 = (Tuple) villagerStockList.get(Integer.valueOf(par0)); + return var2 == null ? 1 + : (((Integer) var2.getFirst()).intValue() >= ((Integer) var2.getSecond()).intValue() ? ((Integer) var2.getFirst()).intValue() + : ((Integer) var2.getFirst()).intValue() + par1Random.nextInt(((Integer) var2.getSecond()).intValue() - ((Integer) var2.getFirst()).intValue())); + } + + private static void addBlacksmithItem(MerchantRecipeList par0MerchantRecipeList, int par1, Random par2Random, float par3) { + if (par2Random.nextFloat() < par3) { + int var4 = getRandomCountForBlacksmithItem(par1, par2Random); + ItemStack var5; + ItemStack var6; + + if (var4 < 0) { + var5 = new ItemStack(Item.emerald.itemID, 1, 0); + var6 = new ItemStack(par1, -var4, 0); + } else { + var5 = new ItemStack(Item.emerald.itemID, var4, 0); + var6 = new ItemStack(par1, 1, 0); + } + + par0MerchantRecipeList.add(new MerchantRecipe(var5, var6)); + } + } + + private static int getRandomCountForBlacksmithItem(int par0, Random par1Random) { + Tuple var2 = (Tuple) blacksmithSellingList.get(Integer.valueOf(par0)); + return var2 == null ? 1 + : (((Integer) var2.getFirst()).intValue() >= ((Integer) var2.getSecond()).intValue() ? ((Integer) var2.getFirst()).intValue() + : ((Integer) var2.getFirst()).intValue() + par1Random.nextInt(((Integer) var2.getSecond()).intValue() - ((Integer) var2.getFirst()).intValue())); + } + + public void handleHealthUpdate(byte par1) { + if (par1 == 12) { + this.generateRandomParticles("heart"); + } else if (par1 == 13) { + this.generateRandomParticles("angryVillager"); + } else if (par1 == 14) { + this.generateRandomParticles("happyVillager"); + } else { + super.handleHealthUpdate(par1); + } + } + + /** + * par1 is the particleName + */ + private void generateRandomParticles(String par1Str) { + for (int var2 = 0; var2 < 5; ++var2) { + double var3 = this.rand.nextGaussian() * 0.02D; + double var5 = this.rand.nextGaussian() * 0.02D; + double var7 = this.rand.nextGaussian() * 0.02D; + this.worldObj.spawnParticle(par1Str, this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, this.posY + 1.0D + (double) (this.rand.nextFloat() * this.height), + this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, var3, var5, var7); + } + } + + /** + * Initialize this creature. + */ + public void initCreature() { + this.setProfession(this.worldObj.rand.nextInt(5)); + } + + public void func_82187_q() { + this.field_82190_bM = true; + } + + public EntityVillager func_90012_b(EntityAgeable par1EntityAgeable) { + EntityVillager var2 = new EntityVillager(); + var2.setWorld(worldObj); + var2.initCreature(); + return var2; + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.func_90012_b(par1EntityAgeable); + } + + static { + villagerStockList.put(Integer.valueOf(Item.coal.itemID), new Tuple(Integer.valueOf(16), Integer.valueOf(24))); + villagerStockList.put(Integer.valueOf(Item.ingotIron.itemID), new Tuple(Integer.valueOf(8), Integer.valueOf(10))); + villagerStockList.put(Integer.valueOf(Item.ingotGold.itemID), new Tuple(Integer.valueOf(8), Integer.valueOf(10))); + villagerStockList.put(Integer.valueOf(Item.diamond.itemID), new Tuple(Integer.valueOf(4), Integer.valueOf(6))); + villagerStockList.put(Integer.valueOf(Item.paper.itemID), new Tuple(Integer.valueOf(24), Integer.valueOf(36))); + villagerStockList.put(Integer.valueOf(Item.book.itemID), new Tuple(Integer.valueOf(11), Integer.valueOf(13))); + villagerStockList.put(Integer.valueOf(Item.writtenBook.itemID), new Tuple(Integer.valueOf(1), Integer.valueOf(1))); + villagerStockList.put(Integer.valueOf(Item.enderPearl.itemID), new Tuple(Integer.valueOf(3), Integer.valueOf(4))); + villagerStockList.put(Integer.valueOf(Item.eyeOfEnder.itemID), new Tuple(Integer.valueOf(2), Integer.valueOf(3))); + villagerStockList.put(Integer.valueOf(Item.porkRaw.itemID), new Tuple(Integer.valueOf(14), Integer.valueOf(18))); + villagerStockList.put(Integer.valueOf(Item.beefRaw.itemID), new Tuple(Integer.valueOf(14), Integer.valueOf(18))); + villagerStockList.put(Integer.valueOf(Item.chickenRaw.itemID), new Tuple(Integer.valueOf(14), Integer.valueOf(18))); + villagerStockList.put(Integer.valueOf(Item.fishCooked.itemID), new Tuple(Integer.valueOf(9), Integer.valueOf(13))); + villagerStockList.put(Integer.valueOf(Item.seeds.itemID), new Tuple(Integer.valueOf(34), Integer.valueOf(48))); + villagerStockList.put(Integer.valueOf(Item.melonSeeds.itemID), new Tuple(Integer.valueOf(30), Integer.valueOf(38))); + villagerStockList.put(Integer.valueOf(Item.pumpkinSeeds.itemID), new Tuple(Integer.valueOf(30), Integer.valueOf(38))); + villagerStockList.put(Integer.valueOf(Item.wheat.itemID), new Tuple(Integer.valueOf(18), Integer.valueOf(22))); + villagerStockList.put(Integer.valueOf(Block.cloth.blockID), new Tuple(Integer.valueOf(14), Integer.valueOf(22))); + villagerStockList.put(Integer.valueOf(Item.rottenFlesh.itemID), new Tuple(Integer.valueOf(36), Integer.valueOf(64))); + blacksmithSellingList.put(Integer.valueOf(Item.flintAndSteel.itemID), new Tuple(Integer.valueOf(3), Integer.valueOf(4))); + blacksmithSellingList.put(Integer.valueOf(Item.shears.itemID), new Tuple(Integer.valueOf(3), Integer.valueOf(4))); + blacksmithSellingList.put(Integer.valueOf(Item.swordIron.itemID), new Tuple(Integer.valueOf(7), Integer.valueOf(11))); + blacksmithSellingList.put(Integer.valueOf(Item.swordDiamond.itemID), new Tuple(Integer.valueOf(12), Integer.valueOf(14))); + blacksmithSellingList.put(Integer.valueOf(Item.axeIron.itemID), new Tuple(Integer.valueOf(6), Integer.valueOf(8))); + blacksmithSellingList.put(Integer.valueOf(Item.axeDiamond.itemID), new Tuple(Integer.valueOf(9), Integer.valueOf(12))); + blacksmithSellingList.put(Integer.valueOf(Item.pickaxeIron.itemID), new Tuple(Integer.valueOf(7), Integer.valueOf(9))); + blacksmithSellingList.put(Integer.valueOf(Item.pickaxeDiamond.itemID), new Tuple(Integer.valueOf(10), Integer.valueOf(12))); + blacksmithSellingList.put(Integer.valueOf(Item.shovelIron.itemID), new Tuple(Integer.valueOf(4), Integer.valueOf(6))); + blacksmithSellingList.put(Integer.valueOf(Item.shovelDiamond.itemID), new Tuple(Integer.valueOf(7), Integer.valueOf(8))); + blacksmithSellingList.put(Integer.valueOf(Item.hoeIron.itemID), new Tuple(Integer.valueOf(4), Integer.valueOf(6))); + blacksmithSellingList.put(Integer.valueOf(Item.hoeDiamond.itemID), new Tuple(Integer.valueOf(7), Integer.valueOf(8))); + blacksmithSellingList.put(Integer.valueOf(Item.bootsIron.itemID), new Tuple(Integer.valueOf(4), Integer.valueOf(6))); + blacksmithSellingList.put(Integer.valueOf(Item.bootsDiamond.itemID), new Tuple(Integer.valueOf(7), Integer.valueOf(8))); + blacksmithSellingList.put(Integer.valueOf(Item.helmetIron.itemID), new Tuple(Integer.valueOf(4), Integer.valueOf(6))); + blacksmithSellingList.put(Integer.valueOf(Item.helmetDiamond.itemID), new Tuple(Integer.valueOf(7), Integer.valueOf(8))); + blacksmithSellingList.put(Integer.valueOf(Item.plateIron.itemID), new Tuple(Integer.valueOf(10), Integer.valueOf(14))); + blacksmithSellingList.put(Integer.valueOf(Item.plateDiamond.itemID), new Tuple(Integer.valueOf(16), Integer.valueOf(19))); + blacksmithSellingList.put(Integer.valueOf(Item.legsIron.itemID), new Tuple(Integer.valueOf(8), Integer.valueOf(10))); + blacksmithSellingList.put(Integer.valueOf(Item.legsDiamond.itemID), new Tuple(Integer.valueOf(11), Integer.valueOf(14))); + blacksmithSellingList.put(Integer.valueOf(Item.bootsChain.itemID), new Tuple(Integer.valueOf(5), Integer.valueOf(7))); + blacksmithSellingList.put(Integer.valueOf(Item.helmetChain.itemID), new Tuple(Integer.valueOf(5), Integer.valueOf(7))); + blacksmithSellingList.put(Integer.valueOf(Item.plateChain.itemID), new Tuple(Integer.valueOf(11), Integer.valueOf(15))); + blacksmithSellingList.put(Integer.valueOf(Item.legsChain.itemID), new Tuple(Integer.valueOf(9), Integer.valueOf(11))); + blacksmithSellingList.put(Integer.valueOf(Item.bread.itemID), new Tuple(Integer.valueOf(-4), Integer.valueOf(-2))); + blacksmithSellingList.put(Integer.valueOf(Item.melon.itemID), new Tuple(Integer.valueOf(-8), Integer.valueOf(-4))); + blacksmithSellingList.put(Integer.valueOf(Item.appleRed.itemID), new Tuple(Integer.valueOf(-8), Integer.valueOf(-4))); + blacksmithSellingList.put(Integer.valueOf(Item.cookie.itemID), new Tuple(Integer.valueOf(-10), Integer.valueOf(-7))); + blacksmithSellingList.put(Integer.valueOf(Block.glass.blockID), new Tuple(Integer.valueOf(-5), Integer.valueOf(-3))); + blacksmithSellingList.put(Integer.valueOf(Block.bookShelf.blockID), new Tuple(Integer.valueOf(3), Integer.valueOf(4))); + blacksmithSellingList.put(Integer.valueOf(Item.plateLeather.itemID), new Tuple(Integer.valueOf(4), Integer.valueOf(5))); + blacksmithSellingList.put(Integer.valueOf(Item.bootsLeather.itemID), new Tuple(Integer.valueOf(2), Integer.valueOf(4))); + blacksmithSellingList.put(Integer.valueOf(Item.helmetLeather.itemID), new Tuple(Integer.valueOf(2), Integer.valueOf(4))); + blacksmithSellingList.put(Integer.valueOf(Item.legsLeather.itemID), new Tuple(Integer.valueOf(2), Integer.valueOf(4))); + blacksmithSellingList.put(Integer.valueOf(Item.saddle.itemID), new Tuple(Integer.valueOf(6), Integer.valueOf(8))); + blacksmithSellingList.put(Integer.valueOf(Item.expBottle.itemID), new Tuple(Integer.valueOf(-4), Integer.valueOf(-1))); + blacksmithSellingList.put(Integer.valueOf(Item.redstone.itemID), new Tuple(Integer.valueOf(-4), Integer.valueOf(-1))); + blacksmithSellingList.put(Integer.valueOf(Item.compass.itemID), new Tuple(Integer.valueOf(10), Integer.valueOf(12))); + blacksmithSellingList.put(Integer.valueOf(Item.pocketSundial.itemID), new Tuple(Integer.valueOf(10), Integer.valueOf(12))); + blacksmithSellingList.put(Integer.valueOf(Block.glowStone.blockID), new Tuple(Integer.valueOf(-3), Integer.valueOf(-1))); + blacksmithSellingList.put(Integer.valueOf(Item.porkCooked.itemID), new Tuple(Integer.valueOf(-7), Integer.valueOf(-5))); + blacksmithSellingList.put(Integer.valueOf(Item.beefCooked.itemID), new Tuple(Integer.valueOf(-7), Integer.valueOf(-5))); + blacksmithSellingList.put(Integer.valueOf(Item.chickenCooked.itemID), new Tuple(Integer.valueOf(-8), Integer.valueOf(-6))); + blacksmithSellingList.put(Integer.valueOf(Item.eyeOfEnder.itemID), new Tuple(Integer.valueOf(7), Integer.valueOf(11))); + blacksmithSellingList.put(Integer.valueOf(Item.arrow.itemID), new Tuple(Integer.valueOf(-12), Integer.valueOf(-8))); + } +} diff --git a/src/main/java/net/minecraft/src/EntityWaterMob.java b/src/main/java/net/minecraft/src/EntityWaterMob.java new file mode 100644 index 0000000..ef6f6de --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityWaterMob.java @@ -0,0 +1,57 @@ +package net.minecraft.src; + +public abstract class EntityWaterMob extends EntityCreature implements IAnimals { + + public boolean canBreatheUnderwater() { + return true; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + return this.worldObj.checkNoEntityCollision(this.boundingBox); + } + + /** + * Get number of ticks, at least during which the living entity will be silent. + */ + public int getTalkInterval() { + return 120; + } + + /** + * Determines if an entity can be despawned, used on idle far away entities + */ + protected boolean canDespawn() { + return true; + } + + /** + * Get the experience points the entity currently has. + */ + protected int getExperiencePoints(EntityPlayer par1EntityPlayer) { + return 1 + this.worldObj.rand.nextInt(3); + } + + /** + * Gets called every tick from main Entity class + */ + public void onEntityUpdate() { + int var1 = this.getAir(); + super.onEntityUpdate(); + + if (this.isEntityAlive() && !this.isInsideOfMaterial(Material.water)) { + --var1; + this.setAir(var1); + + if (this.getAir() == -20) { + this.setAir(0); + this.attackEntityFrom(DamageSource.drown, 2); + } + } else { + this.setAir(300); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityWeatherEffect.java b/src/main/java/net/minecraft/src/EntityWeatherEffect.java new file mode 100644 index 0000000..81df0ac --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityWeatherEffect.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public abstract class EntityWeatherEffect extends Entity { + public EntityWeatherEffect(World par1World) { + super(); + this.setWorld(par1World); + } +} diff --git a/src/main/java/net/minecraft/src/EntityWitch.java b/src/main/java/net/minecraft/src/EntityWitch.java new file mode 100644 index 0000000..4b869b8 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityWitch.java @@ -0,0 +1,216 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class EntityWitch extends EntityMob implements IRangedAttackMob { + /** List of items a witch should drop on death. */ + private static final int[] witchDrops = new int[] { Item.lightStoneDust.itemID, Item.sugar.itemID, Item.redstone.itemID, Item.spiderEye.itemID, Item.glassBottle.itemID, Item.gunpowder.itemID, Item.stick.itemID, Item.stick.itemID }; + + /** + * Timer used as interval for a witch's attack, decremented every tick if + * aggressive and when reaches zero the witch will throw a potion at the target + * entity. + */ + private int witchAttackTimer = 0; + + public EntityWitch() { + super(); + this.moveSpeed = 0.25F; + } + + protected void entityInit() { + super.entityInit(); + this.getDataWatcher().addObject(21, Byte.valueOf((byte) 0)); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.witch.idle"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.witch.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.witch.death"; + } + + /** + * Set whether this witch is aggressive at an entity. + */ + public void setAggressive(boolean par1) { + this.getDataWatcher().updateObject(21, Byte.valueOf((byte) (par1 ? 1 : 0))); + } + + /** + * Return whether this witch is aggressive at an entity. + */ + public boolean getAggressive() { + return this.getDataWatcher().getWatchableObjectByte(21) == 1; + } + + public int getMaxHealth() { + return 26; + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (!this.worldObj.isRemote) { + if (this.getAggressive()) { + if (this.witchAttackTimer-- <= 0) { + this.setAggressive(false); + ItemStack var1 = this.getHeldItem(); + this.setCurrentItemOrArmor(0, (ItemStack) null); + + if (var1 != null && var1.itemID == Item.potion.itemID) { + List var2 = Item.potion.getEffects(var1); + + if (var2 != null) { + Iterator var3 = var2.iterator(); + + while (var3.hasNext()) { + PotionEffect var4 = (PotionEffect) var3.next(); + this.addPotionEffect(new PotionEffect(var4)); + } + } + } + } + } else { + short var5 = -1; + + if (this.rand.nextFloat() < 0.15F && this.isBurning() && !this.isPotionActive(Potion.fireResistance)) { + var5 = 16307; + } else if (this.rand.nextFloat() < 0.05F && this.health < this.getMaxHealth()) { + var5 = 16341; + } else if (this.rand.nextFloat() < 0.25F && this.getAttackTarget() != null && !this.isPotionActive(Potion.moveSpeed) && this.getAttackTarget().getDistanceSqToEntity(this) > 121.0D) { + var5 = 16274; + } else if (this.rand.nextFloat() < 0.25F && this.getAttackTarget() != null && !this.isPotionActive(Potion.moveSpeed) && this.getAttackTarget().getDistanceSqToEntity(this) > 121.0D) { + var5 = 16274; + } + + if (var5 > -1) { + this.setCurrentItemOrArmor(0, new ItemStack(Item.potion, 1, var5)); + this.witchAttackTimer = this.getHeldItem().getMaxItemUseDuration(); + this.setAggressive(true); + } + } + + if (this.rand.nextFloat() < 7.5E-4F) { + this.worldObj.setEntityState(this, (byte) 15); + } + } + + super.onLivingUpdate(); + } + + public void handleHealthUpdate(byte par1) { + if (par1 == 15) { + for (int var2 = 0; var2 < this.rand.nextInt(35) + 10; ++var2) { + this.worldObj.spawnParticle("witchMagic", this.posX + this.rand.nextGaussian() * 0.12999999523162842D, this.boundingBox.maxY + 0.5D + this.rand.nextGaussian() * 0.12999999523162842D, + this.posZ + this.rand.nextGaussian() * 0.12999999523162842D, 0.0D, 0.0D, 0.0D); + } + } else { + super.handleHealthUpdate(par1); + } + } + + /** + * Reduces damage, depending on potions + */ + protected int applyPotionDamageCalculations(DamageSource par1DamageSource, int par2) { + par2 = super.applyPotionDamageCalculations(par1DamageSource, par2); + + if (par1DamageSource.getEntity() == this) { + par2 = 0; + } + + if (par1DamageSource.isMagicDamage()) { + par2 = (int) ((double) par2 * 0.15D); + } + + return par2; + } + + /** + * This method returns a value to be applied directly to entity speed, this + * factor is less than 1 when a slowdown potion effect is applied, more than 1 + * when a haste potion effect is applied and 2 for fleeing entities. + */ + public float getSpeedModifier() { + float var1 = super.getSpeedModifier(); + + if (this.getAggressive()) { + var1 *= 0.75F; + } + + return var1; + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(3) + 1; + + for (int var4 = 0; var4 < var3; ++var4) { + int var5 = this.rand.nextInt(3); + int var6 = witchDrops[this.rand.nextInt(witchDrops.length)]; + + if (par2 > 0) { + var5 += this.rand.nextInt(par2 + 1); + } + + for (int var7 = 0; var7 < var5; ++var7) { + this.dropItem(var6, 1); + } + } + } + + /** + * Attack the specified entity using a ranged attack. + */ + public void attackEntityWithRangedAttack(EntityLiving par1EntityLiving, float par2) { + if (!this.getAggressive()) { + EntityPotion var3 = new EntityPotion(this.worldObj, this, 32732); + var3.rotationPitch -= -20.0F; + double var4 = par1EntityLiving.posX + par1EntityLiving.motionX - this.posX; + double var6 = par1EntityLiving.posY + (double) par1EntityLiving.getEyeHeight() - 1.100000023841858D - this.posY; + double var8 = par1EntityLiving.posZ + par1EntityLiving.motionZ - this.posZ; + float var10 = MathHelper.sqrt_double(var4 * var4 + var8 * var8); + + if (var10 >= 8.0F && !par1EntityLiving.isPotionActive(Potion.moveSlowdown)) { + var3.setPotionDamage(32698); + } else if (par1EntityLiving.getHealth() >= 8 && !par1EntityLiving.isPotionActive(Potion.poison)) { + var3.setPotionDamage(32660); + } else if (var10 <= 3.0F && !par1EntityLiving.isPotionActive(Potion.weakness) && this.rand.nextFloat() < 0.25F) { + var3.setPotionDamage(32696); + } + + var3.setThrowableHeading(var4, var6 + (double) (var10 * 0.2F), var8, 0.75F, 8.0F); + this.worldObj.spawnEntityInWorld(var3); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityWither.java b/src/main/java/net/minecraft/src/EntityWither.java new file mode 100644 index 0000000..de7eef2 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityWither.java @@ -0,0 +1,539 @@ +package net.minecraft.src; + +import java.util.List; + + + +public class EntityWither extends EntityMob implements IBossDisplayData, IRangedAttackMob { + private float[] field_82220_d = new float[2]; + private float[] field_82221_e = new float[2]; + private float[] field_82217_f = new float[2]; + private float[] field_82218_g = new float[2]; + private int[] field_82223_h = new int[2]; + private int[] field_82224_i = new int[2]; + private int field_82222_j; + + /** Selector used to determine the entities a wither boss should attack. */ + private static final IEntitySelector attackEntitySelector = new EntityWitherAttackFilter(); + + public EntityWither() { + super(); + this.setEntityHealth(this.getMaxHealth()); + this.setSize(0.9F, 4.0F); + this.isImmuneToFire = true; + this.moveSpeed = 0.6F; + this.experienceValue = 50; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Integer(100)); + this.dataWatcher.addObject(17, new Integer(0)); + this.dataWatcher.addObject(18, new Integer(0)); + this.dataWatcher.addObject(19, new Integer(0)); + this.dataWatcher.addObject(20, new Integer(0)); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("Invul", this.func_82212_n()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.func_82215_s(par1NBTTagCompound.getInteger("Invul")); + this.dataWatcher.updateObject(16, Integer.valueOf(this.health)); + } + + public float getShadowSize() { + return this.height / 8.0F; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.wither.idle"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.wither.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.wither.death"; + } + + /** + * Returns the texture's file path as a String. + */ + public boolean isInvul() { + int var1 = this.func_82212_n(); + return var1 > 0 && (var1 > 80 || var1 / 5 % 2 != 1); + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (!this.worldObj.isRemote) { + this.dataWatcher.updateObject(16, Integer.valueOf(this.health)); + } + + this.motionY *= 0.6000000238418579D; + double var4; + double var6; + double var8; + + if (!this.worldObj.isRemote && this.getWatchedTargetId(0) > 0) { + Entity var1 = this.worldObj.getEntityByID(this.getWatchedTargetId(0)); + + if (var1 != null) { + if (this.posY < var1.posY || !this.isArmored() && this.posY < var1.posY + 5.0D) { + if (this.motionY < 0.0D) { + this.motionY = 0.0D; + } + + this.motionY += (0.5D - this.motionY) * 0.6000000238418579D; + } + + double var2 = var1.posX - this.posX; + var4 = var1.posZ - this.posZ; + var6 = var2 * var2 + var4 * var4; + + if (var6 > 9.0D) { + var8 = (double) MathHelper.sqrt_double(var6); + this.motionX += (var2 / var8 * 0.5D - this.motionX) * 0.6000000238418579D; + this.motionZ += (var4 / var8 * 0.5D - this.motionZ) * 0.6000000238418579D; + } + } + } + + if (this.motionX * this.motionX + this.motionZ * this.motionZ > 0.05000000074505806D) { + this.rotationYaw = (float) Math.atan2(this.motionZ, this.motionX) * (180F / (float) Math.PI) - 90.0F; + } + + super.onLivingUpdate(); + int var20; + + for (var20 = 0; var20 < 2; ++var20) { + this.field_82218_g[var20] = this.field_82221_e[var20]; + this.field_82217_f[var20] = this.field_82220_d[var20]; + } + + int var21; + + for (var20 = 0; var20 < 2; ++var20) { + var21 = this.getWatchedTargetId(var20 + 1); + Entity var3 = null; + + if (var21 > 0) { + var3 = this.worldObj.getEntityByID(var21); + } + + if (var3 != null) { + var4 = this.func_82214_u(var20 + 1); + var6 = this.func_82208_v(var20 + 1); + var8 = this.func_82213_w(var20 + 1); + double var10 = var3.posX - var4; + double var12 = var3.posY + (double) var3.getEyeHeight() - var6; + double var14 = var3.posZ - var8; + double var16 = (double) MathHelper.sqrt_double(var10 * var10 + var14 * var14); + float var18 = (float) (Math.atan2(var14, var10) * 180.0D / Math.PI) - 90.0F; + float var19 = (float) (-(Math.atan2(var12, var16) * 180.0D / Math.PI)); + this.field_82220_d[var20] = this.func_82204_b(this.field_82220_d[var20], var19, 40.0F); + this.field_82221_e[var20] = this.func_82204_b(this.field_82221_e[var20], var18, 10.0F); + } else { + this.field_82221_e[var20] = this.func_82204_b(this.field_82221_e[var20], this.renderYawOffset, 10.0F); + } + } + + boolean var22 = this.isArmored(); + + for (var21 = 0; var21 < 3; ++var21) { + double var23 = this.func_82214_u(var21); + double var5 = this.func_82208_v(var21); + double var7 = this.func_82213_w(var21); + this.worldObj.spawnParticle("smoke", var23 + this.rand.nextGaussian() * 0.30000001192092896D, var5 + this.rand.nextGaussian() * 0.30000001192092896D, var7 + this.rand.nextGaussian() * 0.30000001192092896D, 0.0D, 0.0D, 0.0D); + + if (var22 && this.worldObj.rand.nextInt(4) == 0) { + this.worldObj.spawnParticle("mobSpell", var23 + this.rand.nextGaussian() * 0.30000001192092896D, var5 + this.rand.nextGaussian() * 0.30000001192092896D, var7 + this.rand.nextGaussian() * 0.30000001192092896D, + 0.699999988079071D, 0.699999988079071D, 0.5D); + } + } + + if (this.func_82212_n() > 0) { + for (var21 = 0; var21 < 3; ++var21) { + this.worldObj.spawnParticle("mobSpell", this.posX + this.rand.nextGaussian() * 1.0D, this.posY + (double) (this.rand.nextFloat() * 3.3F), this.posZ + this.rand.nextGaussian() * 1.0D, 0.699999988079071D, 0.699999988079071D, + 0.8999999761581421D); + } + } + } + + protected void updateAITasks() { + int var1; + + if (this.func_82212_n() > 0) { + var1 = this.func_82212_n() - 1; + + if (var1 <= 0) { + this.worldObj.newExplosion(this, this.posX, this.posY + (double) this.getEyeHeight(), this.posZ, 7.0F, false, this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")); + this.worldObj.func_82739_e(1013, (int) this.posX, (int) this.posY, (int) this.posZ, 0); + } + + this.func_82215_s(var1); + + if (this.ticksExisted % 10 == 0) { + this.heal(10); + } + } else { + super.updateAITasks(); + int var12; + + for (var1 = 1; var1 < 3; ++var1) { + if (this.ticksExisted >= this.field_82223_h[var1 - 1]) { + this.field_82223_h[var1 - 1] = this.ticksExisted + 10 + this.rand.nextInt(10); + + if (this.worldObj.difficultySetting >= 2) { + int var10001 = var1 - 1; + int var10003 = this.field_82224_i[var1 - 1]; + this.field_82224_i[var10001] = this.field_82224_i[var1 - 1] + 1; + + if (var10003 > 15) { + float var2 = 10.0F; + float var3 = 5.0F; + double var4 = MathHelper.getRandomDoubleInRange(this.rand, this.posX - (double) var2, this.posX + (double) var2); + double var6 = MathHelper.getRandomDoubleInRange(this.rand, this.posY - (double) var3, this.posY + (double) var3); + double var8 = MathHelper.getRandomDoubleInRange(this.rand, this.posZ - (double) var2, this.posZ + (double) var2); + this.func_82209_a(var1 + 1, var4, var6, var8, true); + this.field_82224_i[var1 - 1] = 0; + } + } + + var12 = this.getWatchedTargetId(var1); + + if (var12 > 0) { + Entity var14 = this.worldObj.getEntityByID(var12); + + if (var14 != null && var14.isEntityAlive() && this.getDistanceSqToEntity(var14) <= 900.0D && this.canEntityBeSeen(var14)) { + this.func_82216_a(var1 + 1, (EntityLiving) var14); + this.field_82223_h[var1 - 1] = this.ticksExisted + 40 + this.rand.nextInt(20); + this.field_82224_i[var1 - 1] = 0; + } else { + this.func_82211_c(var1, 0); + } + } else { + List var13 = this.worldObj.selectEntitiesWithinAABB(EntityLiving.class, this.boundingBox.expand(20.0D, 8.0D, 20.0D), attackEntitySelector); + + for (int var16 = 0; var16 < 10 && !var13.isEmpty(); ++var16) { + EntityLiving var5 = (EntityLiving) var13.get(this.rand.nextInt(var13.size())); + + if (var5 != this && var5.isEntityAlive() && this.canEntityBeSeen(var5)) { + if (var5 instanceof EntityPlayer) { + if (!((EntityPlayer) var5).capabilities.disableDamage) { + this.func_82211_c(var1, var5.entityId); + } + } else { + this.func_82211_c(var1, var5.entityId); + } + + break; + } + + var13.remove(var5); + } + } + } + } + + if (this.getAttackTarget() != null) { + this.func_82211_c(0, this.getAttackTarget().entityId); + } else { + this.func_82211_c(0, 0); + } + + if (this.field_82222_j > 0) { + --this.field_82222_j; + + if (this.field_82222_j == 0 && this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")) { + var1 = MathHelper.floor_double(this.posY); + var12 = MathHelper.floor_double(this.posX); + int var15 = MathHelper.floor_double(this.posZ); + boolean var17 = false; + + for (int var18 = -1; var18 <= 1; ++var18) { + for (int var19 = -1; var19 <= 1; ++var19) { + for (int var7 = 0; var7 <= 3; ++var7) { + int var20 = var12 + var18; + int var9 = var1 + var7; + int var10 = var15 + var19; + int var11 = this.worldObj.getBlockId(var20, var9, var10); + + if (var11 > 0 && var11 != Block.bedrock.blockID && var11 != Block.endPortal.blockID && var11 != Block.endPortalFrame.blockID) { + var17 = this.worldObj.destroyBlock(var20, var9, var10, true) || var17; + } + } + } + } + + if (var17) { + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1012, (int) this.posX, (int) this.posY, (int) this.posZ, 0); + } + } + } + + if (this.ticksExisted % 20 == 0) { + this.heal(1); + } + } + } + + public void func_82206_m() { + this.func_82215_s(220); + this.setEntityHealth(this.getMaxHealth() / 3); + } + + /** + * Sets the Entity inside a web block. + */ + public void setInWeb() { + } + + /** + * Returns the current armor value as determined by a call to + * InventoryPlayer.getTotalArmorValue + */ + public int getTotalArmorValue() { + return 4; + } + + private double func_82214_u(int par1) { + if (par1 <= 0) { + return this.posX; + } else { + float var2 = (this.renderYawOffset + (float) (180 * (par1 - 1))) / 180.0F * (float) Math.PI; + float var3 = MathHelper.cos(var2); + return this.posX + (double) var3 * 1.3D; + } + } + + private double func_82208_v(int par1) { + return par1 <= 0 ? this.posY + 3.0D : this.posY + 2.2D; + } + + private double func_82213_w(int par1) { + if (par1 <= 0) { + return this.posZ; + } else { + float var2 = (this.renderYawOffset + (float) (180 * (par1 - 1))) / 180.0F * (float) Math.PI; + float var3 = MathHelper.sin(var2); + return this.posZ + (double) var3 * 1.3D; + } + } + + private float func_82204_b(float par1, float par2, float par3) { + float var4 = MathHelper.wrapAngleTo180_float(par2 - par1); + + if (var4 > par3) { + var4 = par3; + } + + if (var4 < -par3) { + var4 = -par3; + } + + return par1 + var4; + } + + private void func_82216_a(int par1, EntityLiving par2EntityLiving) { + this.func_82209_a(par1, par2EntityLiving.posX, par2EntityLiving.posY + (double) par2EntityLiving.getEyeHeight() * 0.5D, par2EntityLiving.posZ, par1 == 0 && this.rand.nextFloat() < 0.001F); + } + + private void func_82209_a(int par1, double par2, double par4, double par6, boolean par8) { + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1014, (int) this.posX, (int) this.posY, (int) this.posZ, 0); + double var9 = this.func_82214_u(par1); + double var11 = this.func_82208_v(par1); + double var13 = this.func_82213_w(par1); + double var15 = par2 - var9; + double var17 = par4 - var11; + double var19 = par6 - var13; + EntityWitherSkull var21 = new EntityWitherSkull(this.worldObj, this, var15, var17, var19); + + if (par8) { + var21.setInvulnerable(true); + } + + var21.posY = var11; + var21.posX = var9; + var21.posZ = var13; + this.worldObj.spawnEntityInWorld(var21); + } + + /** + * Attack the specified entity using a ranged attack. + */ + public void attackEntityWithRangedAttack(EntityLiving par1EntityLiving, float par2) { + this.func_82216_a(0, par1EntityLiving); + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else if (par1DamageSource == DamageSource.drown) { + return false; + } else if (this.func_82212_n() > 0) { + return false; + } else { + Entity var3; + + if (this.isArmored()) { + var3 = par1DamageSource.getSourceOfDamage(); + + if (var3 instanceof EntityArrow) { + return false; + } + } + + var3 = par1DamageSource.getEntity(); + + if (var3 != null && !(var3 instanceof EntityPlayer) && var3 instanceof EntityLiving && ((EntityLiving) var3).getCreatureAttribute() == this.getCreatureAttribute()) { + return false; + } else { + if (this.field_82222_j <= 0) { + this.field_82222_j = 20; + } + + for (int var4 = 0; var4 < this.field_82224_i.length; ++var4) { + this.field_82224_i[var4] += 3; + } + + return super.attackEntityFrom(par1DamageSource, par2); + } + } + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has + * recently been hit by a player. @param par2 - Level of Looting used to kill + * this mob. + */ + protected void dropFewItems(boolean par1, int par2) { + this.dropItem(Item.netherStar.itemID, 1); + } + + /** + * Makes the entity despawn if requirements are reached + */ + protected void despawnEntity() { + this.entityAge = 0; + } + + public int getBrightnessForRender(float par1) { + return 15728880; + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return !this.isDead; + } + + /** + * Returns the health points of the dragon. + */ + public int getBossHealth() { + return this.dataWatcher.getWatchableObjectInt(16); + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * adds a PotionEffect to the entity + */ + public void addPotionEffect(PotionEffect par1PotionEffect) { + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() { + return true; + } + + public int getMaxHealth() { + return 300; + } + + public float func_82207_a(int par1) { + return this.field_82221_e[par1]; + } + + public float func_82210_r(int par1) { + return this.field_82220_d[par1]; + } + + public int func_82212_n() { + return this.dataWatcher.getWatchableObjectInt(20); + } + + public void func_82215_s(int par1) { + this.dataWatcher.updateObject(20, Integer.valueOf(par1)); + } + + /** + * Returns the target entity ID if present, or -1 if not @param par1 The target + * offset, should be from 0-2 + */ + public int getWatchedTargetId(int par1) { + return this.dataWatcher.getWatchableObjectInt(17 + par1); + } + + public void func_82211_c(int par1, int par2) { + this.dataWatcher.updateObject(17 + par1, Integer.valueOf(par2)); + } + + /** + * Returns whether the wither is armored with its boss armor or not by checking + * whether its health is below half of its maximum. + */ + public boolean isArmored() { + return this.getBossHealth() <= this.getMaxHealth() / 2; + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.UNDEAD; + } + + /** + * Called when a player mounts an entity. e.g. mounts a pig, mounts a boat. + */ + public void mountEntity(Entity par1Entity) { + this.ridingEntity = null; + } +} diff --git a/src/main/java/net/minecraft/src/EntityWitherAttackFilter.java b/src/main/java/net/minecraft/src/EntityWitherAttackFilter.java new file mode 100644 index 0000000..cc95a1a --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityWitherAttackFilter.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +final class EntityWitherAttackFilter implements IEntitySelector { + /** + * Return whether the specified entity is applicable to this filter. + */ + public boolean isEntityApplicable(Entity par1Entity) { + return par1Entity instanceof EntityLiving && ((EntityLiving) par1Entity).getCreatureAttribute() != EnumCreatureAttribute.UNDEAD; + } +} diff --git a/src/main/java/net/minecraft/src/EntityWitherSkull.java b/src/main/java/net/minecraft/src/EntityWitherSkull.java new file mode 100644 index 0000000..5519f89 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityWitherSkull.java @@ -0,0 +1,115 @@ +package net.minecraft.src; + + + +public class EntityWitherSkull extends EntityFireball { + public EntityWitherSkull() { + super(); + this.setSize(0.3125F, 0.3125F); + } + + public EntityWitherSkull(World par1World, EntityLiving par2EntityLiving, double par3, double par5, double par7) { + super(par1World, par2EntityLiving, par3, par5, par7); + this.setSize(0.3125F, 0.3125F); + } + + /** + * Return the motion factor for this projectile. The factor is multiplied by the + * original motion. + */ + protected float getMotionFactor() { + return this.isInvulnerable() ? 0.73F : super.getMotionFactor(); + } + + public EntityWitherSkull(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { + super(par1World, par2, par4, par6, par8, par10, par12); + this.setSize(0.3125F, 0.3125F); + } + + /** + * Returns true if the entity is on fire. Used by render to add the fire effect + * on rendering. + */ + public boolean isBurning() { + return false; + } + + public float func_82146_a(Explosion par1Explosion, World par2World, int par3, int par4, int par5, Block par6Block) { + float var7 = super.func_82146_a(par1Explosion, par2World, par3, par4, par5, par6Block); + + if (this.isInvulnerable() && par6Block != Block.bedrock && par6Block != Block.endPortal && par6Block != Block.endPortalFrame) { + var7 = Math.min(0.8F, var7); + } + + return var7; + } + + /** + * Called when this EntityFireball hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (!this.worldObj.isRemote) { + if (par1MovingObjectPosition.entityHit != null) { + if (this.shootingEntity != null) { + if (par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeMobDamage(this.shootingEntity), 8) && !par1MovingObjectPosition.entityHit.isEntityAlive()) { + this.shootingEntity.heal(5); + } + } else { + par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.magic, 5); + } + + if (par1MovingObjectPosition.entityHit instanceof EntityLiving) { + byte var2 = 0; + + if (this.worldObj.difficultySetting > 1) { + if (this.worldObj.difficultySetting == 2) { + var2 = 10; + } else if (this.worldObj.difficultySetting == 3) { + var2 = 40; + } + } + + if (var2 > 0) { + ((EntityLiving) par1MovingObjectPosition.entityHit).addPotionEffect(new PotionEffect(Potion.wither.id, 20 * var2, 1)); + } + } + } + + this.worldObj.newExplosion(this, this.posX, this.posY, this.posZ, 1.0F, false, this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")); + this.setDead(); + } + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return false; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + return false; + } + + protected void entityInit() { + this.dataWatcher.addObject(10, Byte.valueOf((byte) 0)); + } + + /** + * Return whether this skull comes from an invulnerable (aura) wither boss. + */ + public boolean isInvulnerable() { + return this.dataWatcher.getWatchableObjectByte(10) == 1; + } + + /** + * Set whether this skull comes from an invulnerable (aura) wither boss. + */ + public void setInvulnerable(boolean par1) { + this.dataWatcher.updateObject(10, Byte.valueOf((byte) (par1 ? 1 : 0))); + } +} diff --git a/src/main/java/net/minecraft/src/EntityWolf.java b/src/main/java/net/minecraft/src/EntityWolf.java new file mode 100644 index 0000000..31c141c --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityWolf.java @@ -0,0 +1,409 @@ +package net.minecraft.src; + + + +public class EntityWolf extends EntityTameable { + private float field_70926_e; + private float field_70924_f; + + /** true is the wolf is wet else false */ + private boolean isShaking; + private boolean field_70928_h; + + /** + * This time increases while wolf is shaking and emitting water particles. + */ + private float timeWolfIsShaking; + private float prevTimeWolfIsShaking; + + public EntityWolf() { + super(); + this.setSize(0.6F, 0.8F); + this.moveSpeed = 0.3F; + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + /** + * Sets the active target the Task system uses for tracking + */ + public void setAttackTarget(EntityLiving par1EntityLiving) { + super.setAttackTarget(par1EntityLiving); + + if (par1EntityLiving instanceof EntityPlayer) { + this.setAngry(true); + } + } + + /** + * main AI tick function, replaces updateEntityActionState + */ + protected void updateAITick() { + this.dataWatcher.updateObject(18, Integer.valueOf(this.getHealth())); + } + + public int getMaxHealth() { + return this.isTamed() ? 20 : 8; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(18, new Integer(this.getHealth())); + this.dataWatcher.addObject(19, new Byte((byte) 0)); + this.dataWatcher.addObject(20, new Byte((byte) BlockCloth.getBlockFromDye(1))); + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.wolf.step", 0.15F, 1.0F); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setBoolean("Angry", this.isAngry()); + par1NBTTagCompound.setByte("CollarColor", (byte) this.getCollarColor()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setAngry(par1NBTTagCompound.getBoolean("Angry")); + + if (par1NBTTagCompound.hasKey("CollarColor")) { + this.setCollarColor(par1NBTTagCompound.getByte("CollarColor")); + } + } + + /** + * Determines if an entity can be despawned, used on idle far away entities + */ + protected boolean canDespawn() { + return this.isAngry() && !this.isTamed(); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return this.isAngry() ? "mob.wolf.growl" : (this.rand.nextInt(3) == 0 ? (this.isTamed() && this.dataWatcher.getWatchableObjectInt(18) < 10 ? "mob.wolf.whine" : "mob.wolf.panting") : "mob.wolf.bark"); + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.wolf.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.wolf.death"; + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 0.4F; + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return -1; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (!this.worldObj.isRemote && this.isShaking && !this.field_70928_h && !this.hasPath() && this.onGround) { + this.field_70928_h = true; + this.timeWolfIsShaking = 0.0F; + this.prevTimeWolfIsShaking = 0.0F; + this.worldObj.setEntityState(this, (byte) 8); + } + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + this.field_70924_f = this.field_70926_e; + + if (this.func_70922_bv()) { + this.field_70926_e += (1.0F - this.field_70926_e) * 0.4F; + } else { + this.field_70926_e += (0.0F - this.field_70926_e) * 0.4F; + } + + if (this.func_70922_bv()) { + this.numTicksToChaseTarget = 10; + } + + if (this.isWet()) { + this.isShaking = true; + this.field_70928_h = false; + this.timeWolfIsShaking = 0.0F; + this.prevTimeWolfIsShaking = 0.0F; + } else if ((this.isShaking || this.field_70928_h) && this.field_70928_h) { + if (this.timeWolfIsShaking == 0.0F) { + this.playSound("mob.wolf.shake", this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F); + } + + this.prevTimeWolfIsShaking = this.timeWolfIsShaking; + this.timeWolfIsShaking += 0.05F; + + if (this.prevTimeWolfIsShaking >= 2.0F) { + this.isShaking = false; + this.field_70928_h = false; + this.prevTimeWolfIsShaking = 0.0F; + this.timeWolfIsShaking = 0.0F; + } + + if (this.timeWolfIsShaking > 0.4F) { + float var1 = (float) this.boundingBox.minY; + int var2 = (int) (MathHelper.sin((this.timeWolfIsShaking - 0.4F) * (float) Math.PI) * 7.0F); + + for (int var3 = 0; var3 < var2; ++var3) { + float var4 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F; + float var5 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F; + this.worldObj.spawnParticle("splash", this.posX + (double) var4, (double) (var1 + 0.8F), this.posZ + (double) var5, this.motionX, this.motionY, this.motionZ); + } + } + } + } + + public boolean getWolfShaking() { + return this.isShaking; + } + + /** + * Used when calculating the amount of shading to apply while the wolf is + * shaking. + */ + public float getShadingWhileShaking(float par1) { + return 0.75F + (this.prevTimeWolfIsShaking + (this.timeWolfIsShaking - this.prevTimeWolfIsShaking) * par1) / 2.0F * 0.25F; + } + + public float getShakeAngle(float par1, float par2) { + float var3 = (this.prevTimeWolfIsShaking + (this.timeWolfIsShaking - this.prevTimeWolfIsShaking) * par1 + par2) / 1.8F; + + if (var3 < 0.0F) { + var3 = 0.0F; + } else if (var3 > 1.0F) { + var3 = 1.0F; + } + + return MathHelper.sin(var3 * (float) Math.PI) * MathHelper.sin(var3 * (float) Math.PI * 11.0F) * 0.15F * (float) Math.PI; + } + + public float getInterestedAngle(float par1) { + return (this.field_70924_f + (this.field_70926_e - this.field_70924_f) * par1) * 0.15F * (float) Math.PI; + } + + public float getEyeHeight() { + return this.height * 0.8F; + } + + /** + * The speed it takes to move the entityliving's rotationPitch through the + * faceEntity method. This is only currently use in wolves. + */ + public int getVerticalFaceSpeed() { + return this.isSitting() ? 20 : super.getVerticalFaceSpeed(); + } + + public boolean attackEntityAsMob(Entity par1Entity) { + int var2 = this.isTamed() ? 4 : 2; + return par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), var2); + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + + if (this.isTamed()) { + if (var2 != null) { + if (Item.itemsList[var2.itemID] instanceof ItemFood) { + ItemFood var3 = (ItemFood) Item.itemsList[var2.itemID]; + + if (var3.isWolfsFavoriteMeat() && this.dataWatcher.getWatchableObjectInt(18) < 20) { + if (!par1EntityPlayer.capabilities.isCreativeMode) { + --var2.stackSize; + } + + this.heal(var3.getHealAmount()); + + if (var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null); + } + + return true; + } + } else if (var2.itemID == Item.dyePowder.itemID) { + int var4 = BlockCloth.getBlockFromDye(var2.getItemDamage()); + + if (var4 != this.getCollarColor()) { + this.setCollarColor(var4); + + if (!par1EntityPlayer.capabilities.isCreativeMode && --var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null); + } + + return true; + } + } + } + } else if (var2 != null && var2.itemID == Item.bone.itemID && !this.isAngry()) { + if (!par1EntityPlayer.capabilities.isCreativeMode) { + --var2.stackSize; + } + + if (var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null); + } + + return true; + } + + return super.interact(par1EntityPlayer); + } + + public void handleHealthUpdate(byte par1) { + if (par1 == 8) { + this.field_70928_h = true; + this.timeWolfIsShaking = 0.0F; + this.prevTimeWolfIsShaking = 0.0F; + } else { + super.handleHealthUpdate(par1); + } + } + + public float getTailRotation() { + return this.isAngry() ? 1.5393804F : (this.isTamed() ? (0.55F - (float) (20 - this.dataWatcher.getWatchableObjectInt(18)) * 0.02F) * (float) Math.PI : ((float) Math.PI / 5F)); + } + + /** + * Checks if the parameter is an item which this animal can be fed to breed it + * (wheat, carrots or seeds depending on the animal type) + */ + public boolean isBreedingItem(ItemStack par1ItemStack) { + return par1ItemStack == null ? false : (!(Item.itemsList[par1ItemStack.itemID] instanceof ItemFood) ? false : ((ItemFood) Item.itemsList[par1ItemStack.itemID]).isWolfsFavoriteMeat()); + } + + /** + * Will return how many at most can spawn in a chunk at once. + */ + public int getMaxSpawnedInChunk() { + return 8; + } + + /** + * Determines whether this wolf is angry or not. + */ + public boolean isAngry() { + return (this.dataWatcher.getWatchableObjectByte(16) & 2) != 0; + } + + /** + * Sets whether this wolf is angry or not. + */ + public void setAngry(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 2))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -3))); + } + } + + /** + * Return this wolf's collar color. + */ + public int getCollarColor() { + return this.dataWatcher.getWatchableObjectByte(20) & 15; + } + + /** + * Set this wolf's collar color. + */ + public void setCollarColor(int par1) { + this.dataWatcher.updateObject(20, Byte.valueOf((byte) (par1 & 15))); + } + + /** + * This function is used when two same-species animals in 'love mode' breed to + * generate the new baby animal. + */ + public EntityWolf spawnBabyAnimal(EntityAgeable par1EntityAgeable) { + EntityWolf var2 = new EntityWolf(); + var2.setWorld(worldObj); + String var3 = this.getOwnerName(); + + if (var3 != null && var3.trim().length() > 0) { + var2.setOwner(var3); + var2.setTamed(true); + } + + return var2; + } + + public void func_70918_i(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(19); + + if (par1) { + this.dataWatcher.updateObject(19, Byte.valueOf((byte) 1)); + } else { + this.dataWatcher.updateObject(19, Byte.valueOf((byte) 0)); + } + } + + /** + * Returns true if the mob is currently able to mate with the specified mob. + */ + public boolean canMateWith(EntityAnimal par1EntityAnimal) { + if (par1EntityAnimal == this) { + return false; + } else if (!this.isTamed()) { + return false; + } else if (!(par1EntityAnimal instanceof EntityWolf)) { + return false; + } else { + EntityWolf var2 = (EntityWolf) par1EntityAnimal; + return !var2.isTamed() ? false : (var2.isSitting() ? false : this.isInLove() && var2.isInLove()); + } + } + + public boolean func_70922_bv() { + return this.dataWatcher.getWatchableObjectByte(19) == 1; + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.spawnBabyAnimal(par1EntityAgeable); + } +} diff --git a/src/main/java/net/minecraft/src/EntityXPOrb.java b/src/main/java/net/minecraft/src/EntityXPOrb.java new file mode 100644 index 0000000..460bd6e --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityXPOrb.java @@ -0,0 +1,256 @@ +package net.minecraft.src; + + + +public class EntityXPOrb extends Entity { + /** + * A constantly increasing value that RenderXPOrb uses to control the colour + * shifting (Green / yellow) + */ + public int xpColor; + + /** The age of the XP orb in ticks. */ + public int xpOrbAge = 0; + public int field_70532_c; + + /** The health of this XP orb. */ + private int xpOrbHealth = 5; + + /** This is how much XP this orb has. */ + private int xpValue; + + /** The closest EntityPlayer to this orb. */ + private EntityPlayer closestPlayer; + + /** Threshold color for tracking players */ + private int xpTargetColor; + + public EntityXPOrb(World par1World, double par2, double par4, double par6, int par8) { + super(); + this.setWorld(par1World); + this.setSize(0.5F, 0.5F); + this.yOffset = this.height / 2.0F; + this.setPosition(par2, par4, par6); + this.rotationYaw = (float) (Math.random() * 360.0D); + this.motionX = (double) ((float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D) * 2.0F); + this.motionY = (double) ((float) (Math.random() * 0.2D) * 2.0F); + this.motionZ = (double) ((float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D) * 2.0F); + this.xpValue = par8; + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + public EntityXPOrb() { + super(); + this.setSize(0.25F, 0.25F); + this.yOffset = this.height / 2.0F; + } + + protected void entityInit() { + } + + public int getBrightnessForRender(float par1) { + float var2 = 0.5F; + + if (var2 < 0.0F) { + var2 = 0.0F; + } + + if (var2 > 1.0F) { + var2 = 1.0F; + } + + int var3 = super.getBrightnessForRender(par1); + int var4 = var3 & 255; + int var5 = var3 >> 16 & 255; + var4 += (int) (var2 * 15.0F * 16.0F); + + if (var4 > 240) { + var4 = 240; + } + + return var4 | var5 << 16; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.field_70532_c > 0) { + --this.field_70532_c; + } + + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.motionY -= 0.029999999329447746D; + + if (this.worldObj.getBlockMaterial(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) == Material.lava) { + this.motionY = 0.20000000298023224D; + this.motionX = (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F); + this.motionZ = (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F); + this.playSound("random.fizz", 0.4F, 2.0F + this.rand.nextFloat() * 0.4F); + } + + this.pushOutOfBlocks(this.posX, (this.boundingBox.minY + this.boundingBox.maxY) / 2.0D, this.posZ); + double var1 = 8.0D; + + if (this.xpTargetColor < this.xpColor - 20 + this.entityId % 100) { + if (this.closestPlayer == null || this.closestPlayer.getDistanceSqToEntity(this) > var1 * var1) { + this.closestPlayer = this.worldObj.getClosestPlayerToEntity(this, var1); + } + + this.xpTargetColor = this.xpColor; + } + + if (this.closestPlayer != null) { + double var3 = (this.closestPlayer.posX - this.posX) / var1; + double var5 = (this.closestPlayer.posY + (double) this.closestPlayer.getEyeHeight() - this.posY) / var1; + double var7 = (this.closestPlayer.posZ - this.posZ) / var1; + double var9 = Math.sqrt(var3 * var3 + var5 * var5 + var7 * var7); + double var11 = 1.0D - var9; + + if (var11 > 0.0D) { + var11 *= var11; + this.motionX += var3 / var9 * var11 * 0.1D; + this.motionY += var5 / var9 * var11 * 0.1D; + this.motionZ += var7 / var9 * var11 * 0.1D; + } + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + float var13 = 0.98F; + + if (this.onGround) { + var13 = 0.58800006F; + int var4 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)); + + if (var4 > 0) { + var13 = Block.blocksList[var4].slipperiness * 0.98F; + } + } + + this.motionX *= (double) var13; + this.motionY *= 0.9800000190734863D; + this.motionZ *= (double) var13; + + if (this.onGround) { + this.motionY *= -0.8999999761581421D; + } + + ++this.xpColor; + ++this.xpOrbAge; + + if (this.xpOrbAge >= 6000) { + this.setDead(); + } + } + + /** + * Returns if this entity is in water and will end up adding the waters velocity + * to the entity + */ + public boolean handleWaterMovement() { + return this.worldObj.handleMaterialAcceleration(this.boundingBox, Material.water, this); + } + + /** + * Will deal the specified amount of damage to the entity if the entity isn't + * immune to fire damage. Args: amountDamage + */ + protected void dealFireDamage(int par1) { + this.attackEntityFrom(DamageSource.inFire, par1); + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + this.setBeenAttacked(); + this.xpOrbHealth -= par2; + + if (this.xpOrbHealth <= 0) { + this.setDead(); + } + + return false; + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setShort("Health", (short) ((byte) this.xpOrbHealth)); + par1NBTTagCompound.setShort("Age", (short) this.xpOrbAge); + par1NBTTagCompound.setShort("Value", (short) this.xpValue); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.xpOrbHealth = par1NBTTagCompound.getShort("Health") & 255; + this.xpOrbAge = par1NBTTagCompound.getShort("Age"); + this.xpValue = par1NBTTagCompound.getShort("Value"); + } + + /** + * Called by a player entity when they collide with an entity + */ + public void onCollideWithPlayer(EntityPlayer par1EntityPlayer) { + if (!this.worldObj.isRemote) { + if (this.field_70532_c == 0 && par1EntityPlayer.xpCooldown == 0) { + par1EntityPlayer.xpCooldown = 2; + this.playSound("random.orb", 0.1F, 0.5F * ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.8F)); + par1EntityPlayer.onItemPickup(this, 1); + par1EntityPlayer.addExperience(this.xpValue); + this.setDead(); + } + } + } + + /** + * Returns the XP value of this XP orb. + */ + public int getXpValue() { + return this.xpValue; + } + + /** + * Returns a number from 1 to 10 based on how much XP this orb is worth. This is + * used by RenderXPOrb to determine what texture to use. + */ + public int getTextureByXP() { + return this.xpValue >= 2477 ? 10 + : (this.xpValue >= 1237 ? 9 + : (this.xpValue >= 617 ? 8 + : (this.xpValue >= 307 ? 7 : (this.xpValue >= 149 ? 6 : (this.xpValue >= 73 ? 5 : (this.xpValue >= 37 ? 4 : (this.xpValue >= 17 ? 3 : (this.xpValue >= 7 ? 2 : (this.xpValue >= 3 ? 1 : 0))))))))); + } + + /** + * Get xp split rate (Is called until the xp drop code in + * EntityLiving.onEntityUpdate is complete) + */ + public static int getXPSplit(int par0) { + return par0 >= 2477 ? 2477 : (par0 >= 1237 ? 1237 : (par0 >= 617 ? 617 : (par0 >= 307 ? 307 : (par0 >= 149 ? 149 : (par0 >= 73 ? 73 : (par0 >= 37 ? 37 : (par0 >= 17 ? 17 : (par0 >= 7 ? 7 : (par0 >= 3 ? 3 : 1))))))))); + } + + /** + * If returns false, the item will not inflict any damage against entities. + */ + public boolean canAttackWithItem() { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/EntityZombie.java b/src/main/java/net/minecraft/src/EntityZombie.java new file mode 100644 index 0000000..2b34b41 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityZombie.java @@ -0,0 +1,429 @@ +package net.minecraft.src; + +import java.util.Calendar; + + + +public class EntityZombie extends EntityMob { + /** + * Ticker used to determine the time remaining for this zombie to convert into a + * villager when cured. + */ + private int conversionTime = 0; + + public EntityZombie() { + super(); + this.moveSpeed = 0.23F; + } + + protected int func_96121_ay() { + return 40; + } + + /** + * This method returns a value to be applied directly to entity speed, this + * factor is less than 1 when a slowdown potion effect is applied, more than 1 + * when a haste potion effect is applied and 2 for fleeing entities. + */ + public float getSpeedModifier() { + return super.getSpeedModifier() * (this.isChild() ? 1.5F : 1.0F); + } + + protected void entityInit() { + super.entityInit(); + this.getDataWatcher().addObject(12, Byte.valueOf((byte) 0)); + this.getDataWatcher().addObject(13, Byte.valueOf((byte) 0)); + this.getDataWatcher().addObject(14, Byte.valueOf((byte) 0)); + } + + public int getMaxHealth() { + return 20; + } + + /** + * Returns the current armor value as determined by a call to + * InventoryPlayer.getTotalArmorValue + */ + public int getTotalArmorValue() { + int var1 = super.getTotalArmorValue() + 2; + + if (var1 > 20) { + var1 = 20; + } + + return var1; + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() { + return true; + } + + /** + * If Animal, checks if the age timer is negative + */ + public boolean isChild() { + return this.getDataWatcher().getWatchableObjectByte(12) == 1; + } + + /** + * Set whether this zombie is a child. + */ + public void setChild(boolean par1) { + this.getDataWatcher().updateObject(12, Byte.valueOf((byte) 1)); + } + + /** + * Return whether this zombie is a villager. + */ + public boolean isVillager() { + return this.getDataWatcher().getWatchableObjectByte(13) == 1; + } + + /** + * Set whether this zombie is a villager. + */ + public void setVillager(boolean par1) { + this.getDataWatcher().updateObject(13, Byte.valueOf((byte) (par1 ? 1 : 0))); + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (this.worldObj.isDaytime() && !this.worldObj.isRemote && !this.isChild()) { + float var1 = this.getBrightness(1.0F); + + if (var1 > 0.5F && this.rand.nextFloat() * 30.0F < (var1 - 0.4F) * 2.0F && this.worldObj.canBlockSeeTheSky(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ))) { + boolean var2 = true; + ItemStack var3 = this.getCurrentItemOrArmor(4); + + if (var3 != null) { + if (var3.isItemStackDamageable()) { + var3.setItemDamage(var3.getItemDamageForDisplay() + this.rand.nextInt(2)); + + if (var3.getItemDamageForDisplay() >= var3.getMaxDamage()) { + this.renderBrokenItemStack(var3); + this.setCurrentItemOrArmor(4, (ItemStack) null); + } + } + + var2 = false; + } + + if (var2) { + this.setFire(8); + } + } + } + + super.onLivingUpdate(); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (!this.worldObj.isRemote && this.isConverting()) { + int var1 = this.getConversionTimeBoost(); + this.conversionTime -= var1; + + if (this.conversionTime <= 0) { + this.convertToVillager(); + } + } + + super.onUpdate(); + } + + public boolean attackEntityAsMob(Entity par1Entity) { + boolean var2 = super.attackEntityAsMob(par1Entity); + + if (var2 && this.getHeldItem() == null && this.isBurning() && this.rand.nextFloat() < (float) this.worldObj.difficultySetting * 0.3F) { + par1Entity.setFire(2 * this.worldObj.difficultySetting); + } + + return var2; + } + + /** + * Returns the amount of damage a mob should deal. + */ + public int getAttackStrength(Entity par1Entity) { + ItemStack var2 = this.getHeldItem(); + float var3 = (float) (this.getMaxHealth() - this.getHealth()) / (float) this.getMaxHealth(); + int var4 = 3 + MathHelper.floor_float(var3 * 4.0F); + + if (var2 != null) { + var4 += var2.getDamageVsEntity(this); + } + + return var4; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.zombie.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.zombie.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.zombie.death"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.zombie.step", 0.15F, 1.0F); + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.rottenFlesh.itemID; + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.UNDEAD; + } + + protected void dropRareDrop(int par1) { + switch (this.rand.nextInt(3)) { + case 0: + this.dropItem(Item.ingotIron.itemID, 1); + break; + + case 1: + this.dropItem(Item.carrot.itemID, 1); + break; + + case 2: + this.dropItem(Item.potato.itemID, 1); + } + } + + /** + * Makes entity wear random armor based on difficulty + */ + protected void addRandomArmor() { + super.addRandomArmor(); + + if (this.rand.nextFloat() < (this.worldObj.difficultySetting == 3 ? 0.05F : 0.01F)) { + int var1 = this.rand.nextInt(3); + + if (var1 == 0) { + this.setCurrentItemOrArmor(0, new ItemStack(Item.swordIron)); + } else { + this.setCurrentItemOrArmor(0, new ItemStack(Item.shovelIron)); + } + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + + if (this.isChild()) { + par1NBTTagCompound.setBoolean("IsBaby", true); + } + + if (this.isVillager()) { + par1NBTTagCompound.setBoolean("IsVillager", true); + } + + par1NBTTagCompound.setInteger("ConversionTime", this.isConverting() ? this.conversionTime : -1); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.getBoolean("IsBaby")) { + this.setChild(true); + } + + if (par1NBTTagCompound.getBoolean("IsVillager")) { + this.setVillager(true); + } + + if (par1NBTTagCompound.hasKey("ConversionTime") && par1NBTTagCompound.getInteger("ConversionTime") > -1) { + this.startConversion(par1NBTTagCompound.getInteger("ConversionTime")); + } + } + + /** + * This method gets called when the entity kills another one. + */ + public void onKillEntity(EntityLiving par1EntityLiving) { + super.onKillEntity(par1EntityLiving); + + if (this.worldObj.difficultySetting >= 2 && par1EntityLiving instanceof EntityVillager) { + if (this.worldObj.difficultySetting == 2 && this.rand.nextBoolean()) { + return; + } + + EntityZombie var2 = new EntityZombie(); + var2.setWorld(worldObj); + var2.func_82149_j(par1EntityLiving); + this.worldObj.removeEntity(par1EntityLiving); + var2.initCreature(); + var2.setVillager(true); + + if (par1EntityLiving.isChild()) { + var2.setChild(true); + } + + this.worldObj.spawnEntityInWorld(var2); + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1016, (int) this.posX, (int) this.posY, (int) this.posZ, 0); + } + } + + /** + * Initialize this creature. + */ + public void initCreature() { + this.setCanPickUpLoot(this.rand.nextFloat() < pickUpLootProability[this.worldObj.difficultySetting]); + + if (this.worldObj.rand.nextFloat() < 0.05F) { + this.setVillager(true); + } + + this.addRandomArmor(); + this.func_82162_bC(); + + if (this.getCurrentItemOrArmor(4) == null) { + Calendar var1 = this.worldObj.getCurrentDate(); + + if (var1.get(2) + 1 == 10 && var1.get(5) == 31 && this.rand.nextFloat() < 0.25F) { + this.setCurrentItemOrArmor(4, new ItemStack(this.rand.nextFloat() < 0.1F ? Block.pumpkinLantern : Block.pumpkin)); + this.equipmentDropChances[4] = 0.0F; + } + } + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.getCurrentEquippedItem(); + + if (var2 != null && var2.getItem() == Item.appleGold && var2.getItemDamage() == 0 && this.isVillager() && this.isPotionActive(Potion.weakness)) { + if (!par1EntityPlayer.capabilities.isCreativeMode) { + --var2.stackSize; + } + + if (var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null); + } + + if (!this.worldObj.isRemote) { + this.startConversion(this.rand.nextInt(2401) + 3600); + } + + return true; + } else { + return false; + } + } + + /** + * Starts converting this zombie into a villager. The zombie converts into a + * villager after the specified time in ticks. + */ + protected void startConversion(int par1) { + this.conversionTime = par1; + this.getDataWatcher().updateObject(14, Byte.valueOf((byte) 1)); + this.removePotionEffect(Potion.weakness.id); + this.addPotionEffect(new PotionEffect(Potion.damageBoost.id, par1, Math.min(this.worldObj.difficultySetting - 1, 0))); + this.worldObj.setEntityState(this, (byte) 16); + } + + public void handleHealthUpdate(byte par1) { + if (par1 == 16) { + this.worldObj.playSound(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, "mob.zombie.remedy", 1.0F + this.rand.nextFloat(), this.rand.nextFloat() * 0.7F + 0.3F, false); + } else { + super.handleHealthUpdate(par1); + } + } + + /** + * Returns whether this zombie is in the process of converting to a villager + */ + public boolean isConverting() { + return this.getDataWatcher().getWatchableObjectByte(14) == 1; + } + + /** + * Convert this zombie into a villager. + */ + protected void convertToVillager() { + EntityVillager var1 = new EntityVillager(); + var1.setWorld(worldObj); + var1.func_82149_j(this); + var1.initCreature(); + var1.func_82187_q(); + + if (this.isChild()) { + var1.setGrowingAge(-24000); + } + + this.worldObj.removeEntity(this); + this.worldObj.spawnEntityInWorld(var1); + var1.addPotionEffect(new PotionEffect(Potion.confusion.id, 200, 0)); + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1017, (int) this.posX, (int) this.posY, (int) this.posZ, 0); + } + + /** + * Return the amount of time decremented from conversionTime every tick. + */ + protected int getConversionTimeBoost() { + int var1 = 1; + + if (this.rand.nextFloat() < 0.01F) { + int var2 = 0; + + for (int var3 = (int) this.posX - 4; var3 < (int) this.posX + 4 && var2 < 14; ++var3) { + for (int var4 = (int) this.posY - 4; var4 < (int) this.posY + 4 && var2 < 14; ++var4) { + for (int var5 = (int) this.posZ - 4; var5 < (int) this.posZ + 4 && var2 < 14; ++var5) { + int var6 = this.worldObj.getBlockId(var3, var4, var5); + + if (var6 == Block.fenceIron.blockID || var6 == Block.bed.blockID) { + if (this.rand.nextFloat() < 0.3F) { + ++var1; + } + + ++var2; + } + } + } + } + } + + return var1; + } +} diff --git a/src/main/java/net/minecraft/src/EnumAction.java b/src/main/java/net/minecraft/src/EnumAction.java new file mode 100644 index 0000000..f658f73 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumAction.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public enum EnumAction { + none, eat, drink, block, bow; +} diff --git a/src/main/java/net/minecraft/src/EnumArmorMaterial.java b/src/main/java/net/minecraft/src/EnumArmorMaterial.java new file mode 100644 index 0000000..2c72d49 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumArmorMaterial.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +public enum EnumArmorMaterial { + CLOTH(5, new int[] { 1, 3, 2, 1 }, 15), CHAIN(15, new int[] { 2, 5, 4, 1 }, 12), IRON(15, new int[] { 2, 6, 5, 2 }, 9), GOLD(7, new int[] { 2, 5, 3, 1 }, 25), DIAMOND(33, new int[] { 3, 8, 6, 3 }, 10); + + /** + * Holds the maximum damage factor (each piece multiply this by it's own value) + * of the material, this is the item damage (how much can absorb before breaks) + */ + private int maxDamageFactor; + + /** + * Holds the damage reduction (each 1 points is half a shield on gui) of each + * piece of armor (helmet, plate, legs and boots) + */ + private int[] damageReductionAmountArray; + + /** Return the enchantability factor of the material */ + private int enchantability; + + private EnumArmorMaterial(int par3, int[] par4ArrayOfInteger, int par5) { + this.maxDamageFactor = par3; + this.damageReductionAmountArray = par4ArrayOfInteger; + this.enchantability = par5; + } + + /** + * Returns the durability for a armor slot of for this type. + */ + public int getDurability(int par1) { + return ItemArmor.getMaxDamageArray()[par1] * this.maxDamageFactor; + } + + /** + * Return the damage reduction (each 1 point is a half a shield on gui) of the + * piece index passed (0 = helmet, 1 = plate, 2 = legs and 3 = boots) + */ + public int getDamageReductionAmount(int par1) { + return this.damageReductionAmountArray[par1]; + } + + /** + * Return the enchantability factor of the material. + */ + public int getEnchantability() { + return this.enchantability; + } + + /** + * Return the crafting material for this armor material, used to determine the + * item that can be used to repair an armor piece with an anvil + */ + public int getArmorCraftingMaterial() { + return this == CLOTH ? Item.leather.itemID : (this == CHAIN ? Item.ingotIron.itemID : (this == GOLD ? Item.ingotGold.itemID : (this == IRON ? Item.ingotIron.itemID : (this == DIAMOND ? Item.diamond.itemID : 0)))); + } +} diff --git a/src/main/java/net/minecraft/src/EnumArt.java b/src/main/java/net/minecraft/src/EnumArt.java new file mode 100644 index 0000000..de22d35 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumArt.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public enum EnumArt { + Kebab("Kebab", 16, 16, 0, 0), Aztec("Aztec", 16, 16, 16, 0), Alban("Alban", 16, 16, 32, 0), Aztec2("Aztec2", 16, 16, 48, 0), Bomb("Bomb", 16, 16, 64, 0), Plant("Plant", 16, 16, 80, 0), Wasteland("Wasteland", 16, 16, 96, 0), + Pool("Pool", 32, 16, 0, 32), Courbet("Courbet", 32, 16, 32, 32), Sea("Sea", 32, 16, 64, 32), Sunset("Sunset", 32, 16, 96, 32), Creebet("Creebet", 32, 16, 128, 32), Wanderer("Wanderer", 16, 32, 0, 64), Graham("Graham", 16, 32, 16, 64), + Match("Match", 32, 32, 0, 128), Bust("Bust", 32, 32, 32, 128), Stage("Stage", 32, 32, 64, 128), Void("Void", 32, 32, 96, 128), SkullAndRoses("SkullAndRoses", 32, 32, 128, 128), Wither("Wither", 32, 32, 160, 128), + Fighters("Fighters", 64, 32, 0, 96), Pointer("Pointer", 64, 64, 0, 192), Pigscene("Pigscene", 64, 64, 64, 192), BurningSkull("BurningSkull", 64, 64, 128, 192), Skeleton("Skeleton", 64, 48, 192, 64), + DonkeyKong("DonkeyKong", 64, 48, 192, 112); + + /** Holds the maximum length of paintings art title. */ + public static final int maxArtTitleLength = "SkullAndRoses".length(); + + /** Painting Title. */ + public final String title; + public final int sizeX; + public final int sizeY; + public final int offsetX; + public final int offsetY; + + private EnumArt(String par3Str, int par4, int par5, int par6, int par7) { + this.title = par3Str; + this.sizeX = par4; + this.sizeY = par5; + this.offsetX = par6; + this.offsetY = par7; + } +} diff --git a/src/main/java/net/minecraft/src/EnumChatFormatting.java b/src/main/java/net/minecraft/src/EnumChatFormatting.java new file mode 100644 index 0000000..40d65cb --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumChatFormatting.java @@ -0,0 +1,80 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + +public enum EnumChatFormatting { + BLACK('0'), DARK_BLUE('1'), DARK_GREEN('2'), DARK_AQUA('3'), DARK_RED('4'), DARK_PURPLE('5'), GOLD('6'), GRAY('7'), DARK_GRAY('8'), BLUE('9'), GREEN('a'), AQUA('b'), RED('c'), LIGHT_PURPLE('d'), YELLOW('e'), WHITE('f'), + OBFUSCATED('k', true), BOLD('l', true), STRIKETHROUGH('m', true), UNDERLINE('n', true), ITALIC('o', true), RESET('r'); + + private static final Map field_96321_w = new HashMap(); + private static final Map field_96331_x = new HashMap(); + private static final Pattern field_96330_y = Pattern.compile("(?i)" + String.valueOf('\u00a7') + "[0-9A-FK-OR]"); + private final char field_96329_z; + private final boolean field_96303_A; + private final String field_96304_B; + + private EnumChatFormatting(char par3) { + this(par3, false); + } + + private EnumChatFormatting(char par3, boolean par4) { + this.field_96329_z = par3; + this.field_96303_A = par4; + this.field_96304_B = "\u00a7" + par3; + } + + public char func_96298_a() { + return this.field_96329_z; + } + + public boolean func_96301_b() { + return this.field_96303_A; + } + + public boolean func_96302_c() { + return !this.field_96303_A && this != RESET; + } + + public String func_96297_d() { + return this.name().toLowerCase(); + } + + public String toString() { + return this.field_96304_B; + } + + public static EnumChatFormatting func_96300_b(String par0Str) { + return par0Str == null ? null : (EnumChatFormatting) field_96331_x.get(par0Str.toLowerCase()); + } + + public static Collection func_96296_a(boolean par0, boolean par1) { + ArrayList var2 = new ArrayList(); + EnumChatFormatting[] var3 = values(); + int var4 = var3.length; + + for (int var5 = 0; var5 < var4; ++var5) { + EnumChatFormatting var6 = var3[var5]; + + if ((!var6.func_96302_c() || par0) && (!var6.func_96301_b() || par1)) { + var2.add(var6.func_96297_d()); + } + } + + return var2; + } + + static { + EnumChatFormatting[] var0 = values(); + int var1 = var0.length; + + for (int var2 = 0; var2 < var1; ++var2) { + EnumChatFormatting var3 = var0[var2]; + field_96321_w.put(Character.valueOf(var3.func_96298_a()), var3); + field_96331_x.put(var3.func_96297_d(), var3); + } + } +} diff --git a/src/main/java/net/minecraft/src/EnumCreatureAttribute.java b/src/main/java/net/minecraft/src/EnumCreatureAttribute.java new file mode 100644 index 0000000..1fdf55e --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumCreatureAttribute.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public enum EnumCreatureAttribute { + UNDEFINED, UNDEAD, ARTHROPOD; +} diff --git a/src/main/java/net/minecraft/src/EnumCreatureType.java b/src/main/java/net/minecraft/src/EnumCreatureType.java new file mode 100644 index 0000000..912fa7e --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumCreatureType.java @@ -0,0 +1,54 @@ +package net.minecraft.src; + +public enum EnumCreatureType { + monster(IMob.class, 70, Material.air, false, false), creature(EntityAnimal.class, 10, Material.air, true, true), ambient(EntityAmbientCreature.class, 15, Material.air, true, false), + waterCreature(EntityWaterMob.class, 5, Material.water, true, false); + + /** + * The root class of creatures associated with this EnumCreatureType (IMobs for + * aggressive creatures, EntityAnimals for friendly ones) + */ + private final Class creatureClass; + private final int maxNumberOfCreature; + private final Material creatureMaterial; + + /** A flag indicating whether this creature type is peaceful. */ + private final boolean isPeacefulCreature; + + /** Whether this creature type is an animal. */ + private final boolean isAnimal; + + private EnumCreatureType(Class par3Class, int par4, Material par5Material, boolean par6, boolean par7) { + this.creatureClass = par3Class; + this.maxNumberOfCreature = par4; + this.creatureMaterial = par5Material; + this.isPeacefulCreature = par6; + this.isAnimal = par7; + } + + public Class getCreatureClass() { + return this.creatureClass; + } + + public int getMaxNumberOfCreature() { + return this.maxNumberOfCreature; + } + + public Material getCreatureMaterial() { + return this.creatureMaterial; + } + + /** + * Gets whether or not this creature type is peaceful. + */ + public boolean getPeacefulCreature() { + return this.isPeacefulCreature; + } + + /** + * Return whether this creature type is an animal. + */ + public boolean getAnimal() { + return this.isAnimal; + } +} diff --git a/src/main/java/net/minecraft/src/EnumDoor.java b/src/main/java/net/minecraft/src/EnumDoor.java new file mode 100644 index 0000000..0efbad3 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumDoor.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public enum EnumDoor { + OPENING, WOOD_DOOR, GRATES, IRON_DOOR; +} diff --git a/src/main/java/net/minecraft/src/EnumDoorHelper.java b/src/main/java/net/minecraft/src/EnumDoorHelper.java new file mode 100644 index 0000000..064ded1 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumDoorHelper.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +class EnumDoorHelper { + static final int[] doorEnum = new int[EnumDoor.values().length]; + + static { + try { + doorEnum[EnumDoor.OPENING.ordinal()] = 1; + } catch (NoSuchFieldError var4) { + ; + } + + try { + doorEnum[EnumDoor.WOOD_DOOR.ordinal()] = 2; + } catch (NoSuchFieldError var3) { + ; + } + + try { + doorEnum[EnumDoor.GRATES.ordinal()] = 3; + } catch (NoSuchFieldError var2) { + ; + } + + try { + doorEnum[EnumDoor.IRON_DOOR.ordinal()] = 4; + } catch (NoSuchFieldError var1) { + ; + } + } +} diff --git a/src/main/java/net/minecraft/src/EnumEnchantmentType.java b/src/main/java/net/minecraft/src/EnumEnchantmentType.java new file mode 100644 index 0000000..afb8224 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumEnchantmentType.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +public enum EnumEnchantmentType { + all, armor, armor_feet, armor_legs, armor_torso, armor_head, weapon, digger, bow; + + /** + * Return true if the item passed can be enchanted by a enchantment of this + * type. + */ + public boolean canEnchantItem(Item par1Item) { + if (this == all) { + return true; + } else if (par1Item instanceof ItemArmor) { + if (this == armor) { + return true; + } else { + ItemArmor var2 = (ItemArmor) par1Item; + return var2.armorType == 0 ? this == armor_head : (var2.armorType == 2 ? this == armor_legs : (var2.armorType == 1 ? this == armor_torso : (var2.armorType == 3 ? this == armor_feet : false))); + } + } else { + return par1Item instanceof ItemSword ? this == weapon : (par1Item instanceof ItemTool ? this == digger : (par1Item instanceof ItemBow ? this == bow : false)); + } + } +} diff --git a/src/main/java/net/minecraft/src/EnumEntitySize.java b/src/main/java/net/minecraft/src/EnumEntitySize.java new file mode 100644 index 0000000..e395d30 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumEntitySize.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +public enum EnumEntitySize { + SIZE_1, SIZE_2, SIZE_3, SIZE_4, SIZE_5, SIZE_6; + + public int multiplyBy32AndRound(double par1) { + double var3 = par1 - ((double) MathHelper.floor_double(par1) + 0.5D); + + switch (EnumEntitySizeHelper.field_96565_a[this.ordinal()]) { + case 1: + if (var3 < 0.0D) { + if (var3 < -0.3125D) { + return MathHelper.ceiling_double_int(par1 * 32.0D); + } + } else if (var3 < 0.3125D) { + return MathHelper.ceiling_double_int(par1 * 32.0D); + } + + return MathHelper.floor_double(par1 * 32.0D); + + case 2: + if (var3 < 0.0D) { + if (var3 < -0.3125D) { + return MathHelper.floor_double(par1 * 32.0D); + } + } else if (var3 < 0.3125D) { + return MathHelper.floor_double(par1 * 32.0D); + } + + return MathHelper.ceiling_double_int(par1 * 32.0D); + + case 3: + if (var3 > 0.0D) { + return MathHelper.floor_double(par1 * 32.0D); + } + + return MathHelper.ceiling_double_int(par1 * 32.0D); + + case 4: + if (var3 < 0.0D) { + if (var3 < -0.1875D) { + return MathHelper.ceiling_double_int(par1 * 32.0D); + } + } else if (var3 < 0.1875D) { + return MathHelper.ceiling_double_int(par1 * 32.0D); + } + + return MathHelper.floor_double(par1 * 32.0D); + + case 5: + if (var3 < 0.0D) { + if (var3 < -0.1875D) { + return MathHelper.floor_double(par1 * 32.0D); + } + } else if (var3 < 0.1875D) { + return MathHelper.floor_double(par1 * 32.0D); + } + + return MathHelper.ceiling_double_int(par1 * 32.0D); + + case 6: + default: + if (var3 > 0.0D) { + return MathHelper.ceiling_double_int(par1 * 32.0D); + } else { + return MathHelper.floor_double(par1 * 32.0D); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/EnumEntitySizeHelper.java b/src/main/java/net/minecraft/src/EnumEntitySizeHelper.java new file mode 100644 index 0000000..60d41da --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumEntitySizeHelper.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +class EnumEntitySizeHelper { + static final int[] field_96565_a = new int[EnumEntitySize.values().length]; + + static { + try { + field_96565_a[EnumEntitySize.SIZE_1.ordinal()] = 1; + } catch (NoSuchFieldError var6) { + ; + } + + try { + field_96565_a[EnumEntitySize.SIZE_2.ordinal()] = 2; + } catch (NoSuchFieldError var5) { + ; + } + + try { + field_96565_a[EnumEntitySize.SIZE_3.ordinal()] = 3; + } catch (NoSuchFieldError var4) { + ; + } + + try { + field_96565_a[EnumEntitySize.SIZE_4.ordinal()] = 4; + } catch (NoSuchFieldError var3) { + ; + } + + try { + field_96565_a[EnumEntitySize.SIZE_5.ordinal()] = 5; + } catch (NoSuchFieldError var2) { + ; + } + + try { + field_96565_a[EnumEntitySize.SIZE_6.ordinal()] = 6; + } catch (NoSuchFieldError var1) { + ; + } + } +} diff --git a/src/main/java/net/minecraft/src/EnumFacing.java b/src/main/java/net/minecraft/src/EnumFacing.java new file mode 100644 index 0000000..e4deaaa --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumFacing.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +public enum EnumFacing { + DOWN(0, 1, 0, -1, 0), UP(1, 0, 0, 1, 0), NORTH(2, 3, 0, 0, -1), SOUTH(3, 2, 0, 0, 1), EAST(4, 5, -1, 0, 0), WEST(5, 4, 1, 0, 0); + + /** Face order for D-U-N-S-E-W. */ + private final int order_a; + + /** Face order for U-D-S-N-W-E. */ + private final int order_b; + private final int frontOffsetX; + private final int frontOffsetY; + private final int frontOffsetZ; + + /** List of all values in EnumFacing. Order is D-U-N-S-E-W. */ + private static final EnumFacing[] faceList = new EnumFacing[6]; + + private EnumFacing(int par3, int par4, int par5, int par6, int par7) { + this.order_a = par3; + this.order_b = par4; + this.frontOffsetX = par5; + this.frontOffsetY = par6; + this.frontOffsetZ = par7; + } + + /** + * Returns a offset that addresses the block in front of this facing. + */ + public int getFrontOffsetX() { + return this.frontOffsetX; + } + + public int getFrontOffsetY() { + return this.frontOffsetY; + } + + /** + * Returns a offset that addresses the block in front of this facing. + */ + public int getFrontOffsetZ() { + return this.frontOffsetZ; + } + + /** + * Returns the facing that represents the block in front of it. + */ + public static EnumFacing getFront(int par0) { + return faceList[par0 % faceList.length]; + } + + static { + EnumFacing[] var0 = values(); + int var1 = var0.length; + + for (int var2 = 0; var2 < var1; ++var2) { + EnumFacing var3 = var0[var2]; + faceList[var3.order_a] = var3; + } + } +} diff --git a/src/main/java/net/minecraft/src/EnumGameType.java b/src/main/java/net/minecraft/src/EnumGameType.java new file mode 100644 index 0000000..ad730ea --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumGameType.java @@ -0,0 +1,104 @@ +package net.minecraft.src; + +public enum EnumGameType { + NOT_SET(-1, ""), SURVIVAL(0, "survival"), CREATIVE(1, "creative"), ADVENTURE(2, "adventure"); + + int id; + String name; + + private EnumGameType(int par3, String par4Str) { + this.id = par3; + this.name = par4Str; + } + + /** + * Returns the ID of this game type + */ + public int getID() { + return this.id; + } + + /** + * Returns the name of this game type + */ + public String getName() { + return this.name; + } + + /** + * Configures the player capabilities based on the game type + */ + public void configurePlayerCapabilities(PlayerCapabilities par1PlayerCapabilities) { + if (this == CREATIVE) { + par1PlayerCapabilities.allowFlying = true; + par1PlayerCapabilities.isCreativeMode = true; + par1PlayerCapabilities.disableDamage = true; + } else { + par1PlayerCapabilities.allowFlying = false; + par1PlayerCapabilities.isCreativeMode = false; + par1PlayerCapabilities.disableDamage = false; + par1PlayerCapabilities.isFlying = false; + } + + par1PlayerCapabilities.allowEdit = !this.isAdventure(); + } + + /** + * Returns true if this is the ADVENTURE game type + */ + public boolean isAdventure() { + return this == ADVENTURE; + } + + /** + * Returns true if this is the CREATIVE game type + */ + public boolean isCreative() { + return this == CREATIVE; + } + + /** + * Returns true if this is the SURVIVAL or ADVENTURE game type + */ + public boolean isSurvivalOrAdventure() { + return this == SURVIVAL || this == ADVENTURE; + } + + /** + * Returns the game type with the specified ID, or SURVIVAL if none found. Args: + * id + */ + public static EnumGameType getByID(int par0) { + EnumGameType[] var1 = values(); + int var2 = var1.length; + + for (int var3 = 0; var3 < var2; ++var3) { + EnumGameType var4 = var1[var3]; + + if (var4.id == par0) { + return var4; + } + } + + return SURVIVAL; + } + + /** + * Returns the game type with the specified name, or SURVIVAL if none found. + * This is case sensitive. Args: name + */ + public static EnumGameType getByName(String par0Str) { + EnumGameType[] var1 = values(); + int var2 = var1.length; + + for (int var3 = 0; var3 < var2; ++var3) { + EnumGameType var4 = var1[var3]; + + if (var4.name.equals(par0Str)) { + return var4; + } + } + + return SURVIVAL; + } +} diff --git a/src/main/java/net/minecraft/src/EnumMobType.java b/src/main/java/net/minecraft/src/EnumMobType.java new file mode 100644 index 0000000..88e88c2 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumMobType.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public enum EnumMobType { + everything, mobs, players; +} diff --git a/src/main/java/net/minecraft/src/EnumMovingObjectType.java b/src/main/java/net/minecraft/src/EnumMovingObjectType.java new file mode 100644 index 0000000..04b42c9 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumMovingObjectType.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public enum EnumMovingObjectType { + TILE, ENTITY; +} diff --git a/src/main/java/net/minecraft/src/EnumOS.java b/src/main/java/net/minecraft/src/EnumOS.java new file mode 100644 index 0000000..ebef948 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumOS.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public enum EnumOS { + LINUX, SOLARIS, WINDOWS, MACOS, UNKNOWN; +} diff --git a/src/main/java/net/minecraft/src/EnumOSHelper.java b/src/main/java/net/minecraft/src/EnumOSHelper.java new file mode 100644 index 0000000..06a0538 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumOSHelper.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnumOSHelper { + public static final int[] field_90049_a = new int[EnumOS.values().length]; + + static { + try { + field_90049_a[EnumOS.LINUX.ordinal()] = 1; + } catch (NoSuchFieldError var4) { + ; + } + + try { + field_90049_a[EnumOS.SOLARIS.ordinal()] = 2; + } catch (NoSuchFieldError var3) { + ; + } + + try { + field_90049_a[EnumOS.WINDOWS.ordinal()] = 3; + } catch (NoSuchFieldError var2) { + ; + } + + try { + field_90049_a[EnumOS.MACOS.ordinal()] = 4; + } catch (NoSuchFieldError var1) { + ; + } + } +} diff --git a/src/main/java/net/minecraft/src/EnumOptions.java b/src/main/java/net/minecraft/src/EnumOptions.java new file mode 100644 index 0000000..922853f --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumOptions.java @@ -0,0 +1,53 @@ +package net.minecraft.src; + +public enum EnumOptions { + MUSIC("options.music", true, false), SOUND("options.sound", true, false), INVERT_MOUSE("options.invertMouse", false, true), SENSITIVITY("options.sensitivity", true, false), FOV("options.fov", true, false), + GAMMA("options.gamma", true, false), RENDER_DISTANCE("options.renderDistance", false, false), VIEW_BOBBING("options.viewBobbing", false, true), ANAGLYPH("options.anaglyph", false, true), + /*ADVANCED_OPENGL("options.advancedOpengl", false, true),*/ FRAMERATE_LIMIT("options.framerateLimit", false, false), DIFFICULTY("options.difficulty", false, false), GRAPHICS("options.graphics", false, false), + AMBIENT_OCCLUSION("options.ao", false, false), GUI_SCALE("options.guiScale", false, false), RENDER_CLOUDS("options.renderClouds", false, true), PARTICLES("options.particles", false, false), + CHAT_VISIBILITY("options.chat.visibility", false, false), CHAT_COLOR("options.chat.color", false, true), CHAT_LINKS("options.chat.links", false, true), CHAT_OPACITY("options.chat.opacity", true, false), + CHAT_LINKS_PROMPT("options.chat.links.prompt", false, true), USE_SERVER_TEXTURES("options.serverTextures", false, true), SNOOPER_ENABLED("options.snooper", false, true), USE_FULLSCREEN("options.fullscreen", false, true), + ENABLE_VSYNC("options.vsync", false, true), ENABLE_FOG("options.fog", false, true), SHOW_CAPE("options.showCape", false, true), ANTIALIASING("options.framebufferAntialias", false, false), CHAT_SCALE("options.chat.scale", true, false), CHAT_WIDTH("options.chat.width", true, false), + CHAT_HEIGHT_FOCUSED("options.chat.height.focused", true, false), CHAT_HEIGHT_UNFOCUSED("options.chat.height.unfocused", true, false); + + private final boolean enumFloat; + private final boolean enumBoolean; + private final String enumString; + + public static EnumOptions getEnumOptions(int par0) { + EnumOptions[] var1 = values(); + int var2 = var1.length; + + for (int var3 = 0; var3 < var2; ++var3) { + EnumOptions var4 = var1[var3]; + + if (var4.returnEnumOrdinal() == par0) { + return var4; + } + } + + return null; + } + + private EnumOptions(String par3Str, boolean par4, boolean par5) { + this.enumString = par3Str; + this.enumFloat = par4; + this.enumBoolean = par5; + } + + public boolean getEnumFloat() { + return this.enumFloat; + } + + public boolean getEnumBoolean() { + return this.enumBoolean; + } + + public int returnEnumOrdinal() { + return this.ordinal(); + } + + public String getEnumString() { + return this.enumString; + } +} diff --git a/src/main/java/net/minecraft/src/EnumOptionsHelper.java b/src/main/java/net/minecraft/src/EnumOptionsHelper.java new file mode 100644 index 0000000..d2c6bcf --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumOptionsHelper.java @@ -0,0 +1,91 @@ +package net.minecraft.src; + +class EnumOptionsHelper { + static final int[] enumOptionsMappingHelperArray = new int[EnumOptions.values().length]; + + static { + try { + enumOptionsMappingHelperArray[EnumOptions.INVERT_MOUSE.ordinal()] = 1; + } catch (NoSuchFieldError var14) { + ; + } + + try { + enumOptionsMappingHelperArray[EnumOptions.VIEW_BOBBING.ordinal()] = 2; + } catch (NoSuchFieldError var13) { + ; + } + + try { + enumOptionsMappingHelperArray[EnumOptions.ANAGLYPH.ordinal()] = 3; + } catch (NoSuchFieldError var12) { + ; + } + + try { + enumOptionsMappingHelperArray[EnumOptions.RENDER_CLOUDS.ordinal()] = 5; + } catch (NoSuchFieldError var10) { + ; + } + + try { + enumOptionsMappingHelperArray[EnumOptions.CHAT_COLOR.ordinal()] = 6; + } catch (NoSuchFieldError var9) { + ; + } + + try { + enumOptionsMappingHelperArray[EnumOptions.CHAT_LINKS.ordinal()] = 7; + } catch (NoSuchFieldError var8) { + ; + } + + try { + enumOptionsMappingHelperArray[EnumOptions.CHAT_LINKS_PROMPT.ordinal()] = 8; + } catch (NoSuchFieldError var7) { + ; + } + + try { + enumOptionsMappingHelperArray[EnumOptions.USE_SERVER_TEXTURES.ordinal()] = 9; + } catch (NoSuchFieldError var6) { + ; + } + + try { + enumOptionsMappingHelperArray[EnumOptions.SNOOPER_ENABLED.ordinal()] = 10; + } catch (NoSuchFieldError var5) { + ; + } + + try { + enumOptionsMappingHelperArray[EnumOptions.USE_FULLSCREEN.ordinal()] = 11; + } catch (NoSuchFieldError var4) { + ; + } + + try { + enumOptionsMappingHelperArray[EnumOptions.ENABLE_VSYNC.ordinal()] = 12; + } catch (NoSuchFieldError var3) { + ; + } + + try { + enumOptionsMappingHelperArray[EnumOptions.SHOW_CAPE.ordinal()] = 13; + } catch (NoSuchFieldError var2) { + ; + } + + try { + enumOptionsMappingHelperArray[EnumOptions.ANTIALIASING.ordinal()] = 14; + } catch (NoSuchFieldError var1) { + ; + } + + try { + enumOptionsMappingHelperArray[EnumOptions.ENABLE_FOG.ordinal()] = 15; + } catch (NoSuchFieldError var10) { + ; + } + } +} diff --git a/src/main/java/net/minecraft/src/EnumRarity.java b/src/main/java/net/minecraft/src/EnumRarity.java new file mode 100644 index 0000000..9a9fc05 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumRarity.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +public enum EnumRarity { + common(15, "Common"), uncommon(14, "Uncommon"), rare(11, "Rare"), epic(13, "Epic"); + + /** + * A decimal representation of the hex color codes of a the color assigned to + * this rarity type. (13 becomes d as in \247d which is light purple) + */ + public final int rarityColor; + + /** Rarity name. */ + public final String rarityName; + + private EnumRarity(int par3, String par4Str) { + this.rarityColor = par3; + this.rarityName = par4Str; + } +} diff --git a/src/main/java/net/minecraft/src/EnumSkyBlock.java b/src/main/java/net/minecraft/src/EnumSkyBlock.java new file mode 100644 index 0000000..b128101 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumSkyBlock.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +public enum EnumSkyBlock { + Sky(15), Block(0); + + public final int defaultLightValue; + + private EnumSkyBlock(int par3) { + this.defaultLightValue = par3; + } +} diff --git a/src/main/java/net/minecraft/src/EnumStatus.java b/src/main/java/net/minecraft/src/EnumStatus.java new file mode 100644 index 0000000..a1d834c --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumStatus.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public enum EnumStatus { + OK, NOT_POSSIBLE_HERE, NOT_POSSIBLE_NOW, TOO_FAR_AWAY, OTHER_PROBLEM, NOT_SAFE; +} diff --git a/src/main/java/net/minecraft/src/EnumToolMaterial.java b/src/main/java/net/minecraft/src/EnumToolMaterial.java new file mode 100644 index 0000000..16c3094 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumToolMaterial.java @@ -0,0 +1,83 @@ +package net.minecraft.src; + +public enum EnumToolMaterial { + WOOD(0, 59, 2.0F, 0, 15), STONE(1, 131, 4.0F, 1, 5), IRON(2, 250, 6.0F, 2, 14), EMERALD(3, 1561, 8.0F, 3, 10), GOLD(0, 32, 12.0F, 0, 22); + + /** + * The level of material this tool can harvest (3 = DIAMOND, 2 = IRON, 1 = + * STONE, 0 = IRON/GOLD) + */ + private final int harvestLevel; + + /** + * The number of uses this material allows. (wood = 59, stone = 131, iron = 250, + * diamond = 1561, gold = 32) + */ + private final int maxUses; + + /** + * The strength of this tool material against blocks which it is effective + * against. + */ + private final float efficiencyOnProperMaterial; + + /** Damage versus entities. */ + private final int damageVsEntity; + + /** Defines the natural enchantability factor of the material. */ + private final int enchantability; + + private EnumToolMaterial(int par3, int par4, float par5, int par6, int par7) { + this.harvestLevel = par3; + this.maxUses = par4; + this.efficiencyOnProperMaterial = par5; + this.damageVsEntity = par6; + this.enchantability = par7; + } + + /** + * The number of uses this material allows. (wood = 59, stone = 131, iron = 250, + * diamond = 1561, gold = 32) + */ + public int getMaxUses() { + return this.maxUses; + } + + /** + * The strength of this tool material against blocks which it is effective + * against. + */ + public float getEfficiencyOnProperMaterial() { + return this.efficiencyOnProperMaterial; + } + + /** + * Damage versus entities. + */ + public int getDamageVsEntity() { + return this.damageVsEntity; + } + + /** + * The level of material this tool can harvest (3 = DIAMOND, 2 = IRON, 1 = + * STONE, 0 = IRON/GOLD) + */ + public int getHarvestLevel() { + return this.harvestLevel; + } + + /** + * Return the natural enchantability factor of the material. + */ + public int getEnchantability() { + return this.enchantability; + } + + /** + * Return the crafting material for this tool material, used to determine the + * item that can be used to repair a tool with an anvil + */ + public int getToolCraftingMaterial() { + return this == WOOD ? Block.planks.blockID : (this == STONE ? Block.cobblestone.blockID : (this == GOLD ? Item.ingotGold.itemID : (this == IRON ? Item.ingotIron.itemID : (this == EMERALD ? Item.diamond.itemID : 0)))); + } +} diff --git a/src/main/java/net/minecraft/src/Explosion.java b/src/main/java/net/minecraft/src/Explosion.java new file mode 100644 index 0000000..6ac7a57 --- /dev/null +++ b/src/main/java/net/minecraft/src/Explosion.java @@ -0,0 +1,225 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; + + + +public class Explosion { + /** whether or not the explosion sets fire to blocks around it */ + public boolean isFlaming = false; + + /** whether or not this explosion spawns smoke particles */ + public boolean isSmoking = true; + private int field_77289_h = 16; + private Random explosionRNG = new Random(); + private World worldObj; + public double explosionX; + public double explosionY; + public double explosionZ; + public Entity exploder; + public float explosionSize; + + /** A list of ChunkPositions of blocks affected by this explosion */ + public List affectedBlockPositions = new ArrayList(); + private Map field_77288_k = new HashMap(); + + public Explosion(World par1World, Entity par2Entity, double par3, double par5, double par7, float par9) { + this.worldObj = par1World; + this.exploder = par2Entity; + this.explosionSize = par9; + this.explosionX = par3; + this.explosionY = par5; + this.explosionZ = par7; + } + + /** + * Does the first part of the explosion (destroy blocks) + */ + public void doExplosionA() { + float var1 = this.explosionSize; + HashSet var2 = new HashSet(); + int var3; + int var4; + int var5; + double var15; + double var17; + double var19; + + for (var3 = 0; var3 < this.field_77289_h; ++var3) { + for (var4 = 0; var4 < this.field_77289_h; ++var4) { + for (var5 = 0; var5 < this.field_77289_h; ++var5) { + if (var3 == 0 || var3 == this.field_77289_h - 1 || var4 == 0 || var4 == this.field_77289_h - 1 || var5 == 0 || var5 == this.field_77289_h - 1) { + double var6 = (double) ((float) var3 / ((float) this.field_77289_h - 1.0F) * 2.0F - 1.0F); + double var8 = (double) ((float) var4 / ((float) this.field_77289_h - 1.0F) * 2.0F - 1.0F); + double var10 = (double) ((float) var5 / ((float) this.field_77289_h - 1.0F) * 2.0F - 1.0F); + double var12 = Math.sqrt(var6 * var6 + var8 * var8 + var10 * var10); + var6 /= var12; + var8 /= var12; + var10 /= var12; + float var14 = this.explosionSize * (0.7F + this.worldObj.rand.nextFloat() * 0.6F); + var15 = this.explosionX; + var17 = this.explosionY; + var19 = this.explosionZ; + + for (float var21 = 0.3F; var14 > 0.0F; var14 -= var21 * 0.75F) { + int var22 = MathHelper.floor_double(var15); + int var23 = MathHelper.floor_double(var17); + int var24 = MathHelper.floor_double(var19); + int var25 = this.worldObj.getBlockId(var22, var23, var24); + + if (var25 > 0) { + Block var26 = Block.blocksList[var25]; + float var27 = this.exploder != null ? this.exploder.func_82146_a(this, this.worldObj, var22, var23, var24, var26) : var26.getExplosionResistance(this.exploder); + var14 -= (var27 + 0.3F) * var21; + } + + if (var14 > 0.0F && (this.exploder == null || this.exploder.func_96091_a(this, this.worldObj, var22, var23, var24, var25, var14))) { + var2.add(new ChunkPosition(var22, var23, var24)); + } + + var15 += var6 * (double) var21; + var17 += var8 * (double) var21; + var19 += var10 * (double) var21; + } + } + } + } + } + + this.affectedBlockPositions.addAll(var2); + this.explosionSize *= 2.0F; + var3 = MathHelper.floor_double(this.explosionX - (double) this.explosionSize - 1.0D); + var4 = MathHelper.floor_double(this.explosionX + (double) this.explosionSize + 1.0D); + var5 = MathHelper.floor_double(this.explosionY - (double) this.explosionSize - 1.0D); + int var29 = MathHelper.floor_double(this.explosionY + (double) this.explosionSize + 1.0D); + int var7 = MathHelper.floor_double(this.explosionZ - (double) this.explosionSize - 1.0D); + int var30 = MathHelper.floor_double(this.explosionZ + (double) this.explosionSize + 1.0D); + List var9 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this.exploder, AxisAlignedBB.getAABBPool().getAABB((double) var3, (double) var5, (double) var7, (double) var4, (double) var29, (double) var30)); + Vec3 var31 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.explosionX, this.explosionY, this.explosionZ); + + for (int var11 = 0; var11 < var9.size(); ++var11) { + Entity var32 = (Entity) var9.get(var11); + double var13 = var32.getDistance(this.explosionX, this.explosionY, this.explosionZ) / (double) this.explosionSize; + + if (var13 <= 1.0D) { + var15 = var32.posX - this.explosionX; + var17 = var32.posY + (double) var32.getEyeHeight() - this.explosionY; + var19 = var32.posZ - this.explosionZ; + double var33 = (double) MathHelper.sqrt_double(var15 * var15 + var17 * var17 + var19 * var19); + + if (var33 != 0.0D) { + var15 /= var33; + var17 /= var33; + var19 /= var33; + double var34 = (double) this.worldObj.getBlockDensity(var31, var32.boundingBox); + double var35 = (1.0D - var13) * var34; + var32.attackEntityFrom(DamageSource.setExplosionSource(this), (int) ((var35 * var35 + var35) / 2.0D * 8.0D * (double) this.explosionSize + 1.0D)); + double var36 = EnchantmentProtection.func_92092_a(var32, var35); + var32.motionX += var15 * var36; + var32.motionY += var17 * var36; + var32.motionZ += var19 * var36; + + if (var32 instanceof EntityPlayer) { + this.field_77288_k.put((EntityPlayer) var32, this.worldObj.getWorldVec3Pool().getVecFromPool(var15 * var35, var17 * var35, var19 * var35)); + } + } + } + } + + this.explosionSize = var1; + } + + /** + * Does the second part of the explosion (sound, particles, drop spawn) + */ + public void doExplosionB(boolean par1) { + this.worldObj.playSoundEffect(this.explosionX, this.explosionY, this.explosionZ, "random.explode", 4.0F, (1.0F + (this.worldObj.rand.nextFloat() - this.worldObj.rand.nextFloat()) * 0.2F) * 0.7F); + + if (this.explosionSize >= 2.0F && this.isSmoking) { + this.worldObj.spawnParticle("hugeexplosion", this.explosionX, this.explosionY, this.explosionZ, 1.0D, 0.0D, 0.0D); + } else { + this.worldObj.spawnParticle("largeexplode", this.explosionX, this.explosionY, this.explosionZ, 1.0D, 0.0D, 0.0D); + } + + Iterator var2; + ChunkPosition var3; + int var4; + int var5; + int var6; + int var7; + + if (this.isSmoking) { + var2 = this.affectedBlockPositions.iterator(); + + while (var2.hasNext()) { + var3 = (ChunkPosition) var2.next(); + var4 = var3.x; + var5 = var3.y; + var6 = var3.z; + var7 = this.worldObj.getBlockId(var4, var5, var6); + + if (par1) { + double var8 = (double) ((float) var4 + this.worldObj.rand.nextFloat()); + double var10 = (double) ((float) var5 + this.worldObj.rand.nextFloat()); + double var12 = (double) ((float) var6 + this.worldObj.rand.nextFloat()); + double var14 = var8 - this.explosionX; + double var16 = var10 - this.explosionY; + double var18 = var12 - this.explosionZ; + double var20 = (double) MathHelper.sqrt_double(var14 * var14 + var16 * var16 + var18 * var18); + var14 /= var20; + var16 /= var20; + var18 /= var20; + double var22 = 0.5D / (var20 / (double) this.explosionSize + 0.1D); + var22 *= (double) (this.worldObj.rand.nextFloat() * this.worldObj.rand.nextFloat() + 0.3F); + var14 *= var22; + var16 *= var22; + var18 *= var22; + this.worldObj.spawnParticle("explode", (var8 + this.explosionX * 1.0D) / 2.0D, (var10 + this.explosionY * 1.0D) / 2.0D, (var12 + this.explosionZ * 1.0D) / 2.0D, var14, var16, var18); + this.worldObj.spawnParticle("smoke", var8, var10, var12, var14, var16, var18); + } + + if (var7 > 0) { + Block var24 = Block.blocksList[var7]; + + if (var24.canDropFromExplosion(this)) { + var24.dropBlockAsItemWithChance(this.worldObj, var4, var5, var6, this.worldObj.getBlockMetadata(var4, var5, var6), 1.0F / this.explosionSize, 0); + } + + this.worldObj.setBlock(var4, var5, var6, 0, 0, 3); + var24.onBlockDestroyedByExplosion(this.worldObj, var4, var5, var6, this); + } + } + } + + if (this.isFlaming) { + var2 = this.affectedBlockPositions.iterator(); + + while (var2.hasNext()) { + var3 = (ChunkPosition) var2.next(); + var4 = var3.x; + var5 = var3.y; + var6 = var3.z; + var7 = this.worldObj.getBlockId(var4, var5, var6); + int var25 = this.worldObj.getBlockId(var4, var5 - 1, var6); + + if (var7 == 0 && Block.opaqueCubeLookup[var25] && this.explosionRNG.nextInt(3) == 0) { + this.worldObj.setBlock(var4, var5, var6, Block.fire.blockID); + } + } + } + } + + public Map func_77277_b() { + return this.field_77288_k; + } + + public EntityLiving func_94613_c() { + return this.exploder == null ? null : (this.exploder instanceof EntityTNTPrimed ? ((EntityTNTPrimed) this.exploder).getTntPlacedBy() : (this.exploder instanceof EntityLiving ? (EntityLiving) this.exploder : null)); + } +} diff --git a/src/main/java/net/minecraft/src/ExtendedBlockStorage.java b/src/main/java/net/minecraft/src/ExtendedBlockStorage.java new file mode 100644 index 0000000..b1f1bd8 --- /dev/null +++ b/src/main/java/net/minecraft/src/ExtendedBlockStorage.java @@ -0,0 +1,287 @@ +package net.minecraft.src; + +public class ExtendedBlockStorage { + /** + * Contains the bottom-most Y block represented by this ExtendedBlockStorage. + * Typically a multiple of 16. + */ + private int yBase; + + /** + * A total count of the number of non-air blocks in this block storage's Chunk. + */ + private int blockRefCount; + + /** + * Contains the number of blocks in this block storage's parent chunk that + * require random ticking. Used to cull the Chunk from random tick updates for + * performance reasons. + */ + private int tickRefCount; + + /** + * Contains the least significant 8 bits of each block ID belonging to this + * block storage's parent Chunk. + */ + private byte[] blockLSBArray; + + /** + * Contains the most significant 4 bits of each block ID belonging to this block + * storage's parent Chunk. + */ + private NibbleArray blockMSBArray; + + /** + * Stores the metadata associated with blocks in this ExtendedBlockStorage. + */ + private NibbleArray blockMetadataArray; + + /** The NibbleArray containing a block of Block-light data. */ + private NibbleArray blocklightArray; + + /** The NibbleArray containing a block of Sky-light data. */ + private NibbleArray skylightArray; + + public ExtendedBlockStorage(int par1, boolean par2) { + this.yBase = par1; + this.blockLSBArray = new byte[4096]; + this.blockMetadataArray = new NibbleArray(this.blockLSBArray.length, 4); + this.blocklightArray = new NibbleArray(this.blockLSBArray.length, 4); + + if (par2) { + this.skylightArray = new NibbleArray(this.blockLSBArray.length, 4); + } + } + + /** + * Returns the extended block ID for a location in a chunk, merged from a byte + * array and a NibbleArray to form a full 12-bit block ID. + */ + public int getExtBlockID(int par1, int par2, int par3) { + int var4 = this.blockLSBArray[par2 << 8 | par3 << 4 | par1] & 255; + return this.blockMSBArray != null ? this.blockMSBArray.get(par1, par2, par3) << 8 | var4 : var4; + } + + /** + * Sets the extended block ID for a location in a chunk, splitting bits 11..8 + * into a NibbleArray and bits 7..0 into a byte array. Also performs reference + * counting to determine whether or not to broadly cull this Chunk from the + * random-update tick list. + */ + public void setExtBlockID(int par1, int par2, int par3, int par4) { + int var5 = this.blockLSBArray[par2 << 8 | par3 << 4 | par1] & 255; + + if (this.blockMSBArray != null) { + var5 |= this.blockMSBArray.get(par1, par2, par3) << 8; + } + + if (var5 == 0 && par4 != 0) { + ++this.blockRefCount; + + if (Block.blocksList[par4] != null && Block.blocksList[par4].getTickRandomly()) { + ++this.tickRefCount; + } + } else if (var5 != 0 && par4 == 0) { + --this.blockRefCount; + + if (Block.blocksList[var5] != null && Block.blocksList[var5].getTickRandomly()) { + --this.tickRefCount; + } + } else if (Block.blocksList[var5] != null && Block.blocksList[var5].getTickRandomly() && (Block.blocksList[par4] == null || !Block.blocksList[par4].getTickRandomly())) { + --this.tickRefCount; + } else if ((Block.blocksList[var5] == null || !Block.blocksList[var5].getTickRandomly()) && Block.blocksList[par4] != null && Block.blocksList[par4].getTickRandomly()) { + ++this.tickRefCount; + } + + this.blockLSBArray[par2 << 8 | par3 << 4 | par1] = (byte) (par4 & 255); + + if (par4 > 255) { + if (this.blockMSBArray == null) { + this.blockMSBArray = new NibbleArray(this.blockLSBArray.length, 4); + } + + this.blockMSBArray.set(par1, par2, par3, (par4 & 3840) >> 8); + } else if (this.blockMSBArray != null) { + this.blockMSBArray.set(par1, par2, par3, 0); + } + } + + /** + * Returns the metadata associated with the block at the given coordinates in + * this ExtendedBlockStorage. + */ + public int getExtBlockMetadata(int par1, int par2, int par3) { + return this.blockMetadataArray.get(par1, par2, par3); + } + + /** + * Sets the metadata of the Block at the given coordinates in this + * ExtendedBlockStorage to the given metadata. + */ + public void setExtBlockMetadata(int par1, int par2, int par3, int par4) { + this.blockMetadataArray.set(par1, par2, par3, par4); + } + + /** + * Returns whether or not this block storage's Chunk is fully empty, based on + * its internal reference count. + */ + public boolean isEmpty() { + return this.blockRefCount == 0; + } + + /** + * Returns whether or not this block storage's Chunk will require random + * ticking, used to avoid looping through random block ticks when there are no + * blocks that would randomly tick. + */ + public boolean getNeedsRandomTick() { + return this.tickRefCount > 0; + } + + /** + * Returns the Y location of this ExtendedBlockStorage. + */ + public int getYLocation() { + return this.yBase; + } + + /** + * Sets the saved Sky-light value in the extended block storage structure. + */ + public void setExtSkylightValue(int par1, int par2, int par3, int par4) { + this.skylightArray.set(par1, par2, par3, par4); + } + + /** + * Gets the saved Sky-light value in the extended block storage structure. + */ + public int getExtSkylightValue(int par1, int par2, int par3) { + return this.skylightArray.get(par1, par2, par3); + } + + /** + * Sets the saved Block-light value in the extended block storage structure. + */ + public void setExtBlocklightValue(int par1, int par2, int par3, int par4) { + this.blocklightArray.set(par1, par2, par3, par4); + } + + /** + * Gets the saved Block-light value in the extended block storage structure. + */ + public int getExtBlocklightValue(int par1, int par2, int par3) { + return this.blocklightArray.get(par1, par2, par3); + } + + public void removeInvalidBlocks() { + this.blockRefCount = 0; + this.tickRefCount = 0; + + for (int var1 = 0; var1 < 16; ++var1) { + for (int var2 = 0; var2 < 16; ++var2) { + for (int var3 = 0; var3 < 16; ++var3) { + int var4 = this.getExtBlockID(var1, var2, var3); + + if (var4 > 0) { + if (Block.blocksList[var4] == null) { + this.blockLSBArray[var2 << 8 | var3 << 4 | var1] = 0; + + if (this.blockMSBArray != null) { + this.blockMSBArray.set(var1, var2, var3, 0); + } + } else { + ++this.blockRefCount; + + if (Block.blocksList[var4].getTickRandomly()) { + ++this.tickRefCount; + } + } + } + } + } + } + } + + public byte[] getBlockLSBArray() { + return this.blockLSBArray; + } + + public void clearMSBArray() { + this.blockMSBArray = null; + } + + /** + * Returns the block ID MSB (bits 11..8) array for this storage array's Chunk. + */ + public NibbleArray getBlockMSBArray() { + return this.blockMSBArray; + } + + public NibbleArray getMetadataArray() { + return this.blockMetadataArray; + } + + /** + * Returns the NibbleArray instance containing Block-light data. + */ + public NibbleArray getBlocklightArray() { + return this.blocklightArray; + } + + /** + * Returns the NibbleArray instance containing Sky-light data. + */ + public NibbleArray getSkylightArray() { + return this.skylightArray; + } + + /** + * Sets the array of block ID least significant bits for this + * ExtendedBlockStorage. + */ + public void setBlockLSBArray(byte[] par1ArrayOfByte) { + this.blockLSBArray = par1ArrayOfByte; + } + + /** + * Sets the array of blockID most significant bits (blockMSBArray) for this + * ExtendedBlockStorage. + */ + public void setBlockMSBArray(NibbleArray par1NibbleArray) { + this.blockMSBArray = par1NibbleArray; + } + + /** + * Sets the NibbleArray of block metadata (blockMetadataArray) for this + * ExtendedBlockStorage. + */ + public void setBlockMetadataArray(NibbleArray par1NibbleArray) { + this.blockMetadataArray = par1NibbleArray; + } + + /** + * Sets the NibbleArray instance used for Block-light values in this particular + * storage block. + */ + public void setBlocklightArray(NibbleArray par1NibbleArray) { + this.blocklightArray = par1NibbleArray; + } + + /** + * Sets the NibbleArray instance used for Sky-light values in this particular + * storage block. + */ + public void setSkylightArray(NibbleArray par1NibbleArray) { + this.skylightArray = par1NibbleArray; + } + + /** + * Called by a Chunk to initialize the MSB array if getBlockMSBArray returns + * null. Returns the newly-created NibbleArray instance. + */ + public NibbleArray createBlockMSBArray() { + this.blockMSBArray = new NibbleArray(this.blockLSBArray.length, 4); + return this.blockMSBArray; + } +} diff --git a/src/main/java/net/minecraft/src/Facing.java b/src/main/java/net/minecraft/src/Facing.java new file mode 100644 index 0000000..938aeb8 --- /dev/null +++ b/src/main/java/net/minecraft/src/Facing.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +public class Facing { + /** + * Converts a side to the opposite side. This is the same as XOR'ing it with 1. + */ + public static final int[] oppositeSide = new int[] { 1, 0, 3, 2, 5, 4 }; + + /** + * gives the offset required for this axis to get the block at that side. + */ + public static final int[] offsetsXForSide = new int[] { 0, 0, 0, 0, -1, 1 }; + + /** + * gives the offset required for this axis to get the block at that side. + */ + public static final int[] offsetsYForSide = new int[] { -1, 1, 0, 0, 0, 0 }; + + /** + * gives the offset required for this axis to get the block at that side. + */ + public static final int[] offsetsZForSide = new int[] { 0, 0, -1, 1, 0, 0 }; + public static final String[] facings = new String[] { "DOWN", "UP", "NORTH", "SOUTH", "WEST", "EAST" }; +} diff --git a/src/main/java/net/minecraft/src/FilterIMob.java b/src/main/java/net/minecraft/src/FilterIMob.java new file mode 100644 index 0000000..d918d1f --- /dev/null +++ b/src/main/java/net/minecraft/src/FilterIMob.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +final class FilterIMob implements IEntitySelector { + /** + * Return whether the specified entity is applicable to this filter. + */ + public boolean isEntityApplicable(Entity par1Entity) { + return par1Entity instanceof IMob; + } +} diff --git a/src/main/java/net/minecraft/src/FlatGeneratorInfo.java b/src/main/java/net/minecraft/src/FlatGeneratorInfo.java new file mode 100644 index 0000000..e46019c --- /dev/null +++ b/src/main/java/net/minecraft/src/FlatGeneratorInfo.java @@ -0,0 +1,263 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +public class FlatGeneratorInfo { + /** List of layers on this preset. */ + private final List flatLayers = new ArrayList(); + + /** List of world features enabled on this preset. */ + private final Map worldFeatures = new HashMap(); + private int biomeToUse = 0; + + /** + * Return the biome used on this preset. + */ + public int getBiome() { + return this.biomeToUse; + } + + /** + * Set the biome used on this preset. + */ + public void setBiome(int par1) { + this.biomeToUse = par1; + } + + /** + * Return the list of world features enabled on this preset. + */ + public Map getWorldFeatures() { + return this.worldFeatures; + } + + /** + * Return the list of layers on this preset. + */ + public List getFlatLayers() { + return this.flatLayers; + } + + public void func_82645_d() { + int var1 = 0; + FlatLayerInfo var3; + + for (Iterator var2 = this.flatLayers.iterator(); var2.hasNext(); var1 += var3.getLayerCount()) { + var3 = (FlatLayerInfo) var2.next(); + var3.setMinY(var1); + } + } + + public String toString() { + StringBuilder var1 = new StringBuilder(); + var1.append(2); + var1.append(";"); + int var2; + + for (var2 = 0; var2 < this.flatLayers.size(); ++var2) { + if (var2 > 0) { + var1.append(","); + } + + var1.append(((FlatLayerInfo) this.flatLayers.get(var2)).toString()); + } + + var1.append(";"); + var1.append(this.biomeToUse); + + if (!this.worldFeatures.isEmpty()) { + var1.append(";"); + var2 = 0; + Iterator var3 = this.worldFeatures.entrySet().iterator(); + + while (var3.hasNext()) { + Entry var4 = (Entry) var3.next(); + + if (var2++ > 0) { + var1.append(","); + } + + var1.append(((String) var4.getKey()).toLowerCase()); + Map var5 = (Map) var4.getValue(); + + if (!var5.isEmpty()) { + var1.append("("); + int var6 = 0; + Iterator var7 = var5.entrySet().iterator(); + + while (var7.hasNext()) { + Entry var8 = (Entry) var7.next(); + + if (var6++ > 0) { + var1.append(" "); + } + + var1.append((String) var8.getKey()); + var1.append("="); + var1.append((String) var8.getValue()); + } + + var1.append(")"); + } + } + } else { + var1.append(";"); + } + + return var1.toString(); + } + + private static FlatLayerInfo func_82646_a(String par0Str, int par1) { + String[] var2 = par0Str.split("x", 2); + int var3 = 1; + int var5 = 0; + + if (var2.length == 2) { + try { + var3 = Integer.parseInt(var2[0]); + + if (par1 + var3 >= 256) { + var3 = 256 - par1; + } + + if (var3 < 0) { + var3 = 0; + } + } catch (Throwable var7) { + return null; + } + } + + int var4; + + try { + String var6 = var2[var2.length - 1]; + var2 = var6.split(":", 2); + var4 = Integer.parseInt(var2[0]); + + if (var2.length > 1) { + var5 = Integer.parseInt(var2[1]); + } + + if (Block.blocksList[var4] == null) { + var4 = 0; + var5 = 0; + } + + if (var5 < 0 || var5 > 15) { + var5 = 0; + } + } catch (Throwable var8) { + return null; + } + + FlatLayerInfo var9 = new FlatLayerInfo(var3, var4, var5); + var9.setMinY(par1); + return var9; + } + + private static List func_82652_b(String par0Str) { + if (par0Str != null && par0Str.length() >= 1) { + ArrayList var1 = new ArrayList(); + String[] var2 = par0Str.split(","); + int var3 = 0; + String[] var4 = var2; + int var5 = var2.length; + + for (int var6 = 0; var6 < var5; ++var6) { + String var7 = var4[var6]; + FlatLayerInfo var8 = func_82646_a(var7, var3); + + if (var8 == null) { + return null; + } + + var1.add(var8); + var3 += var8.getLayerCount(); + } + + return var1; + } else { + return null; + } + } + + public static FlatGeneratorInfo createFlatGeneratorFromString(String par0Str) { + if (par0Str == null) { + return getDefaultFlatGenerator(); + } else { + String[] var1 = par0Str.split(";", -1); + int var2 = var1.length == 1 ? 0 : MathHelper.parseIntWithDefault(var1[0], 0); + + if (var2 >= 0 && var2 <= 2) { + FlatGeneratorInfo var3 = new FlatGeneratorInfo(); + int var4 = var1.length == 1 ? 0 : 1; + List var5 = func_82652_b(var1[var4++]); + + if (var5 != null && !var5.isEmpty()) { + var3.getFlatLayers().addAll(var5); + var3.func_82645_d(); + int var6 = BiomeGenBase.plains.biomeID; + + if (var2 > 0 && var1.length > var4) { + var6 = MathHelper.parseIntWithDefault(var1[var4++], var6); + } + + var3.setBiome(var6); + + if (var2 > 0 && var1.length > var4) { + String[] var7 = var1[var4++].toLowerCase().split(","); + String[] var8 = var7; + int var9 = var7.length; + + for (int var10 = 0; var10 < var9; ++var10) { + String var11 = var8[var10]; + String[] var12 = var11.split("\\(", 2); + HashMap var13 = new HashMap(); + + if (var12[0].length() > 0) { + var3.getWorldFeatures().put(var12[0], var13); + + if (var12.length > 1 && var12[1].endsWith(")") && var12[1].length() > 1) { + String[] var14 = var12[1].substring(0, var12[1].length() - 1).split(" "); + + for (int var15 = 0; var15 < var14.length; ++var15) { + String[] var16 = var14[var15].split("=", 2); + + if (var16.length == 2) { + var13.put(var16[0], var16[1]); + } + } + } + } + } + } else { + var3.getWorldFeatures().put("village", new HashMap()); + } + + return var3; + } else { + return getDefaultFlatGenerator(); + } + } else { + return getDefaultFlatGenerator(); + } + } + } + + public static FlatGeneratorInfo getDefaultFlatGenerator() { + FlatGeneratorInfo var0 = new FlatGeneratorInfo(); + var0.setBiome(BiomeGenBase.plains.biomeID); + var0.getFlatLayers().add(new FlatLayerInfo(1, Block.bedrock.blockID)); + var0.getFlatLayers().add(new FlatLayerInfo(2, Block.dirt.blockID)); + var0.getFlatLayers().add(new FlatLayerInfo(1, Block.grass.blockID)); + var0.func_82645_d(); + var0.getWorldFeatures().put("village", new HashMap()); + return var0; + } +} diff --git a/src/main/java/net/minecraft/src/FlatLayerInfo.java b/src/main/java/net/minecraft/src/FlatLayerInfo.java new file mode 100644 index 0000000..5d94d8f --- /dev/null +++ b/src/main/java/net/minecraft/src/FlatLayerInfo.java @@ -0,0 +1,76 @@ +package net.minecraft.src; + +public class FlatLayerInfo { + /** Amount of layers for this set of layers. */ + private int layerCount; + + /** Block type used on this set of layers. */ + private int layerFillBlock; + + /** Block metadata used on this set of laeyrs. */ + private int layerFillBlockMeta; + private int layerMinimumY; + + public FlatLayerInfo(int par1, int par2) { + this.layerCount = 1; + this.layerFillBlock = 0; + this.layerFillBlockMeta = 0; + this.layerMinimumY = 0; + this.layerCount = par1; + this.layerFillBlock = par2; + } + + public FlatLayerInfo(int par1, int par2, int par3) { + this(par1, par2); + this.layerFillBlockMeta = par3; + } + + /** + * Return the amount of layers for this set of layers. + */ + public int getLayerCount() { + return this.layerCount; + } + + /** + * Return the block type used on this set of layers. + */ + public int getFillBlock() { + return this.layerFillBlock; + } + + /** + * Return the block metadata used on this set of layers. + */ + public int getFillBlockMeta() { + return this.layerFillBlockMeta; + } + + /** + * Return the minimum Y coordinate for this layer, set during generation. + */ + public int getMinY() { + return this.layerMinimumY; + } + + /** + * Set the minimum Y coordinate for this layer. + */ + public void setMinY(int par1) { + this.layerMinimumY = par1; + } + + public String toString() { + String var1 = Integer.toString(this.layerFillBlock); + + if (this.layerCount > 1) { + var1 = this.layerCount + "x" + var1; + } + + if (this.layerFillBlockMeta > 0) { + var1 = var1 + ":" + this.layerFillBlockMeta; + } + + return var1; + } +} diff --git a/src/main/java/net/minecraft/src/FontRenderer.java b/src/main/java/net/minecraft/src/FontRenderer.java new file mode 100644 index 0000000..501880c --- /dev/null +++ b/src/main/java/net/minecraft/src/FontRenderer.java @@ -0,0 +1,789 @@ +package net.minecraft.src; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.EaglerImage; + +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class FontRenderer { + /** Array of width of all the characters in default.png */ + private int[] charWidth = new int[256]; + + /** the height in pixels of default text */ + public int FONT_HEIGHT = 9; + public Random fontRandom = new Random(); + + /** + * Array of the start/end column (in upper/lower nibble) for every glyph in the + * /font directory. + */ + private byte[] glyphWidth = new byte[65536]; + + /** + * Array of RGB triplets defining the 16 standard chat colors followed by 16 + * darker version of the same colors for drop shadows. + */ + private int[] colorCode = new int[32]; + private final TextureLocation fontTexture; + private final String fontTextureName; + + /** The RenderEngine used to load and setup glyph textures. */ + private final RenderEngine renderEngine; + + /** Current X coordinate at which to draw the next character. */ + private float posX; + + /** Current Y coordinate at which to draw the next character. */ + private float posY; + + /** + * If true, strings should be rendered with Unicode fonts instead of the + * default.png font + */ + private boolean unicodeFlag; + + /** + * If true, the Unicode Bidirectional Algorithm should be run before rendering + * any string. + */ + private boolean bidiFlag; + + /** Used to specify new red value for the current color. */ + private float red; + + /** Used to specify new blue value for the current color. */ + private float blue; + + /** Used to specify new green value for the current color. */ + private float green; + + /** Used to speify new alpha value for the current color. */ + private float alpha; + + /** Text color of the currently rendering string. */ + private int textColor; + + /** Set if the "k" style (random) is active in currently rendering string */ + private boolean randomStyle = false; + + /** Set if the "l" style (bold) is active in currently rendering string */ + private boolean boldStyle = false; + + /** Set if the "o" style (italic) is active in currently rendering string */ + private boolean italicStyle = false; + + /** + * Set if the "n" style (underlined) is active in currently rendering string + */ + private boolean underlineStyle = false; + + /** + * Set if the "m" style (strikethrough) is active in currently rendering string + */ + private boolean strikethroughStyle = false; + + public FontRenderer(GameSettings par1GameSettings, String par2Str, RenderEngine par3RenderEngine, boolean par4) { + this.fontTexture = new TextureLocation(par2Str); + this.fontTextureName = par2Str; + this.renderEngine = par3RenderEngine; + this.unicodeFlag = par4; + this.readFontData(); + fontTexture.bindTexture(); + + for (int var5 = 0; var5 < 32; ++var5) { + int var6 = (var5 >> 3 & 1) * 85; + int var7 = (var5 >> 2 & 1) * 170 + var6; + int var8 = (var5 >> 1 & 1) * 170 + var6; + int var9 = (var5 >> 0 & 1) * 170 + var6; + + if (var5 == 6) { + var7 += 85; + } + + if (par1GameSettings.anaglyph) { + int var10 = (var7 * 30 + var8 * 59 + var9 * 11) / 100; + int var11 = (var7 * 30 + var8 * 70) / 100; + int var12 = (var7 * 30 + var9 * 70) / 100; + var7 = var10; + var8 = var11; + var9 = var12; + } + + if (var5 >= 16) { + var7 /= 4; + var8 /= 4; + var9 /= 4; + } + + this.colorCode[var5] = (var7 & 255) << 16 | (var8 & 255) << 8 | var9 & 255; + } + } + + public void readFontData() { + this.readGlyphSizes(); + this.readFontTexture(this.fontTextureName); + } + + private void readFontTexture(String par1Str) { + EaglerImage e = EaglerImage.loadImage(EaglerAdapter.loadResourceBytes(par1Str)); + int[] var5 = e.data; + int var3 = e.w; + int var4 = e.h; + int var6 = 0; + + while (var6 < 256) { + int var7 = var6 % 16; + int var8 = var6 / 16; + int var9 = 7; + + while (true) { + if (var9 >= 0) { + int var10 = var7 * 8 + var9; + boolean var11 = true; + + for (int var12 = 0; var12 < 8 && var11; ++var12) { + int var13 = (var8 * 8 + var12) * var3; + int var14 = var5[var10 + var13] & 255; + + if (var14 > 0) { + var11 = false; + } + } + + if (var11) { + --var9; + continue; + } + } + + if (var6 == 32) { + var9 = 2; + } + + this.charWidth[var6] = var9 + 2; + ++var6; + break; + } + } + } + + private void readGlyphSizes() { + this.glyphWidth = EaglerAdapter.loadResourceBytes("/font/glyph_sizes.bin"); + } + + /** + * Pick how to render a single character and return the width used. + */ + private float renderCharAtPos(int par1, char par2, boolean par3) { + return par2 == 32 ? 4.0F : (par1 > 0 && !this.unicodeFlag ? this.renderDefaultChar(par1 + 32, par3) : this.renderUnicodeChar(par2, par3)); + } + + /** + * Render a single character with the default.png font at current (posX,posY) + * location... + */ + private float renderDefaultChar(int par1, boolean par2) { + float var3 = (float) (par1 % 16 * 8); + float var4 = (float) (par1 / 16 * 8); + float var5 = par2 ? 1.0F : 0.0F; + float var6 = (float) this.charWidth[par1] - 0.01F; + Tessellator t = Tessellator.instance; + t.addVertexWithUV(this.posX + var5, this.posY, 0.0F, var3 / 128.0F, var4 / 128.0F); + t.addVertexWithUV(this.posX - var5, this.posY + 7.99F, 0.0F, var3 / 128.0F, (var4 + 7.99F) / 128.0F); + t.addVertexWithUV(this.posX + var6 - var5, this.posY + 7.99F, 0.0F, (var3 + var6) / 128.0F, (var4 + 7.99F) / 128.0F); + t.addVertexWithUV(this.posX + var6 + var5, this.posY, 0.0F, (var3 + var6) / 128.0F, var4 / 128.0F); + return (float) this.charWidth[par1]; + } + + /** + * Load one of the /font/glyph_XX.png into a new GL texture and store the + * texture ID in glyphTextureName array. + */ + private void loadGlyphTexture(int par1) { + String var2 = String.format("/font/glyph_%02X.png", new Object[] { Integer.valueOf(par1) }); + this.renderEngine.bindTexture(var2); + } + + /** + * Render a single Unicode character at current (posX,posY) location using one + * of the /font/glyph_XX.png files... + */ + private float renderUnicodeChar(char par1, boolean par2) { + if (this.glyphWidth[par1] == 0) { + return 0.0F; + } else { + Tessellator t = Tessellator.instance; + t.draw(); + int var3 = par1 / 256; + this.loadGlyphTexture(var3); + int var4 = this.glyphWidth[par1] >>> 4; + int var5 = this.glyphWidth[par1] & 15; + float var6 = (float) var4; + float var7 = (float) (var5 + 1); + float var8 = (float) (par1 % 16 * 16) + var6; + float var9 = (float) ((par1 & 255) / 16 * 16); + float var10 = var7 - var6 - 0.02F; + float var11 = par2 ? 1.0F : 0.0F; + t.startDrawing(EaglerAdapter.GL_TRIANGLE_STRIP); + t.addVertexWithUV(this.posX + var11, this.posY, 0.0F, var8 / 256.0F, var9 / 256.0F); + t.addVertexWithUV(this.posX - var11, this.posY + 7.99F, 0.0F, var8 / 256.0F, (var9 + 15.98F) / 256.0F); + t.addVertexWithUV(this.posX + var10 / 2.0F + var11, this.posY, 0.0F, (var8 + var10) / 256.0F, var9 / 256.0F); + t.addVertexWithUV(this.posX + var10 / 2.0F - var11, this.posY + 7.99F, 0.0F, (var8 + var10) / 256.0F, (var9 + 15.98F) / 256.0F); + t.draw(); + this.fontTexture.bindTexture(); + t.startDrawingQuads(); + return (var7 - var6) / 2.0F + 1.0F; + } + } + + /** + * Draws the specified string with a shadow. + */ + public int drawStringWithShadow(String par1Str, int par2, int par3, int par4) { + return this.drawString(par1Str, par2, par3, par4, true); + } + + /** + * Draws the specified string. + */ + public int drawString(String par1Str, int par2, int par3, int par4) { + return this.drawString(par1Str, par2, par3, par4, false); + } + + /** + * Draws the specified string. Args: string, x, y, color, dropShadow + */ + public int drawString(String par1Str, int par2, int par3, int par4, boolean par5) { + this.resetStyles(); + + int var6; + + if (par5) { + var6 = this.renderString(par1Str, par2 + 1, par3 + 1, par4, true); + var6 = Math.max(var6, this.renderString(par1Str, par2, par3, par4, false)); + } else { + var6 = this.renderString(par1Str, par2, par3, par4, false); + } + + return var6; + } + + /** + * Reset all style flag fields in the class to false; called at the start of + * string rendering + */ + private void resetStyles() { + this.randomStyle = false; + this.boldStyle = false; + this.italicStyle = false; + this.underlineStyle = false; + this.strikethroughStyle = false; + } + + /** + * Render a single line string at the current (posX,posY) and update posX + */ + private void renderStringAtPos(String par1Str, boolean par2) { + Tessellator t = Tessellator.instance; + this.fontTexture.bindTexture(); + t.startDrawingQuads(); + for (int var3 = 0; var3 < par1Str.length(); ++var3) { + char var4 = par1Str.charAt(var3); + int var5; + int var6; + + if (var4 == '\u00a7' && var3 + 1 < par1Str.length()) { + var5 = "0123456789abcdefklmnor".indexOf((char)Character.toLowerCase(par1Str.charAt(var3 + 1))); + + if (var5 < 16) { + this.randomStyle = false; + this.boldStyle = false; + this.strikethroughStyle = false; + this.underlineStyle = false; + this.italicStyle = false; + + if (var5 < 0 || var5 > 15) { + var5 = 15; + } + + if (par2) { + var5 += 16; + } + + t.draw(); + t.startDrawingQuads(); + + var6 = this.colorCode[var5]; + this.textColor = var6; + EaglerAdapter.glColor4f((float) ((var6 >> 16) & 255) / 255.0F, (float) ((var6 >> 8) & 255) / 255.0F, (float) (var6 & 255) / 255.0F, this.alpha); + } else if (var5 == 16) { + this.randomStyle = true; + } else if (var5 == 17) { + this.boldStyle = true; + } else if (var5 == 18) { + this.strikethroughStyle = true; + } else if (var5 == 19) { + this.underlineStyle = true; + } else if (var5 == 20) { + this.italicStyle = true; + } else if (var5 == 21) { + this.randomStyle = false; + this.boldStyle = false; + this.strikethroughStyle = false; + this.underlineStyle = false; + this.italicStyle = false; + t.draw(); + t.startDrawingQuads(); + EaglerAdapter.glColor4f(this.red, this.blue, this.green, this.alpha); + } + + ++var3; + } else { + var5 = ChatAllowedCharacters.allowedCharacters.indexOf(var4); + + if (this.randomStyle && var5 > 0) { + do { + var6 = this.fontRandom.nextInt(ChatAllowedCharacters.allowedCharacters.length()); + } while (this.charWidth[var5 + 32] != this.charWidth[var6 + 32]); + + var5 = var6; + } + + float var11 = this.unicodeFlag ? 0.5F : 1.0F; + boolean var7 = (var5 <= 0 || this.unicodeFlag) && par2; + + if (var7) { + this.posX -= var11; + this.posY -= var11; + } + + float var8 = this.renderCharAtPos(var5, var4, this.italicStyle); + + if (var7) { + this.posX += var11; + this.posY += var11; + } + + if (this.boldStyle) { + this.posX += var11; + + if (var7) { + this.posX -= var11; + this.posY -= var11; + } + + this.renderCharAtPos(var5, var4, this.italicStyle); + this.posX -= var11; + + if (var7) { + this.posX += var11; + this.posY += var11; + } + + ++var8; + } + + Tessellator var9; + + if (this.strikethroughStyle) { + var9 = Tessellator.instance; + var9.draw(); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + var9.startDrawingQuads(); + var9.addVertex((double) this.posX, (double) (this.posY + (float) (this.FONT_HEIGHT / 2)), 0.0D); + var9.addVertex((double) (this.posX + var8), (double) (this.posY + (float) (this.FONT_HEIGHT / 2)), 0.0D); + var9.addVertex((double) (this.posX + var8), (double) (this.posY + (float) (this.FONT_HEIGHT / 2) - 1.0F), 0.0D); + var9.addVertex((double) this.posX, (double) (this.posY + (float) (this.FONT_HEIGHT / 2) - 1.0F), 0.0D); + var9.draw(); + var9.startDrawingQuads(); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + } + + if (this.underlineStyle) { + var9 = Tessellator.instance; + var9.draw(); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + var9.startDrawingQuads(); + int var10 = this.underlineStyle ? -1 : 0; + var9.addVertex((double) (this.posX + (float) var10), (double) (this.posY + (float) this.FONT_HEIGHT), 0.0D); + var9.addVertex((double) (this.posX + var8), (double) (this.posY + (float) this.FONT_HEIGHT), 0.0D); + var9.addVertex((double) (this.posX + var8), (double) (this.posY + (float) this.FONT_HEIGHT - 1.0F), 0.0D); + var9.addVertex((double) (this.posX + (float) var10), (double) (this.posY + (float) this.FONT_HEIGHT - 1.0F), 0.0D); + var9.draw(); + var9.startDrawingQuads(); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + } + + this.posX += (float) ((int) var8); + } + } + t.draw(); + } + + /** + * Render string either left or right aligned depending on bidiFlag + */ + private int renderStringAligned(String par1Str, int par2, int par3, int par4, int par5, boolean par6) { + return this.renderString(par1Str, par2, par3, par5, par6); + } + + /** + * Render single line string by setting GL color, current (posX,posY), and + * calling renderStringAtPos() + */ + private int renderString(String par1Str, int par2, int par3, int par4, boolean par5) { + if (par1Str == null) { + return 0; + } else { + if ((par4 & -67108864) == 0) { + par4 |= -16777216; + } + + if (par5) { + par4 = (par4 & 16579836) >> 2 | par4 & -16777216; + } + + this.red = (float) (par4 >> 16 & 255) / 255.0F; + this.blue = (float) (par4 >> 8 & 255) / 255.0F; + this.green = (float) (par4 & 255) / 255.0F; + this.alpha = (float) (par4 >> 24 & 255) / 255.0F; + EaglerAdapter.glColor4f(this.red, this.blue, this.green, this.alpha); + this.posX = (float) par2; + this.posY = (float) par3; + this.renderStringAtPos(par1Str, par5); + return (int) this.posX; + } + } + + /** + * Returns the width of this string. Equivalent of + * FontMetrics.stringWidth(String s). + */ + public int getStringWidth(String par1Str) { + if (par1Str == null) { + return 0; + } else { + int var2 = 0; + boolean var3 = false; + + for (int var4 = 0; var4 < par1Str.length(); ++var4) { + char var5 = par1Str.charAt(var4); + int var6 = this.getCharWidth(var5); + + if (var6 < 0 && var4 < par1Str.length() - 1) { + ++var4; + var5 = par1Str.charAt(var4); + + if (var5 != 108 && var5 != 76) { + if (var5 == 114 || var5 == 82) { + var3 = false; + } + } else { + var3 = true; + } + + var6 = 0; + } + + var2 += var6; + + if (var3) { + ++var2; + } + } + + return var2; + } + } + + /** + * Returns the width of this character as rendered. + */ + public int getCharWidth(char par1) { + if (par1 == 167) { + return -1; + } else if (par1 == 32) { + return 4; + } else { + int var2 = ChatAllowedCharacters.allowedCharacters.indexOf(par1); + + if (var2 >= 0 && !this.unicodeFlag) { + return this.charWidth[var2 + 32]; + } else if (this.glyphWidth[par1] != 0) { + int var3 = this.glyphWidth[par1] >>> 4; + int var4 = this.glyphWidth[par1] & 15; + + if (var4 > 7) { + var4 = 15; + var3 = 0; + } + + ++var4; + return (var4 - var3) / 2 + 1; + } else { + return 0; + } + } + } + + /** + * Trims a string to fit a specified Width. + */ + public String trimStringToWidth(String par1Str, int par2) { + return this.trimStringToWidth(par1Str, par2, false); + } + + /** + * Trims a string to a specified width, and will reverse it if par3 is set. + */ + public String trimStringToWidth(String par1Str, int par2, boolean par3) { + StringBuilder var4 = new StringBuilder(); + int var5 = 0; + int var6 = par3 ? par1Str.length() - 1 : 0; + int var7 = par3 ? -1 : 1; + boolean var8 = false; + boolean var9 = false; + + for (int var10 = var6; var10 >= 0 && var10 < par1Str.length() && var5 < par2; var10 += var7) { + char var11 = par1Str.charAt(var10); + int var12 = this.getCharWidth(var11); + + if (var8) { + var8 = false; + + if (var11 != 108 && var11 != 76) { + if (var11 == 114 || var11 == 82) { + var9 = false; + } + } else { + var9 = true; + } + } else if (var12 < 0) { + var8 = true; + } else { + var5 += var12; + + if (var9) { + ++var5; + } + } + + if (var5 > par2) { + break; + } + + if (par3) { + var4.insert(0, var11); + } else { + var4.append(var11); + } + } + + return var4.toString(); + } + + /** + * Remove all newline characters from the end of the string + */ + private String trimStringNewline(String par1Str) { + while (par1Str != null && par1Str.endsWith("\n")) { + par1Str = par1Str.substring(0, par1Str.length() - 1); + } + + return par1Str; + } + + /** + * Splits and draws a String with wordwrap (maximum length is parameter k) + */ + public void drawSplitString(String par1Str, int par2, int par3, int par4, int par5) { + this.resetStyles(); + this.textColor = par5; + par1Str = this.trimStringNewline(par1Str); + this.renderSplitString(par1Str, par2, par3, par4, false); + } + + /** + * Perform actual work of rendering a multi-line string with wordwrap and with + * darker drop shadow color if flag is set + */ + private void renderSplitString(String par1Str, int par2, int par3, int par4, boolean par5) { + List var6 = this.listFormattedStringToWidth(par1Str, par4); + + for (Iterator var7 = var6.iterator(); var7.hasNext(); par3 += this.FONT_HEIGHT) { + String var8 = (String) var7.next(); + this.renderStringAligned(var8, par2, par3, par4, this.textColor, par5); + } + } + + /** + * Returns the width of the wordwrapped String (maximum length is parameter k) + */ + public int splitStringWidth(String par1Str, int par2) { + return this.FONT_HEIGHT * this.listFormattedStringToWidth(par1Str, par2).size(); + } + + /** + * Set unicodeFlag controlling whether strings should be rendered with Unicode + * fonts instead of the default.png font. + */ + public void setUnicodeFlag(boolean par1) { + this.unicodeFlag = par1; + } + + /** + * Get unicodeFlag controlling whether strings should be rendered with Unicode + * fonts instead of the default.png font. + */ + public boolean getUnicodeFlag() { + return this.unicodeFlag; + } + + /** + * Set bidiFlag to control if the Unicode Bidirectional Algorithm should be run + * before rendering any string. + */ + public void setBidiFlag(boolean par1) { + this.bidiFlag = par1; + } + + /** + * Breaks a string into a list of pieces that will fit a specified width. + */ + public List listFormattedStringToWidth(String par1Str, int par2) { + return Arrays.asList(this.wrapFormattedStringToWidth(par1Str, par2).split("\n")); + } + + /** + * Inserts newline and formatting into a string to wrap it within the specified + * width. + */ + String wrapFormattedStringToWidth(String par1Str, int par2) { + int var3 = this.sizeStringToWidth(par1Str, par2); + + if (par1Str.length() <= var3) { + return par1Str; + } else { + String var4 = par1Str.substring(0, var3); + char var5 = par1Str.charAt(var3); + boolean var6 = var5 == 32 || var5 == 10; + String var7 = getFormatFromString(var4) + par1Str.substring(var3 + (var6 ? 1 : 0)); + return var4 + "\n" + this.wrapFormattedStringToWidth(var7, par2); + } + } + + /** + * Determines how many characters from the string will fit into the specified + * width. + */ + private int sizeStringToWidth(String par1Str, int par2) { + int var3 = par1Str.length(); + int var4 = 0; + int var5 = 0; + int var6 = -1; + + for (boolean var7 = false; var5 < var3; ++var5) { + char var8 = par1Str.charAt(var5); + + switch (var8) { + case 10: + --var5; + break; + + case 167: + if (var5 < var3 - 1) { + ++var5; + char var9 = par1Str.charAt(var5); + + if (var9 != 108 && var9 != 76) { + if (var9 == 114 || var9 == 82 || isFormatColor(var9)) { + var7 = false; + } + } else { + var7 = true; + } + } + + break; + + case 32: + var6 = var5; + + default: + var4 += this.getCharWidth(var8); + + if (var7) { + ++var4; + } + } + + if (var8 == 10) { + ++var5; + var6 = var5; + break; + } + + if (var4 > par2) { + break; + } + } + + return var5 != var3 && var6 != -1 && var6 < var5 ? var6 : var5; + } + + /** + * Checks if the char code is a hexadecimal character, used to set colour. + */ + private static boolean isFormatColor(char par0) { + return par0 >= 48 && par0 <= 57 || par0 >= 97 && par0 <= 102 || par0 >= 65 && par0 <= 70; + } + + /** + * Checks if the char code is O-K...lLrRk-o... used to set special formatting. + */ + private static boolean isFormatSpecial(char par0) { + return par0 >= 107 && par0 <= 111 || par0 >= 75 && par0 <= 79 || par0 == 114 || par0 == 82; + } + + /** + * Digests a string for nonprinting formatting characters then returns a string + * containing only that formatting. + */ + private static String getFormatFromString(String par0Str) { + String var1 = ""; + int var2 = -1; + int var3 = par0Str.length(); + + while ((var2 = par0Str.indexOf(167, var2 + 1)) != -1) { + if (var2 < var3 - 1) { + char var4 = par0Str.charAt(var2 + 1); + + if (isFormatColor(var4)) { + var1 = "\u00a7" + var4; + } else if (isFormatSpecial(var4)) { + var1 = var1 + "\u00a7" + var4; + } + } + } + + return var1; + } + + /** + * Get bidiFlag that controls if the Unicode Bidirectional Algorithm should be + * run before rendering any string + */ + public boolean getBidiFlag() { + return this.bidiFlag; + } +} diff --git a/src/main/java/net/minecraft/src/FoodStats.java b/src/main/java/net/minecraft/src/FoodStats.java new file mode 100644 index 0000000..7a03def --- /dev/null +++ b/src/main/java/net/minecraft/src/FoodStats.java @@ -0,0 +1,134 @@ +package net.minecraft.src; + + + +public class FoodStats { + /** The player's food level. */ + private int foodLevel = 20; + + /** The player's food saturation. */ + private float foodSaturationLevel = 5.0F; + + /** The player's food exhaustion. */ + private float foodExhaustionLevel; + + /** The player's food timer value. */ + private int foodTimer = 0; + private int prevFoodLevel = 20; + + /** + * Args: int foodLevel, float foodSaturationModifier + */ + public void addStats(int par1, float par2) { + this.foodLevel = Math.min(par1 + this.foodLevel, 20); + this.foodSaturationLevel = Math.min(this.foodSaturationLevel + (float) par1 * par2 * 2.0F, (float) this.foodLevel); + } + + /** + * Eat some food. + */ + public void addStats(ItemFood par1ItemFood) { + this.addStats(par1ItemFood.getHealAmount(), par1ItemFood.getSaturationModifier()); + } + + /** + * Handles the food game logic. + */ + public void onUpdate(EntityPlayer par1EntityPlayer) { + int var2 = par1EntityPlayer.worldObj.difficultySetting; + this.prevFoodLevel = this.foodLevel; + + if (this.foodExhaustionLevel > 4.0F) { + this.foodExhaustionLevel -= 4.0F; + + if (this.foodSaturationLevel > 0.0F) { + this.foodSaturationLevel = Math.max(this.foodSaturationLevel - 1.0F, 0.0F); + } else if (var2 > 0) { + this.foodLevel = Math.max(this.foodLevel - 1, 0); + } + } + + if (this.foodLevel >= 18 && par1EntityPlayer.shouldHeal()) { + ++this.foodTimer; + + if (this.foodTimer >= 80) { + par1EntityPlayer.heal(1); + this.foodTimer = 0; + } + } else if (this.foodLevel <= 0) { + ++this.foodTimer; + + if (this.foodTimer >= 80) { + if (par1EntityPlayer.getHealth() > 10 || var2 >= 3 || par1EntityPlayer.getHealth() > 1 && var2 >= 2) { + par1EntityPlayer.attackEntityFrom(DamageSource.starve, 1); + } + + this.foodTimer = 0; + } + } else { + this.foodTimer = 0; + } + } + + /** + * Reads food stats from an NBT object. + */ + public void readNBT(NBTTagCompound par1NBTTagCompound) { + if (par1NBTTagCompound.hasKey("foodLevel")) { + this.foodLevel = par1NBTTagCompound.getInteger("foodLevel"); + this.foodTimer = par1NBTTagCompound.getInteger("foodTickTimer"); + this.foodSaturationLevel = par1NBTTagCompound.getFloat("foodSaturationLevel"); + this.foodExhaustionLevel = par1NBTTagCompound.getFloat("foodExhaustionLevel"); + } + } + + /** + * Writes food stats to an NBT object. + */ + public void writeNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setInteger("foodLevel", this.foodLevel); + par1NBTTagCompound.setInteger("foodTickTimer", this.foodTimer); + par1NBTTagCompound.setFloat("foodSaturationLevel", this.foodSaturationLevel); + par1NBTTagCompound.setFloat("foodExhaustionLevel", this.foodExhaustionLevel); + } + + /** + * Get the player's food level. + */ + public int getFoodLevel() { + return this.foodLevel; + } + + public int getPrevFoodLevel() { + return this.prevFoodLevel; + } + + /** + * If foodLevel is not max. + */ + public boolean needFood() { + return this.foodLevel < 20; + } + + /** + * adds input to foodExhaustionLevel to a max of 40 + */ + public void addExhaustion(float par1) { + this.foodExhaustionLevel = Math.min(this.foodExhaustionLevel + par1, 40.0F); + } + + /** + * Get the player's food saturation level. + */ + public float getSaturationLevel() { + return this.foodSaturationLevel; + } + + public void setFoodLevel(int par1) { + this.foodLevel = par1; + } + + public void setFoodSaturationLevel(float par1) { + this.foodSaturationLevel = par1; + } +} diff --git a/src/main/java/net/minecraft/src/Frustrum.java b/src/main/java/net/minecraft/src/Frustrum.java new file mode 100644 index 0000000..120e305 --- /dev/null +++ b/src/main/java/net/minecraft/src/Frustrum.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +public class Frustrum implements ICamera { + private ClippingHelper clippingHelper = ClippingHelperImpl.getInstance(); + private double xPosition; + private double yPosition; + private double zPosition; + + public void setPosition(double par1, double par3, double par5) { + this.xPosition = par1; + this.yPosition = par3; + this.zPosition = par5; + } + + /** + * Calls the clipping helper. Returns true if the box is inside all 6 clipping + * planes, otherwise returns false. + */ + public boolean isBoxInFrustum(double par1, double par3, double par5, double par7, double par9, double par11) { + return this.clippingHelper.isBoxInFrustum(par1 - this.xPosition, par3 - this.yPosition, par5 - this.zPosition, par7 - this.xPosition, par9 - this.yPosition, par11 - this.zPosition); + } + + /** + * Returns true if the bounding box is inside all 6 clipping planes, otherwise + * returns false. + */ + public boolean isBoundingBoxInFrustum(AxisAlignedBB par1AxisAlignedBB) { + return this.isBoxInFrustum(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ, par1AxisAlignedBB.maxX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.maxZ); + } +} diff --git a/src/main/java/net/minecraft/src/FurnaceRecipes.java b/src/main/java/net/minecraft/src/FurnaceRecipes.java new file mode 100644 index 0000000..c1f39b5 --- /dev/null +++ b/src/main/java/net/minecraft/src/FurnaceRecipes.java @@ -0,0 +1,64 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.Map; + +public class FurnaceRecipes { + private static final FurnaceRecipes smeltingBase = new FurnaceRecipes(); + + /** The list of smelting results. */ + private Map smeltingList = new HashMap(); + private Map experienceList = new HashMap(); + + /** + * Used to call methods addSmelting and getSmeltingResult. + */ + public static final FurnaceRecipes smelting() { + return smeltingBase; + } + + private FurnaceRecipes() { + this.addSmelting(Block.oreIron.blockID, new ItemStack(Item.ingotIron), 0.7F); + this.addSmelting(Block.oreGold.blockID, new ItemStack(Item.ingotGold), 1.0F); + this.addSmelting(Block.oreDiamond.blockID, new ItemStack(Item.diamond), 1.0F); + this.addSmelting(Block.sand.blockID, new ItemStack(Block.glass), 0.1F); + this.addSmelting(Item.porkRaw.itemID, new ItemStack(Item.porkCooked), 0.35F); + this.addSmelting(Item.beefRaw.itemID, new ItemStack(Item.beefCooked), 0.35F); + this.addSmelting(Item.chickenRaw.itemID, new ItemStack(Item.chickenCooked), 0.35F); + this.addSmelting(Item.fishRaw.itemID, new ItemStack(Item.fishCooked), 0.35F); + this.addSmelting(Block.cobblestone.blockID, new ItemStack(Block.stone), 0.1F); + this.addSmelting(Item.clay.itemID, new ItemStack(Item.brick), 0.3F); + this.addSmelting(Block.cactus.blockID, new ItemStack(Item.dyePowder, 1, 2), 0.2F); + this.addSmelting(Block.wood.blockID, new ItemStack(Item.coal, 1, 1), 0.15F); + this.addSmelting(Block.oreEmerald.blockID, new ItemStack(Item.emerald), 1.0F); + this.addSmelting(Item.potato.itemID, new ItemStack(Item.bakedPotato), 0.35F); + this.addSmelting(Block.netherrack.blockID, new ItemStack(Item.netherrackBrick), 0.1F); + this.addSmelting(Block.oreCoal.blockID, new ItemStack(Item.coal), 0.1F); + this.addSmelting(Block.oreRedstone.blockID, new ItemStack(Item.redstone), 0.7F); + this.addSmelting(Block.oreLapis.blockID, new ItemStack(Item.dyePowder, 1, 4), 0.2F); + this.addSmelting(Block.oreNetherQuartz.blockID, new ItemStack(Item.netherQuartz), 0.2F); + } + + /** + * Adds a smelting recipe. + */ + public void addSmelting(int par1, ItemStack par2ItemStack, float par3) { + this.smeltingList.put(Integer.valueOf(par1), par2ItemStack); + this.experienceList.put(Integer.valueOf(par2ItemStack.itemID), Float.valueOf(par3)); + } + + /** + * Returns the smelting result of an item. + */ + public ItemStack getSmeltingResult(int par1) { + return (ItemStack) this.smeltingList.get(Integer.valueOf(par1)); + } + + public Map getSmeltingList() { + return this.smeltingList; + } + + public float getExperience(int par1) { + return this.experienceList.containsKey(Integer.valueOf(par1)) ? ((Float) this.experienceList.get(Integer.valueOf(par1))).floatValue() : 0.0F; + } +} diff --git a/src/main/java/net/minecraft/src/GLAllocation.java b/src/main/java/net/minecraft/src/GLAllocation.java new file mode 100644 index 0000000..0380efa --- /dev/null +++ b/src/main/java/net/minecraft/src/GLAllocation.java @@ -0,0 +1,90 @@ +package net.minecraft.src; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import net.lax1dude.eaglercraft.ConfigConstants; +import net.lax1dude.eaglercraft.EaglerAdapter; + +public class GLAllocation { + private static final Map field_74531_a = new HashMap(); + private static final List field_74530_b = new ArrayList(); + + /** + * Generates the specified number of display lists and returns the first index. + */ + public static synchronized int generateDisplayLists(int par0) { + int var1 = EaglerAdapter.glGenLists(par0); + field_74531_a.put(Integer.valueOf(var1), Integer.valueOf(par0)); + return var1; + } + + /** + * Generates texture names and stores them in the specified buffer. + */ + public static synchronized int generateTextureNames() { + int var0 = EaglerAdapter.glGenTextures(); + field_74530_b.add(Integer.valueOf(var0)); + return var0; + } + + public static synchronized void deleteDisplayLists(int par0) { + EaglerAdapter.glDeleteLists(par0, ((Integer) field_74531_a.remove(Integer.valueOf(par0))).intValue()); + } + + public static synchronized void func_98302_b() { + for (int var0 = 0; var0 < field_74530_b.size(); ++var0) { + EaglerAdapter.glDeleteTextures(((Integer) field_74530_b.get(var0)).intValue()); + } + + field_74530_b.clear(); + } + + /** + * Deletes all textures and display lists. Called when Minecraft is shutdown to + * free up resources. + */ + public static synchronized void deleteTexturesAndDisplayLists() { + Iterator var0 = field_74531_a.entrySet().iterator(); + + while (var0.hasNext()) { + Entry var1 = (Entry) var0.next(); + EaglerAdapter.glDeleteLists(((Integer) var1.getKey()).intValue(), ((Integer) var1.getValue()).intValue()); + } + + field_74531_a.clear(); + func_98302_b(); + } + + /** + * Creates and returns a direct byte buffer with the specified capacity. Applies + * native ordering to speed up access. + */ + public static synchronized ByteBuffer createDirectByteBuffer(int par0) { + return EaglerAdapter.isWebGL ? ByteBuffer.wrap(new byte[par0]).order(ByteOrder.nativeOrder()) : ByteBuffer.allocateDirect(par0).order(ByteOrder.nativeOrder()); + } + + /** + * Creates and returns a direct int buffer with the specified capacity. Applies + * native ordering to speed up access. + */ + public static IntBuffer createDirectIntBuffer(int par0) { + return EaglerAdapter.isWebGL ? IntBuffer.wrap(new int[par0]) : createDirectByteBuffer(par0 << 2).asIntBuffer(); + } + + /** + * Creates and returns a direct float buffer with the specified capacity. + * Applies native ordering to speed up access. + */ + public static FloatBuffer createDirectFloatBuffer(int par0) { + return EaglerAdapter.isWebGL ? FloatBuffer.wrap(new float[par0]) : createDirectByteBuffer(par0 << 2).asFloatBuffer(); + } +} diff --git a/src/main/java/net/minecraft/src/GameRuleValue.java b/src/main/java/net/minecraft/src/GameRuleValue.java new file mode 100644 index 0000000..d5e1fa8 --- /dev/null +++ b/src/main/java/net/minecraft/src/GameRuleValue.java @@ -0,0 +1,46 @@ +package net.minecraft.src; + +class GameRuleValue { + private String valueString; + private boolean valueBoolean; + private int valueInteger; + private double valueDouble; + + public GameRuleValue(String par1Str) { + this.setValue(par1Str); + } + + /** + * Set this game rule value. + */ + public void setValue(String par1Str) { + this.valueString = par1Str; + this.valueBoolean = Boolean.parseBoolean(par1Str); + + try { + this.valueInteger = Integer.parseInt(par1Str); + } catch (NumberFormatException var4) { + ; + } + + try { + this.valueDouble = Double.parseDouble(par1Str); + } catch (NumberFormatException var3) { + ; + } + } + + /** + * Gets the GameRule's value as String. + */ + public String getGameRuleStringValue() { + return this.valueString; + } + + /** + * Gets the GameRule's value as boolean. + */ + public boolean getGameRuleBooleanValue() { + return this.valueBoolean; + } +} diff --git a/src/main/java/net/minecraft/src/GameRules.java b/src/main/java/net/minecraft/src/GameRules.java new file mode 100644 index 0000000..2061fb1 --- /dev/null +++ b/src/main/java/net/minecraft/src/GameRules.java @@ -0,0 +1,97 @@ +package net.minecraft.src; + +import java.util.Collection; +import java.util.Iterator; +import java.util.TreeMap; + +public class GameRules { + private TreeMap theGameRules = new TreeMap(); + + public GameRules() { + this.addGameRule("doFireTick", "true"); + this.addGameRule("mobGriefing", "true"); + this.addGameRule("keepInventory", "false"); + this.addGameRule("doMobSpawning", "true"); + this.addGameRule("doMobLoot", "true"); + this.addGameRule("doTileDrops", "true"); + this.addGameRule("commandBlockOutput", "true"); + } + + /** + * Define a game rule and its default value. + */ + public void addGameRule(String par1Str, String par2Str) { + this.theGameRules.put(par1Str, new GameRuleValue(par2Str)); + } + + public void setOrCreateGameRule(String par1Str, String par2Str) { + GameRuleValue var3 = (GameRuleValue) this.theGameRules.get(par1Str); + + if (var3 != null) { + var3.setValue(par2Str); + } else { + this.addGameRule(par1Str, par2Str); + } + } + + /** + * Gets the string Game Rule value. + */ + public String getGameRuleStringValue(String par1Str) { + GameRuleValue var2 = (GameRuleValue) this.theGameRules.get(par1Str); + return var2 != null ? var2.getGameRuleStringValue() : ""; + } + + /** + * Gets the boolean Game Rule value. + */ + public boolean getGameRuleBooleanValue(String par1Str) { + GameRuleValue var2 = (GameRuleValue) this.theGameRules.get(par1Str); + return var2 != null ? var2.getGameRuleBooleanValue() : false; + } + + /** + * Return the defined game rules as NBT. + */ + public NBTTagCompound writeGameRulesToNBT() { + NBTTagCompound var1 = new NBTTagCompound("GameRules"); + Iterator var2 = this.theGameRules.keySet().iterator(); + + while (var2.hasNext()) { + String var3 = (String) var2.next(); + GameRuleValue var4 = (GameRuleValue) this.theGameRules.get(var3); + var1.setString(var3, var4.getGameRuleStringValue()); + } + + return var1; + } + + /** + * Set defined game rules from NBT. + */ + public void readGameRulesFromNBT(NBTTagCompound par1NBTTagCompound) { + Collection var2 = par1NBTTagCompound.getTags(); + Iterator var3 = var2.iterator(); + + while (var3.hasNext()) { + NBTBase var4 = (NBTBase) var3.next(); + String var5 = var4.getName(); + String var6 = par1NBTTagCompound.getString(var4.getName()); + this.setOrCreateGameRule(var5, var6); + } + } + + /** + * Return the defined game rules. + */ + public String[] getRules() { + return (String[]) this.theGameRules.keySet().toArray(new String[0]); + } + + /** + * Return whether the specified game rule is defined. + */ + public boolean hasRule(String par1Str) { + return this.theGameRules.containsKey(par1Str); + } +} diff --git a/src/main/java/net/minecraft/src/GameSettings.java b/src/main/java/net/minecraft/src/GameSettings.java new file mode 100644 index 0000000..4a1e193 --- /dev/null +++ b/src/main/java/net/minecraft/src/GameSettings.java @@ -0,0 +1,573 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.LocalStorageManager; +import net.minecraft.client.Minecraft; + +public class GameSettings { + private static final String[] RENDER_DISTANCES = new String[] { "options.renderDistance.far", "options.renderDistance.normal", "options.renderDistance.short", "options.renderDistance.tiny" }; + private static final String[] DIFFICULTIES = new String[] { "options.difficulty.peaceful", "options.difficulty.easy", "options.difficulty.normal", "options.difficulty.hard" }; + + /** GUI scale values */ + private static final String[] GUISCALES = new String[] { "options.guiScale.auto", "options.guiScale.small", "options.guiScale.normal", "options.guiScale.large" }; + private static final String[] CHAT_VISIBILITIES = new String[] { "options.chat.visibility.full", "options.chat.visibility.system", "options.chat.visibility.hidden" }; + private static final String[] PARTICLES = new String[] { "options.particles.all", "options.particles.decreased", "options.particles.minimal" }; + + /** Limit framerate labels */ + private static final String[] LIMIT_FRAMERATES = new String[] { "performance.max", "performance.balanced", "performance.powersaver" }; + private static final String[] AMBIENT_OCCLUSIONS = new String[] { "options.ao.off", "options.ao.min", "options.ao.max" }; + private static final String[] ANTIALIASING = new String[] { "options.framebufferAntialias.none", "options.framebufferAntialias.auto", "options.framebufferAntialias.fxaa" , "options.framebufferAntialias.msaa4", "options.framebufferAntialias.msaa8" }; + public float musicVolume = 0.0F; + public float soundVolume = 1.0F; + public float mouseSensitivity = 0.5F; + public boolean invertMouse = false; + public int renderDistance = 1; + public boolean viewBobbing = true; + public boolean anaglyph = false; + + /** Advanced OpenGL */ + public boolean advancedOpengl = false; + public int limitFramerate = 1; + public boolean fancyGraphics = false; + public boolean enableFog = true; + + /** Smooth Lighting */ + public int ambientOcclusion = 0; + + /** Clouds flag */ + public boolean clouds = false; + + /** The name of the selected texture pack. */ + public String skin = "Default"; + public int chatVisibility = 0; + public boolean chatColours = true; + public boolean chatLinks = true; + public boolean chatLinksPrompt = true; + public float chatOpacity = 1.0F; + public boolean serverTextures = true; + public boolean snooperEnabled = false; + public boolean fullScreen = false; + public boolean enableVsync = true; + public boolean hideServerAddress = false; + + /** + * Whether to show advanced information on item tooltips, toggled by F3+H + */ + public boolean advancedItemTooltips = false; + + /** Whether to pause when the game loses focus, toggled by F3+P */ + public boolean pauseOnLostFocus = true; + + /** Whether to show your cape */ + public boolean showCape = true; + public boolean touchscreen = false; + public int antialiasMode = 1; + public int overrideWidth = 0; + public int overrideHeight = 0; + public boolean heldItemTooltips = true; + public float chatScale = 1.0F; + public float chatWidth = 1.0F; + public float chatHeightUnfocused = 0.44366196F; + public float chatHeightFocused = 1.0F; + public KeyBinding keyBindForward = new KeyBinding("key.forward", 17); + public KeyBinding keyBindLeft = new KeyBinding("key.left", 30); + public KeyBinding keyBindBack = new KeyBinding("key.back", 31); + public KeyBinding keyBindRight = new KeyBinding("key.right", 32); + public KeyBinding keyBindJump = new KeyBinding("key.jump", 57); + public KeyBinding keyBindInventory = new KeyBinding("key.inventory", 18); + public KeyBinding keyBindDrop = new KeyBinding("key.drop", 16); + public KeyBinding keyBindChat = new KeyBinding("key.chat", 20); + public KeyBinding keyBindSneak = new KeyBinding("key.sneak", 42); + public KeyBinding keyBindAttack = new KeyBinding("key.attack", -100); + public KeyBinding keyBindUseItem = new KeyBinding("key.use", -99); + public KeyBinding keyBindPlayerList = new KeyBinding("key.playerlist", 15); + public KeyBinding keyBindPickBlock = new KeyBinding("key.pickItem", -98); + public KeyBinding keyBindSprint = new KeyBinding("key.sprint", 19); + public KeyBinding keyBindZoom = new KeyBinding("key.zoom", 46); + public KeyBinding keyBindFunction = new KeyBinding("key.function", 33); + public KeyBinding[] keyBindings; + protected Minecraft mc; + public int difficulty; + public boolean hideGUI; + public int thirdPersonView; + + /** true if debug info should be displayed instead of version */ + public boolean showDebugInfo; + public boolean showDebugProfilerChart; + + /** The lastServer string. */ + public String lastServer; + + /** No clipping for singleplayer */ + public boolean noclip; + + /** Smooth Camera Toggle */ + public boolean smoothCamera; + public boolean debugCamEnable; + + /** No clipping movement rate */ + public float noclipRate; + + /** Change rate for debug camera */ + public float debugCamRate; + public float fovSetting; + public float gammaSetting; + + /** GUI scale */ + public int guiScale; + + /** Determines amount of particles. 0 = All, 1 = Decreased, 2 = Minimal */ + public int particleSetting; + + /** Game settings language */ + public String language; + + public GameSettings(Minecraft par1Minecraft) { + this.keyBindings = new KeyBinding[] { this.keyBindAttack, this.keyBindUseItem, this.keyBindForward, this.keyBindLeft, this.keyBindBack, this.keyBindRight, this.keyBindJump, this.keyBindSneak, this.keyBindDrop, this.keyBindInventory, + this.keyBindChat, this.keyBindPlayerList, this.keyBindPickBlock, this.keyBindSprint, this.keyBindZoom, this.keyBindFunction }; + this.difficulty = 2; + this.hideGUI = false; + this.thirdPersonView = 0; + this.showDebugInfo = false; + this.showDebugProfilerChart = true; + this.lastServer = ""; + this.noclip = false; + this.smoothCamera = false; + this.debugCamEnable = false; + this.noclipRate = 1.0F; + this.debugCamRate = 1.0F; + this.fovSetting = 0.0F; + this.gammaSetting = 1.0F; + this.guiScale = 3; + this.particleSetting = 0; + this.language = "en_US"; + this.mc = par1Minecraft; + this.loadOptions(); + } + + public String getKeyBindingDescription(int par1) { + StringTranslate var2 = StringTranslate.getInstance(); + return var2.translateKey(this.keyBindings[par1].keyDescription); + } + + /** + * The string that appears inside the button/slider in the options menu. + */ + public String getOptionDisplayString(int par1) { + int var2 = this.keyBindings[par1].keyCode; + return getKeyDisplayString(var2); + } + + /** + * Represents a key or mouse button as a string. Args: key + */ + public static String getKeyDisplayString(int par0) { + return par0 < 0 ? StatCollector.translateToLocalFormatted("key.mouseButton", new Object[] { Integer.valueOf(par0 + 101) }) : EaglerAdapter.getKeyName(par0); + } + + /** + * Returns whether the specified key binding is currently being pressed. + */ + public static boolean isKeyDown(KeyBinding par0KeyBinding) { + return par0KeyBinding.keyCode < 0 ? EaglerAdapter.mouseIsButtonDown(par0KeyBinding.keyCode + 100) : EaglerAdapter.isKeyDown(par0KeyBinding.keyCode); + } + + /** + * Sets a key binding. + */ + public void setKeyBinding(int par1, int par2) { + this.keyBindings[par1].keyCode = par2; + this.saveOptions(); + } + + /** + * If the specified option is controlled by a slider (float value), this will + * set the float value. + */ + public void setOptionFloatValue(EnumOptions par1EnumOptions, float par2) { + if (par1EnumOptions == EnumOptions.MUSIC) { + this.musicVolume = par2; + this.mc.sndManager.onSoundOptionsChanged(); + } + + if (par1EnumOptions == EnumOptions.SOUND) { + this.soundVolume = par2; + this.mc.sndManager.onSoundOptionsChanged(); + } + + if (par1EnumOptions == EnumOptions.SENSITIVITY) { + this.mouseSensitivity = par2; + } + + if (par1EnumOptions == EnumOptions.FOV) { + this.fovSetting = par2; + } + + if (par1EnumOptions == EnumOptions.GAMMA) { + this.gammaSetting = par2; + } + + if (par1EnumOptions == EnumOptions.CHAT_OPACITY) { + this.chatOpacity = par2; + this.mc.ingameGUI.getChatGUI().func_96132_b(); + } + + if (par1EnumOptions == EnumOptions.CHAT_HEIGHT_FOCUSED) { + this.chatHeightFocused = par2; + this.mc.ingameGUI.getChatGUI().func_96132_b(); + } + + if (par1EnumOptions == EnumOptions.CHAT_HEIGHT_UNFOCUSED) { + this.chatHeightUnfocused = par2; + this.mc.ingameGUI.getChatGUI().func_96132_b(); + } + + if (par1EnumOptions == EnumOptions.CHAT_WIDTH) { + this.chatWidth = par2; + this.mc.ingameGUI.getChatGUI().func_96132_b(); + } + + if (par1EnumOptions == EnumOptions.CHAT_SCALE) { + this.chatScale = par2; + this.mc.ingameGUI.getChatGUI().func_96132_b(); + } + } + + /** + * For non-float options. Toggles the option on/off, or cycles through the list + * i.e. render distances. + */ + public void setOptionValue(EnumOptions par1EnumOptions, int par2) { + if (par1EnumOptions == EnumOptions.INVERT_MOUSE) { + this.invertMouse = !this.invertMouse; + } + + if (par1EnumOptions == EnumOptions.RENDER_DISTANCE) { + this.renderDistance = this.renderDistance + par2 & 3; + } + + if (par1EnumOptions == EnumOptions.GUI_SCALE) { + this.guiScale = this.guiScale + par2 & 3; + } + + if (par1EnumOptions == EnumOptions.PARTICLES) { + this.particleSetting = (this.particleSetting + par2) % 3; + } + + if (par1EnumOptions == EnumOptions.VIEW_BOBBING) { + this.viewBobbing = !this.viewBobbing; + } + + if (par1EnumOptions == EnumOptions.RENDER_CLOUDS) { + this.clouds = !this.clouds; + } + + if (par1EnumOptions == EnumOptions.ENABLE_FOG) { + this.enableFog = !this.enableFog; + } + + if (par1EnumOptions == EnumOptions.ANAGLYPH) { + this.anaglyph = !this.anaglyph; + this.mc.renderEngine.refreshTextures(); + } + + if (par1EnumOptions == EnumOptions.FRAMERATE_LIMIT) { + this.limitFramerate = (this.limitFramerate + par2 + 3) % 3; + } + + if (par1EnumOptions == EnumOptions.DIFFICULTY) { + this.difficulty = this.difficulty + par2 & 3; + } + + if (par1EnumOptions == EnumOptions.GRAPHICS) { + this.fancyGraphics = !this.fancyGraphics; + this.mc.renderGlobal.loadRenderers(); + } + + if (par1EnumOptions == EnumOptions.AMBIENT_OCCLUSION) { + this.ambientOcclusion = (this.ambientOcclusion + par2) % 3; + this.mc.renderGlobal.loadRenderers(); + } + + if (par1EnumOptions == EnumOptions.CHAT_VISIBILITY) { + this.chatVisibility = (this.chatVisibility + par2) % 3; + } + + if (par1EnumOptions == EnumOptions.CHAT_COLOR) { + this.chatColours = !this.chatColours; + } + + if (par1EnumOptions == EnumOptions.CHAT_LINKS) { + this.chatLinks = !this.chatLinks; + } + + if (par1EnumOptions == EnumOptions.CHAT_LINKS_PROMPT) { + this.chatLinksPrompt = !this.chatLinksPrompt; + } + + if (par1EnumOptions == EnumOptions.USE_SERVER_TEXTURES) { + this.serverTextures = !this.serverTextures; + } + + if (par1EnumOptions == EnumOptions.SNOOPER_ENABLED) { + this.snooperEnabled = !this.snooperEnabled; + } + + if (par1EnumOptions == EnumOptions.SHOW_CAPE) { + this.showCape = !this.showCape; + } + + if (par1EnumOptions == EnumOptions.ANTIALIASING) { + this.antialiasMode = (this.antialiasMode + par2) % 5; + } + + if (par1EnumOptions == EnumOptions.USE_FULLSCREEN) { + this.fullScreen = !this.fullScreen; + + if (this.mc.isFullScreen() != this.fullScreen) { + this.mc.toggleFullscreen(); + } + } + + if (par1EnumOptions == EnumOptions.ENABLE_VSYNC) { + this.enableVsync = !this.enableVsync; + EaglerAdapter.setVSyncEnabled(this.enableVsync); + } + + this.saveOptions(); + } + + public float getOptionFloatValue(EnumOptions par1EnumOptions) { + return par1EnumOptions == EnumOptions.FOV ? this.fovSetting + : (par1EnumOptions == EnumOptions.GAMMA ? this.gammaSetting + : (par1EnumOptions == EnumOptions.MUSIC ? this.musicVolume + : (par1EnumOptions == EnumOptions.SOUND ? this.soundVolume + : (par1EnumOptions == EnumOptions.SENSITIVITY ? this.mouseSensitivity + : (par1EnumOptions == EnumOptions.CHAT_OPACITY ? this.chatOpacity + : (par1EnumOptions == EnumOptions.CHAT_HEIGHT_FOCUSED ? this.chatHeightFocused + : (par1EnumOptions == EnumOptions.CHAT_HEIGHT_UNFOCUSED ? this.chatHeightUnfocused + : (par1EnumOptions == EnumOptions.CHAT_SCALE ? this.chatScale : (par1EnumOptions == EnumOptions.CHAT_WIDTH ? this.chatWidth : 0.0F))))))))); + } + + public boolean getOptionOrdinalValue(EnumOptions par1EnumOptions) { + switch (EnumOptionsHelper.enumOptionsMappingHelperArray[par1EnumOptions.ordinal()]) { + case 1: + return this.invertMouse; + + case 2: + return this.viewBobbing; + + case 3: + return this.anaglyph; + + case 4: + return this.advancedOpengl; + + case 5: + return this.clouds; + + case 6: + return this.chatColours; + + case 7: + return this.chatLinks; + + case 8: + return this.chatLinksPrompt; + + case 9: + return this.serverTextures; + + case 10: + return this.snooperEnabled; + + case 11: + return this.fullScreen; + + case 12: + return this.enableVsync; + + case 13: + return this.showCape; + + case 14: + return this.touchscreen; + + case 15: + return this.enableFog; + + default: + return false; + } + } + + /** + * Returns the translation of the given index in the given String array. If the + * index is smaller than 0 or greater than/equal to the length of the String + * array, it is changed to 0. + */ + private static String getTranslation(String[] par0ArrayOfStr, int par1) { + if (par1 < 0 || par1 >= par0ArrayOfStr.length) { + par1 = 0; + } + + StringTranslate var2 = StringTranslate.getInstance(); + return var2.translateKey(par0ArrayOfStr[par1]); + } + + /** + * Gets a key binding. + */ + public String getKeyBinding(EnumOptions par1EnumOptions) { + StringTranslate var2 = StringTranslate.getInstance(); + String var3 = var2.translateKey(par1EnumOptions.getEnumString()) + ": "; + + if (par1EnumOptions.getEnumFloat()) { + float var5 = this.getOptionFloatValue(par1EnumOptions); + return par1EnumOptions == EnumOptions.SENSITIVITY ? (var5 == 0.0F ? var3 + var2.translateKey("options.sensitivity.min") : (var5 == 1.0F ? var3 + var2.translateKey("options.sensitivity.max") : var3 + (int) (var5 * 200.0F) + "%")) + : (par1EnumOptions == EnumOptions.FOV ? (var5 == 0.0F ? var3 + var2.translateKey("options.fov.min") : (var5 == 1.0F ? var3 + var2.translateKey("options.fov.max") : var3 + (int) (70.0F + var5 * 40.0F))) + : (par1EnumOptions == EnumOptions.GAMMA ? (var5 == 0.0F ? var3 + var2.translateKey("options.gamma.min") : (var5 == 1.0F ? var3 + var2.translateKey("options.gamma.max") : var3 + "+" + (int) (var5 * 100.0F) + "%")) + : (par1EnumOptions == EnumOptions.CHAT_OPACITY ? var3 + (int) (var5 * 90.0F + 10.0F) + "%" + : (par1EnumOptions == EnumOptions.CHAT_HEIGHT_UNFOCUSED ? var3 + GuiNewChat.func_96130_b(var5) + "px" + : (par1EnumOptions == EnumOptions.CHAT_HEIGHT_FOCUSED ? var3 + GuiNewChat.func_96130_b(var5) + "px" + : (par1EnumOptions == EnumOptions.CHAT_WIDTH ? var3 + GuiNewChat.func_96128_a(var5) + "px" + : (var5 == 0.0F ? var3 + var2.translateKey("options.off") : var3 + (int) (var5 * 100.0F) + "%"))))))); + } else if (par1EnumOptions.getEnumBoolean()) { + boolean var4 = this.getOptionOrdinalValue(par1EnumOptions); + return var4 ? var3 + var2.translateKey("options.on") : var3 + var2.translateKey("options.off"); + } else { + return par1EnumOptions == EnumOptions.RENDER_DISTANCE ? var3 + getTranslation(RENDER_DISTANCES, this.renderDistance) + : (par1EnumOptions == EnumOptions.DIFFICULTY ? var3 + getTranslation(DIFFICULTIES, this.difficulty) + : (par1EnumOptions == EnumOptions.GUI_SCALE ? var3 + getTranslation(GUISCALES, this.guiScale) + : (par1EnumOptions == EnumOptions.CHAT_VISIBILITY ? var3 + getTranslation(CHAT_VISIBILITIES, this.chatVisibility) + : (par1EnumOptions == EnumOptions.PARTICLES ? var3 + getTranslation(PARTICLES, this.particleSetting) + : (par1EnumOptions == EnumOptions.FRAMERATE_LIMIT ? var3 + getTranslation(LIMIT_FRAMERATES, this.limitFramerate) + : (par1EnumOptions == EnumOptions.AMBIENT_OCCLUSION ? var3 + getTranslation(AMBIENT_OCCLUSIONS, this.ambientOcclusion) + : (par1EnumOptions == EnumOptions.ANTIALIASING ? var3 + getTranslation(ANTIALIASING, this.antialiasMode) + : (par1EnumOptions == EnumOptions.GRAPHICS ? (this.fancyGraphics ? var3 + var2.translateKey("options.graphics.fancy") : var3 + var2.translateKey("options.graphics.fast")) + : var3)))))))); + } + } + + /** + * Loads the options from the options file. It appears that this has replaced + * the previous 'loadOptions' + */ + public void loadOptions() { + NBTTagCompound yee = LocalStorageManager.gameSettingsStorage; + if(!yee.hasNoTags()) { + if(yee.hasKey("musicVolume")) this.musicVolume = yee.getFloat("musicVolume"); + if(yee.hasKey("soundVolume")) this.soundVolume = yee.getFloat("soundVolume"); + if(yee.hasKey("sensitivity")) this.mouseSensitivity = yee.getFloat("sensitivity"); + if(yee.hasKey("fov")) this.fovSetting = yee.getFloat("fov"); + if(yee.hasKey("gamma")) this.gammaSetting = yee.getFloat("gamma"); + if(yee.hasKey("invertMouse")) this.invertMouse = yee.getBoolean("invertMouse"); + if(yee.hasKey("viewDistance")) this.renderDistance = yee.getInteger("viewDistance"); + if(yee.hasKey("guiScale")) this.guiScale = yee.getInteger("guiScale"); + if(yee.hasKey("particles")) this.particleSetting = yee.getInteger("particles"); + if(yee.hasKey("viewBobbing")) this.viewBobbing = yee.getBoolean("viewBobbing"); + if(yee.hasKey("anaglyph")) this.anaglyph = yee.getBoolean("anaglyph"); + if(yee.hasKey("limitFramerate")) this.limitFramerate = yee.getInteger("limitFramerate"); + if(yee.hasKey("fancyGraphics")) this.fancyGraphics = yee.getBoolean("fancyGraphics"); + if(yee.hasKey("ambientOcclusion")) this.ambientOcclusion = yee.getInteger("ambientOcclusion"); + if(yee.hasKey("clouds")) this.clouds = yee.getBoolean("clouds"); + if(yee.hasKey("fog")) this.enableFog = yee.getBoolean("fog"); + if(yee.hasKey("lastServer")) this.lastServer = yee.getString("lastServer"); + if(yee.hasKey("language")) this.language = yee.getString("language"); + if(yee.hasKey("chatVisibility")) this.chatVisibility = yee.getInteger("chatVisibility"); + if(yee.hasKey("chatColours")) this.chatColours = yee.getBoolean("chatColours"); + if(yee.hasKey("chatLinks")) this.chatLinks = yee.getBoolean("chatLinks"); + if(yee.hasKey("chatLinksPrompt")) this.chatLinksPrompt = yee.getBoolean("chatLinksPrompt"); + if(yee.hasKey("chatOpacity")) this.chatOpacity = yee.getFloat("chatOpacity"); + if(yee.hasKey("fullScreen")) this.fullScreen = yee.getBoolean("fullScreen"); + if(yee.hasKey("hideServerAddress")) this.hideServerAddress = yee.getBoolean("hideServerAddress"); + if(yee.hasKey("advancedTooltips")) this.advancedItemTooltips = yee.getBoolean("advancedTooltips"); + if(yee.hasKey("pauseOnLostFocus")) this.pauseOnLostFocus = yee.getBoolean("pauseOnLostFocus"); + if(yee.hasKey("showCape")) this.showCape = yee.getBoolean("showCape"); + if(yee.hasKey("touchscreen")) this.touchscreen = yee.getBoolean("touchscreen"); + if(yee.hasKey("forceHeight")) this.overrideHeight = yee.getInteger("forceHeight"); + if(yee.hasKey("forceWidth")) this.overrideWidth = yee.getInteger("forceWidth"); + if(yee.hasKey("antialiasMode")) this.antialiasMode = yee.getInteger("antialiasMode"); + if(yee.hasKey("heldItemTooltips")) this.heldItemTooltips = yee.getBoolean("heldItemTooltips"); + if(yee.hasKey("chatHeightFocused")) this.chatHeightFocused = yee.getFloat("chatHeightFocused"); + if(yee.hasKey("chatHeightUnfocused")) this.chatHeightUnfocused = yee.getFloat("chatHeightUnfocused"); + if(yee.hasKey("chatScale")) this.chatScale = yee.getFloat("chatScale"); + if(yee.hasKey("chatWidth")) this.chatWidth = yee.getFloat("chatWidth"); + + for (int var4 = 0; var4 < this.keyBindings.length; ++var4) { + if(yee.hasKey(keyBindings[var4].keyDescription)) this.keyBindings[var4].keyCode = yee.getInteger(keyBindings[var4].keyDescription); + } + + KeyBinding.resetKeyBindingArrayAndHash(); + } + } + + /** + * Saves the options to the options file. + */ + public void saveOptions() { + NBTTagCompound yee = LocalStorageManager.gameSettingsStorage; + + yee.setFloat("musicVolume", this.musicVolume); + yee.setFloat("soundVolume", this.soundVolume); + yee.setFloat("sensitivity", this.mouseSensitivity); + yee.setFloat("fov", this.fovSetting); + yee.setFloat("gamma", this.gammaSetting); + yee.setBoolean("invertMouse", this.invertMouse); + yee.setInteger("viewDistance", this.renderDistance); + yee.setInteger("guiScale", this.guiScale); + yee.setInteger("particles", this.particleSetting); + yee.setBoolean("viewBobbing", this.viewBobbing); + yee.setBoolean("anaglyph", this.anaglyph); + yee.setInteger("limitFramerate", this.limitFramerate); + yee.setBoolean("fancyGraphics", this.fancyGraphics); + yee.setInteger("ambientOcclusion", this.ambientOcclusion); + yee.setBoolean("clouds", this.clouds); + yee.setBoolean("fog", this.enableFog); + yee.setString("lastServer", this.lastServer); + yee.setString("language", this.language); + yee.setInteger("chatVisibility", this.chatVisibility); + yee.setBoolean("chatColours", this.chatColours); + yee.setBoolean("chatLinks", this.chatLinks); + yee.setBoolean("chatLinksPrompt", this.chatLinksPrompt); + yee.setFloat("chatOpacity", this.chatOpacity); + yee.setBoolean("fullScreen", this.fullScreen); + yee.setBoolean("hideServerAddress", this.hideServerAddress); + yee.setBoolean("advancedTooltips", this.advancedItemTooltips); + yee.setBoolean("pauseOnLostFocus", this.pauseOnLostFocus); + yee.setBoolean("showCape", this.showCape); + yee.setBoolean("touchscreen", this.touchscreen); + yee.setInteger("forceHeight", this.overrideHeight); + yee.setInteger("forceWidth", this.overrideWidth); + yee.setInteger("antialiasMode", this.antialiasMode); + yee.setBoolean("heldItemTooltips", this.heldItemTooltips); + yee.setFloat("chatHeightFocused", this.chatHeightFocused); + yee.setFloat("chatHeightUnfocused", this.chatHeightUnfocused); + yee.setFloat("chatScale", this.chatScale); + yee.setFloat("chatWidth", this.chatWidth); + + for (int var4 = 0; var4 < this.keyBindings.length; ++var4) { + yee.setInteger(keyBindings[var4].keyDescription, keyBindings[var4].keyCode); + } + + LocalStorageManager.saveStorageG(); + + this.sendSettingsToServer(); + } + + /** + * Send a client info packet with settings information to the server + */ + public void sendSettingsToServer() { + if (this.mc.thePlayer != null) { + this.mc.thePlayer.sendQueue.addToSendQueue(new Packet204ClientInfo(this.language, this.renderDistance, this.chatVisibility, this.chatColours, this.difficulty, this.showCape)); + } + } + + /** + * Should render clouds + */ + public boolean shouldRenderClouds() { + return this.renderDistance < 2 && this.clouds; + } +} diff --git a/src/main/java/net/minecraft/src/Gui.java b/src/main/java/net/minecraft/src/Gui.java new file mode 100644 index 0000000..00b0260 --- /dev/null +++ b/src/main/java/net/minecraft/src/Gui.java @@ -0,0 +1,150 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class Gui { + protected float zLevel = 0.0F; + + protected void drawHorizontalLine(int par1, int par2, int par3, int par4) { + if (par2 < par1) { + int var5 = par1; + par1 = par2; + par2 = var5; + } + + drawRect(par1, par3, par2 + 1, par3 + 1, par4); + } + + protected void drawVerticalLine(int par1, int par2, int par3, int par4) { + if (par3 < par2) { + int var5 = par2; + par2 = par3; + par3 = var5; + } + + drawRect(par1, par2 + 1, par1 + 1, par3, par4); + } + + /** + * Draws a solid color rectangle with the specified coordinates and color. Args: + * x1, y1, x2, y2, color + */ + public static void drawRect(int par0, int par1, int par2, int par3, int par4) { + int var5; + + if (par0 < par2) { + var5 = par0; + par0 = par2; + par2 = var5; + } + + if (par1 < par3) { + var5 = par1; + par1 = par3; + par3 = var5; + } + + float var10 = (float) (par4 >> 24 & 255) / 255.0F; + float var6 = (float) (par4 >> 16 & 255) / 255.0F; + float var7 = (float) (par4 >> 8 & 255) / 255.0F; + float var8 = (float) (par4 & 255) / 255.0F; + Tessellator var9 = Tessellator.instance; + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glColor4f(var6, var7, var8, var10); + var9.startDrawingQuads(); + var9.addVertex((double) par0, (double) par3, 0.0D); + var9.addVertex((double) par2, (double) par3, 0.0D); + var9.addVertex((double) par2, (double) par1, 0.0D); + var9.addVertex((double) par0, (double) par1, 0.0D); + var9.draw(); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + } + + /** + * Draws a rectangle with a vertical gradient between the specified colors. + */ + protected void drawGradientRect(int par1, int par2, int par3, int par4, int par5, int par6) { + float var7 = (float) (par5 >> 24 & 255) / 255.0F; + float var8 = (float) (par5 >> 16 & 255) / 255.0F; + float var9 = (float) (par5 >> 8 & 255) / 255.0F; + float var10 = (float) (par5 & 255) / 255.0F; + float var11 = (float) (par6 >> 24 & 255) / 255.0F; + float var12 = (float) (par6 >> 16 & 255) / 255.0F; + float var13 = (float) (par6 >> 8 & 255) / 255.0F; + float var14 = (float) (par6 & 255) / 255.0F; + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glShadeModel(EaglerAdapter.GL_SMOOTH); + Tessellator var15 = Tessellator.instance; + var15.startDrawingQuads(); + var15.setColorRGBA_F(var8, var9, var10, var7); + var15.addVertex((double) par3, (double) par2, (double) this.zLevel); + var15.addVertex((double) par1, (double) par2, (double) this.zLevel); + var15.setColorRGBA_F(var12, var13, var14, var11); + var15.addVertex((double) par1, (double) par4, (double) this.zLevel); + var15.addVertex((double) par3, (double) par4, (double) this.zLevel); + var15.draw(); + EaglerAdapter.glShadeModel(EaglerAdapter.GL_FLAT); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + } + + /** + * Renders the specified text to the screen, center-aligned. + */ + public void drawCenteredString(FontRenderer par1FontRenderer, String par2Str, int par3, int par4, int par5) { + par1FontRenderer.drawStringWithShadow(par2Str, par3 - par1FontRenderer.getStringWidth(par2Str) / 2, par4, par5); + } + + /** + * Renders the specified text to the screen. + */ + public void drawString(FontRenderer par1FontRenderer, String par2Str, int par3, int par4, int par5) { + par1FontRenderer.drawStringWithShadow(par2Str, par3, par4, par5); + } + + /** + * Draws a textured rectangle at the stored z-value. Args: x, y, u, v, width, + * height + */ + public void drawTexturedModalRect(int par1, int par2, int par3, int par4, int par5, int par6) { + float var7 = 0.00390625F; + float var8 = 0.00390625F; + Tessellator var9 = Tessellator.instance; + var9.startDrawingQuads(); + var9.addVertexWithUV((double) (par1 + 0), (double) (par2 + par6), (double) this.zLevel, (double) ((float) (par3 + 0) * var7), (double) ((float) (par4 + par6) * var8)); + var9.addVertexWithUV((double) (par1 + par5), (double) (par2 + par6), (double) this.zLevel, (double) ((float) (par3 + par5) * var7), (double) ((float) (par4 + par6) * var8)); + var9.addVertexWithUV((double) (par1 + par5), (double) (par2 + 0), (double) this.zLevel, (double) ((float) (par3 + par5) * var7), (double) ((float) (par4 + 0) * var8)); + var9.addVertexWithUV((double) (par1 + 0), (double) (par2 + 0), (double) this.zLevel, (double) ((float) (par3 + 0) * var7), (double) ((float) (par4 + 0) * var8)); + var9.draw(); + } + + public static void static_drawTexturedModalRect(int par1, int par2, int par3, int par4, int par5, int par6) { + float var7 = 0.00390625F; + float var8 = 0.00390625F; + Tessellator var9 = Tessellator.instance; + var9.startDrawingQuads(); + var9.addVertexWithUV((double) (par1 + 0), (double) (par2 + par6), 0.0D, (double) ((float) (par3 + 0) * var7), (double) ((float) (par4 + par6) * var8)); + var9.addVertexWithUV((double) (par1 + par5), (double) (par2 + par6), 0.0D, (double) ((float) (par3 + par5) * var7), (double) ((float) (par4 + par6) * var8)); + var9.addVertexWithUV((double) (par1 + par5), (double) (par2 + 0), 0.0D, (double) ((float) (par3 + par5) * var7), (double) ((float) (par4 + 0) * var8)); + var9.addVertexWithUV((double) (par1 + 0), (double) (par2 + 0), 0.0D, (double) ((float) (par3 + 0) * var7), (double) ((float) (par4 + 0) * var8)); + var9.draw(); + } + + public void drawTexturedModelRectFromIcon(int par1, int par2, Icon par3Icon, int par4, int par5) { + Tessellator var6 = Tessellator.instance; + var6.startDrawingQuads(); + var6.addVertexWithUV((double) (par1 + 0), (double) (par2 + par5), (double) this.zLevel, (double) par3Icon.getMinU(), (double) par3Icon.getMaxV()); + var6.addVertexWithUV((double) (par1 + par4), (double) (par2 + par5), (double) this.zLevel, (double) par3Icon.getMaxU(), (double) par3Icon.getMaxV()); + var6.addVertexWithUV((double) (par1 + par4), (double) (par2 + 0), (double) this.zLevel, (double) par3Icon.getMaxU(), (double) par3Icon.getMinV()); + var6.addVertexWithUV((double) (par1 + 0), (double) (par2 + 0), (double) this.zLevel, (double) par3Icon.getMinU(), (double) par3Icon.getMinV()); + var6.draw(); + } +} diff --git a/src/main/java/net/minecraft/src/GuiAchievement.java b/src/main/java/net/minecraft/src/GuiAchievement.java new file mode 100644 index 0000000..dd4fe9f --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiAchievement.java @@ -0,0 +1,138 @@ +package net.minecraft.src; + +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiAchievement extends Gui { + /** Holds the instance of the game (Minecraft) */ + private Minecraft theGame; + + /** Holds the latest width scaled to fit the game window. */ + private int achievementWindowWidth; + + /** Holds the latest height scaled to fit the game window. */ + private int achievementWindowHeight; + private String achievementGetLocalText; + private String achievementStatName; + + /** Holds the achievement that will be displayed on the GUI. */ + private Achievement theAchievement; + private long achievementTime; + + /** + * Holds a instance of RenderItem, used to draw the achievement icons on screen + * (is based on ItemStack) + */ + private RenderItem itemRender; + private boolean haveAchiement; + + public GuiAchievement(Minecraft par1Minecraft) { + this.theGame = par1Minecraft; + this.itemRender = new RenderItem(); + } + + /** + * Queue a taken achievement to be displayed. + */ + public void queueTakenAchievement(Achievement par1Achievement) { + this.achievementGetLocalText = StatCollector.translateToLocal("achievement.get"); + this.achievementStatName = StatCollector.translateToLocal(par1Achievement.getName()); + this.achievementTime = Minecraft.getSystemTime(); + this.theAchievement = par1Achievement; + this.haveAchiement = false; + } + + /** + * Queue a information about a achievement to be displayed. + */ + public void queueAchievementInformation(Achievement par1Achievement) { + this.achievementGetLocalText = StatCollector.translateToLocal(par1Achievement.getName()); + this.achievementStatName = par1Achievement.getDescription(); + this.achievementTime = Minecraft.getSystemTime() - 2500L; + this.theAchievement = par1Achievement; + this.haveAchiement = true; + } + + /** + * Update the display of the achievement window to match the game window. + */ + private void updateAchievementWindowScale() { + EaglerAdapter.glViewport(0, 0, this.theGame.displayWidth, this.theGame.displayHeight); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glLoadIdentity(); + this.achievementWindowWidth = this.theGame.displayWidth; + this.achievementWindowHeight = this.theGame.displayHeight; + ScaledResolution var1 = new ScaledResolution(this.theGame.gameSettings, this.theGame.displayWidth, this.theGame.displayHeight); + this.achievementWindowWidth = var1.getScaledWidth(); + this.achievementWindowHeight = var1.getScaledHeight(); + EaglerAdapter.glClear(EaglerAdapter.GL_DEPTH_BUFFER_BIT); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glOrtho(0.0F, this.achievementWindowWidth, this.achievementWindowHeight, 0.0F, 1000.0F, 3000.0F); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glTranslatef(0.0F, 0.0F, -2000.0F); + } + + private static final TextureLocation bg = new TextureLocation("/achievement/bg.png"); + + /** + * Updates the small achievement tooltip window, showing a queued achievement if + * is needed. + */ + public void updateAchievementWindow() { + if (this.theAchievement != null && this.achievementTime != 0L) { + double var1 = (double) (Minecraft.getSystemTime() - this.achievementTime) / 3000.0D; + + if (!this.haveAchiement && (var1 < 0.0D || var1 > 1.0D)) { + this.achievementTime = 0L; + } else { + this.updateAchievementWindowScale(); + EaglerAdapter.glDisable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glDepthMask(false); + double var3 = var1 * 2.0D; + + if (var3 > 1.0D) { + var3 = 2.0D - var3; + } + + var3 *= 4.0D; + var3 = 1.0D - var3; + + if (var3 < 0.0D) { + var3 = 0.0D; + } + + var3 *= var3; + var3 *= var3; + int var5 = this.achievementWindowWidth - 160; + int var6 = 0 - (int) (var3 * 36.0D); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + bg.bindTexture(); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + this.drawTexturedModalRect(var5, var6, 96, 202, 160, 32); + + if (this.haveAchiement) { + this.theGame.fontRenderer.drawSplitString(this.achievementStatName, var5 + 30, var6 + 7, 120, -1); + } else { + this.theGame.fontRenderer.drawString(this.achievementGetLocalText, var5 + 30, var6 + 7, -256); + this.theGame.fontRenderer.drawString(this.achievementStatName, var5 + 30, var6 + 18, -1); + } + + RenderHelper.enableGUIStandardItemLighting(); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + EaglerAdapter.glEnable(EaglerAdapter.GL_COLOR_MATERIAL); + this.itemRender.renderItemAndEffectIntoGUI(this.theGame.fontRenderer, this.theGame.renderEngine, this.theAchievement.theItemStack, var5 + 8, var6 + 8); + RenderHelper.disableStandardItemLighting(); + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + EaglerAdapter.glDepthMask(true); + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/GuiBeacon.java b/src/main/java/net/minecraft/src/GuiBeacon.java new file mode 100644 index 0000000..add326a --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiBeacon.java @@ -0,0 +1,177 @@ +package net.minecraft.src; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.util.Iterator; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiBeacon extends GuiContainer { + private TileEntityBeacon beacon; + private GuiBeaconButtonConfirm beaconConfirmButton; + private boolean buttonsNotDrawn; + + public GuiBeacon(InventoryPlayer par1, TileEntityBeacon par2) { + super(new ContainerBeacon(par1, par2)); + this.beacon = par2; + this.xSize = 230; + this.ySize = 219; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + super.initGui(); + this.buttonList.add(this.beaconConfirmButton = new GuiBeaconButtonConfirm(this, -1, this.guiLeft + 164, this.guiTop + 107)); + this.buttonList.add(new GuiBeaconButtonCancel(this, -2, this.guiLeft + 190, this.guiTop + 107)); + this.buttonsNotDrawn = true; + this.beaconConfirmButton.enabled = false; + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + super.updateScreen(); + + if (this.buttonsNotDrawn && this.beacon.getLevels() >= 0) { + this.buttonsNotDrawn = false; + int var2; + int var3; + int var4; + int var5; + GuiBeaconButtonPower var6; + + for (int var1 = 0; var1 <= 2; ++var1) { + var2 = TileEntityBeacon.effectsList[var1].length; + var3 = var2 * 22 + (var2 - 1) * 2; + + for (var4 = 0; var4 < var2; ++var4) { + var5 = TileEntityBeacon.effectsList[var1][var4].id; + var6 = new GuiBeaconButtonPower(this, var1 << 8 | var5, this.guiLeft + 76 + var4 * 24 - var3 / 2, this.guiTop + 22 + var1 * 25, var5, var1); + this.buttonList.add(var6); + + if (var1 >= this.beacon.getLevels()) { + var6.enabled = false; + } else if (var5 == this.beacon.getPrimaryEffect()) { + var6.func_82254_b(true); + } + } + } + + byte var7 = 3; + var2 = TileEntityBeacon.effectsList[var7].length + 1; + var3 = var2 * 22 + (var2 - 1) * 2; + + for (var4 = 0; var4 < var2 - 1; ++var4) { + var5 = TileEntityBeacon.effectsList[var7][var4].id; + var6 = new GuiBeaconButtonPower(this, var7 << 8 | var5, this.guiLeft + 167 + var4 * 24 - var3 / 2, this.guiTop + 47, var5, var7); + this.buttonList.add(var6); + + if (var7 >= this.beacon.getLevels()) { + var6.enabled = false; + } else if (var5 == this.beacon.getSecondaryEffect()) { + var6.func_82254_b(true); + } + } + + if (this.beacon.getPrimaryEffect() > 0) { + GuiBeaconButtonPower var8 = new GuiBeaconButtonPower(this, var7 << 8 | this.beacon.getPrimaryEffect(), this.guiLeft + 167 + (var2 - 1) * 24 - var3 / 2, this.guiTop + 47, this.beacon.getPrimaryEffect(), var7); + this.buttonList.add(var8); + + if (var7 >= this.beacon.getLevels()) { + var8.enabled = false; + } else if (this.beacon.getPrimaryEffect() == this.beacon.getSecondaryEffect()) { + var8.func_82254_b(true); + } + } + } + + this.beaconConfirmButton.enabled = this.beacon.getStackInSlot(0) != null && this.beacon.getPrimaryEffect() > 0; + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.id == -2) { + this.mc.displayGuiScreen((GuiScreen) null); + } else if (par1GuiButton.id == -1) { + String var2 = "MC|Beacon"; + ByteArrayOutputStream var3 = new ByteArrayOutputStream(); + DataOutputStream var4 = new DataOutputStream(var3); + + try { + var4.writeInt(this.beacon.getPrimaryEffect()); + var4.writeInt(this.beacon.getSecondaryEffect()); + this.mc.getNetHandler().addToSendQueue(new Packet250CustomPayload(var2, var3.toByteArray())); + } catch (Exception var6) { + var6.printStackTrace(); + } + + this.mc.displayGuiScreen((GuiScreen) null); + } else if (par1GuiButton instanceof GuiBeaconButtonPower) { + if (((GuiBeaconButtonPower) par1GuiButton).func_82255_b()) { + return; + } + + int var7 = par1GuiButton.id; + int var8 = var7 & 255; + int var9 = var7 >> 8; + + if (var9 < 3) { + this.beacon.setPrimaryEffect(var8); + } else { + this.beacon.setSecondaryEffect(var8); + } + + this.buttonList.clear(); + this.initGui(); + this.updateScreen(); + } + } + + /** + * Draw the foreground layer for the GuiContainer (everything in front of the + * items) + */ + protected void drawGuiContainerForegroundLayer(int par1, int par2) { + RenderHelper.disableStandardItemLighting(); + this.drawCenteredString(this.fontRenderer, StatCollector.translateToLocal("tile.beacon.primary"), 62, 10, 14737632); + this.drawCenteredString(this.fontRenderer, StatCollector.translateToLocal("tile.beacon.secondary"), 169, 10, 14737632); + Iterator var3 = this.buttonList.iterator(); + + while (var3.hasNext()) { + GuiButton var4 = (GuiButton) var3.next(); + + if (var4.func_82252_a()) { + var4.func_82251_b(par1 - this.guiLeft, par2 - this.guiTop); + break; + } + } + + RenderHelper.enableGUIStandardItemLighting(); + } + + private static final TextureLocation tex = new TextureLocation("/gui/beacon.png"); + + /** + * Draw the background layer for the GuiContainer (everything behind the items) + */ + protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex.bindTexture(); + int var4 = (this.width - this.xSize) / 2; + int var5 = (this.height - this.ySize) / 2; + this.drawTexturedModalRect(var4, var5, 0, 0, this.xSize, this.ySize); + itemRenderer.zLevel = 100.0F; + itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, new ItemStack(Item.emerald), var4 + 42, var5 + 109); + itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, new ItemStack(Item.diamond), var4 + 42 + 22, var5 + 109); + itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, new ItemStack(Item.ingotGold), var4 + 42 + 44, var5 + 109); + itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, new ItemStack(Item.ingotIron), var4 + 42 + 66, var5 + 109); + itemRenderer.zLevel = 0.0F; + } +} diff --git a/src/main/java/net/minecraft/src/GuiBeaconButton.java b/src/main/java/net/minecraft/src/GuiBeaconButton.java new file mode 100644 index 0000000..f9a0dd3 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiBeaconButton.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +class GuiBeaconButton extends GuiButton { + /** Texture for this button. */ + private final TextureLocation buttonTexture; + private final int field_82257_l; + private final int field_82258_m; + private boolean field_82256_n; + + protected GuiBeaconButton(int par1, int par2, int par3, String par4Str, int par5, int par6) { + super(par1, par2, par3, 22, 22, ""); + this.buttonTexture = new TextureLocation(par4Str); + this.field_82257_l = par5; + this.field_82258_m = par6; + } + + private static final TextureLocation tex_beacon = new TextureLocation("/gui/beacon.png"); + + /** + * Draws this button to the screen. + */ + public void drawButton(Minecraft par1Minecraft, int par2, int par3) { + if (this.drawButton) { + tex_beacon.bindTexture(); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.field_82253_i = par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height; + short var4 = 219; + int var5 = 0; + + if (!this.enabled) { + var5 += this.width * 2; + } else if (this.field_82256_n) { + var5 += this.width * 1; + } else if (this.field_82253_i) { + var5 += this.width * 3; + } + + this.drawTexturedModalRect(this.xPosition, this.yPosition, var5, var4, this.width, this.height); + + this.buttonTexture.bindTexture(); + this.drawTexturedModalRect(this.xPosition + 2, this.yPosition + 2, this.field_82257_l, this.field_82258_m, 18, 18); + } + } + + public boolean func_82255_b() { + return this.field_82256_n; + } + + public void func_82254_b(boolean par1) { + this.field_82256_n = par1; + } +} diff --git a/src/main/java/net/minecraft/src/GuiBeaconButtonCancel.java b/src/main/java/net/minecraft/src/GuiBeaconButtonCancel.java new file mode 100644 index 0000000..0a6b908 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiBeaconButtonCancel.java @@ -0,0 +1,15 @@ +package net.minecraft.src; + +class GuiBeaconButtonCancel extends GuiBeaconButton { + /** Beacon GUI this button belongs to. */ + final GuiBeacon beaconGui; + + public GuiBeaconButtonCancel(GuiBeacon par1, int par2, int par3, int par4) { + super(par2, par3, par4, "/gui/beacon.png", 112, 220); + this.beaconGui = par1; + } + + public void func_82251_b(int par1, int par2) { + this.beaconGui.drawCreativeTabHoveringText(StatCollector.translateToLocal("gui.cancel"), par1, par2); + } +} diff --git a/src/main/java/net/minecraft/src/GuiBeaconButtonConfirm.java b/src/main/java/net/minecraft/src/GuiBeaconButtonConfirm.java new file mode 100644 index 0000000..2a8ff05 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiBeaconButtonConfirm.java @@ -0,0 +1,15 @@ +package net.minecraft.src; + +class GuiBeaconButtonConfirm extends GuiBeaconButton { + /** Beacon GUI this button belongs to. */ + final GuiBeacon beaconGui; + + public GuiBeaconButtonConfirm(GuiBeacon par1, int par2, int par3, int par4) { + super(par2, par3, par4, "/gui/beacon.png", 90, 220); + this.beaconGui = par1; + } + + public void func_82251_b(int par1, int par2) { + this.beaconGui.drawCreativeTabHoveringText(StatCollector.translateToLocal("gui.done"), par1, par2); + } +} diff --git a/src/main/java/net/minecraft/src/GuiBeaconButtonPower.java b/src/main/java/net/minecraft/src/GuiBeaconButtonPower.java new file mode 100644 index 0000000..ac4b286 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiBeaconButtonPower.java @@ -0,0 +1,26 @@ +package net.minecraft.src; + +class GuiBeaconButtonPower extends GuiBeaconButton { + private final int field_82261_l; + private final int field_82262_m; + + /** Beacon GUI this button belongs to. */ + final GuiBeacon beaconGui; + + public GuiBeaconButtonPower(GuiBeacon par1GuiBeacon, int par2, int par3, int par4, int par5, int par6) { + super(par2, par3, par4, "/gui/inventory.png", 0 + Potion.potionTypes[par5].getStatusIconIndex() % 8 * 18, 198 + Potion.potionTypes[par5].getStatusIconIndex() / 8 * 18); + this.beaconGui = par1GuiBeacon; + this.field_82261_l = par5; + this.field_82262_m = par6; + } + + public void func_82251_b(int par1, int par2) { + String var3 = StatCollector.translateToLocal(Potion.potionTypes[this.field_82261_l].getName()); + + if (this.field_82262_m >= 3 && this.field_82261_l != Potion.regeneration.id) { + var3 = var3 + " II"; + } + + this.beaconGui.drawCreativeTabHoveringText(var3, par1, par2); + } +} diff --git a/src/main/java/net/minecraft/src/GuiBrewingStand.java b/src/main/java/net/minecraft/src/GuiBrewingStand.java new file mode 100644 index 0000000..c48a347 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiBrewingStand.java @@ -0,0 +1,80 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiBrewingStand extends GuiContainer { + private TileEntityBrewingStand brewingStand; + + public GuiBrewingStand(InventoryPlayer par1InventoryPlayer, TileEntityBrewingStand par2TileEntityBrewingStand) { + super(new ContainerBrewingStand(par1InventoryPlayer, par2TileEntityBrewingStand)); + this.brewingStand = par2TileEntityBrewingStand; + } + + /** + * Draw the foreground layer for the GuiContainer (everything in front of the + * items) + */ + protected void drawGuiContainerForegroundLayer(int par1, int par2) { + String var3 = this.brewingStand.isInvNameLocalized() ? this.brewingStand.getInvName() : StatCollector.translateToLocal(this.brewingStand.getInvName()); + this.fontRenderer.drawString(var3, this.xSize / 2 - this.fontRenderer.getStringWidth(var3) / 2, 6, 4210752); + this.fontRenderer.drawString(StatCollector.translateToLocal("container.inventory"), 8, this.ySize - 96 + 2, 4210752); + } + + private static final TextureLocation tex = new TextureLocation("/gui/alchemy.png"); + + /** + * Draw the background layer for the GuiContainer (everything behind the items) + */ + protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex.bindTexture(); + int var4 = (this.width - this.xSize) / 2; + int var5 = (this.height - this.ySize) / 2; + this.drawTexturedModalRect(var4, var5, 0, 0, this.xSize, this.ySize); + int var6 = this.brewingStand.getBrewTime(); + + if (var6 > 0) { + int var7 = (int) (28.0F * (1.0F - (float) var6 / 400.0F)); + + if (var7 > 0) { + this.drawTexturedModalRect(var4 + 97, var5 + 16, 176, 0, 9, var7); + } + + int var8 = var6 / 2 % 7; + + switch (var8) { + case 0: + var7 = 29; + break; + + case 1: + var7 = 24; + break; + + case 2: + var7 = 20; + break; + + case 3: + var7 = 16; + break; + + case 4: + var7 = 11; + break; + + case 5: + var7 = 6; + break; + + case 6: + var7 = 0; + } + + if (var7 > 0) { + this.drawTexturedModalRect(var4 + 65, var5 + 14 + 29 - var7, 185, 29 - var7, 12, var7); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/GuiButton.java b/src/main/java/net/minecraft/src/GuiButton.java new file mode 100644 index 0000000..efa0eda --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiButton.java @@ -0,0 +1,121 @@ +package net.minecraft.src; + +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiButton extends Gui { + /** Button width in pixels */ + protected int width; + + /** Button height in pixels */ + protected int height; + + /** The x position of this control. */ + public int xPosition; + + /** The y position of this control. */ + public int yPosition; + + /** The string displayed on this control. */ + public String displayString; + + /** ID for this control. */ + public int id; + + /** True if this control is enabled, false to disable. */ + public boolean enabled; + + /** Hides the button completely if false. */ + public boolean drawButton; + protected boolean field_82253_i; + + public GuiButton(int par1, int par2, int par3, String par4Str) { + this(par1, par2, par3, 200, 20, par4Str); + } + + public GuiButton(int par1, int par2, int par3, int par4, int par5, String par6Str) { + this.width = 200; + this.height = 20; + this.enabled = true; + this.drawButton = true; + this.id = par1; + this.xPosition = par2; + this.yPosition = par3; + this.width = par4; + this.height = par5; + this.displayString = par6Str; + } + + /** + * Returns 0 if the button is disabled, 1 if the mouse is NOT hovering over this + * button and 2 if it IS hovering over this button. + */ + protected int getHoverState(boolean par1) { + byte var2 = 1; + + if (!this.enabled) { + var2 = 0; + } else if (par1) { + var2 = 2; + } + + return var2; + } + + private static final TextureLocation tex_gui = new TextureLocation("/gui/gui.png"); + + /** + * Draws this button to the screen. + */ + public void drawButton(Minecraft par1Minecraft, int par2, int par3) { + if (this.drawButton) { + FontRenderer var4 = par1Minecraft.fontRenderer; + tex_gui.bindTexture(); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.field_82253_i = par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height; + int var5 = this.getHoverState(this.field_82253_i); + this.drawTexturedModalRect(this.xPosition, this.yPosition, 0, 46 + var5 * 20, this.width / 2, this.height); + this.drawTexturedModalRect(this.xPosition + this.width / 2, this.yPosition, 200 - this.width / 2, 46 + var5 * 20, this.width / 2, this.height); + this.mouseDragged(par1Minecraft, par2, par3); + int var6 = 14737632; + + if (!this.enabled) { + var6 = -6250336; + } else if (this.field_82253_i) { + var6 = 16777120; + } + + this.drawCenteredString(var4, this.displayString, this.xPosition + this.width / 2, this.yPosition + (this.height - 8) / 2, var6); + } + } + + /** + * Fired when the mouse button is dragged. Equivalent of + * MouseListener.mouseDragged(MouseEvent e). + */ + protected void mouseDragged(Minecraft par1Minecraft, int par2, int par3) { + } + + /** + * Fired when the mouse button is released. Equivalent of + * MouseListener.mouseReleased(MouseEvent e). + */ + public void mouseReleased(int par1, int par2) { + } + + /** + * Returns true if the mouse has been pressed on this control. Equivalent of + * MouseListener.mousePressed(MouseEvent e). + */ + public boolean mousePressed(Minecraft par1Minecraft, int par2, int par3) { + return this.enabled && this.drawButton && par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height; + } + + public boolean func_82252_a() { + return this.field_82253_i; + } + + public void func_82251_b(int par1, int par2) { + } +} diff --git a/src/main/java/net/minecraft/src/GuiButtonLanguage.java b/src/main/java/net/minecraft/src/GuiButtonLanguage.java new file mode 100644 index 0000000..b984024 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiButtonLanguage.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiButtonLanguage extends GuiButton { + public GuiButtonLanguage(int par1, int par2, int par3) { + super(par1, par2, par3, 20, 20, ""); + } + + private static final TextureLocation tex_gui = new TextureLocation("/gui/gui.png"); + + /** + * Draws this button to the screen. + */ + public void drawButton(Minecraft par1Minecraft, int par2, int par3) { + if (this.drawButton) { + tex_gui.bindTexture(); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + boolean var4 = par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height; + int var5 = 106; + + if (var4) { + var5 += this.height; + } + + this.drawTexturedModalRect(this.xPosition, this.yPosition, 0, var5, this.width, this.height); + } + } +} diff --git a/src/main/java/net/minecraft/src/GuiButtonLink.java b/src/main/java/net/minecraft/src/GuiButtonLink.java new file mode 100644 index 0000000..73d92bf --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiButtonLink.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +public class GuiButtonLink extends GuiButton { + public GuiButtonLink(int par1, int par2, int par3, int par4, int par5, String par6Str) { + super(par1, par2, par3, par4, par5, par6Str); + } + + public void func_96135_a(String par1Str) { + + } +} diff --git a/src/main/java/net/minecraft/src/GuiButtonMerchant.java b/src/main/java/net/minecraft/src/GuiButtonMerchant.java new file mode 100644 index 0000000..1909650 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiButtonMerchant.java @@ -0,0 +1,45 @@ +package net.minecraft.src; + +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +class GuiButtonMerchant extends GuiButton { + /** + * If true, then next page button will face to right, if false then next page + * button will face to left. + */ + private final boolean mirrored; + + public GuiButtonMerchant(int par1, int par2, int par3, boolean par4) { + super(par1, par2, par3, 12, 19, ""); + this.mirrored = par4; + } + + private static final TextureLocation tex = new TextureLocation("/gui/trading.png"); + + /** + * Draws this button to the screen. + */ + public void drawButton(Minecraft par1Minecraft, int par2, int par3) { + if (this.drawButton) { + tex.bindTexture(); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + boolean var4 = par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height; + int var5 = 0; + int var6 = 176; + + if (!this.enabled) { + var6 += this.width * 2; + } else if (var4) { + var6 += this.width; + } + + if (!this.mirrored) { + var5 += this.height; + } + + this.drawTexturedModalRect(this.xPosition, this.yPosition, var6, var5, this.width, this.height); + } + } +} diff --git a/src/main/java/net/minecraft/src/GuiButtonNextPage.java b/src/main/java/net/minecraft/src/GuiButtonNextPage.java new file mode 100644 index 0000000..c88d630 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiButtonNextPage.java @@ -0,0 +1,42 @@ +package net.minecraft.src; + +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +class GuiButtonNextPage extends GuiButton { + /** + * True for pointing right (next page), false for pointing left (previous page). + */ + private final boolean nextPage; + + public GuiButtonNextPage(int par1, int par2, int par3, boolean par4) { + super(par1, par2, par3, 23, 13, ""); + this.nextPage = par4; + } + + private static final TextureLocation tex = new TextureLocation("/gui/book.png"); + + /** + * Draws this button to the screen. + */ + public void drawButton(Minecraft par1Minecraft, int par2, int par3) { + if (this.drawButton) { + boolean var4 = par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height; + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex.bindTexture(); + int var5 = 0; + int var6 = 192; + + if (var4) { + var5 += 23; + } + + if (!this.nextPage) { + var6 += 13; + } + + this.drawTexturedModalRect(this.xPosition, this.yPosition, var5, var6, 23, 13); + } + } +} diff --git a/src/main/java/net/minecraft/src/GuiChat.java b/src/main/java/net/minecraft/src/GuiChat.java new file mode 100644 index 0000000..7e6d75f --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiChat.java @@ -0,0 +1,292 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +public class GuiChat extends GuiScreen { + private String field_73898_b = ""; + + /** + * keeps position of which chat message you will select when you press up, (does + * not increase for duplicated messages sent immediately after each other) + */ + private int sentHistoryCursor = -1; + private boolean field_73897_d = false; + private boolean field_73905_m = false; + private int field_73903_n = 0; + private List field_73904_o = new ArrayList(); + + /** used to pass around the URI to various dialogues and to the host os */ + private String clickedURI = null; + + /** Chat entry field */ + protected GuiTextField inputField; + + /** + * is the text that appears when you press the chat key and the input box + * appears pre-filled + */ + private String defaultInputFieldText = ""; + + public GuiChat() { + } + + public GuiChat(String par1Str) { + this.defaultInputFieldText = par1Str; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + EaglerAdapter.enableRepeatEvents(true); + this.sentHistoryCursor = this.mc.ingameGUI.getChatGUI().getSentMessages().size(); + this.inputField = new GuiTextField(this.fontRenderer, 4, this.height - 12, this.width - 4, 12); + this.inputField.setMaxStringLength(100); + this.inputField.setEnableBackgroundDrawing(false); + this.inputField.setFocused(true); + this.inputField.setText(this.defaultInputFieldText); + this.inputField.setCanLoseFocus(false); + } + + /** + * Called when the screen is unloaded. Used to disable keyboard repeat events + */ + public void onGuiClosed() { + EaglerAdapter.enableRepeatEvents(false); + this.mc.ingameGUI.getChatGUI().resetScroll(); + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + this.inputField.updateCursorCounter(); + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + this.field_73905_m = false; + + if (par2 == 15) { + this.completePlayerName(); + } else { + this.field_73897_d = false; + } + + if (par2 == 1) { + this.mc.displayGuiScreen((GuiScreen) null); + } else if (par2 == 28) { + String var3 = this.inputField.getText().trim(); + + if (var3.length() > 0) { + this.mc.ingameGUI.getChatGUI().addToSentMessages(var3); + + if (!this.mc.handleClientCommand(var3)) { + this.mc.thePlayer.sendChatMessage(var3); + } + } + + this.mc.displayGuiScreen((GuiScreen) null); + } else if (par2 == 200) { + this.getSentHistory(-1); + } else if (par2 == 208) { + this.getSentHistory(1); + } else if (par2 == 201) { + this.mc.ingameGUI.getChatGUI().scroll(this.mc.ingameGUI.getChatGUI().func_96127_i() - 1); + } else if (par2 == 209) { + this.mc.ingameGUI.getChatGUI().scroll(-this.mc.ingameGUI.getChatGUI().func_96127_i() + 1); + } else { + this.inputField.textboxKeyTyped(par1, par2); + } + } + + /** + * Handles mouse input. + */ + public void handleMouseInput() { + super.handleMouseInput(); + int var1 = EaglerAdapter.mouseGetEventDWheel(); + + if (var1 != 0) { + if (var1 > 1) { + var1 = 1; + } + + if (var1 < -1) { + var1 = -1; + } + + if (!isShiftKeyDown()) { + var1 *= 7; + } + + this.mc.ingameGUI.getChatGUI().scroll(var1); + } + } + + /** + * Called when the mouse is clicked. + */ + protected void mouseClicked(int par1, int par2, int par3) { + if (par3 == 0 && this.mc.gameSettings.chatLinks) { + ChatClickData var4 = this.mc.ingameGUI.getChatGUI().func_73766_a(EaglerAdapter.mouseGetX(), EaglerAdapter.mouseGetY()); + + if (var4 != null) { + String var5 = var4.getClickedUrl(); + + if (var5 != null) { + if (this.mc.gameSettings.chatLinksPrompt) { + this.clickedURI = var5; + this.mc.displayGuiScreen(new GuiConfirmOpenLink(this, var4.getClickedUrl(), 0, false)); + } else { + EaglerAdapter.openLink(var4.getClickedUrl()); + } + + return; + } + } + } + + this.inputField.mouseClicked(par1, par2, par3); + super.mouseClicked(par1, par2, par3); + } + + public void confirmClicked(boolean par1, int par2) { + if (par2 == 0) { + if (par1) { + EaglerAdapter.openLink(this.clickedURI); + } + + this.clickedURI = null; + this.mc.displayGuiScreen(this); + } + } + + /** + * Autocompletes player name + */ + public void completePlayerName() { + String var3; + + if (this.field_73897_d) { + this.inputField.deleteFromCursor(this.inputField.func_73798_a(-1, this.inputField.getCursorPosition(), false) - this.inputField.getCursorPosition()); + + if (this.field_73903_n >= this.field_73904_o.size()) { + this.field_73903_n = 0; + } + } else { + int var1 = this.inputField.func_73798_a(-1, this.inputField.getCursorPosition(), false); + this.field_73904_o.clear(); + this.field_73903_n = 0; + String var2 = this.inputField.getText().substring(var1).toLowerCase(); + var3 = this.inputField.getText().substring(0, this.inputField.getCursorPosition()); + this.func_73893_a(var3, var2); + + if (this.field_73904_o.isEmpty()) { + return; + } + + this.field_73897_d = true; + this.inputField.deleteFromCursor(var1 - this.inputField.getCursorPosition()); + } + + if (this.field_73904_o.size() > 1) { + StringBuilder var4 = new StringBuilder(); + + for (Iterator var5 = this.field_73904_o.iterator(); var5.hasNext(); var4.append(var3)) { + var3 = (String) var5.next(); + + if (var4.length() > 0) { + var4.append(", "); + } + } + + this.mc.ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion(var4.toString(), 1); + } + + this.inputField.writeText((String) this.field_73904_o.get(this.field_73903_n++)); + } + + private void func_73893_a(String par1Str, String par2Str) { + if (par1Str.length() >= 1) { + this.mc.thePlayer.sendQueue.addToSendQueue(new Packet203AutoComplete(par1Str)); + this.field_73905_m = true; + } + } + + /** + * input is relative and is applied directly to the sentHistoryCursor so -1 is + * the previous message, 1 is the next message from the current cursor position + */ + public void getSentHistory(int par1) { + int var2 = this.sentHistoryCursor + par1; + int var3 = this.mc.ingameGUI.getChatGUI().getSentMessages().size(); + + if (var2 < 0) { + var2 = 0; + } + + if (var2 > var3) { + var2 = var3; + } + + if (var2 != this.sentHistoryCursor) { + if (var2 == var3) { + this.sentHistoryCursor = var3; + this.inputField.setText(this.field_73898_b); + } else { + if (this.sentHistoryCursor == var3) { + this.field_73898_b = this.inputField.getText(); + } + + this.inputField.setText((String) this.mc.ingameGUI.getChatGUI().getSentMessages().get(var2)); + this.sentHistoryCursor = var2; + } + } + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + drawRect(2, this.height - 14, this.width - 2, this.height - 2, Integer.MIN_VALUE); + this.inputField.drawTextBox(); + super.drawScreen(par1, par2, par3); + } + + public void func_73894_a(String[] par1ArrayOfStr) { + if (this.field_73905_m) { + this.field_73904_o.clear(); + String[] var2 = par1ArrayOfStr; + int var3 = par1ArrayOfStr.length; + + for (int var4 = 0; var4 < var3; ++var4) { + String var5 = var2[var4]; + + if (var5.length() > 0) { + this.field_73904_o.add(var5); + } + } + + if (this.field_73904_o.size() > 0) { + this.field_73897_d = true; + this.completePlayerName(); + } + } + } + + /** + * Returns true if this GUI should pause the game when it is displayed in + * single-player + */ + public boolean doesGuiPauseGame() { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/GuiChest.java b/src/main/java/net/minecraft/src/GuiChest.java new file mode 100644 index 0000000..221f32b --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiChest.java @@ -0,0 +1,48 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiChest extends GuiContainer { + private IInventory upperChestInventory; + private IInventory lowerChestInventory; + + /** + * window height is calculated with this values, the more rows, the heigher + */ + private int inventoryRows = 0; + + public GuiChest(IInventory par1IInventory, IInventory par2IInventory) { + super(new ContainerChest(par1IInventory, par2IInventory)); + this.upperChestInventory = par1IInventory; + this.lowerChestInventory = par2IInventory; + this.allowUserInput = false; + short var3 = 222; + int var4 = var3 - 108; + this.inventoryRows = par2IInventory.getSizeInventory() / 9; + this.ySize = var4 + this.inventoryRows * 18; + } + + /** + * Draw the foreground layer for the GuiContainer (everything in front of the + * items) + */ + protected void drawGuiContainerForegroundLayer(int par1, int par2) { + this.fontRenderer.drawString(this.lowerChestInventory.isInvNameLocalized() ? this.lowerChestInventory.getInvName() : StatCollector.translateToLocal(this.lowerChestInventory.getInvName()), 8, 6, 4210752); + this.fontRenderer.drawString(this.upperChestInventory.isInvNameLocalized() ? this.upperChestInventory.getInvName() : StatCollector.translateToLocal(this.upperChestInventory.getInvName()), 8, this.ySize - 96 + 2, 4210752); + } + + private static final TextureLocation tex = new TextureLocation("/gui/container.png"); + + /** + * Draw the background layer for the GuiContainer (everything behind the items) + */ + protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex.bindTexture(); + int var4 = (this.width - this.xSize) / 2; + int var5 = (this.height - this.ySize) / 2; + this.drawTexturedModalRect(var4, var5, 0, 0, this.xSize, this.inventoryRows * 18 + 17); + this.drawTexturedModalRect(var4, var5 + this.inventoryRows * 18 + 17, 0, 126, this.xSize, 96); + } +} diff --git a/src/main/java/net/minecraft/src/GuiCommandBlock.java b/src/main/java/net/minecraft/src/GuiCommandBlock.java new file mode 100644 index 0000000..b723d3c --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiCommandBlock.java @@ -0,0 +1,118 @@ +package net.minecraft.src; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +public class GuiCommandBlock extends GuiScreen { + /** Text field containing the command block's command. */ + private GuiTextField commandTextField; + + /** Command block being edited. */ + private final TileEntityCommandBlock commandBlock; + private GuiButton doneBtn; + private GuiButton cancelBtn; + + public GuiCommandBlock(TileEntityCommandBlock par1) { + this.commandBlock = par1; + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + this.commandTextField.updateCursorCounter(); + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + StringTranslate var1 = StringTranslate.getInstance(); + EaglerAdapter.enableRepeatEvents(true); + this.buttonList.clear(); + this.buttonList.add(this.doneBtn = new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + 12, var1.translateKey("gui.done"))); + this.buttonList.add(this.cancelBtn = new GuiButton(1, this.width / 2 - 100, this.height / 4 + 120 + 12, var1.translateKey("gui.cancel"))); + this.commandTextField = new GuiTextField(this.fontRenderer, this.width / 2 - 150, 60, 300, 20); + this.commandTextField.setMaxStringLength(32767); + this.commandTextField.setFocused(true); + this.commandTextField.setText(this.commandBlock.getCommand()); + this.doneBtn.enabled = this.commandTextField.getText().trim().length() > 0; + } + + /** + * Called when the screen is unloaded. Used to disable keyboard repeat events + */ + public void onGuiClosed() { + EaglerAdapter.enableRepeatEvents(false); + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.enabled) { + if (par1GuiButton.id == 1) { + this.mc.displayGuiScreen((GuiScreen) null); + } else if (par1GuiButton.id == 0) { + String var2 = "MC|AdvCdm"; + ByteArrayOutputStream var3 = new ByteArrayOutputStream(); + DataOutputStream var4 = new DataOutputStream(var3); + + try { + var4.writeInt(this.commandBlock.xCoord); + var4.writeInt(this.commandBlock.yCoord); + var4.writeInt(this.commandBlock.zCoord); + Packet.writeString(this.commandTextField.getText(), var4); + this.mc.getNetHandler().addToSendQueue(new Packet250CustomPayload(var2, var3.toByteArray())); + } catch (Exception var6) { + var6.printStackTrace(); + } + + this.mc.displayGuiScreen((GuiScreen) null); + } + } + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + this.commandTextField.textboxKeyTyped(par1, par2); + this.doneBtn.enabled = this.commandTextField.getText().trim().length() > 0; + + if (par2 != 28 && par1 != 13) { + if (par2 == 1) { + this.actionPerformed(this.cancelBtn); + } + } else { + this.actionPerformed(this.doneBtn); + } + } + + /** + * Called when the mouse is clicked. + */ + protected void mouseClicked(int par1, int par2, int par3) { + super.mouseClicked(par1, par2, par3); + this.commandTextField.mouseClicked(par1, par2, par3); + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + StringTranslate var4 = StringTranslate.getInstance(); + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, var4.translateKey("advMode.setCommand"), this.width / 2, this.height / 4 - 60 + 20, 16777215); + this.drawString(this.fontRenderer, var4.translateKey("advMode.command"), this.width / 2 - 150, 47, 10526880); + this.drawString(this.fontRenderer, var4.translateKey("advMode.nearestPlayer"), this.width / 2 - 150, 97, 10526880); + this.drawString(this.fontRenderer, var4.translateKey("advMode.randomPlayer"), this.width / 2 - 150, 108, 10526880); + this.drawString(this.fontRenderer, var4.translateKey("advMode.allPlayers"), this.width / 2 - 150, 119, 10526880); + this.commandTextField.drawTextBox(); + super.drawScreen(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/GuiConfirmOpenLink.java b/src/main/java/net/minecraft/src/GuiConfirmOpenLink.java new file mode 100644 index 0000000..1fc38e2 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiConfirmOpenLink.java @@ -0,0 +1,64 @@ +package net.minecraft.src; + +public class GuiConfirmOpenLink extends GuiYesNo { + /** Text to warn players from opening unsafe links. */ + private String openLinkWarning; + + /** Label for the Copy to Clipboard button. */ + private String copyLinkButtonText; + private String field_92028_p; + private boolean field_92027_q = true; + + public GuiConfirmOpenLink(GuiScreen par1GuiScreen, String par2Str, int par3, boolean par4) { + super(par1GuiScreen, StringTranslate.getInstance().translateKey(par4 ? "chat.link.confirmTrusted" : "chat.link.confirm"), par2Str, par3); + StringTranslate var5 = StringTranslate.getInstance(); + this.buttonText1 = var5.translateKey(par4 ? "chat.link.open" : "gui.yes"); + this.buttonText2 = var5.translateKey(par4 ? "gui.cancel" : "gui.no"); + this.copyLinkButtonText = var5.translateKey("chat.copy"); + this.openLinkWarning = var5.translateKey("chat.link.warning"); + this.field_92028_p = par2Str; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + this.buttonList.add(new GuiButton(0, this.width / 3 - 83 + 0, this.height / 6 + 96, 100, 20, this.buttonText1)); + this.buttonList.add(new GuiButton(2, this.width / 3 - 83 + 105, this.height / 6 + 96, 100, 20, this.copyLinkButtonText)); + this.buttonList.add(new GuiButton(1, this.width / 3 - 83 + 210, this.height / 6 + 96, 100, 20, this.buttonText2)); + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.id == 2) { + this.copyLinkToClipboard(); + } + + this.parentScreen.confirmClicked(par1GuiButton.id == 0, this.worldNumber); + } + + /** + * Copies the link to the system clipboard. + */ + public void copyLinkToClipboard() { + setClipboardString(this.field_92028_p); + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + super.drawScreen(par1, par2, par3); + + if (this.field_92027_q) { + this.drawCenteredString(this.fontRenderer, this.openLinkWarning, this.width / 2, 110, 16764108); + } + } + + public void func_92026_h() { + this.field_92027_q = false; + } +} diff --git a/src/main/java/net/minecraft/src/GuiConnecting.java b/src/main/java/net/minecraft/src/GuiConnecting.java new file mode 100644 index 0000000..c6b6ab1 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiConnecting.java @@ -0,0 +1,177 @@ +package net.minecraft.src; + +import java.io.IOException; + +import net.lax1dude.eaglercraft.EaglerProfile; +import net.minecraft.client.Minecraft; + +public class GuiConnecting extends GuiScreen { + /** A reference to the NetClientHandler. */ + private NetClientHandler clientHandler; + private INetworkManager networkConnection; + private String uri; + + /** True if the connection attempt has been cancelled. */ + private boolean cancelled = false; + private final GuiScreen field_98098_c; + + public GuiConnecting(GuiScreen par1GuiScreen, Minecraft par2Minecraft, ServerData par3ServerData) { + this.mc = par2Minecraft; + this.field_98098_c = par1GuiScreen; + this.clientHandler = null; + this.networkConnection = null; + this.uri = par3ServerData.serverIP; + //ServerAddress var4 = ServerAddress.func_78860_a(par3ServerData.serverIP); + par2Minecraft.loadWorld((WorldClient) null); + par2Minecraft.setServerData(par3ServerData); + //this.spawnNewServerThread(var4.getIP(), var4.getPort()); + } + + //private void spawnNewServerThread(String par1Str, int par2) { + // System.out.println("Connecting to " + par1Str + ", " + par2); + // (new ThreadConnectToServer(this, par1Str, par2)).start(); + //} + + private int timer; + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + if (timer > 2 && this.clientHandler == null) { + try { + String uria = null; + if(uri.startsWith("ws://")) { + uria = uri.substring(5); + }else if(uri.startsWith("wss://")){ + uria = uri.substring(6); + }else if(!uri.contains("://")){ + uria = uri; + uri = "ws://" + uri; + }else { + this.mc.displayGuiScreen(new GuiDisconnected(this.field_98098_c, "connect.failed", "disconnect.genericReason", "invalid uri websocket protocol", "")); + return; + } + int i = uria.indexOf(':'); + int port = -1; + + if(i == -1) port = uri.startsWith("wss") ? 443 : 80; + if(uria.endsWith("/")) uria = uria.substring(0, uria.length() - 1); + + if(port == -1) { + try { + int i2 = uria.indexOf('/'); + port = Integer.parseInt(uria.substring(i + 1, i2 == -1 ? uria.length() : i2 - 1)); + }catch(Throwable t) { + this.mc.displayGuiScreen(new GuiDisconnected(this.field_98098_c, "connect.failed", "disconnect.genericReason", "invalid port number", "")); + return; + } + } + + this.clientHandler = new NetClientHandler(this.mc, uri, 0); + this.clientHandler.addToSendQueue(new Packet2ClientProtocol(69, EaglerProfile.username, uria, port)); + this.clientHandler.addToSendQueue(new Packet250CustomPayload("EAG|MySkin", EaglerProfile.getSkinPacket())); + } catch (IOException e) { + e.printStackTrace(); + this.mc.displayGuiScreen(new GuiDisconnected(this.field_98098_c, "connect.failed", "disconnect.genericReason", "could not connect to "+uri, e.toString())); + + } + } + if(this.clientHandler != null) { + this.clientHandler.processReadPackets(); + } + ++timer; + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + StringTranslate var1 = StringTranslate.getInstance(); + this.buttonList.clear(); + this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 120 + 12, var1.translateKey("gui.cancel"))); + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.id == 0) { + this.cancelled = true; + + if (this.clientHandler != null) { + this.clientHandler.disconnect(); + } + + this.mc.displayGuiScreen(this.field_98098_c); + } + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.drawDefaultBackground(); + StringTranslate var4 = StringTranslate.getInstance(); + + if (this.clientHandler == null) { + this.drawCenteredString(this.fontRenderer, var4.translateKey("connect.connecting"), this.width / 2, this.height / 2 - 50, 16777215); + this.drawCenteredString(this.fontRenderer, "", this.width / 2, this.height / 2 - 10, 16777215); + } else { + this.drawCenteredString(this.fontRenderer, var4.translateKey("connect.authorizing"), this.width / 2, this.height / 2 - 50, 16777215); + this.drawCenteredString(this.fontRenderer, this.clientHandler.field_72560_a, this.width / 2, this.height / 2 - 10, 16777215); + } + + super.drawScreen(par1, par2, par3); + } + + /** + * Sets the NetClientHandler. + */ + public static NetClientHandler setNetClientHandler(GuiConnecting par0GuiConnecting, NetClientHandler par1NetClientHandler) { + return par0GuiConnecting.clientHandler = par1NetClientHandler; + } + + public static Minecraft func_74256_a(GuiConnecting par0GuiConnecting) { + return par0GuiConnecting.mc; + } + + public static boolean isCancelled(GuiConnecting par0GuiConnecting) { + return par0GuiConnecting.cancelled; + } + + public static Minecraft func_74254_c(GuiConnecting par0GuiConnecting) { + return par0GuiConnecting.mc; + } + + /** + * Gets the NetClientHandler. + */ + public static NetClientHandler getNetClientHandler(GuiConnecting par0GuiConnecting) { + return par0GuiConnecting.clientHandler; + } + + public static GuiScreen func_98097_e(GuiConnecting par0GuiConnecting) { + return par0GuiConnecting.field_98098_c; + } + + public static Minecraft func_74250_f(GuiConnecting par0GuiConnecting) { + return par0GuiConnecting.mc; + } + + public static Minecraft func_74251_g(GuiConnecting par0GuiConnecting) { + return par0GuiConnecting.mc; + } + + public static Minecraft func_98096_h(GuiConnecting par0GuiConnecting) { + return par0GuiConnecting.mc; + } +} diff --git a/src/main/java/net/minecraft/src/GuiContainer.java b/src/main/java/net/minecraft/src/GuiContainer.java new file mode 100644 index 0000000..d8dd8c9 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiContainer.java @@ -0,0 +1,723 @@ +package net.minecraft.src; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public abstract class GuiContainer extends GuiScreen { + /** Stacks renderer. Icons, stack size, health, etc... */ + protected static RenderItem itemRenderer = null; + + /** The X size of the inventory window in pixels. */ + protected int xSize = 176; + + /** The Y size of the inventory window in pixels. */ + protected int ySize = 166; + + /** A list of the players inventory slots. */ + public Container inventorySlots; + + /** + * Starting X position for the Gui. Inconsistent use for Gui backgrounds. + */ + protected int guiLeft; + + /** + * Starting Y position for the Gui. Inconsistent use for Gui backgrounds. + */ + protected int guiTop; + private Slot theSlot; + + /** Used when touchscreen is enabled */ + private Slot clickedSlot = null; + + /** Used when touchscreen is enabled */ + private boolean isRightMouseClick = false; + + /** Used when touchscreen is enabled */ + private ItemStack draggedStack = null; + private int field_85049_r = 0; + private int field_85048_s = 0; + private Slot returningStackDestSlot = null; + private long returningStackTime = 0L; + + /** Used when touchscreen is enabled */ + private ItemStack returningStack = null; + private Slot field_92033_y = null; + private long field_92032_z = 0L; + protected final Set field_94077_p = new HashSet(); + protected boolean field_94076_q; + private int field_94071_C = 0; + private int field_94067_D = 0; + private boolean field_94068_E = false; + private int field_94069_F; + private long field_94070_G = 0L; + private Slot field_94072_H = null; + private int field_94073_I = 0; + private boolean field_94074_J; + private ItemStack field_94075_K = null; + + public GuiContainer(Container par1Container) { + this.inventorySlots = par1Container; + this.field_94068_E = true; + if(itemRenderer == null) itemRenderer = new RenderItem(); + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + super.initGui(); + this.mc.thePlayer.openContainer = this.inventorySlots; + this.guiLeft = (this.width - this.xSize) / 2; + this.guiTop = (this.height - this.ySize) / 2; + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.drawDefaultBackground(); + int var4 = this.guiLeft; + int var5 = this.guiTop; + this.drawGuiContainerBackgroundLayer(par3, par1, par2); + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + RenderHelper.disableStandardItemLighting(); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glDisable(EaglerAdapter.GL_DEPTH_TEST); + super.drawScreen(par1, par2, par3); + RenderHelper.enableGUIStandardItemLighting(); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef((float) var4, (float) var5, 0.0F); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + this.theSlot = null; + short var6 = 240; + short var7 = 240; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) var6 / 1.0F, (float) var7 / 1.0F); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + int var9; + + for (int var13 = 0; var13 < this.inventorySlots.inventorySlots.size(); ++var13) { + Slot var15 = (Slot) this.inventorySlots.inventorySlots.get(var13); + this.drawSlotInventory(var15); + + if (this.isMouseOverSlot(var15, par1, par2)) { + this.theSlot = var15; + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glDisable(EaglerAdapter.GL_DEPTH_TEST); + int var8 = var15.xDisplayPosition; + var9 = var15.yDisplayPosition; + this.drawGradientRect(var8, var9, var8 + 16, var9 + 16, -2130706433, -2130706433); + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + } + } + + this.drawGuiContainerForegroundLayer(par1, par2); + InventoryPlayer var14 = this.mc.thePlayer.inventory; + ItemStack var16 = this.draggedStack == null ? var14.getItemStack() : this.draggedStack; + + if (var16 != null) { + byte var17 = 8; + var9 = this.draggedStack == null ? 8 : 16; + String var10 = null; + + if (this.draggedStack != null && this.isRightMouseClick) { + var16 = var16.copy(); + var16.stackSize = MathHelper.ceiling_float_int((float) var16.stackSize / 2.0F); + } else if (this.field_94076_q && this.field_94077_p.size() > 1) { + var16 = var16.copy(); + var16.stackSize = this.field_94069_F; + + if (var16.stackSize == 0) { + var10 = "" + EnumChatFormatting.YELLOW + "0"; + } + } + + this.drawItemStack(var16, par1 - var4 - var17, par2 - var5 - var9, var10); + } + + if (this.returningStack != null) { + float var18 = (float) (Minecraft.getSystemTime() - this.returningStackTime) / 100.0F; + + if (var18 >= 1.0F) { + var18 = 1.0F; + this.returningStack = null; + } + + var9 = this.returningStackDestSlot.xDisplayPosition - this.field_85049_r; + int var20 = this.returningStackDestSlot.yDisplayPosition - this.field_85048_s; + int var11 = this.field_85049_r + (int) ((float) var9 * var18); + int var12 = this.field_85048_s + (int) ((float) var20 * var18); + this.drawItemStack(this.returningStack, var11, var12, (String) null); + } + + EaglerAdapter.glPopMatrix(); + + if (var14.getItemStack() == null && this.theSlot != null && this.theSlot.getHasStack()) { + ItemStack var19 = this.theSlot.getStack(); + this.drawItemStackTooltip(var19, par1, par2); + } + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + RenderHelper.enableStandardItemLighting(); + } + + private void drawItemStack(ItemStack par1ItemStack, int par2, int par3, String par4Str) { + EaglerAdapter.glTranslatef(0.0F, 0.0F, 32.0F); + this.zLevel = 200.0F; + itemRenderer.zLevel = 200.0F; + itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, par1ItemStack, par2, par3); + itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, par1ItemStack, par2, par3 - (this.draggedStack == null ? 0 : 8), par4Str); + this.zLevel = 0.0F; + itemRenderer.zLevel = 0.0F; + } + + protected void drawItemStackTooltip(ItemStack par1ItemStack, int par2, int par3) { + List var4 = par1ItemStack.getTooltip(this.mc.thePlayer, this.mc.gameSettings.advancedItemTooltips); + + for (int var5 = 0; var5 < var4.size(); ++var5) { + if (var5 == 0) { + var4.set(var5, "\u00a7" + Integer.toHexString(par1ItemStack.getRarity().rarityColor) + (String) var4.get(var5)); + } else { + var4.set(var5, EnumChatFormatting.GRAY + (String) var4.get(var5)); + } + } + + this.func_102021_a(var4, par2, par3); + } + + /** + * Draws the text when mouse is over creative inventory tab. Params: current + * creative tab to be checked, current mouse x position, current mouse y + * position. + */ + protected void drawCreativeTabHoveringText(String par1Str, int par2, int par3) { + this.func_102021_a(Arrays.asList(new String[] { par1Str }), par2, par3); + } + + protected void func_102021_a(List par1List, int par2, int par3) { + if (!par1List.isEmpty()) { + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + RenderHelper.disableStandardItemLighting(); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glDisable(EaglerAdapter.GL_DEPTH_TEST); + int var4 = 0; + Iterator var5 = par1List.iterator(); + + while (var5.hasNext()) { + String var6 = (String) var5.next(); + int var7 = this.fontRenderer.getStringWidth(var6); + + if (var7 > var4) { + var4 = var7; + } + } + + int var14 = par2 + 12; + int var15 = par3 - 12; + int var8 = 8; + + if (par1List.size() > 1) { + var8 += 2 + (par1List.size() - 1) * 10; + } + + if (var14 + var4 > this.width) { + var14 -= 28 + var4; + } + + if (var15 + var8 + 6 > this.height) { + var15 = this.height - var8 - 6; + } + + this.zLevel = 300.0F; + itemRenderer.zLevel = 300.0F; + int var9 = -267386864; + this.drawGradientRect(var14 - 3, var15 - 4, var14 + var4 + 3, var15 - 3, var9, var9); + this.drawGradientRect(var14 - 3, var15 + var8 + 3, var14 + var4 + 3, var15 + var8 + 4, var9, var9); + this.drawGradientRect(var14 - 3, var15 - 3, var14 + var4 + 3, var15 + var8 + 3, var9, var9); + this.drawGradientRect(var14 - 4, var15 - 3, var14 - 3, var15 + var8 + 3, var9, var9); + this.drawGradientRect(var14 + var4 + 3, var15 - 3, var14 + var4 + 4, var15 + var8 + 3, var9, var9); + int var10 = 1347420415; + int var11 = (var10 & 16711422) >> 1 | var10 & -16777216; + this.drawGradientRect(var14 - 3, var15 - 3 + 1, var14 - 3 + 1, var15 + var8 + 3 - 1, var10, var11); + this.drawGradientRect(var14 + var4 + 2, var15 - 3 + 1, var14 + var4 + 3, var15 + var8 + 3 - 1, var10, var11); + this.drawGradientRect(var14 - 3, var15 - 3, var14 + var4 + 3, var15 - 3 + 1, var10, var10); + this.drawGradientRect(var14 - 3, var15 + var8 + 2, var14 + var4 + 3, var15 + var8 + 3, var11, var11); + + for (int var12 = 0; var12 < par1List.size(); ++var12) { + String var13 = (String) par1List.get(var12); + this.fontRenderer.drawStringWithShadow(var13, var14, var15, -1); + + if (var12 == 0) { + var15 += 2; + } + + var15 += 10; + } + + this.zLevel = 0.0F; + itemRenderer.zLevel = 0.0F; + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + RenderHelper.enableGUIStandardItemLighting(); + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + } + } + + /** + * Draw the foreground layer for the GuiContainer (everything in front of the + * items) + */ + protected void drawGuiContainerForegroundLayer(int par1, int par2) { + } + + /** + * Draw the background layer for the GuiContainer (everything behind the items) + */ + protected abstract void drawGuiContainerBackgroundLayer(float var1, int var2, int var3); + + private static final TextureLocation items = new TextureLocation("/gui/items.png"); + + /** + * Draws an inventory slot + */ + private void drawSlotInventory(Slot par1Slot) { + int var2 = par1Slot.xDisplayPosition; + int var3 = par1Slot.yDisplayPosition; + ItemStack var4 = par1Slot.getStack(); + boolean var5 = false; + boolean var6 = par1Slot == this.clickedSlot && this.draggedStack != null && !this.isRightMouseClick; + ItemStack var7 = this.mc.thePlayer.inventory.getItemStack(); + String var8 = null; + + if (par1Slot == this.clickedSlot && this.draggedStack != null && this.isRightMouseClick && var4 != null) { + var4 = var4.copy(); + var4.stackSize /= 2; + } else if (this.field_94076_q && this.field_94077_p.contains(par1Slot) && var7 != null) { + if (this.field_94077_p.size() == 1) { + return; + } + + if (Container.func_94527_a(par1Slot, var7, true) && this.inventorySlots.func_94531_b(par1Slot)) { + var4 = var7.copy(); + var5 = true; + Container.func_94525_a(this.field_94077_p, this.field_94071_C, var4, par1Slot.getStack() == null ? 0 : par1Slot.getStack().stackSize); + + if (var4.stackSize > var4.getMaxStackSize()) { + var8 = EnumChatFormatting.YELLOW + "" + var4.getMaxStackSize(); + var4.stackSize = var4.getMaxStackSize(); + } + + if (var4.stackSize > par1Slot.getSlotStackLimit()) { + var8 = EnumChatFormatting.YELLOW + "" + par1Slot.getSlotStackLimit(); + var4.stackSize = par1Slot.getSlotStackLimit(); + } + } else { + this.field_94077_p.remove(par1Slot); + this.func_94066_g(); + } + } + + this.zLevel = 100.0F; + itemRenderer.zLevel = 100.0F; + + if (var4 == null) { + Icon var9 = par1Slot.getBackgroundIconIndex(); + + if (var9 != null) { + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + items.bindTexture(); + this.drawTexturedModelRectFromIcon(var2, var3, var9, 16, 16); + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + var6 = true; + } + } + + if (!var6) { + if (var5) { + drawRect(var2, var3, var2 + 16, var3 + 16, -2130706433); + } + + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, var4, var2, var3); + itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, var4, var2, var3, var8); + } + + itemRenderer.zLevel = 0.0F; + this.zLevel = 0.0F; + } + + private void func_94066_g() { + ItemStack var1 = this.mc.thePlayer.inventory.getItemStack(); + + if (var1 != null && this.field_94076_q) { + this.field_94069_F = var1.stackSize; + ItemStack var4; + int var5; + + for (Iterator var2 = this.field_94077_p.iterator(); var2.hasNext(); this.field_94069_F -= var4.stackSize - var5) { + Slot var3 = (Slot) var2.next(); + var4 = var1.copy(); + var5 = var3.getStack() == null ? 0 : var3.getStack().stackSize; + Container.func_94525_a(this.field_94077_p, this.field_94071_C, var4, var5); + + if (var4.stackSize > var4.getMaxStackSize()) { + var4.stackSize = var4.getMaxStackSize(); + } + + if (var4.stackSize > var3.getSlotStackLimit()) { + var4.stackSize = var3.getSlotStackLimit(); + } + } + } + } + + /** + * Returns the slot at the given coordinates or null if there is none. + */ + private Slot getSlotAtPosition(int par1, int par2) { + for (int var3 = 0; var3 < this.inventorySlots.inventorySlots.size(); ++var3) { + Slot var4 = (Slot) this.inventorySlots.inventorySlots.get(var3); + + if (this.isMouseOverSlot(var4, par1, par2)) { + return var4; + } + } + + return null; + } + + /** + * Called when the mouse is clicked. + */ + protected void mouseClicked(int par1, int par2, int par3) { + super.mouseClicked(par1, par2, par3); + boolean var4 = par3 == this.mc.gameSettings.keyBindPickBlock.keyCode + 100; + Slot var5 = this.getSlotAtPosition(par1, par2); + long var6 = Minecraft.getSystemTime(); + this.field_94074_J = this.field_94072_H == var5 && var6 - this.field_94070_G < 250L && this.field_94073_I == par3; + this.field_94068_E = false; + + if (par3 == 0 || par3 == 1 || var4) { + int var8 = this.guiLeft; + int var9 = this.guiTop; + boolean var10 = par1 < var8 || par2 < var9 || par1 >= var8 + this.xSize || par2 >= var9 + this.ySize; + int var11 = -1; + + if (var5 != null) { + var11 = var5.slotNumber; + } + + if (var10) { + var11 = -999; + } + + if (this.mc.gameSettings.touchscreen && var10 && this.mc.thePlayer.inventory.getItemStack() == null) { + this.mc.displayGuiScreen((GuiScreen) null); + return; + } + + if (var11 != -1) { + if (this.mc.gameSettings.touchscreen) { + if (var5 != null && var5.getHasStack()) { + this.clickedSlot = var5; + this.draggedStack = null; + this.isRightMouseClick = par3 == 1; + } else { + this.clickedSlot = null; + } + } else if (!this.field_94076_q) { + if (this.mc.thePlayer.inventory.getItemStack() == null) { + if (par3 == this.mc.gameSettings.keyBindPickBlock.keyCode + 100) { + this.handleMouseClick(var5, var11, par3, 3); + } else { + boolean var12 = var11 != -999 && (EaglerAdapter.isKeyDown(42) || EaglerAdapter.isKeyDown(54)); + byte var13 = 0; + + if (var12) { + this.field_94075_K = var5 != null && var5.getHasStack() ? var5.getStack() : null; + var13 = 1; + } else if (var11 == -999) { + var13 = 4; + } + + this.handleMouseClick(var5, var11, par3, var13); + } + + this.field_94068_E = true; + } else { + this.field_94076_q = true; + this.field_94067_D = par3; + this.field_94077_p.clear(); + + if (par3 == 0) { + this.field_94071_C = 0; + } else if (par3 == 1) { + this.field_94071_C = 1; + } + } + } + } + } + + this.field_94072_H = var5; + this.field_94070_G = var6; + this.field_94073_I = par3; + } + + protected void func_85041_a(int par1, int par2, int par3, long par4) { + Slot var6 = this.getSlotAtPosition(par1, par2); + ItemStack var7 = this.mc.thePlayer.inventory.getItemStack(); + + if (this.clickedSlot != null && this.mc.gameSettings.touchscreen) { + if (par3 == 0 || par3 == 1) { + if (this.draggedStack == null) { + if (var6 != this.clickedSlot) { + this.draggedStack = this.clickedSlot.getStack().copy(); + } + } else if (this.draggedStack.stackSize > 1 && var6 != null && Container.func_94527_a(var6, this.draggedStack, false)) { + long var8 = Minecraft.getSystemTime(); + + if (this.field_92033_y == var6) { + if (var8 - this.field_92032_z > 500L) { + this.handleMouseClick(this.clickedSlot, this.clickedSlot.slotNumber, 0, 0); + this.handleMouseClick(var6, var6.slotNumber, 1, 0); + this.handleMouseClick(this.clickedSlot, this.clickedSlot.slotNumber, 0, 0); + this.field_92032_z = var8 + 750L; + --this.draggedStack.stackSize; + } + } else { + this.field_92033_y = var6; + this.field_92032_z = var8; + } + } + } + } else if (this.field_94076_q && var6 != null && var7 != null && var7.stackSize > this.field_94077_p.size() && Container.func_94527_a(var6, var7, true) && var6.isItemValid(var7) && this.inventorySlots.func_94531_b(var6)) { + this.field_94077_p.add(var6); + this.func_94066_g(); + } + } + + /** + * Called when the mouse is moved or a mouse button is released. Signature: + * (mouseX, mouseY, which) which==-1 is mouseMove, which==0 or which==1 is + * mouseUp + */ + protected void mouseMovedOrUp(int par1, int par2, int par3) { + Slot var4 = this.getSlotAtPosition(par1, par2); + int var5 = this.guiLeft; + int var6 = this.guiTop; + boolean var7 = par1 < var5 || par2 < var6 || par1 >= var5 + this.xSize || par2 >= var6 + this.ySize; + int var8 = -1; + + if (var4 != null) { + var8 = var4.slotNumber; + } + + if (var7) { + var8 = -999; + } + + Slot var10; + Iterator var11; + + if (this.field_94074_J && var4 != null && par3 == 0 && this.inventorySlots.func_94530_a((ItemStack) null, var4)) { + if (isShiftKeyDown()) { + if (var4 != null && var4.inventory != null && this.field_94075_K != null) { + var11 = this.inventorySlots.inventorySlots.iterator(); + + while (var11.hasNext()) { + var10 = (Slot) var11.next(); + + if (var10 != null && var10.canTakeStack(this.mc.thePlayer) && var10.getHasStack() && var10.inventory == var4.inventory && Container.func_94527_a(var10, this.field_94075_K, true)) { + this.handleMouseClick(var10, var10.slotNumber, par3, 1); + } + } + } + } else { + this.handleMouseClick(var4, var8, par3, 6); + } + + this.field_94074_J = false; + this.field_94070_G = 0L; + } else { + if (this.field_94076_q && this.field_94067_D != par3) { + this.field_94076_q = false; + this.field_94077_p.clear(); + this.field_94068_E = true; + return; + } + + if (this.field_94068_E) { + this.field_94068_E = false; + return; + } + + boolean var9; + + if (this.clickedSlot != null && this.mc.gameSettings.touchscreen) { + if (par3 == 0 || par3 == 1) { + if (this.draggedStack == null && var4 != this.clickedSlot) { + this.draggedStack = this.clickedSlot.getStack(); + } + + var9 = Container.func_94527_a(var4, this.draggedStack, false); + + if (var8 != -1 && this.draggedStack != null && var9) { + this.handleMouseClick(this.clickedSlot, this.clickedSlot.slotNumber, par3, 0); + this.handleMouseClick(var4, var8, 0, 0); + + if (this.mc.thePlayer.inventory.getItemStack() != null) { + this.handleMouseClick(this.clickedSlot, this.clickedSlot.slotNumber, par3, 0); + this.field_85049_r = par1 - var5; + this.field_85048_s = par2 - var6; + this.returningStackDestSlot = this.clickedSlot; + this.returningStack = this.draggedStack; + this.returningStackTime = Minecraft.getSystemTime(); + } else { + this.returningStack = null; + } + } else if (this.draggedStack != null) { + this.field_85049_r = par1 - var5; + this.field_85048_s = par2 - var6; + this.returningStackDestSlot = this.clickedSlot; + this.returningStack = this.draggedStack; + this.returningStackTime = Minecraft.getSystemTime(); + } + + this.draggedStack = null; + this.clickedSlot = null; + } + } else if (this.field_94076_q && !this.field_94077_p.isEmpty()) { + this.handleMouseClick((Slot) null, -999, Container.func_94534_d(0, this.field_94071_C), 5); + var11 = this.field_94077_p.iterator(); + + while (var11.hasNext()) { + var10 = (Slot) var11.next(); + this.handleMouseClick(var10, var10.slotNumber, Container.func_94534_d(1, this.field_94071_C), 5); + } + + this.handleMouseClick((Slot) null, -999, Container.func_94534_d(2, this.field_94071_C), 5); + } else if (this.mc.thePlayer.inventory.getItemStack() != null) { + if (par3 == this.mc.gameSettings.keyBindPickBlock.keyCode + 100) { + this.handleMouseClick(var4, var8, par3, 3); + } else { + var9 = var8 != -999 && (EaglerAdapter.isKeyDown(42) || EaglerAdapter.isKeyDown(54)); + + if (var9) { + this.field_94075_K = var4 != null && var4.getHasStack() ? var4.getStack() : null; + } + + this.handleMouseClick(var4, var8, par3, var9 ? 1 : 0); + } + } + } + + if (this.mc.thePlayer.inventory.getItemStack() == null) { + this.field_94070_G = 0L; + } + + this.field_94076_q = false; + } + + /** + * Returns if the passed mouse position is over the specified slot. + */ + private boolean isMouseOverSlot(Slot par1Slot, int par2, int par3) { + return this.isPointInRegion(par1Slot.xDisplayPosition, par1Slot.yDisplayPosition, 16, 16, par2, par3); + } + + /** + * Args: left, top, width, height, pointX, pointY. Note: left, top are local to + * Gui, pointX, pointY are local to screen + */ + protected boolean isPointInRegion(int par1, int par2, int par3, int par4, int par5, int par6) { + int var7 = this.guiLeft; + int var8 = this.guiTop; + par5 -= var7; + par6 -= var8; + return par5 >= par1 - 1 && par5 < par1 + par3 + 1 && par6 >= par2 - 1 && par6 < par2 + par4 + 1; + } + + protected void handleMouseClick(Slot par1Slot, int par2, int par3, int par4) { + if (par1Slot != null) { + par2 = par1Slot.slotNumber; + } + + this.mc.playerController.windowClick(this.inventorySlots.windowId, par2, par3, par4, this.mc.thePlayer); + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + if (par2 == 1 || par2 == this.mc.gameSettings.keyBindInventory.keyCode) { + this.mc.thePlayer.closeScreen(); + } + + this.checkHotbarKeys(par2); + + if (this.theSlot != null && this.theSlot.getHasStack()) { + if (par2 == this.mc.gameSettings.keyBindPickBlock.keyCode) { + this.handleMouseClick(this.theSlot, this.theSlot.slotNumber, 0, 3); + } else if (par2 == this.mc.gameSettings.keyBindDrop.keyCode) { + this.handleMouseClick(this.theSlot, this.theSlot.slotNumber, isCtrlKeyDown() ? 1 : 0, 4); + } + } + } + + /** + * This function is what controls the hotbar shortcut check when you press a + * number key when hovering a stack. + */ + protected boolean checkHotbarKeys(int par1) { + if (this.mc.thePlayer.inventory.getItemStack() == null && this.theSlot != null) { + for (int var2 = 0; var2 < 9; ++var2) { + if (par1 == 2 + var2) { + this.handleMouseClick(this.theSlot, this.theSlot.slotNumber, var2, 2); + return true; + } + } + } + + return false; + } + + /** + * Called when the screen is unloaded. Used to disable keyboard repeat events + */ + public void onGuiClosed() { + if (this.mc.thePlayer != null) { + this.inventorySlots.onCraftGuiClosed(this.mc.thePlayer); + } + } + + /** + * Returns true if this GUI should pause the game when it is displayed in + * single-player + */ + public boolean doesGuiPauseGame() { + return false; + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + super.updateScreen(); + + if (!this.mc.thePlayer.isEntityAlive() || this.mc.thePlayer.isDead) { + this.mc.thePlayer.closeScreen(); + } + } +} diff --git a/src/main/java/net/minecraft/src/GuiContainerCreative.java b/src/main/java/net/minecraft/src/GuiContainerCreative.java new file mode 100644 index 0000000..4e522d0 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiContainerCreative.java @@ -0,0 +1,690 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiContainerCreative extends InventoryEffectRenderer { + private static InventoryBasic inventory = new InventoryBasic("tmp", true, 45); + + /** Currently selected creative inventory tab index. */ + private static int selectedTabIndex = CreativeTabs.tabBlock.getTabIndex(); + + /** Amount scrolled in Creative mode inventory (0 = top, 1 = bottom) */ + private float currentScroll = 0.0F; + + /** True if the scrollbar is being dragged */ + private boolean isScrolling = false; + + /** + * True if the left mouse button was held down last time drawScreen was called. + */ + private boolean wasClicking; + private GuiTextField searchField; + + /** + * Used to back up the ContainerCreative's inventory slots before filling it + * with the player's inventory slots for the inventory tab. + */ + private List backupContainerSlots; + private Slot field_74235_v = null; + private boolean field_74234_w = false; + private CreativeCrafting field_82324_x; + + public GuiContainerCreative(EntityPlayer par1EntityPlayer) { + super(new ContainerCreative(par1EntityPlayer)); + par1EntityPlayer.openContainer = this.inventorySlots; + this.allowUserInput = true; + par1EntityPlayer.addStat(AchievementList.openInventory, 1); + this.ySize = 136; + this.xSize = 195; + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + if (!this.mc.playerController.isInCreativeMode()) { + this.mc.displayGuiScreen(new GuiInventory(this.mc.thePlayer)); + } + } + + protected void handleMouseClick(Slot par1Slot, int par2, int par3, int par4) { + this.field_74234_w = true; + boolean var5 = par4 == 1; + par4 = par2 == -999 && par4 == 0 ? 4 : par4; + ItemStack var7; + InventoryPlayer var11; + + if (par1Slot == null && selectedTabIndex != CreativeTabs.tabInventory.getTabIndex() && par4 != 5) { + var11 = this.mc.thePlayer.inventory; + + if (var11.getItemStack() != null) { + if (par3 == 0) { + this.mc.thePlayer.dropPlayerItem(var11.getItemStack()); + this.mc.playerController.func_78752_a(var11.getItemStack()); + var11.setItemStack((ItemStack) null); + } + + if (par3 == 1) { + var7 = var11.getItemStack().splitStack(1); + this.mc.thePlayer.dropPlayerItem(var7); + this.mc.playerController.func_78752_a(var7); + + if (var11.getItemStack().stackSize == 0) { + var11.setItemStack((ItemStack) null); + } + } + } + } else { + int var10; + + if (par1Slot == this.field_74235_v && var5) { + for (var10 = 0; var10 < this.mc.thePlayer.inventoryContainer.getInventory().size(); ++var10) { + this.mc.playerController.sendSlotPacket((ItemStack) null, var10); + } + } else { + ItemStack var6; + + if (selectedTabIndex == CreativeTabs.tabInventory.getTabIndex()) { + if (par1Slot == this.field_74235_v) { + this.mc.thePlayer.inventory.setItemStack((ItemStack) null); + } else if (par4 == 4 && par1Slot != null && par1Slot.getHasStack()) { + var6 = par1Slot.decrStackSize(par3 == 0 ? 1 : par1Slot.getStack().getMaxStackSize()); + this.mc.thePlayer.dropPlayerItem(var6); + this.mc.playerController.func_78752_a(var6); + } else if (par4 == 4 && this.mc.thePlayer.inventory.getItemStack() != null) { + this.mc.thePlayer.dropPlayerItem(this.mc.thePlayer.inventory.getItemStack()); + this.mc.playerController.func_78752_a(this.mc.thePlayer.inventory.getItemStack()); + this.mc.thePlayer.inventory.setItemStack((ItemStack) null); + } else { + this.mc.thePlayer.inventoryContainer.slotClick(par1Slot == null ? par2 : SlotCreativeInventory.func_75240_a((SlotCreativeInventory) par1Slot).slotNumber, par3, par4, this.mc.thePlayer); + this.mc.thePlayer.inventoryContainer.detectAndSendChanges(); + } + } else if (par4 != 5 && par1Slot.inventory == inventory) { + var11 = this.mc.thePlayer.inventory; + var7 = var11.getItemStack(); + ItemStack var8 = par1Slot.getStack(); + ItemStack var9; + + if (par4 == 2) { + if (var8 != null && par3 >= 0 && par3 < 9) { + var9 = var8.copy(); + var9.stackSize = var9.getMaxStackSize(); + this.mc.thePlayer.inventory.setInventorySlotContents(par3, var9); + this.mc.thePlayer.inventoryContainer.detectAndSendChanges(); + } + + return; + } + + if (par4 == 3) { + if (var11.getItemStack() == null && par1Slot.getHasStack()) { + var9 = par1Slot.getStack().copy(); + var9.stackSize = var9.getMaxStackSize(); + var11.setItemStack(var9); + } + + return; + } + + if (par4 == 4) { + if (var8 != null) { + var9 = var8.copy(); + var9.stackSize = par3 == 0 ? 1 : var9.getMaxStackSize(); + this.mc.thePlayer.dropPlayerItem(var9); + this.mc.playerController.func_78752_a(var9); + } + + return; + } + + if (var7 != null && var8 != null && var7.isItemEqual(var8)) { + if (par3 == 0) { + if (var5) { + var7.stackSize = var7.getMaxStackSize(); + } else if (var7.stackSize < var7.getMaxStackSize()) { + ++var7.stackSize; + } + } else if (var7.stackSize <= 1) { + var11.setItemStack((ItemStack) null); + } else { + --var7.stackSize; + } + } else if (var8 != null && var7 == null) { + var11.setItemStack(ItemStack.copyItemStack(var8)); + var7 = var11.getItemStack(); + + if (var5) { + var7.stackSize = var7.getMaxStackSize(); + } + } else { + var11.setItemStack((ItemStack) null); + } + } else { + this.inventorySlots.slotClick(par1Slot == null ? par2 : par1Slot.slotNumber, par3, par4, this.mc.thePlayer); + + if (Container.func_94532_c(par3) == 2) { + for (var10 = 0; var10 < 9; ++var10) { + this.mc.playerController.sendSlotPacket(this.inventorySlots.getSlot(45 + var10).getStack(), 36 + var10); + } + } else if (par1Slot != null) { + var6 = this.inventorySlots.getSlot(par1Slot.slotNumber).getStack(); + this.mc.playerController.sendSlotPacket(var6, par1Slot.slotNumber - this.inventorySlots.inventorySlots.size() + 9 + 36); + } + } + } + } + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + if (this.mc.playerController.isInCreativeMode()) { + super.initGui(); + this.buttonList.clear(); + EaglerAdapter.enableRepeatEvents(true); + this.searchField = new GuiTextField(this.fontRenderer, this.guiLeft + 82, this.guiTop + 6, 89, this.fontRenderer.FONT_HEIGHT); + this.searchField.setMaxStringLength(15); + this.searchField.setEnableBackgroundDrawing(false); + this.searchField.setVisible(false); + this.searchField.setTextColor(16777215); + int var1 = selectedTabIndex; + selectedTabIndex = -1; + this.setCurrentCreativeTab(CreativeTabs.creativeTabArray[var1]); + this.field_82324_x = new CreativeCrafting(this.mc); + this.mc.thePlayer.inventoryContainer.addCraftingToCrafters(this.field_82324_x); + } else { + this.mc.displayGuiScreen(new GuiInventory(this.mc.thePlayer)); + } + } + + /** + * Called when the screen is unloaded. Used to disable keyboard repeat events + */ + public void onGuiClosed() { + super.onGuiClosed(); + + if (this.mc.thePlayer != null && this.mc.thePlayer.inventory != null) { + this.mc.thePlayer.inventoryContainer.removeCraftingFromCrafters(this.field_82324_x); + } + + EaglerAdapter.enableRepeatEvents(false); + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + if (selectedTabIndex != CreativeTabs.tabAllSearch.getTabIndex()) { + if (GameSettings.isKeyDown(this.mc.gameSettings.keyBindChat)) { + this.setCurrentCreativeTab(CreativeTabs.tabAllSearch); + } else { + super.keyTyped(par1, par2); + } + } else { + if (this.field_74234_w) { + this.field_74234_w = false; + this.searchField.setText(""); + } + + if (!this.checkHotbarKeys(par2)) { + if (this.searchField.textboxKeyTyped(par1, par2)) { + this.updateCreativeSearch(); + } else { + super.keyTyped(par1, par2); + } + } + } + } + + private void updateCreativeSearch() { + ContainerCreative var1 = (ContainerCreative) this.inventorySlots; + var1.itemList.clear(); + Item[] var2 = Item.itemsList; + int var3 = var2.length; + int var4; + + for (var4 = 0; var4 < var3; ++var4) { + Item var5 = var2[var4]; + + if (var5 != null && var5.getCreativeTab() != null) { + var5.getSubItems(var5.itemID, (CreativeTabs) null, var1.itemList); + } + } + + Enchantment[] var8 = Enchantment.enchantmentsList; + var3 = var8.length; + + for (var4 = 0; var4 < var3; ++var4) { + Enchantment var11 = var8[var4]; + + if (var11 != null && var11.type != null) { + Item.enchantedBook.func_92113_a(var11, var1.itemList); + } + } + + Iterator var9 = var1.itemList.iterator(); + String var10 = this.searchField.getText().toLowerCase(); + + while (var9.hasNext()) { + ItemStack var12 = (ItemStack) var9.next(); + boolean var13 = false; + Iterator var6 = var12.getTooltip(this.mc.thePlayer, this.mc.gameSettings.advancedItemTooltips).iterator(); + + while (true) { + if (var6.hasNext()) { + String var7 = (String) var6.next(); + + if (!var7.toLowerCase().contains(var10)) { + continue; + } + + var13 = true; + } + + if (!var13) { + var9.remove(); + } + + break; + } + } + + this.currentScroll = 0.0F; + var1.scrollTo(0.0F); + } + + /** + * Draw the foreground layer for the GuiContainer (everything in front of the + * items) + */ + protected void drawGuiContainerForegroundLayer(int par1, int par2) { + CreativeTabs var3 = CreativeTabs.creativeTabArray[selectedTabIndex]; + + if (var3.drawInForegroundOfTab()) { + this.fontRenderer.drawString(var3.getTranslatedTabLabel(), 8, 6, 4210752); + } + } + + /** + * Called when the mouse is clicked. + */ + protected void mouseClicked(int par1, int par2, int par3) { + if (par3 == 0) { + int var4 = par1 - this.guiLeft; + int var5 = par2 - this.guiTop; + CreativeTabs[] var6 = CreativeTabs.creativeTabArray; + int var7 = var6.length; + + for (int var8 = 0; var8 < var7; ++var8) { + CreativeTabs var9 = var6[var8]; + + if (this.func_74232_a(var9, var4, var5)) { + return; + } + } + } + + super.mouseClicked(par1, par2, par3); + } + + /** + * Called when the mouse is moved or a mouse button is released. Signature: + * (mouseX, mouseY, which) which==-1 is mouseMove, which==0 or which==1 is + * mouseUp + */ + protected void mouseMovedOrUp(int par1, int par2, int par3) { + if (par3 == 0) { + int var4 = par1 - this.guiLeft; + int var5 = par2 - this.guiTop; + CreativeTabs[] var6 = CreativeTabs.creativeTabArray; + int var7 = var6.length; + + for (int var8 = 0; var8 < var7; ++var8) { + CreativeTabs var9 = var6[var8]; + + if (this.func_74232_a(var9, var4, var5)) { + this.setCurrentCreativeTab(var9); + return; + } + } + } + + super.mouseMovedOrUp(par1, par2, par3); + } + + /** + * returns (if you are not on the inventoryTab) and (the flag isn't set) and( + * you have more than 1 page of items) + */ + private boolean needsScrollBars() { + return selectedTabIndex != CreativeTabs.tabInventory.getTabIndex() && CreativeTabs.creativeTabArray[selectedTabIndex].shouldHidePlayerInventory() && ((ContainerCreative) this.inventorySlots).hasMoreThan1PageOfItemsInList(); + } + + private void setCurrentCreativeTab(CreativeTabs par1CreativeTabs) { + int var2 = selectedTabIndex; + selectedTabIndex = par1CreativeTabs.getTabIndex(); + ContainerCreative var3 = (ContainerCreative) this.inventorySlots; + this.field_94077_p.clear(); + var3.itemList.clear(); + par1CreativeTabs.displayAllReleventItems(var3.itemList); + + if (par1CreativeTabs == CreativeTabs.tabInventory) { + Container var4 = this.mc.thePlayer.inventoryContainer; + + if (this.backupContainerSlots == null) { + this.backupContainerSlots = var3.inventorySlots; + } + + var3.inventorySlots = new ArrayList(); + + for (int var5 = 0; var5 < var4.inventorySlots.size(); ++var5) { + SlotCreativeInventory var6 = new SlotCreativeInventory(this, (Slot) var4.inventorySlots.get(var5), var5); + var3.inventorySlots.add(var6); + int var7; + int var8; + int var9; + + if (var5 >= 5 && var5 < 9) { + var7 = var5 - 5; + var8 = var7 / 2; + var9 = var7 % 2; + var6.xDisplayPosition = 9 + var8 * 54; + var6.yDisplayPosition = 6 + var9 * 27; + } else if (var5 >= 0 && var5 < 5) { + var6.yDisplayPosition = -2000; + var6.xDisplayPosition = -2000; + } else if (var5 < var4.inventorySlots.size()) { + var7 = var5 - 9; + var8 = var7 % 9; + var9 = var7 / 9; + var6.xDisplayPosition = 9 + var8 * 18; + + if (var5 >= 36) { + var6.yDisplayPosition = 112; + } else { + var6.yDisplayPosition = 54 + var9 * 18; + } + } + } + + this.field_74235_v = new Slot(inventory, 0, 173, 112); + var3.inventorySlots.add(this.field_74235_v); + } else if (var2 == CreativeTabs.tabInventory.getTabIndex()) { + var3.inventorySlots = this.backupContainerSlots; + this.backupContainerSlots = null; + } + + if (this.searchField != null) { + if (par1CreativeTabs == CreativeTabs.tabAllSearch) { + this.searchField.setVisible(true); + this.searchField.setCanLoseFocus(false); + this.searchField.setFocused(true); + this.searchField.setText(""); + this.updateCreativeSearch(); + } else { + this.searchField.setVisible(false); + this.searchField.setCanLoseFocus(true); + this.searchField.setFocused(false); + } + } + + this.currentScroll = 0.0F; + var3.scrollTo(0.0F); + } + + /** + * Handles mouse input. + */ + public void handleMouseInput() { + super.handleMouseInput(); + int var1 = EaglerAdapter.mouseGetEventDWheel(); + + if (var1 != 0 && this.needsScrollBars()) { + int var2 = ((ContainerCreative) this.inventorySlots).itemList.size() / 9 - 5 + 1; + + if (var1 > 0) { + var1 = 1; + } + + if (var1 < 0) { + var1 = -1; + } + + this.currentScroll = (float) ((double) this.currentScroll - (double) var1 / (double) var2); + + if (this.currentScroll < 0.0F) { + this.currentScroll = 0.0F; + } + + if (this.currentScroll > 1.0F) { + this.currentScroll = 1.0F; + } + + ((ContainerCreative) this.inventorySlots).scrollTo(this.currentScroll); + } + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + boolean var4 = EaglerAdapter.mouseIsButtonDown(0); + int var5 = this.guiLeft; + int var6 = this.guiTop; + int var7 = var5 + 175; + int var8 = var6 + 18; + int var9 = var7 + 14; + int var10 = var8 + 112; + + if (!this.wasClicking && var4 && par1 >= var7 && par2 >= var8 && par1 < var9 && par2 < var10) { + this.isScrolling = this.needsScrollBars(); + } + + if (!var4) { + this.isScrolling = false; + } + + this.wasClicking = var4; + + if (this.isScrolling) { + this.currentScroll = ((float) (par2 - var8) - 7.5F) / ((float) (var10 - var8) - 15.0F); + + if (this.currentScroll < 0.0F) { + this.currentScroll = 0.0F; + } + + if (this.currentScroll > 1.0F) { + this.currentScroll = 1.0F; + } + + ((ContainerCreative) this.inventorySlots).scrollTo(this.currentScroll); + } + + super.drawScreen(par1, par2, par3); + CreativeTabs[] var11 = CreativeTabs.creativeTabArray; + int var12 = var11.length; + + for (int var13 = 0; var13 < var12; ++var13) { + CreativeTabs var14 = var11[var13]; + + if (this.renderCreativeInventoryHoveringText(var14, par1, par2)) { + break; + } + } + + if (this.field_74235_v != null && selectedTabIndex == CreativeTabs.tabInventory.getTabIndex() && this.isPointInRegion(this.field_74235_v.xDisplayPosition, this.field_74235_v.yDisplayPosition, 16, 16, par1, par2)) { + this.drawCreativeTabHoveringText(StringTranslate.getInstance().translateKey("inventory.binSlot"), par1, par2); + } + + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + } + + private static final TextureLocation tex = new TextureLocation("/gui/allitems.png"); + + /** + * Draw the background layer for the GuiContainer (everything behind the items) + */ + protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + RenderHelper.enableGUIStandardItemLighting(); + CreativeTabs var4 = CreativeTabs.creativeTabArray[selectedTabIndex]; + CreativeTabs[] var5 = CreativeTabs.creativeTabArray; + int var6 = var5.length; + int var7; + + for (var7 = 0; var7 < var6; ++var7) { + CreativeTabs var8 = var5[var7]; + tex.bindTexture(); + + if (var8.getTabIndex() != selectedTabIndex) { + this.renderCreativeTab(var8); + } + } + + this.mc.renderEngine.bindTexture("/gui/creative_inv/" + var4.getBackgroundImageName()); + this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize); + this.searchField.drawTextBox(); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + int var9 = this.guiLeft + 175; + var6 = this.guiTop + 18; + var7 = var6 + 112; + tex.bindTexture(); + + if (var4.shouldHidePlayerInventory()) { + this.drawTexturedModalRect(var9, var6 + (int) ((float) (var7 - var6 - 17) * this.currentScroll), 232 + (this.needsScrollBars() ? 0 : 12), 0, 12, 15); + } + + this.renderCreativeTab(var4); + + if (var4 == CreativeTabs.tabInventory) { + GuiInventory.drawPlayerOnGui(this.mc, this.guiLeft + 43, this.guiTop + 45, 20, (float) (this.guiLeft + 43 - par2), (float) (this.guiTop + 45 - 30 - par3)); + } + } + + protected boolean func_74232_a(CreativeTabs par1CreativeTabs, int par2, int par3) { + int var4 = par1CreativeTabs.getTabColumn(); + int var5 = 28 * var4; + byte var6 = 0; + + if (var4 == 5) { + var5 = this.xSize - 28 + 2; + } else if (var4 > 0) { + var5 += var4; + } + + int var7; + + if (par1CreativeTabs.isTabInFirstRow()) { + var7 = var6 - 32; + } else { + var7 = var6 + this.ySize; + } + + return par2 >= var5 && par2 <= var5 + 28 && par3 >= var7 && par3 <= var7 + 32; + } + + /** + * Renders the creative inventory hovering text if mouse is over it. Returns + * true if did render or false otherwise. Params: current creative tab to be + * checked, current mouse x position, current mouse y position. + */ + protected boolean renderCreativeInventoryHoveringText(CreativeTabs par1CreativeTabs, int par2, int par3) { + int var4 = par1CreativeTabs.getTabColumn(); + int var5 = 28 * var4; + byte var6 = 0; + + if (var4 == 5) { + var5 = this.xSize - 28 + 2; + } else if (var4 > 0) { + var5 += var4; + } + + int var7; + + if (par1CreativeTabs.isTabInFirstRow()) { + var7 = var6 - 32; + } else { + var7 = var6 + this.ySize; + } + + if (this.isPointInRegion(var5 + 3, var7 + 3, 23, 27, par2, par3)) { + this.drawCreativeTabHoveringText(par1CreativeTabs.getTranslatedTabLabel(), par2, par3); + return true; + } else { + return false; + } + } + + /** + * Renders passed creative inventory tab into the screen. + */ + protected void renderCreativeTab(CreativeTabs par1CreativeTabs) { + boolean var2 = par1CreativeTabs.getTabIndex() == selectedTabIndex; + boolean var3 = par1CreativeTabs.isTabInFirstRow(); + int var4 = par1CreativeTabs.getTabColumn(); + int var5 = var4 * 28; + int var6 = 0; + int var7 = this.guiLeft + 28 * var4; + int var8 = this.guiTop; + byte var9 = 32; + + if (var2) { + var6 += 32; + } + + if (var4 == 5) { + var7 = this.guiLeft + this.xSize - 28; + } else if (var4 > 0) { + var7 += var4; + } + + if (var3) { + var8 -= 28; + } else { + var6 += 64; + var8 += this.ySize - 4; + } + + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + this.drawTexturedModalRect(var7, var8, var5, var6, 28, var9); + this.zLevel = 100.0F; + itemRenderer.zLevel = 100.0F; + var7 += 6; + var8 += 8 + (var3 ? 1 : -1); + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + ItemStack var10 = new ItemStack(par1CreativeTabs.getTabIconItem()); + itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, var10, var7, var8); + itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, var10, var7, var8); + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + itemRenderer.zLevel = 0.0F; + this.zLevel = 0.0F; + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + } + + public int func_74230_h() { + return selectedTabIndex; + } + + /** + * Returns the creative inventory + */ + static InventoryBasic getInventory() { + return inventory; + } +} diff --git a/src/main/java/net/minecraft/src/GuiControls.java b/src/main/java/net/minecraft/src/GuiControls.java new file mode 100644 index 0000000..d05b253 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiControls.java @@ -0,0 +1,132 @@ +package net.minecraft.src; + +public class GuiControls extends GuiScreen { + /** + * A reference to the screen object that created this. Used for navigating + * between screens. + */ + private GuiScreen parentScreen; + + /** The title string that is displayed in the top-center of the screen. */ + protected String screenTitle = "Controls"; + + /** Reference to the GameSettings object. */ + private GameSettings options; + + /** The ID of the button that has been pressed. */ + private int buttonId = -1; + + public GuiControls(GuiScreen par1GuiScreen, GameSettings par2GameSettings) { + this.parentScreen = par1GuiScreen; + this.options = par2GameSettings; + } + + /** + * Gets the distance from the left border of the window to left border of the + * controls screen + */ + private int getLeftBorder() { + return this.width / 2 - 155; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + StringTranslate var1 = StringTranslate.getInstance(); + int var2 = this.getLeftBorder(); + + for (int var3 = 0; var3 < this.options.keyBindings.length; ++var3) { + this.buttonList.add(new GuiSmallButton(var3, var2 + var3 % 2 * 160, this.height / 6 + 20 * (var3 >> 1), 70, 20, this.options.getOptionDisplayString(var3))); + } + + this.buttonList.add(new GuiButton(200, this.width / 2 - 100, this.height / 6 + 168, var1.translateKey("gui.done"))); + this.screenTitle = var1.translateKey("controls.title"); + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + for (int var2 = 0; var2 < this.options.keyBindings.length; ++var2) { + ((GuiButton) this.buttonList.get(var2)).displayString = this.options.getOptionDisplayString(var2); + } + + if (par1GuiButton.id == 200) { + this.mc.displayGuiScreen(this.parentScreen); + } else { + this.buttonId = par1GuiButton.id; + par1GuiButton.displayString = "> " + this.options.getOptionDisplayString(par1GuiButton.id) + " <"; + } + } + + /** + * Called when the mouse is clicked. + */ + protected void mouseClicked(int par1, int par2, int par3) { + if (this.buttonId >= 0) { + this.options.setKeyBinding(this.buttonId, -100 + par3); + ((GuiButton) this.buttonList.get(this.buttonId)).displayString = this.options.getOptionDisplayString(this.buttonId); + this.buttonId = -1; + KeyBinding.resetKeyBindingArrayAndHash(); + } else { + super.mouseClicked(par1, par2, par3); + } + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + if (this.buttonId >= 0) { + this.options.setKeyBinding(this.buttonId, par2); + ((GuiButton) this.buttonList.get(this.buttonId)).displayString = this.options.getOptionDisplayString(this.buttonId); + this.buttonId = -1; + KeyBinding.resetKeyBindingArrayAndHash(); + } else { + super.keyTyped(par1, par2); + } + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, 20, 16777215); + int var4 = this.getLeftBorder(); + int var5 = 0; + + while (var5 < this.options.keyBindings.length) { + boolean var6 = false; + int var7 = 0; + + while (true) { + if (var7 < this.options.keyBindings.length) { + if (var7 == var5 || this.options.keyBindings[var5].keyCode != this.options.keyBindings[var7].keyCode) { + ++var7; + continue; + } + + var6 = true; + } + + if (this.buttonId == var5) { + ((GuiButton) this.buttonList.get(var5)).displayString = "" + EnumChatFormatting.WHITE + "> " + EnumChatFormatting.YELLOW + "??? " + EnumChatFormatting.WHITE + "<"; + } else if (var6) { + ((GuiButton) this.buttonList.get(var5)).displayString = EnumChatFormatting.RED + this.options.getOptionDisplayString(var5); + } else { + ((GuiButton) this.buttonList.get(var5)).displayString = this.options.getOptionDisplayString(var5); + } + + this.drawString(this.fontRenderer, this.options.getKeyBindingDescription(var5), var4 + var5 % 2 * 160 + 70 + 6, this.height / 6 + 20 * (var5 >> 1) + 7, -1); + ++var5; + break; + } + } + + super.drawScreen(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/GuiCrafting.java b/src/main/java/net/minecraft/src/GuiCrafting.java new file mode 100644 index 0000000..a7e9d69 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiCrafting.java @@ -0,0 +1,32 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiCrafting extends GuiContainer { + public GuiCrafting(InventoryPlayer par1InventoryPlayer, World par2World, int par3, int par4, int par5) { + super(new ContainerWorkbench(par1InventoryPlayer, par2World, par3, par4, par5)); + } + + /** + * Draw the foreground layer for the GuiContainer (everything in front of the + * items) + */ + protected void drawGuiContainerForegroundLayer(int par1, int par2) { + this.fontRenderer.drawString(StatCollector.translateToLocal("container.crafting"), 28, 6, 4210752); + this.fontRenderer.drawString(StatCollector.translateToLocal("container.inventory"), 8, this.ySize - 96 + 2, 4210752); + } + + private static final TextureLocation tex = new TextureLocation("/gui/crafting.png"); + + /** + * Draw the background layer for the GuiContainer (everything behind the items) + */ + protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex.bindTexture(); + int var4 = (this.width - this.xSize) / 2; + int var5 = (this.height - this.ySize) / 2; + this.drawTexturedModalRect(var4, var5, 0, 0, this.xSize, this.ySize); + } +} diff --git a/src/main/java/net/minecraft/src/GuiDisconnected.java b/src/main/java/net/minecraft/src/GuiDisconnected.java new file mode 100644 index 0000000..cae4b43 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiDisconnected.java @@ -0,0 +1,73 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class GuiDisconnected extends GuiScreen { + /** The error message. */ + private String errorMessage; + + /** The details about the error. */ + private String errorDetail; + private Object[] field_74247_c; + private List field_74245_d; + private final GuiScreen field_98095_n; + + public GuiDisconnected(GuiScreen par1GuiScreen, String par2Str, String par3Str, Object... par4ArrayOfObj) { + StringTranslate var5 = StringTranslate.getInstance(); + this.field_98095_n = par1GuiScreen; + this.errorMessage = var5.translateKey(par2Str); + this.errorDetail = par3Str; + this.field_74247_c = par4ArrayOfObj; + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + StringTranslate var1 = StringTranslate.getInstance(); + this.buttonList.clear(); + this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 120 + 12, var1.translateKey("gui.toMenu"))); + + if (this.field_74247_c != null) { + this.field_74245_d = this.fontRenderer.listFormattedStringToWidth(var1.translateKeyFormat(this.errorDetail, this.field_74247_c), this.width - 50); + } else { + this.field_74245_d = this.fontRenderer.listFormattedStringToWidth(var1.translateKey(this.errorDetail), this.width - 50); + } + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.id == 0) { + this.mc.displayGuiScreen(this.field_98095_n); + } + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, this.errorMessage, this.width / 2, this.height / 2 - 50, 11184810); + int var4 = this.height / 2 - 30; + + if (this.field_74245_d != null) { + for (Iterator var5 = this.field_74245_d.iterator(); var5.hasNext(); var4 += this.fontRenderer.FONT_HEIGHT) { + String var6 = (String) var5.next(); + this.drawCenteredString(this.fontRenderer, var6, this.width / 2, var4, 16777215); + } + } + + super.drawScreen(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/GuiDispenser.java b/src/main/java/net/minecraft/src/GuiDispenser.java new file mode 100644 index 0000000..5e07966 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiDispenser.java @@ -0,0 +1,36 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiDispenser extends GuiContainer { + public TileEntityDispenser field_94078_r; + + public GuiDispenser(InventoryPlayer par1InventoryPlayer, TileEntityDispenser par2TileEntityDispenser) { + super(new ContainerDispenser(par1InventoryPlayer, par2TileEntityDispenser)); + this.field_94078_r = par2TileEntityDispenser; + } + + /** + * Draw the foreground layer for the GuiContainer (everything in front of the + * items) + */ + protected void drawGuiContainerForegroundLayer(int par1, int par2) { + String var3 = this.field_94078_r.isInvNameLocalized() ? this.field_94078_r.getInvName() : StatCollector.translateToLocal(this.field_94078_r.getInvName()); + this.fontRenderer.drawString(var3, this.xSize / 2 - this.fontRenderer.getStringWidth(var3) / 2, 6, 4210752); + this.fontRenderer.drawString(StatCollector.translateToLocal("container.inventory"), 8, this.ySize - 96 + 2, 4210752); + } + + private static final TextureLocation tex = new TextureLocation("/gui/trap.png"); + + /** + * Draw the background layer for the GuiContainer (everything behind the items) + */ + protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex.bindTexture(); + int var4 = (this.width - this.xSize) / 2; + int var5 = (this.height - this.ySize) / 2; + this.drawTexturedModalRect(var4, var5, 0, 0, this.xSize, this.ySize); + } +} diff --git a/src/main/java/net/minecraft/src/GuiDownloadTerrain.java b/src/main/java/net/minecraft/src/GuiDownloadTerrain.java new file mode 100644 index 0000000..d3aafd6 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiDownloadTerrain.java @@ -0,0 +1,52 @@ +package net.minecraft.src; + +public class GuiDownloadTerrain extends GuiScreen { + /** Network object that downloads the terrain data. */ + private NetClientHandler netHandler; + + /** Counts the number of screen updates. */ + private int updateCounter = 0; + + public GuiDownloadTerrain(NetClientHandler par1NetClientHandler) { + this.netHandler = par1NetClientHandler; + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + this.buttonList.clear(); + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + ++this.updateCounter; + + if (this.updateCounter % 20 == 0) { + this.netHandler.addToSendQueue(new Packet0KeepAlive()); + } + + if (this.netHandler != null) { + this.netHandler.processReadPackets(); + } + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.drawBackground(0); + StringTranslate var4 = StringTranslate.getInstance(); + this.drawCenteredString(this.fontRenderer, var4.translateKey("multiplayer.downloadingTerrain"), this.width / 2, this.height / 2 - 50, 16777215); + super.drawScreen(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/GuiEditSign.java b/src/main/java/net/minecraft/src/GuiEditSign.java new file mode 100644 index 0000000..ef46275 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiEditSign.java @@ -0,0 +1,147 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +public class GuiEditSign extends GuiScreen { + /** + * This String is just a local copy of the characters allowed in text rendering + * of minecraft. + */ + private static final String allowedCharacters = ChatAllowedCharacters.allowedCharacters; + + /** The title string that is displayed in the top-center of the screen. */ + protected String screenTitle = "Edit sign message:"; + + /** Reference to the sign object. */ + private TileEntitySign entitySign; + + /** Counts the number of screen updates. */ + private int updateCounter; + + /** The number of the line that is being edited. */ + private int editLine = 0; + + /** "Done" button for the GUI. */ + private GuiButton doneBtn; + + public GuiEditSign(TileEntitySign par1TileEntitySign) { + this.entitySign = par1TileEntitySign; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + this.buttonList.clear(); + EaglerAdapter.enableRepeatEvents(true); + this.buttonList.add(this.doneBtn = new GuiButton(0, this.width / 2 - 100, this.height / 4 + 120, "Done")); + this.entitySign.setEditable(false); + } + + /** + * Called when the screen is unloaded. Used to disable keyboard repeat events + */ + public void onGuiClosed() { + EaglerAdapter.enableRepeatEvents(false); + NetClientHandler var1 = this.mc.getNetHandler(); + + if (var1 != null) { + var1.addToSendQueue(new Packet130UpdateSign(this.entitySign.xCoord, this.entitySign.yCoord, this.entitySign.zCoord, this.entitySign.signText)); + } + + this.entitySign.setEditable(true); + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + ++this.updateCounter; + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.enabled) { + if (par1GuiButton.id == 0) { + this.entitySign.onInventoryChanged(); + this.mc.displayGuiScreen((GuiScreen) null); + } + } + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + if (par2 == 200) { + this.editLine = this.editLine - 1 & 3; + } + + if (par2 == 208 || par2 == 28) { + this.editLine = this.editLine + 1 & 3; + } + + if (par2 == 14 && this.entitySign.signText[this.editLine].length() > 0) { + this.entitySign.signText[this.editLine] = this.entitySign.signText[this.editLine].substring(0, this.entitySign.signText[this.editLine].length() - 1); + } + + if (allowedCharacters.indexOf(par1) >= 0 && this.entitySign.signText[this.editLine].length() < 15) { + this.entitySign.signText[this.editLine] = this.entitySign.signText[this.editLine] + par1; + } + + if (par2 == 1) { + this.actionPerformed(this.doneBtn); + } + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, 40, 16777215); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef((float) (this.width / 2), 0.0F, 50.0F); + float var4 = 93.75F; + EaglerAdapter.glScalef(-var4, -var4, -var4); + EaglerAdapter.glRotatef(180.0F, 0.0F, 1.0F, 0.0F); + Block var5 = this.entitySign.getBlockType(); + + if (var5 == Block.signPost) { + float var6 = (float) (this.entitySign.getBlockMetadata() * 360) / 16.0F; + EaglerAdapter.glRotatef(var6, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glTranslatef(0.0F, -1.0625F, 0.0F); + } else { + int var8 = this.entitySign.getBlockMetadata(); + float var7 = 0.0F; + + if (var8 == 2) { + var7 = 180.0F; + } + + if (var8 == 4) { + var7 = 90.0F; + } + + if (var8 == 5) { + var7 = -90.0F; + } + + EaglerAdapter.glRotatef(var7, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glTranslatef(0.0F, -1.0625F, 0.0F); + } + + if (this.updateCounter / 6 % 2 == 0) { + this.entitySign.lineBeingEdited = this.editLine; + } + + TileEntityRenderer.instance.renderTileEntityAt(this.entitySign, -0.5D, -0.75D, -0.5D, 0.0F); + this.entitySign.lineBeingEdited = -1; + EaglerAdapter.glPopMatrix(); + super.drawScreen(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/GuiEnchantment.java b/src/main/java/net/minecraft/src/GuiEnchantment.java new file mode 100644 index 0000000..75d4053 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiEnchantment.java @@ -0,0 +1,226 @@ +package net.minecraft.src; + +import java.util.Random; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiEnchantment extends GuiContainer { + /** The book model used on the GUI. */ + private static ModelBook bookModel = new ModelBook(); + private Random rand = new Random(); + + /** ContainerEnchantment object associated with this gui */ + private ContainerEnchantment containerEnchantment; + public int field_74214_o; + public float field_74213_p; + public float field_74212_q; + public float field_74211_r; + public float field_74210_s; + public float field_74209_t; + public float field_74208_u; + ItemStack theItemStack; + private String field_94079_C; + + public GuiEnchantment(InventoryPlayer par1InventoryPlayer, World par2World, int par3, int par4, int par5, String par6Str) { + super(new ContainerEnchantment(par1InventoryPlayer, par2World, par3, par4, par5)); + this.containerEnchantment = (ContainerEnchantment) this.inventorySlots; + this.field_94079_C = par6Str; + } + + /** + * Draw the foreground layer for the GuiContainer (everything in front of the + * items) + */ + protected void drawGuiContainerForegroundLayer(int par1, int par2) { + this.fontRenderer.drawString(this.field_94079_C == null ? StatCollector.translateToLocal("container.enchant") : this.field_94079_C, 12, 5, 4210752); + this.fontRenderer.drawString(StatCollector.translateToLocal("container.inventory"), 8, this.ySize - 96 + 2, 4210752); + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + super.updateScreen(); + this.func_74205_h(); + } + + /** + * Called when the mouse is clicked. + */ + protected void mouseClicked(int par1, int par2, int par3) { + super.mouseClicked(par1, par2, par3); + int var4 = (this.width - this.xSize) / 2; + int var5 = (this.height - this.ySize) / 2; + + for (int var6 = 0; var6 < 3; ++var6) { + int var7 = par1 - (var4 + 60); + int var8 = par2 - (var5 + 14 + 19 * var6); + + if (var7 >= 0 && var8 >= 0 && var7 < 108 && var8 < 19 && this.containerEnchantment.enchantItem(this.mc.thePlayer, var6)) { + this.mc.playerController.sendEnchantPacket(this.containerEnchantment.windowId, var6); + } + } + } + + private static final TextureLocation tex_enchant = new TextureLocation("/gui/enchant.png"); + private static final TextureLocation tex_book = new TextureLocation("/item/book.png"); + + /** + * Draw the background layer for the GuiContainer (everything behind the items) + */ + protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex_enchant.bindTexture(); + int var4 = (this.width - this.xSize) / 2; + int var5 = (this.height - this.ySize) / 2; + this.drawTexturedModalRect(var4, var5, 0, 0, this.xSize, this.ySize); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glLoadIdentity(); + ScaledResolution var6 = new ScaledResolution(this.mc.gameSettings, this.mc.displayWidth, this.mc.displayHeight); + EaglerAdapter.glViewport((var6.getScaledWidth() - 320) / 2 * var6.getScaleFactor(), (var6.getScaledHeight() - 240) / 2 * var6.getScaleFactor(), 320 * var6.getScaleFactor(), 240 * var6.getScaleFactor()); + EaglerAdapter.glTranslatef(-0.34F, 0.23F, 0.0F); + EaglerAdapter.gluPerspective(90.0F, 1.3333334F, 9.0F, 80.0F); + float var7 = 1.0F; + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glLoadIdentity(); + RenderHelper.enableStandardItemLighting(); + EaglerAdapter.glTranslatef(0.0F, 3.3F, -16.0F); + EaglerAdapter.glScalef(var7, var7, var7); + float var8 = 5.0F; + EaglerAdapter.glScalef(var8, var8, var8); + EaglerAdapter.glRotatef(180.0F, 0.0F, 0.0F, 1.0F); + tex_book.bindTexture(); + EaglerAdapter.glRotatef(20.0F, 1.0F, 0.0F, 0.0F); + float var9 = this.field_74208_u + (this.field_74209_t - this.field_74208_u) * par1; + EaglerAdapter.glTranslatef((1.0F - var9) * 0.2F, (1.0F - var9) * 0.1F, (1.0F - var9) * 0.25F); + EaglerAdapter.glRotatef(-(1.0F - var9) * 90.0F - 90.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(180.0F, 1.0F, 0.0F, 0.0F); + float var10 = this.field_74212_q + (this.field_74213_p - this.field_74212_q) * par1 + 0.25F; + float var11 = this.field_74212_q + (this.field_74213_p - this.field_74212_q) * par1 + 0.75F; + var10 = (var10 - (float) MathHelper.truncateDoubleToInt((double) var10)) * 1.6F - 0.3F; + var11 = (var11 - (float) MathHelper.truncateDoubleToInt((double) var11)) * 1.6F - 0.3F; + + if (var10 < 0.0F) { + var10 = 0.0F; + } + + if (var11 < 0.0F) { + var11 = 0.0F; + } + + if (var10 > 1.0F) { + var10 = 1.0F; + } + + if (var11 > 1.0F) { + var11 = 1.0F; + } + + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + bookModel.render((Entity) null, 0.0F, var10, var11, var9, 0.0F, 0.0625F); + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + RenderHelper.disableStandardItemLighting(); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glViewport(0, 0, this.mc.displayWidth, this.mc.displayHeight); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glPopMatrix(); + RenderHelper.disableStandardItemLighting(); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex_enchant.bindTexture(); + EnchantmentNameParts.instance.setRandSeed(this.containerEnchantment.nameSeed); + + for (int var12 = 0; var12 < 3; ++var12) { + String var13 = EnchantmentNameParts.instance.generateRandomEnchantName(); + this.zLevel = 0.0F; + tex_enchant.bindTexture(); + int var14 = this.containerEnchantment.enchantLevels[var12]; + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + if (var14 == 0) { + this.drawTexturedModalRect(var4 + 60, var5 + 14 + 19 * var12, 0, 185, 108, 19); + } else { + String var15 = "" + var14; + FontRenderer var16 = this.mc.standardGalacticFontRenderer; + int var17 = 6839882; + + if (this.mc.thePlayer.experienceLevel < var14 && !this.mc.thePlayer.capabilities.isCreativeMode) { + this.drawTexturedModalRect(var4 + 60, var5 + 14 + 19 * var12, 0, 185, 108, 19); + var16.drawSplitString(var13, var4 + 62, var5 + 16 + 19 * var12, 104, (var17 & 16711422) >> 1); + var16 = this.mc.fontRenderer; + var17 = 4226832; + var16.drawStringWithShadow(var15, var4 + 62 + 104 - var16.getStringWidth(var15), var5 + 16 + 19 * var12 + 7, var17); + } else { + int var18 = par2 - (var4 + 60); + int var19 = par3 - (var5 + 14 + 19 * var12); + + if (var18 >= 0 && var19 >= 0 && var18 < 108 && var19 < 19) { + this.drawTexturedModalRect(var4 + 60, var5 + 14 + 19 * var12, 0, 204, 108, 19); + var17 = 16777088; + } else { + this.drawTexturedModalRect(var4 + 60, var5 + 14 + 19 * var12, 0, 166, 108, 19); + } + + var16.drawSplitString(var13, var4 + 62, var5 + 16 + 19 * var12, 104, var17); + var16 = this.mc.fontRenderer; + var17 = 8453920; + var16.drawStringWithShadow(var15, var4 + 62 + 104 - var16.getStringWidth(var15), var5 + 16 + 19 * var12 + 7, var17); + } + } + } + } + + public void func_74205_h() { + ItemStack var1 = this.inventorySlots.getSlot(0).getStack(); + + if (!ItemStack.areItemStacksEqual(var1, this.theItemStack)) { + this.theItemStack = var1; + + do { + this.field_74211_r += (float) (this.rand.nextInt(4) - this.rand.nextInt(4)); + } while (this.field_74213_p <= this.field_74211_r + 1.0F && this.field_74213_p >= this.field_74211_r - 1.0F); + } + + ++this.field_74214_o; + this.field_74212_q = this.field_74213_p; + this.field_74208_u = this.field_74209_t; + boolean var2 = false; + + for (int var3 = 0; var3 < 3; ++var3) { + if (this.containerEnchantment.enchantLevels[var3] != 0) { + var2 = true; + } + } + + if (var2) { + this.field_74209_t += 0.2F; + } else { + this.field_74209_t -= 0.2F; + } + + if (this.field_74209_t < 0.0F) { + this.field_74209_t = 0.0F; + } + + if (this.field_74209_t > 1.0F) { + this.field_74209_t = 1.0F; + } + + float var5 = (this.field_74211_r - this.field_74213_p) * 0.4F; + float var4 = 0.2F; + + if (var5 < -var4) { + var5 = -var4; + } + + if (var5 > var4) { + var5 = var4; + } + + this.field_74210_s += (var5 - this.field_74210_s) * 0.9F; + this.field_74213_p += this.field_74210_s; + } +} diff --git a/src/main/java/net/minecraft/src/GuiErrorScreen.java b/src/main/java/net/minecraft/src/GuiErrorScreen.java new file mode 100644 index 0000000..779260e --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiErrorScreen.java @@ -0,0 +1,51 @@ +package net.minecraft.src; + +public class GuiErrorScreen extends GuiScreen { + /** + * Unused class. Would contain a message drawn to the center of the screen. + */ + private String message1; + + /** + * Unused class. Would contain a message drawn to the center of the screen. + */ + private String message2; + + public GuiErrorScreen(String par1Str, String par2Str) { + this.message1 = par1Str; + this.message2 = par2Str; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + super.initGui(); + this.buttonList.add(new GuiButton(0, this.width / 2 - 100, 140, StatCollector.translateToLocal("gui.cancel"))); + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.drawGradientRect(0, 0, this.width, this.height, -12574688, -11530224); + this.drawCenteredString(this.fontRenderer, this.message1, this.width / 2, 90, 16777215); + this.drawCenteredString(this.fontRenderer, this.message2, this.width / 2, 110, 16777215); + super.drawScreen(par1, par2, par3); + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + this.mc.displayGuiScreen((GuiScreen) null); + } +} diff --git a/src/main/java/net/minecraft/src/GuiFurnace.java b/src/main/java/net/minecraft/src/GuiFurnace.java new file mode 100644 index 0000000..603aeb1 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiFurnace.java @@ -0,0 +1,45 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiFurnace extends GuiContainer { + private TileEntityFurnace furnaceInventory; + + public GuiFurnace(InventoryPlayer par1InventoryPlayer, TileEntityFurnace par2TileEntityFurnace) { + super(new ContainerFurnace(par1InventoryPlayer, par2TileEntityFurnace)); + this.furnaceInventory = par2TileEntityFurnace; + } + + /** + * Draw the foreground layer for the GuiContainer (everything in front of the + * items) + */ + protected void drawGuiContainerForegroundLayer(int par1, int par2) { + String var3 = this.furnaceInventory.isInvNameLocalized() ? this.furnaceInventory.getInvName() : StatCollector.translateToLocal(this.furnaceInventory.getInvName()); + this.fontRenderer.drawString(var3, this.xSize / 2 - this.fontRenderer.getStringWidth(var3) / 2, 6, 4210752); + this.fontRenderer.drawString(StatCollector.translateToLocal("container.inventory"), 8, this.ySize - 96 + 2, 4210752); + } + + private static final TextureLocation tex = new TextureLocation("/gui/furnace.png"); + + /** + * Draw the background layer for the GuiContainer (everything behind the items) + */ + protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex.bindTexture(); + int var4 = (this.width - this.xSize) / 2; + int var5 = (this.height - this.ySize) / 2; + this.drawTexturedModalRect(var4, var5, 0, 0, this.xSize, this.ySize); + int var6; + + if (this.furnaceInventory.isBurning()) { + var6 = this.furnaceInventory.getBurnTimeRemainingScaled(12); + this.drawTexturedModalRect(var4 + 56, var5 + 36 + 12 - var6, 176, 12 - var6, 14, var6 + 2); + } + + var6 = this.furnaceInventory.getCookProgressScaled(24); + this.drawTexturedModalRect(var4 + 79, var5 + 34, 176, 14, var6 + 1, 16); + } +} diff --git a/src/main/java/net/minecraft/src/GuiGameOver.java b/src/main/java/net/minecraft/src/GuiGameOver.java new file mode 100644 index 0000000..20350c8 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiGameOver.java @@ -0,0 +1,105 @@ +package net.minecraft.src; + +import java.util.Iterator; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +public class GuiGameOver extends GuiScreen { + /** + * The cooldown timer for the buttons, increases every tick and enables all + * buttons when reaching 20. + */ + private int cooldownTimer; + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + this.buttonList.clear(); + + if (this.mc.theWorld.getWorldInfo().isHardcoreModeEnabled()) { + if (this.mc.isIntegratedServerRunning()) { + this.buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 + 96, StatCollector.translateToLocal("deathScreen.deleteWorld"))); + } else { + this.buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 + 96, StatCollector.translateToLocal("deathScreen.leaveServer"))); + } + } else { + this.buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 + 72, StatCollector.translateToLocal("deathScreen.respawn"))); + this.buttonList.add(new GuiButton(2, this.width / 2 - 100, this.height / 4 + 96, StatCollector.translateToLocal("deathScreen.titleScreen"))); + } + + GuiButton var2; + + for (Iterator var1 = this.buttonList.iterator(); var1.hasNext(); var2.enabled = false) { + var2 = (GuiButton) var1.next(); + } + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + switch (par1GuiButton.id) { + case 1: + this.mc.thePlayer.respawnPlayer(); + this.mc.displayGuiScreen((GuiScreen) null); + break; + + case 2: + this.mc.theWorld.sendQuittingDisconnectingPacket(); + this.mc.loadWorld((WorldClient) null); + this.mc.displayGuiScreen(new GuiMainMenu()); + } + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.drawGradientRect(0, 0, this.width, this.height, 1615855616, -1602211792); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glScalef(2.0F, 2.0F, 2.0F); + boolean var4 = this.mc.theWorld.getWorldInfo().isHardcoreModeEnabled(); + String var5 = var4 ? StatCollector.translateToLocal("deathScreen.title.hardcore") : StatCollector.translateToLocal("deathScreen.title"); + this.drawCenteredString(this.fontRenderer, var5, this.width / 2 / 2, 30, 16777215); + EaglerAdapter.glPopMatrix(); + + if (var4) { + this.drawCenteredString(this.fontRenderer, StatCollector.translateToLocal("deathScreen.hardcoreInfo"), this.width / 2, 144, 16777215); + } + + this.drawCenteredString(this.fontRenderer, StatCollector.translateToLocal("deathScreen.score") + ": " + EnumChatFormatting.YELLOW + this.mc.thePlayer.getScore(), this.width / 2, 100, 16777215); + super.drawScreen(par1, par2, par3); + } + + /** + * Returns true if this GUI should pause the game when it is displayed in + * single-player + */ + public boolean doesGuiPauseGame() { + return false; + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + super.updateScreen(); + ++this.cooldownTimer; + GuiButton var2; + + if (this.cooldownTimer == 20) { + for (Iterator var1 = this.buttonList.iterator(); var1.hasNext(); var2.enabled = true) { + var2 = (GuiButton) var1.next(); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/GuiHopper.java b/src/main/java/net/minecraft/src/GuiHopper.java new file mode 100644 index 0000000..2d95bdc --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiHopper.java @@ -0,0 +1,39 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiHopper extends GuiContainer { + private IInventory field_94081_r; + private IInventory field_94080_s; + + public GuiHopper(InventoryPlayer par1InventoryPlayer, IInventory par2IInventory) { + super(new ContainerHopper(par1InventoryPlayer, par2IInventory)); + this.field_94081_r = par1InventoryPlayer; + this.field_94080_s = par2IInventory; + this.allowUserInput = false; + this.ySize = 133; + } + + /** + * Draw the foreground layer for the GuiContainer (everything in front of the + * items) + */ + protected void drawGuiContainerForegroundLayer(int par1, int par2) { + this.fontRenderer.drawString(this.field_94080_s.isInvNameLocalized() ? this.field_94080_s.getInvName() : StatCollector.translateToLocal(this.field_94080_s.getInvName()), 8, 6, 4210752); + this.fontRenderer.drawString(this.field_94081_r.isInvNameLocalized() ? this.field_94081_r.getInvName() : StatCollector.translateToLocal(this.field_94081_r.getInvName()), 8, this.ySize - 96 + 2, 4210752); + } + + private static final TextureLocation tex = new TextureLocation("/gui/hopper.png"); + + /** + * Draw the background layer for the GuiContainer (everything behind the items) + */ + protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex.bindTexture(); + int var4 = (this.width - this.xSize) / 2; + int var5 = (this.height - this.ySize) / 2; + this.drawTexturedModalRect(var4, var5, 0, 0, this.xSize, this.ySize); + } +} diff --git a/src/main/java/net/minecraft/src/GuiIngame.java b/src/main/java/net/minecraft/src/GuiIngame.java new file mode 100644 index 0000000..4bc347b --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiIngame.java @@ -0,0 +1,814 @@ +package net.minecraft.src; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; + +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; +import net.lax1dude.eaglercraft.glemu.EffectPipeline; + +public class GuiIngame extends Gui { + private static RenderItem itemRenderer = null; + private final Random rand = new Random(); + private final Minecraft mc; + + /** ChatGUI instance that retains all previous chat data */ + private final GuiNewChat persistantChatGUI; + private int updateCounter = 0; + + /** The string specifying which record music is playing */ + private String recordPlaying = ""; + + /** How many ticks the record playing message will be displayed */ + private int recordPlayingUpFor = 0; + private boolean recordIsPlaying = false; + + /** Previous frame vignette brightness (slowly changes by 1% each frame) */ + public float prevVignetteBrightness = 1.0F; + + /** Remaining ticks the item highlight should be visible */ + private int remainingHighlightTicks; + + /** The ItemStack that is currently being highlighted */ + private ItemStack highlightingItemStack; + + public GuiIngame(Minecraft par1Minecraft) { + this.mc = par1Minecraft; + this.persistantChatGUI = new GuiNewChat(par1Minecraft); + } + + private static final TextureLocation tex_gui = new TextureLocation("/gui/gui.png"); + private static final TextureLocation tex_icons = new TextureLocation("/gui/icons.png"); + private static final TextureLocation tex_pumpkin = new TextureLocation("%blur%/misc/pumpkinblur.png"); + private static final TextureLocation tex_vigg = new TextureLocation("%blur%/misc/vignette.png"); + private static final TextureLocation terrain = new TextureLocation("/terrain.png"); + + /** + * Render the ingame overlay with quick icon bar, ... + */ + public void renderGameOverlay(float par1, boolean par2, int par3, int par4) { + ScaledResolution var5 = new ScaledResolution(this.mc.gameSettings, this.mc.displayWidth, this.mc.displayHeight); + int var6 = var5.getScaledWidth(); + int var7 = var5.getScaledHeight(); + FontRenderer var8 = this.mc.fontRenderer; + this.mc.entityRenderer.setupOverlayRendering(); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + + if (Minecraft.isFancyGraphicsEnabled()) { + this.renderVignette(this.mc.thePlayer.getBrightness(par1), var6, var7); + } else { + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + } + + ItemStack var9 = this.mc.thePlayer.inventory.armorItemInSlot(3); + + if (this.mc.gameSettings.thirdPersonView == 0 && var9 != null && var9.itemID == Block.pumpkin.blockID) { + this.renderPumpkinBlur(var6, var7); + } + + if (!this.mc.thePlayer.isPotionActive(Potion.confusion)) { + float var10 = this.mc.thePlayer.prevTimeInPortal + (this.mc.thePlayer.timeInPortal - this.mc.thePlayer.prevTimeInPortal) * par1; + + if (var10 > 0.0F) { + this.renderPortalOverlay(var10, var6, var7); + } + } + + boolean var11; + int var12; + int var13; + int var16; + int var17; + int var18; + int var20; + int var22; + int var23; + int var24; + int var26; + byte var27; + int var47; + int var52; + + if (!this.mc.playerController.enableEverythingIsScrewedUpMode()) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex_gui.bindTexture(); + InventoryPlayer var31 = this.mc.thePlayer.inventory; + this.zLevel = -90.0F; + this.drawTexturedModalRect(var6 / 2 - 91, var7 - 22, 0, 0, 182, 22); + this.drawTexturedModalRect(var6 / 2 - 91 - 1 + var31.currentItem * 20, var7 - 22 - 1, 0, 22, 24, 22); + tex_icons.bindTexture(); + //EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + //EaglerAdapter.glBlendFunc(EaglerAdapter.GL_ONE_MINUS_DST_COLOR, EaglerAdapter.GL_ONE_MINUS_SRC_COLOR); + this.drawTexturedModalRect(var6 / 2 - 7, var7 / 2 - 7, 0, 0, 16, 16); + //EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + var11 = this.mc.thePlayer.hurtResistantTime / 3 % 2 == 1; + + if (this.mc.thePlayer.hurtResistantTime < 10) { + var11 = false; + } + + var12 = this.mc.thePlayer.getHealth(); + var13 = this.mc.thePlayer.prevHealth; + this.rand.setSeed((long) (this.updateCounter * 312871)); + boolean var14 = false; + FoodStats var15 = this.mc.thePlayer.getFoodStats(); + var16 = var15.getFoodLevel(); + var17 = var15.getPrevFoodLevel(); + this.mc.mcProfiler.startSection("bossHealth"); + this.renderBossHealth(); + this.mc.mcProfiler.endSection(); + int var19; + + if (this.mc.playerController.shouldDrawHUD()) { + var18 = var6 / 2 - 91; + var19 = var6 / 2 + 91; + this.mc.mcProfiler.startSection("expBar"); + var20 = this.mc.thePlayer.xpBarCap(); + + if (var20 > 0) { + short var21 = 182; + var22 = (int) (this.mc.thePlayer.experience * (float) (var21 + 1)); + var23 = var7 - 32 + 3; + this.drawTexturedModalRect(var18, var23, 0, 64, var21, 5); + + if (var22 > 0) { + this.drawTexturedModalRect(var18, var23, 0, 69, var22, 5); + } + } + + var47 = var7 - 39; + var22 = var47 - 10; + var23 = this.mc.thePlayer.getTotalArmorValue(); + var24 = -1; + + if (this.mc.thePlayer.isPotionActive(Potion.regeneration)) { + var24 = this.updateCounter % 25; + } + + this.mc.mcProfiler.endStartSection("healthArmor"); + int var25; + int var28; + int var29; + + for (var25 = 0; var25 < 10; ++var25) { + if (var23 > 0) { + var26 = var18 + var25 * 8; + + if (var25 * 2 + 1 < var23) { + this.drawTexturedModalRect(var26, var22, 34, 9, 9, 9); + } + + if (var25 * 2 + 1 == var23) { + this.drawTexturedModalRect(var26, var22, 25, 9, 9, 9); + } + + if (var25 * 2 + 1 > var23) { + this.drawTexturedModalRect(var26, var22, 16, 9, 9, 9); + } + } + + var26 = 16; + + if (this.mc.thePlayer.isPotionActive(Potion.poison)) { + var26 += 36; + } else if (this.mc.thePlayer.isPotionActive(Potion.wither)) { + var26 += 72; + } + + var27 = 0; + + if (var11) { + var27 = 1; + } + + var28 = var18 + var25 * 8; + var29 = var47; + + if (var12 <= 4) { + var29 = var47 + this.rand.nextInt(2); + } + + if (var25 == var24) { + var29 -= 2; + } + + byte var30 = 0; + + if (this.mc.theWorld.getWorldInfo().isHardcoreModeEnabled()) { + var30 = 5; + } + + this.drawTexturedModalRect(var28, var29, 16 + var27 * 9, 9 * var30, 9, 9); + + if (var11) { + if (var25 * 2 + 1 < var13) { + this.drawTexturedModalRect(var28, var29, var26 + 54, 9 * var30, 9, 9); + } + + if (var25 * 2 + 1 == var13) { + this.drawTexturedModalRect(var28, var29, var26 + 63, 9 * var30, 9, 9); + } + } + + if (var25 * 2 + 1 < var12) { + this.drawTexturedModalRect(var28, var29, var26 + 36, 9 * var30, 9, 9); + } + + if (var25 * 2 + 1 == var12) { + this.drawTexturedModalRect(var28, var29, var26 + 45, 9 * var30, 9, 9); + } + } + + this.mc.mcProfiler.endStartSection("food"); + + for (var25 = 0; var25 < 10; ++var25) { + var26 = var47; + var52 = 16; + byte var53 = 0; + + if (this.mc.thePlayer.isPotionActive(Potion.hunger)) { + var52 += 36; + var53 = 13; + } + + if (this.mc.thePlayer.getFoodStats().getSaturationLevel() <= 0.0F && this.updateCounter % (var16 * 3 + 1) == 0) { + var26 = var47 + (this.rand.nextInt(3) - 1); + } + + if (var14) { + var53 = 1; + } + + var29 = var19 - var25 * 8 - 9; + this.drawTexturedModalRect(var29, var26, 16 + var53 * 9, 27, 9, 9); + + if (var14) { + if (var25 * 2 + 1 < var17) { + this.drawTexturedModalRect(var29, var26, var52 + 54, 27, 9, 9); + } + + if (var25 * 2 + 1 == var17) { + this.drawTexturedModalRect(var29, var26, var52 + 63, 27, 9, 9); + } + } + + if (var25 * 2 + 1 < var16) { + this.drawTexturedModalRect(var29, var26, var52 + 36, 27, 9, 9); + } + + if (var25 * 2 + 1 == var16) { + this.drawTexturedModalRect(var29, var26, var52 + 45, 27, 9, 9); + } + } + + this.mc.mcProfiler.endStartSection("air"); + + if (this.mc.thePlayer.isInsideOfMaterial(Material.water)) { + var25 = this.mc.thePlayer.getAir(); + var26 = MathHelper.ceiling_double_int((double) (var25 - 2) * 10.0D / 300.0D); + var52 = MathHelper.ceiling_double_int((double) var25 * 10.0D / 300.0D) - var26; + + for (var28 = 0; var28 < var26 + var52; ++var28) { + if (var28 < var26) { + this.drawTexturedModalRect(var19 - var28 * 8 - 9, var22, 16, 18, 9, 9); + } else { + this.drawTexturedModalRect(var19 - var28 * 8 - 9, var22, 25, 18, 9, 9); + } + } + } + + this.mc.mcProfiler.endSection(); + } + + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + this.mc.mcProfiler.startSection("actionBar"); + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + RenderHelper.enableGUIStandardItemLighting(); + + for (var18 = 0; var18 < 9; ++var18) { + var19 = var6 / 2 - 90 + var18 * 20 + 2; + var20 = var7 - 16 - 3; + this.renderInventorySlot(var18, var19, var20, par1); + } + + RenderHelper.disableStandardItemLighting(); + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + this.mc.mcProfiler.endSection(); + } + + float var33; + + if (this.mc.thePlayer.getSleepTimer() > 0) { + this.mc.mcProfiler.startSection("sleep"); + EaglerAdapter.glDisable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + int var32 = this.mc.thePlayer.getSleepTimer(); + var33 = (float) var32 / 100.0F; + + if (var33 > 1.0F) { + var33 = 1.0F - (float) (var32 - 100) / 10.0F; + } + + var12 = (int) (220.0F * var33) << 24 | 1052704; + drawRect(0, 0, var6, var7, var12); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + this.mc.mcProfiler.endSection(); + } + + int var36; + int var40; + + if (this.mc.playerController.func_78763_f() && this.mc.thePlayer.experienceLevel > 0) { + this.mc.mcProfiler.startSection("expLevel"); + var11 = false; + var12 = var11 ? 16777215 : 8453920; + String var34 = "" + this.mc.thePlayer.experienceLevel; + var36 = (var6 - var8.getStringWidth(var34)) / 2; + var40 = var7 - 31 - 4; + var8.drawString(var34, var36 + 1, var40, 0); + var8.drawString(var34, var36 - 1, var40, 0); + var8.drawString(var34, var36, var40 + 1, 0); + var8.drawString(var34, var36, var40 - 1, 0); + var8.drawString(var34, var36, var40, var12); + this.mc.mcProfiler.endSection(); + } + + String var35; + + if (this.mc.gameSettings.heldItemTooltips) { + this.mc.mcProfiler.startSection("toolHighlight"); + + if (this.remainingHighlightTicks > 0 && this.highlightingItemStack != null) { + var35 = this.highlightingItemStack.getDisplayName(); + var12 = (var6 - var8.getStringWidth(var35)) / 2; + var13 = var7 - 59; + + if (!this.mc.playerController.shouldDrawHUD()) { + var13 += 14; + } + + var36 = (int) ((float) this.remainingHighlightTicks * 256.0F / 10.0F); + + if (var36 > 255) { + var36 = 255; + } + + if (var36 > 0) { + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + var8.drawStringWithShadow(var35, var12, var13, 16777215 + (var36 << 24)); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glPopMatrix(); + } + } + + this.mc.mcProfiler.endSection(); + } + + if (this.mc.isDemo()) { + this.mc.mcProfiler.startSection("demo"); + var35 = ""; + + if (this.mc.theWorld.getTotalWorldTime() >= 120500L) { + var35 = StatCollector.translateToLocal("demo.demoExpired"); + } else { + var35 = String.format(StatCollector.translateToLocal("demo.remainingTime"), new Object[] { StringUtils.ticksToElapsedTime((int) (120500L - this.mc.theWorld.getTotalWorldTime())) }); + } + + var12 = var8.getStringWidth(var35); + var8.drawStringWithShadow(var35, var6 - var12 - 10, 5, 16777215); + this.mc.mcProfiler.endSection(); + } + + this.mc.debug = "" + Minecraft.debugFPS + " fps, " + Minecraft.debugChunkUpdates + " chunk updates"; + + if (this.mc.gameSettings.showDebugInfo) { + this.mc.mcProfiler.startSection("debug"); + EaglerAdapter.glPushMatrix(); + var8.drawStringWithShadow("minecraft 1.5.2 (" + this.mc.debug + ")", 2, 2, 16777215); + var8.drawStringWithShadow(this.mc.debugInfoRenders(), 2, 12, 16777215); + var8.drawStringWithShadow(this.mc.getEntityDebug(), 2, 22, 16777215); + var8.drawStringWithShadow(this.mc.debugInfoEntities(), 2, 32, 16777215); + var8.drawStringWithShadow(this.mc.getWorldProviderName(), 2, 42, 16777215); + long var39; + long var37; + long var41; + var39 = EaglerAdapter.maxMemory(); + var37 = EaglerAdapter.totalMemory(); + var41 = EaglerAdapter.freeMemory(); + long var44 = var37 - var41; + String var45 = "Used memory: " + var44 * 100L / var39 + "% (" + var44 / 1024L / 1024L + "MB) of " + var39 / 1024L / 1024L + "MB"; + this.drawString(var8, var45, var6 - var8.getStringWidth(var45) - 2, 2, 14737632); + var45 = "Allocated memory: " + var37 * 100L / var39 + "% (" + var37 / 1024L / 1024L + "MB)"; + this.drawString(var8, var45, var6 - var8.getStringWidth(var45) - 2, 12, 14737632); + var47 = MathHelper.floor_double(this.mc.thePlayer.posX); + var22 = MathHelper.floor_double(this.mc.thePlayer.posY); + var23 = MathHelper.floor_double(this.mc.thePlayer.posZ); + this.drawString(var8, "x: "+doubleToShorterString(this.mc.thePlayer.posX)+" ("+var47+") // c: "+(var47 >> 4)+" ("+(var47 & 15)+")", 2, 64, 14737632); + this.drawString(var8, "y: "+doubleToShorterString(this.mc.thePlayer.posY)+" ("+var22+") (feet pos)", 2, 72, 14737632); + this.drawString(var8, "z: "+doubleToShorterString(this.mc.thePlayer.posZ)+" ("+var23+") // c: "+(var23 >> 4)+" ("+(var23 & 15)+")", 2, 80, 14737632); + var24 = MathHelper.floor_double((double) (this.mc.thePlayer.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + this.drawString(var8, "f: " + var24 + " (" + Direction.directions[var24] + ") / " + MathHelper.wrapAngleTo180_float(this.mc.thePlayer.rotationYaw), 2, 88, 14737632); + + //this.drawString(var8, String.format("ws: %.3f, fs: %.3f, g: %b, fl: %d", new Object[] { Float.valueOf(this.mc.thePlayer.capabilities.getWalkSpeed()), Float.valueOf(this.mc.thePlayer.capabilities.getFlySpeed()), + // Boolean.valueOf(this.mc.thePlayer.onGround), Integer.valueOf(this.mc.theWorld.getHeightValue(var47, var23)) }), 2, 104, 14737632); + var45 = "opengl emulator status - v1.0"; + this.drawString(var8, var45, var6 - var8.getStringWidth(var45) - 2, 36, 14737632); + var45 = "lists: "+EaglerAdapter.getDisplayListCount()+", upload: "+(EaglerAdapter.getBitsPerSecond() / 1000000)+"mbps"; + this.drawString(var8, var45, var6 - var8.getStringWidth(var45) - 2, 46, 14737632); + var45 = "verts: "+(EaglerAdapter.getVertexesPerSecond() / 1000)+"k, triangles: "+(EaglerAdapter.getTrianglesPerSecond() / 1000)+"k"; + this.drawString(var8, var45, var6 - var8.getStringWidth(var45) - 2, 56, 14737632); + var45 = "rendering backend: "+(EaglerAdapter.isWebGL ? "webgl10" : "opengl30"); + this.drawString(var8, var45, var6 - var8.getStringWidth(var45) - 2, 66, 14737632); + var45 = "glsl "+(EaglerAdapter._wgetShaderHeader() +", 32 bytes/vert"); + this.drawString(var8, var45, var6 - var8.getStringWidth(var45) - 2, 76, 14737632); + var45 = "Bound Shaders:"; + this.drawString(var8, var45, var6 - var8.getStringWidth(var45) - 2, 100, 14737632); + var45 = "/glsl/core.glsl"; + this.drawString(var8, var45, var6 - var8.getStringWidth(var45) - 2, 110, 14737632); + var45 = "/glsl/occl.glsl"; + this.drawString(var8, var45, var6 - var8.getStringWidth(var45) - 2, 120, 14737632); + for(int i = 0; i < EffectPipeline.pipeline.length; i++) { + var45 = EffectPipeline.pipeline[i]; + this.drawString(var8, var45, var6 - var8.getStringWidth(var45) - 2, 130 + i*10, 14737632); + } + EaglerAdapter.glPopMatrix(); + this.mc.mcProfiler.endSection(); + }else { + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glScalef(0.75f, 0.75f, 0.75f); + var8.drawStringWithShadow(this.mc.renderGlobal.getDebugInfoShort(), 2, 2, 16777215); + var8.drawStringWithShadow("x: "+MathHelper.floor_double(this.mc.thePlayer.posX)+", y: "+MathHelper.floor_double(this.mc.thePlayer.posY)+", z: "+MathHelper.floor_double(this.mc.thePlayer.posZ), 2, 12, 16777215); + EaglerAdapter.glPopMatrix(); + } + + if (this.recordPlayingUpFor > 0) { + this.mc.mcProfiler.startSection("overlayMessage"); + var33 = (float) this.recordPlayingUpFor - par1; + var12 = (int) (var33 * 256.0F / 20.0F); + + if (var12 > 255) { + var12 = 255; + } + + if (var12 > 0) { + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef((float) (var6 / 2), (float) (var7 - 48), 0.0F); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + var13 = 16777215; + + if (this.recordIsPlaying) { + var13 = BiomeGenBase.HSBtoRGB(var33 / 50.0F, 0.7F, 0.6F) & 16777215; + } + + var8.drawString(this.recordPlaying, -var8.getStringWidth(this.recordPlaying) / 2, -4, var13 + (var12 << 24)); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glPopMatrix(); + } + + this.mc.mcProfiler.endSection(); + } + + ScoreObjective var42 = this.mc.theWorld.getScoreboard().func_96539_a(1); + + if (var42 != null) { + this.func_96136_a(var42, var7, var6, var8); + } + + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(0.0F, (float) (var7 - 48), 0.0F); + this.mc.mcProfiler.startSection("chat"); + this.persistantChatGUI.drawChat(this.updateCounter); + this.mc.mcProfiler.endSection(); + EaglerAdapter.glPopMatrix(); + var42 = this.mc.theWorld.getScoreboard().func_96539_a(0); + + if (this.mc.gameSettings.keyBindPlayerList.pressed && (!this.mc.isIntegratedServerRunning() || this.mc.thePlayer.sendQueue.playerInfoList.size() > 1 || var42 != null)) { + this.mc.mcProfiler.startSection("playerList"); + NetClientHandler var38 = this.mc.thePlayer.sendQueue; + List var43 = var38.playerInfoList; + var36 = var38.currentServerMaxPlayers; + var40 = var36; + + for (var16 = 1; var40 > 20; var40 = (var36 + var16 - 1) / var16) { + ++var16; + } + + var17 = 300 / var16; + + if (var17 > 150) { + var17 = 150; + } + + var18 = (var6 - var16 * var17) / 2; + byte var46 = 10; + drawRect(var18 - 1, var46 - 1, var18 + var17 * var16, var46 + 9 * var40, Integer.MIN_VALUE); + + for (var20 = 0; var20 < var36; ++var20) { + var47 = var18 + var20 % var16 * var17; + var22 = var46 + var20 / var16 * 9; + drawRect(var47, var22, var47 + var17 - 1, var22 + 8, 553648127); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + + if (var20 < var43.size()) { + GuiPlayerInfo var48 = (GuiPlayerInfo) var43.get(var20); + ScorePlayerTeam var49 = this.mc.theWorld.getScoreboard().getPlayersTeam(var48.name); + String var51 = ScorePlayerTeam.func_96667_a(var49, var48.name); + var8.drawStringWithShadow(var51, var47, var22, 16777215); + + if (var42 != null) { + var26 = var47 + var8.getStringWidth(var51) + 5; + var52 = var47 + var17 - 12 - 5; + + if (var52 - var26 > 5) { + Score var55 = var42.getScoreboard().func_96529_a(var48.name, var42); + String var57 = EnumChatFormatting.YELLOW + "" + var55.func_96652_c(); + var8.drawStringWithShadow(var57, var52 - var8.getStringWidth(var57), var22, 16777215); + } + } + + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.mc.renderEngine.bindTexture("/gui/icons.png"); + byte var54 = 0; + boolean var56 = false; + + if (var48.responseTime < 0) { + var27 = 5; + } else if (var48.responseTime < 150) { + var27 = 0; + } else if (var48.responseTime < 300) { + var27 = 1; + } else if (var48.responseTime < 600) { + var27 = 2; + } else if (var48.responseTime < 1000) { + var27 = 3; + } else { + var27 = 4; + } + + this.zLevel += 100.0F; + this.drawTexturedModalRect(var47 + var17 - 12, var22, 0 + var54 * 10, 176 + var27 * 8, 10, 8); + this.zLevel -= 100.0F; + } + } + } + + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + } + + private static String doubleToShorterString(double d) { + String s = Double.toString(d); + int i = s.indexOf('.'); + if(s.length() - i > 6) { + s = s.substring(0, i + 6); + } + return s; + } + + private void func_96136_a(ScoreObjective par1ScoreObjective, int par2, int par3, FontRenderer par4FontRenderer) { + Scoreboard var5 = par1ScoreObjective.getScoreboard(); + Collection var6 = var5.func_96534_i(par1ScoreObjective); + + if (var6.size() <= 15) { + int var7 = par4FontRenderer.getStringWidth(par1ScoreObjective.getDisplayName()); + String var11; + + for (Iterator var8 = var6.iterator(); var8.hasNext(); var7 = Math.max(var7, par4FontRenderer.getStringWidth(var11))) { + Score var9 = (Score) var8.next(); + ScorePlayerTeam var10 = var5.getPlayersTeam(var9.func_96653_e()); + var11 = ScorePlayerTeam.func_96667_a(var10, var9.func_96653_e()) + ": " + EnumChatFormatting.RED + var9.func_96652_c(); + } + + int var22 = var6.size() * par4FontRenderer.FONT_HEIGHT; + int var23 = par2 / 2 + var22 / 3; + byte var24 = 3; + int var25 = par3 - var7 - var24; + int var12 = 0; + Iterator var13 = var6.iterator(); + + while (var13.hasNext()) { + Score var14 = (Score) var13.next(); + ++var12; + ScorePlayerTeam var15 = var5.getPlayersTeam(var14.func_96653_e()); + String var16 = ScorePlayerTeam.func_96667_a(var15, var14.func_96653_e()); + String var17 = EnumChatFormatting.RED + "" + var14.func_96652_c(); + int var19 = var23 - var12 * par4FontRenderer.FONT_HEIGHT; + int var20 = par3 - var24 + 2; + drawRect(var25 - 2, var19, var20, var19 + par4FontRenderer.FONT_HEIGHT, 1342177280); + par4FontRenderer.drawString(var16, var25, var19, 553648127); + par4FontRenderer.drawString(var17, var20 - par4FontRenderer.getStringWidth(var17), var19, 553648127); + + if (var12 == var6.size()) { + String var21 = par1ScoreObjective.getDisplayName(); + drawRect(var25 - 2, var19 - par4FontRenderer.FONT_HEIGHT - 1, var20, var19 - 1, 1610612736); + drawRect(var25 - 2, var19 - 1, var20, var19, 1342177280); + par4FontRenderer.drawString(var21, var25 + var7 / 2 - par4FontRenderer.getStringWidth(var21) / 2, var19 - par4FontRenderer.FONT_HEIGHT, 553648127); + } + } + } + } + + /** + * Renders dragon's (boss) health on the HUD + */ + private void renderBossHealth() { + if (BossStatus.bossName != null && BossStatus.statusBarLength > 0) { + --BossStatus.statusBarLength; + FontRenderer var1 = this.mc.fontRenderer; + ScaledResolution var2 = new ScaledResolution(this.mc.gameSettings, this.mc.displayWidth, this.mc.displayHeight); + int var3 = var2.getScaledWidth(); + short var4 = 182; + int var5 = var3 / 2 - var4 / 2; + int var6 = (int) (BossStatus.healthScale * (float) (var4 + 1)); + byte var7 = 12; + this.drawTexturedModalRect(var5, var7, 0, 74, var4, 5); + this.drawTexturedModalRect(var5, var7, 0, 74, var4, 5); + + if (var6 > 0) { + this.drawTexturedModalRect(var5, var7, 0, 79, var6, 5); + } + + String var8 = BossStatus.bossName; + var1.drawStringWithShadow(var8, var3 / 2 - var1.getStringWidth(var8) / 2, var7 - 10, 16777215); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex_icons.bindTexture(); + } + } + + private void renderPumpkinBlur(int par1, int par2) { + EaglerAdapter.glDisable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glDepthMask(false); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + tex_pumpkin.bindTexture(); + Tessellator var3 = Tessellator.instance; + var3.startDrawingQuads(); + var3.addVertexWithUV(0.0D, (double) par2, -90.0D, 0.0D, 1.0D); + var3.addVertexWithUV((double) par1, (double) par2, -90.0D, 1.0D, 1.0D); + var3.addVertexWithUV((double) par1, 0.0D, -90.0D, 1.0D, 0.0D); + var3.addVertexWithUV(0.0D, 0.0D, -90.0D, 0.0D, 0.0D); + var3.draw(); + EaglerAdapter.glDepthMask(true); + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Renders the vignette. Args: vignetteBrightness, width, height + */ + private void renderVignette(float par1, int par2, int par3) { + par1 = 1.0F - par1 * 0.5f; + + if (par1 < 0.0F) { + par1 = 0.0F; + } + + if (par1 > 1.0F) { + par1 = 1.0F; + } + + this.prevVignetteBrightness = (float) ((double) this.prevVignetteBrightness + (double) (par1 - this.prevVignetteBrightness) * 0.01D); + EaglerAdapter.glDisable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glDepthMask(false); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_ZERO, EaglerAdapter.GL_ONE_MINUS_SRC_COLOR); + EaglerAdapter.glColor4f(this.prevVignetteBrightness, this.prevVignetteBrightness, this.prevVignetteBrightness, 1.0F); + tex_vigg.bindTexture(); + Tessellator var4 = Tessellator.instance; + var4.startDrawingQuads(); + var4.addVertexWithUV(0.0D, (double) par3, -90.0D, 0.0D, 1.0D); + var4.addVertexWithUV((double) par2, (double) par3, -90.0D, 1.0D, 1.0D); + var4.addVertexWithUV((double) par2, 0.0D, -90.0D, 1.0D, 0.0D); + var4.addVertexWithUV(0.0D, 0.0D, -90.0D, 0.0D, 0.0D); + var4.draw(); + EaglerAdapter.glDepthMask(true); + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + } + + /** + * Renders the portal overlay. Args: portalStrength, width, height + */ + private void renderPortalOverlay(float par1, int par2, int par3) { + if (par1 < 1.0F) { + par1 *= par1; + par1 *= par1; + par1 = par1 * 0.8F + 0.2F; + } + + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glDisable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glDepthMask(false); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, par1); + terrain.bindTexture(); + Icon var4 = Block.portal.getBlockTextureFromSide(1); + float var5 = var4.getMinU(); + float var6 = var4.getMinV(); + float var7 = var4.getMaxU(); + float var8 = var4.getMaxV(); + Tessellator var9 = Tessellator.instance; + var9.startDrawingQuads(); + var9.addVertexWithUV(0.0D, (double) par3, -90.0D, (double) var5, (double) var8); + var9.addVertexWithUV((double) par2, (double) par3, -90.0D, (double) var7, (double) var8); + var9.addVertexWithUV((double) par2, 0.0D, -90.0D, (double) var7, (double) var6); + var9.addVertexWithUV(0.0D, 0.0D, -90.0D, (double) var5, (double) var6); + var9.draw(); + EaglerAdapter.glDepthMask(true); + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Renders the specified item of the inventory slot at the specified location. + * Args: slot, x, y, partialTick + */ + private void renderInventorySlot(int par1, int par2, int par3, float par4) { + ItemStack var5 = this.mc.thePlayer.inventory.mainInventory[par1]; + + if (var5 != null) { + float var6 = (float) var5.animationsToGo - par4; + + if (var6 > 0.0F) { + EaglerAdapter.glPushMatrix(); + float var7 = 1.0F + var6 / 5.0F; + EaglerAdapter.glTranslatef((float) (par2 + 8), (float) (par3 + 12), 0.0F); + EaglerAdapter.glScalef(1.0F / var7, (var7 + 1.0F) / 2.0F, 1.0F); + EaglerAdapter.glTranslatef((float) (-(par2 + 8)), (float) (-(par3 + 12)), 0.0F); + } + + if(itemRenderer == null) itemRenderer = new RenderItem(); + + itemRenderer.renderItemAndEffectIntoGUI(this.mc.fontRenderer, this.mc.renderEngine, var5, par2, par3); + + if (var6 > 0.0F) { + EaglerAdapter.glPopMatrix(); + } + + itemRenderer.renderItemOverlayIntoGUI(this.mc.fontRenderer, this.mc.renderEngine, var5, par2, par3); + } + } + + /** + * The update tick for the ingame UI + */ + public void updateTick() { + if (this.recordPlayingUpFor > 0) { + --this.recordPlayingUpFor; + } + + ++this.updateCounter; + + if (this.mc.thePlayer != null) { + ItemStack var1 = this.mc.thePlayer.inventory.getCurrentItem(); + + if (var1 == null) { + this.remainingHighlightTicks = 0; + } else if (this.highlightingItemStack != null && var1.itemID == this.highlightingItemStack.itemID && ItemStack.areItemStackTagsEqual(var1, this.highlightingItemStack) + && (var1.isItemStackDamageable() || var1.getItemDamage() == this.highlightingItemStack.getItemDamage())) { + if (this.remainingHighlightTicks > 0) { + --this.remainingHighlightTicks; + } + } else { + this.remainingHighlightTicks = 40; + } + + this.highlightingItemStack = var1; + } + } + + public void setRecordPlayingMessage(String par1Str) { + this.recordPlaying = "Now playing: " + par1Str; + this.recordPlayingUpFor = 60; + this.recordIsPlaying = true; + } + + /** + * returns a pointer to the persistant Chat GUI, containing all previous chat + * messages and such + */ + public GuiNewChat getChatGUI() { + return this.persistantChatGUI; + } + + public int getUpdateCounter() { + return this.updateCounter; + } +} diff --git a/src/main/java/net/minecraft/src/GuiIngameMenu.java b/src/main/java/net/minecraft/src/GuiIngameMenu.java new file mode 100644 index 0000000..6c0b7af --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiIngameMenu.java @@ -0,0 +1,82 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.GuiScreenVoiceChannel; + +public class GuiIngameMenu extends GuiScreen { + /** Also counts the number of updates, not certain as to why yet. */ + private int updateCounter2 = 0; + + /** Counts the number of screen updates. */ + private int updateCounter = 0; + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + this.updateCounter2 = 0; + this.buttonList.clear(); + byte var1 = -16; + this.buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 + 120 + var1, StatCollector.translateToLocal("menu.returnToMenu"))); + + if (!this.mc.isIntegratedServerRunning()) { + ((GuiButton) this.buttonList.get(0)).displayString = StatCollector.translateToLocal("menu.disconnect"); + } + + this.buttonList.add(new GuiButton(4, this.width / 2 - 100, this.height / 4 + 24 + var1, StatCollector.translateToLocal("menu.returnToGame"))); + this.buttonList.add(new GuiButton(5, this.width / 2 - 100, this.height / 4 + 48 + var1, StatCollector.translateToLocal("menu.voicechannel"))); + this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + var1, 98, 20, StatCollector.translateToLocal("menu.options"))); + GuiButton var3; + this.buttonList.add(var3 = new GuiButton(7, this.width / 2 + 2, this.height / 4 + 96 + var1, 98, 20, StatCollector.translateToLocal("menu.shareToLan"))); + var3.enabled = false; + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + switch (par1GuiButton.id) { + case 0: + this.mc.displayGuiScreen(new GuiOptions(this, this.mc.gameSettings)); + break; + + case 1: + par1GuiButton.enabled = false; + this.mc.theWorld.sendQuittingDisconnectingPacket(); + this.mc.loadWorld((WorldClient) null); + this.mc.displayGuiScreen(new GuiMainMenu()); + + case 2: + case 3: + default: + break; + + case 4: + this.mc.displayGuiScreen((GuiScreen) null); + this.mc.setIngameFocus(); + this.mc.sndManager.resumeAllSounds(); + break; + + case 5: + this.mc.displayGuiScreen(new GuiScreenVoiceChannel(this)); + break; + } + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + super.updateScreen(); + ++this.updateCounter; + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, "Game menu", this.width / 2, 40, 16777215); + super.drawScreen(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/GuiInventory.java b/src/main/java/net/minecraft/src/GuiInventory.java new file mode 100644 index 0000000..6b4a116 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiInventory.java @@ -0,0 +1,116 @@ +package net.minecraft.src; + +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; + +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiInventory extends InventoryEffectRenderer { + /** + * x size of the inventory window in pixels. Defined as float, passed as int + */ + private float xSize_lo; + + /** + * y size of the inventory window in pixels. Defined as float, passed as int. + */ + private float ySize_lo; + + public GuiInventory(EntityPlayer par1EntityPlayer) { + super(par1EntityPlayer.inventoryContainer); + this.allowUserInput = true; + par1EntityPlayer.addStat(AchievementList.openInventory, 1); + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + if (this.mc.playerController.isInCreativeMode()) { + this.mc.displayGuiScreen(new GuiContainerCreative(this.mc.thePlayer)); + } + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + this.buttonList.clear(); + + if (this.mc.playerController.isInCreativeMode()) { + this.mc.displayGuiScreen(new GuiContainerCreative(this.mc.thePlayer)); + } else { + super.initGui(); + } + } + + /** + * Draw the foreground layer for the GuiContainer (everything in front of the + * items) + */ + protected void drawGuiContainerForegroundLayer(int par1, int par2) { + this.fontRenderer.drawString(StatCollector.translateToLocal("container.crafting"), 86, 16, 4210752); + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + super.drawScreen(par1, par2, par3); + this.xSize_lo = (float) par1; + this.ySize_lo = (float) par2; + } + + private static final TextureLocation tex = new TextureLocation("/gui/inventory.png"); + + /** + * Draw the background layer for the GuiContainer (everything behind the items) + */ + protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex.bindTexture(); + int var4 = this.guiLeft; + int var5 = this.guiTop; + this.drawTexturedModalRect(var4, var5, 0, 0, this.xSize, this.ySize); + drawPlayerOnGui(this.mc, var4 + 51, var5 + 75, 30, (float) (var4 + 51) - this.xSize_lo, (float) (var5 + 75 - 50) - this.ySize_lo); + } + + public static void drawPlayerOnGui(Minecraft par0Minecraft, int par1, int par2, int par3, float par4, float par5) { + EaglerAdapter.glEnable(EaglerAdapter.GL_COLOR_MATERIAL); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef((float) par1, (float) par2, 50.0F); + EaglerAdapter.glScalef((float) (-par3), (float) par3, (float) par3); + EaglerAdapter.glRotatef(180.0F, 0.0F, 0.0F, 1.0F); + float var6 = par0Minecraft.thePlayer.renderYawOffset; + float var7 = par0Minecraft.thePlayer.rotationYaw; + float var8 = par0Minecraft.thePlayer.rotationPitch; + EaglerAdapter.glRotatef(135.0F, 0.0F, 1.0F, 0.0F); + RenderHelper.enableStandardItemLighting(); + EaglerAdapter.glRotatef(-135.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(-((float) Math.atan((double) (par5 / 40.0F))) * 20.0F, 1.0F, 0.0F, 0.0F); + par0Minecraft.thePlayer.renderYawOffset = (float) Math.atan((double) (par4 / 40.0F)) * 20.0F; + par0Minecraft.thePlayer.rotationYaw = (float) Math.atan((double) (par4 / 40.0F)) * 40.0F; + par0Minecraft.thePlayer.rotationPitch = -((float) Math.atan((double) (par5 / 40.0F))) * 20.0F; + par0Minecraft.thePlayer.rotationYawHead = par0Minecraft.thePlayer.rotationYaw; + EaglerAdapter.glTranslatef(0.0F, par0Minecraft.thePlayer.yOffset, 0.0F); + RenderManager.instance.playerViewY = 180.0F; + RenderManager.instance.renderEntityWithPosYaw(par0Minecraft.thePlayer, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F); + par0Minecraft.thePlayer.renderYawOffset = var6; + par0Minecraft.thePlayer.rotationYaw = var7; + par0Minecraft.thePlayer.rotationPitch = var8; + EaglerAdapter.glPopMatrix(); + RenderHelper.disableStandardItemLighting(); + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + + } +} diff --git a/src/main/java/net/minecraft/src/GuiLanguage.java b/src/main/java/net/minecraft/src/GuiLanguage.java new file mode 100644 index 0000000..c538160 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiLanguage.java @@ -0,0 +1,96 @@ +package net.minecraft.src; + +public class GuiLanguage extends GuiScreen { + /** This GUI's parent GUI. */ + protected GuiScreen parentGui; + + /** + * Timer used to update texture packs, decreases every tick and is reset to 20 + * and updates texture packs upon reaching 0. + */ + private int updateTimer = -1; + + /** This GUI's language list. */ + private GuiSlotLanguage languageList; + + /** For saving the user's language selection to disk. */ + private final GameSettings theGameSettings; + + /** This GUI's 'Done' button. */ + private GuiSmallButton doneButton; + + public GuiLanguage(GuiScreen par1GuiScreen, GameSettings par2GameSettings) { + this.parentGui = par1GuiScreen; + this.theGameSettings = par2GameSettings; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + StringTranslate var1 = StringTranslate.getInstance(); + this.buttonList.add(this.doneButton = new GuiSmallButton(6, this.width / 2 - 75, this.height - 38, var1.translateKey("gui.done"))); + this.languageList = new GuiSlotLanguage(this); + this.languageList.registerScrollButtons(this.buttonList, 7, 8); + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.enabled) { + switch (par1GuiButton.id) { + case 5: + break; + + case 6: + this.mc.displayGuiScreen(this.parentGui); + break; + + default: + this.languageList.actionPerformed(par1GuiButton); + } + } + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.languageList.drawScreen(par1, par2, par3); + + if (this.updateTimer <= 0) { + this.mc.texturePackList.updateAvaliableTexturePacks(); + this.updateTimer += 20; + } + + StringTranslate var4 = StringTranslate.getInstance(); + this.drawCenteredString(this.fontRenderer, var4.translateKey("options.language"), this.width / 2, 16, 16777215); + this.drawCenteredString(this.fontRenderer, "(" + var4.translateKey("options.languageWarning") + ")", this.width / 2, this.height - 56, 8421504); + super.drawScreen(par1, par2, par3); + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + super.updateScreen(); + --this.updateTimer; + } + + /** + * Gets the relevant instance of GameSettings. Synthetic method for use in + * GuiSlotLanguage + */ + static GameSettings getGameSettings(GuiLanguage par0GuiLanguage) { + return par0GuiLanguage.theGameSettings; + } + + /** + * Returns the private doneButton field. + */ + static GuiSmallButton getDoneButton(GuiLanguage par0GuiLanguage) { + return par0GuiLanguage.doneButton; + } +} diff --git a/src/main/java/net/minecraft/src/GuiMainMenu.java b/src/main/java/net/minecraft/src/GuiMainMenu.java new file mode 100644 index 0000000..310ae66 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiMainMenu.java @@ -0,0 +1,521 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.Random; + +import net.lax1dude.eaglercraft.ConfigConstants; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.EaglerImage; + +import net.lax1dude.eaglercraft.GuiScreenEditProfile; +import net.lax1dude.eaglercraft.GuiScreenVoiceChannel; +import net.lax1dude.eaglercraft.LocalStorageManager; +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class GuiMainMenu extends GuiScreen { + /** The RNG used by the Main Menu Screen. */ + private static final Random rand = new Random(); + + /** The splash message. */ + private String splashText = "missingno"; + private GuiButton buttonResetDemo; + + private long start; + + /** + * Texture allocated for the current viewport of the main menu's panorama + * background. + */ + private static int viewportTexture = -1; + private boolean field_96141_q = true; + private static boolean field_96140_r = false; + private static boolean field_96139_s = false; + private final Object field_104025_t = new Object(); + private String field_92025_p; + private String field_104024_v; + + /** An array of all the paths to the panorama pictures. */ + private static final TextureLocation[] titlePanoramaPaths = new TextureLocation[] { new TextureLocation("/title/bg/panorama0.png"), new TextureLocation("/title/bg/panorama1.png"), new TextureLocation("/title/bg/panorama2.png"), new TextureLocation("/title/bg/panorama3.png"), new TextureLocation("/title/bg/panorama4.png"), new TextureLocation("/title/bg/panorama5.png") }; + public static final String field_96138_a = ""; + private int field_92024_r; + private int field_92023_s; + private int field_92022_t; + private int field_92021_u; + private int field_92020_v; + private int field_92019_w; + + private int scrollPosition = 0; + private static final int visibleLines = 21; + + private int dragstart = -1; + private int dragstartI = -1; + + private ArrayList ackLines; + + public boolean showAck = false; + + public GuiMainMenu() { + /* + * this.field_92025_p = ""; String var14 = + * System.getProperty("os_architecture"); var3 = + * System.getProperty("java_version"); + * + * if ("ppc".equalsIgnoreCase(var14)) { this.field_92025_p = "" + + * EnumChatFormatting.BOLD + "Notice!" + EnumChatFormatting.RESET + + * " PowerPC compatibility will be dropped in Minecraft 1.6"; + * this.field_104024_v = "http://tinyurl.com/javappc"; } else if (var3 != null + * && var3.startsWith("1.5")) { this.field_92025_p = "" + + * EnumChatFormatting.BOLD + "Notice!" + EnumChatFormatting.RESET + + * " Java 1.5 compatibility will be dropped in Minecraft 1.6"; + * this.field_104024_v = "http://tinyurl.com/javappc"; } + * + * if (this.field_92025_p.length() == 0) { (new Thread(new + * RunnableTitleScreen(this), "1.6 Update Check Thread")).start(); } + */ + + this.field_92025_p = EaglerAdapter._wisWebGL() ? ("" + EnumChatFormatting.BOLD + "webassembly edition" + EnumChatFormatting.RESET + "") : ("" + EnumChatFormatting.BOLD + "eaglercraft desktop runtime" + EnumChatFormatting.RESET + ""); + this.start = System.currentTimeMillis() + System.currentTimeMillis() % 10000l; + this.ackLines = new ArrayList(); + + if(!LocalStorageManager.gameSettingsStorage.getBoolean("seenAcknowledgements")) { + this.showAck = true; + } + } + + /** + * Returns true if this GUI should pause the game when it is displayed in + * single-player + */ + public boolean doesGuiPauseGame() { + return false; + } + + + public void handleMouseInput() { + super.handleMouseInput(); + if(showAck) { + int var1 = EaglerAdapter.mouseGetEventDWheel(); + if(var1 < 0) { + scrollPosition += 3; + } + if(var1 > 0) { + scrollPosition -= 3; + } + } + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + if(par2 == 1) { + hideAck(); + } + } + + private void hideAck() { + if(!LocalStorageManager.gameSettingsStorage.getBoolean("seenAcknowledgements")) { + LocalStorageManager.gameSettingsStorage.setBoolean("seenAcknowledgements", true); + LocalStorageManager.saveStorageG(); + } + showAck = false; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + if(viewportTexture == -1) viewportTexture = this.mc.renderEngine.makeViewportTexture(256, 256); + Calendar var1 = Calendar.getInstance(); + var1.setTime(new Date()); + + this.splashText = "darviglet!"; + + StringTranslate var2 = StringTranslate.getInstance(); + int var4 = this.height / 4 + 48; + + GuiButton single; + this.buttonList.add(single = new GuiButton(1, this.width / 2 - 100, var4, var2.translateKey("menu.singleplayer"))); + this.buttonList.add(new GuiButton(2, this.width / 2 - 100, var4 + 24 * 1, var2.translateKey("menu.multiplayer"))); + this.buttonList.add(new GuiButton(3, this.width / 2 - 100, var4 + 24 * 2, var2.translateKey("menu.voicechannel"))); + single.enabled = false; + + this.buttonList.add(new GuiButton(0, this.width / 2 - 100, var4 + 72 + 12, 98, 20, var2.translateKey("menu.options"))); + this.buttonList.add(new GuiButton(4, this.width / 2 + 2, var4 + 72 + 12, 98, 20, var2.translateKey("menu.editprofile"))); + + this.buttonList.add(new GuiButtonLanguage(5, this.width / 2 - 124, var4 + 72 + 12)); + Object var5 = this.field_104025_t; + + synchronized (this.field_104025_t) { + this.field_92023_s = this.fontRenderer.getStringWidth(this.field_92025_p); + this.field_92024_r = this.fontRenderer.getStringWidth(field_96138_a); + int var6 = Math.max(this.field_92023_s, this.field_92024_r); + this.field_92022_t = (this.width - var6) / 2; + this.field_92021_u = 82; + this.field_92020_v = this.field_92022_t + var6; + this.field_92019_w = this.field_92021_u + 12; + } + + if(this.ackLines.isEmpty()) { + int width = 315; + String file = EaglerAdapter.fileContents("/credits.txt"); + if(file == null) { + for(int i = 0; i < 30; ++i) { + this.ackLines.add(" -- file not found -- "); + } + }else { + String[] lines = file.split("\n"); + for(String s : lines) { + String s2 = s.trim(); + if(s2.isEmpty()) { + this.ackLines.add(""); + }else { + String[] words = s2.split(" "); + String currentLine = " "; + for(String s3 : words) { + String cCurrentLine = currentLine + s3 + " "; + if(this.mc.fontRenderer.getStringWidth(cCurrentLine) < width) { + currentLine = cCurrentLine; + }else { + this.ackLines.add(currentLine); + currentLine = s3 + " "; + } + } + this.ackLines.add(currentLine); + } + } + } + + } + + } + + protected void mouseClicked(int par1, int par2, int par3) { + if(!showAck) { + super.mouseClicked(par1, par2, par3); + if (par3 == 0) { + int w = this.fontRenderer.getStringWidth("§neaglercraft readme.txt") * 3 / 4; + if(par1 >= (this.width - w - 4) && par1 <= this.width && par2 >= 0 && par2 <= 9) { + showAck = true; + } + w = this.fontRenderer.getStringWidth("§ndebug console") * 3 / 4; + if(par1 >= 0 && par1 <= (w + 4) && par2 >= 0 && par2 <= 9) { + EaglerAdapter.openConsole(); + } + } + }else { + if(par3 == 0) { + int x = (this.width - 345) / 2; + int y = (this.height - 230) / 2; + if(par1 >= (x + 323) && par1 <= (x + 323 + 13) && par2 >= (y + 7) && par2 <= (y + 7 + 13)) { + hideAck(); + } + int trackHeight = 193; + int offset = trackHeight * scrollPosition / this.ackLines.size(); + if(par1 >= (x + 326) && par1 <= (x + 334) && par2 >= (y + 27 + offset) && par2 <= (y + 27 + offset + (visibleLines * trackHeight / this.ackLines.size()) + 1)) { + dragstart = par2; + dragstartI = scrollPosition; + } + } + } + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.id == 0) { + this.mc.displayGuiScreen(new GuiOptions(this, this.mc.gameSettings)); + } + + if (par1GuiButton.id == 5) { + this.mc.displayGuiScreen(new GuiLanguage(this, this.mc.gameSettings)); + } + + if (par1GuiButton.id == 2) { + this.mc.displayGuiScreen(new GuiMultiplayer(this)); + } + + if (par1GuiButton.id == 3) { + this.mc.displayGuiScreen(new GuiScreenVoiceChannel(this)); + } + + if (par1GuiButton.id == 4) { + this.mc.displayGuiScreen(new GuiScreenEditProfile(this)); + } + } + + /** + * Draws the main menu panorama + */ + private void drawPanorama(int par1, int par2, float par3) { + Tessellator var4 = Tessellator.instance; + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.gluPerspective(120.0F, 1.0F, 0.05F, 10.0F); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glRotatef(180.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glDisable(EaglerAdapter.GL_CULL_FACE); + EaglerAdapter.glDepthMask(false); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + byte var5 = 8; + + for (int var6 = 0; var6 < var5 * var5; ++var6) { + EaglerAdapter.glPushMatrix(); + float var7 = ((float) (var6 % var5) / (float) var5 - 0.5F) / 64.0F; + float var8 = ((float) (var6 / var5) / (float) var5 - 0.5F) / 64.0F; + float var9 = 0.0F; + EaglerAdapter.glTranslatef(var7, var8, var9); + + float panTimer = (float)(System.currentTimeMillis() - start) * 0.03f; + EaglerAdapter.glRotatef(MathHelper.sin(panTimer / 400.0F) * 25.0F + 20.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(-(panTimer) * 0.1F, 0.0F, 1.0F, 0.0F); + + for (int var10 = 0; var10 < 6; ++var10) { + EaglerAdapter.glPushMatrix(); + + if (var10 == 1) { + EaglerAdapter.glRotatef(90.0F, 0.0F, 1.0F, 0.0F); + } + + if (var10 == 2) { + EaglerAdapter.glRotatef(180.0F, 0.0F, 1.0F, 0.0F); + } + + if (var10 == 3) { + EaglerAdapter.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F); + } + + if (var10 == 4) { + EaglerAdapter.glRotatef(90.0F, 1.0F, 0.0F, 0.0F); + } + + if (var10 == 5) { + EaglerAdapter.glRotatef(-90.0F, 1.0F, 0.0F, 0.0F); + } + + titlePanoramaPaths[var10].bindTexture(); + var4.startDrawingQuads(); + var4.setColorRGBA_I(16777215, 255 / (var6 + 1)); + float var11 = 0.0F; + var4.addVertexWithUV(-1.0D, -1.0D, 1.0D, (double) (0.0F + var11), (double) (0.0F + var11)); + var4.addVertexWithUV(1.0D, -1.0D, 1.0D, (double) (1.0F - var11), (double) (0.0F + var11)); + var4.addVertexWithUV(1.0D, 1.0D, 1.0D, (double) (1.0F - var11), (double) (1.0F - var11)); + var4.addVertexWithUV(-1.0D, 1.0D, 1.0D, (double) (0.0F + var11), (double) (1.0F - var11)); + var4.draw(); + EaglerAdapter.glPopMatrix(); + } + + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glColorMask(true, true, true, false); + } + + var4.setTranslation(0.0D, 0.0D, 0.0D); + EaglerAdapter.glColorMask(true, true, true, true); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glDepthMask(true); + EaglerAdapter.glEnable(EaglerAdapter.GL_CULL_FACE); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + } + + /** + * Rotate and blurs the skybox view in the main menu + */ + private void rotateAndBlurSkybox(float par1) { + EaglerAdapter.glBindTexture(EaglerAdapter.GL_TEXTURE_2D, viewportTexture); + this.mc.renderEngine.resetBoundTexture(); + EaglerAdapter.glCopyTexSubImage2D(EaglerAdapter.GL_TEXTURE_2D, 0, 0, 0, 0, 0, 256, 256); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glColorMask(true, true, true, true); + Tessellator var2 = Tessellator.instance; + var2.startDrawingQuads(); + byte var3 = 3; + + for (int var4 = 0; var4 < var3; ++var4) { + var2.setColorRGBA_F(1.0F, 1.0F, 1.0F, 1.0F / (float) (var4 + 1)); + int var5 = this.width; + int var6 = this.height; + float var7 = (float) (var4 - var3 / 2) / 256.0F; + var2.addVertexWithUV((double) var5, (double) var6, (double) this.zLevel, (double) (0.0F + var7), 0.0D); + var2.addVertexWithUV((double) var5, 0.0D, (double) this.zLevel, (double) (1.0F + var7), 0.0D); + var2.addVertexWithUV(0.0D, 0.0D, (double) this.zLevel, (double) (1.0F + var7), 1.0D); + var2.addVertexWithUV(0.0D, (double) var6, (double) this.zLevel, (double) (0.0F + var7), 1.0D); + } + + var2.draw(); + EaglerAdapter.glColorMask(true, true, true, true); + this.mc.renderEngine.resetBoundTexture(); + } + + /** + * Renders the skybox in the main menu + */ + private void renderSkybox(int par1, int par2, float par3) { + EaglerAdapter.glViewport(0, 0, 256, 256); + this.drawPanorama(par1, par2, par3); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + this.rotateAndBlurSkybox(par3); + this.rotateAndBlurSkybox(par3); + this.rotateAndBlurSkybox(par3); + this.rotateAndBlurSkybox(par3); + this.rotateAndBlurSkybox(par3); + this.rotateAndBlurSkybox(par3); + this.rotateAndBlurSkybox(par3); + this.rotateAndBlurSkybox(par3); + EaglerAdapter.glViewport(0, 0, this.mc.displayWidth, this.mc.displayHeight); + Tessellator var4 = Tessellator.instance; + var4.startDrawingQuads(); + float var5 = this.width > this.height ? 120.0F / (float) this.width : 120.0F / (float) this.height; + float var6 = (float) this.height * var5 / 256.0F; + float var7 = (float) this.width * var5 / 256.0F; + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MIN_FILTER, EaglerAdapter.GL_LINEAR); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MAG_FILTER, EaglerAdapter.GL_LINEAR); + var4.setColorRGBA_F(1.0F, 1.0F, 1.0F, 1.0F); + int var8 = this.width; + int var9 = this.height; + var4.addVertexWithUV(0.0D, (double) var9, (double) this.zLevel, (double) (0.5F - var6), (double) (0.5F + var7)); + var4.addVertexWithUV((double) var8, (double) var9, (double) this.zLevel, (double) (0.5F - var6), (double) (0.5F - var7)); + var4.addVertexWithUV((double) var8, 0.0D, (double) this.zLevel, (double) (0.5F + var6), (double) (0.5F - var7)); + var4.addVertexWithUV(0.0D, 0.0D, (double) this.zLevel, (double) (0.5F + var6), (double) (0.5F + var7)); + var4.draw(); + } + + private static final TextureLocation mclogo = new TextureLocation("/title/mclogo.png"); + private static final TextureLocation ackbk = new TextureLocation("/gui/demo_bg.png"); + private static final TextureLocation beaconx = new TextureLocation("/gui/beacon.png"); + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + mousex = par1; + mousey = par2; + this.renderSkybox(par1, par2, par3); + Tessellator var4 = Tessellator.instance; + short var5 = 274; + int var6 = this.width / 2 - var5 / 2; + byte var7 = 30; + this.drawGradientRect(0, 0, this.width, this.height, -2130706433, 16777215); + this.drawGradientRect(0, 0, this.width, this.height, 0, Integer.MIN_VALUE); + mclogo.bindTexture(); + + this.drawTexturedModalRect(var6 + 0, var7 + 0, 0, 0, 99, 44); + this.drawTexturedModalRect(var6 + 99, var7 + 0, 129, 0, 27, 44); + this.drawTexturedModalRect(var6 + 99 + 26, var7 + 0, 126, 0, 3, 44); + this.drawTexturedModalRect(var6 + 99 + 26 + 3, var7 + 0, 99, 0, 26, 44); + this.drawTexturedModalRect(var6 + 154, var7 + 0, 0, 45, 155, 44); + + /* + * var4.setColorOpaque_I(16777215); EaglerAdapter.glPushMatrix(); + * EaglerAdapter.glTranslatef((float)(this.width / 2 + 90), 70.0F, 0.0F); + * EaglerAdapter.glRotatef(-20.0F, 0.0F, 0.0F, 1.0F); float var8 = 1.8F - + * MathHelper.abs(MathHelper.sin((float)(Minecraft.getSystemTime() % 1000L) / + * 1000.0F * (float)Math.PI * 2.0F) * 0.1F); var8 = var8 * 100.0F / + * (float)(this.fontRenderer.getStringWidth(this.splashText) + 32); + * EaglerAdapter.glScalef(var8, var8, var8); this.drawCenteredString(this.fontRenderer, + * this.splashText, 0, -8, 16776960); EaglerAdapter.glPopMatrix(); + */ + + this.drawString(this.fontRenderer, "minecraft 1.5.2 [mcp 7.11]", 2, this.height - 20, 16777215); + this.drawString(this.fontRenderer, ConfigConstants.mainMenuString, 2, this.height - 10, 16777215); + + String var10 = "copyright 2020 calder young"; + this.drawString(this.fontRenderer, var10, this.width - this.fontRenderer.getStringWidth(var10) - 2, this.height - 10, 16777215); + + var10 = "all rights reserved"; + this.drawString(this.fontRenderer, var10, this.width - this.fontRenderer.getStringWidth(var10) - 2, this.height - 20, 16777215); + + if (this.field_92025_p != null && this.field_92025_p.length() > 0) { + drawRect(this.field_92022_t - 2, this.field_92021_u - 2, this.field_92020_v + 2, this.field_92019_w - 1, 1428160512); + this.drawString(this.fontRenderer, this.field_92025_p, this.field_92022_t, this.field_92021_u, 16777215); + // this.drawString(this.fontRenderer, field_96138_a, (this.width - + // this.field_92024_r) / 2, ((GuiButton)this.buttonList.get(0)).yPosition - 12, + // 16777215); + } + + var10 = "§neaglercraft readme.txt"; + int w = this.fontRenderer.getStringWidth(var10) * 3 / 4; + if(!showAck && par1 >= (this.width - w - 4) && par1 <= this.width && par2 >= 0 && par2 <= 9) { + drawRect((this.width - w - 4), 0, this.width, 9, 0x55000099); + }else { + drawRect((this.width - w - 4), 0, this.width, 9, 0x55200000); + } + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef((this.width - w - 2), 1.0f, 0.0f); + EaglerAdapter.glScalef(0.75f, 0.75f, 0.75f); + this.drawString(this.fontRenderer, var10, 0, 0, 16777215); + EaglerAdapter.glPopMatrix(); + + var10 = "§ndebug console"; + w = this.fontRenderer.getStringWidth(var10) * 3 / 4; + if(!showAck && par1 >= 0 && par1 <= (w + 4) && par2 >= 0 && par2 <= 9) { + drawRect(0, 0, w + 4, 9, 0x55000099); + }else { + drawRect(0, 0, w + 4, 9, 0x55200000); + } + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(2.0f, 1.0f, 0.0f); + EaglerAdapter.glScalef(0.75f, 0.75f, 0.75f); + this.drawString(this.fontRenderer, var10, 0, 0, 16777215); + EaglerAdapter.glPopMatrix(); + + if(showAck) { + super.drawScreen(0, 0, par3); + this.drawGradientRect(0, 0, this.width, this.height, -1072689136, -804253680); + int x = (this.width - 345) / 2; + int y = (this.height - 230) / 2; + ackbk.bindTexture(); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(x, y, 0.0f); + EaglerAdapter.glScalef(1.39f, 1.39f, 1.39f); + this.drawTexturedModalRect(0, 0, 0, 0, 248, 166); + EaglerAdapter.glPopMatrix(); + beaconx.bindTexture(); + this.drawTexturedModalRect(x + 323, y + 7, 114, 223, 13, 13); + int lines = this.ackLines.size(); + if(scrollPosition < 0) scrollPosition = 0; + if(scrollPosition + visibleLines > lines) scrollPosition = lines - visibleLines; + for(int i = 0; i < visibleLines; ++i) { + this.fontRenderer.drawString(this.ackLines.get(scrollPosition + i), x + 10, y + 10 + (i * 10), 0x404060); + } + int trackHeight = 193; + int offset = trackHeight * scrollPosition / lines; + drawRect(x + 326, y + 27, x + 334, y + 220, 0x33000020); + drawRect(x + 326, y + 27 + offset, x + 334, y + 27 + (visibleLines * trackHeight / lines) + offset + 1, 0x66000000); + }else { + super.drawScreen(par1, par2, par3); + } + } + + private int mousex = 0; + private int mousey = 0; + + public void updateScreen() { + if(EaglerAdapter.mouseIsButtonDown(0) && dragstart > 0) { + int trackHeight = 193; + scrollPosition = (mousey - dragstart) * this.ackLines.size() / trackHeight + dragstartI; + if(scrollPosition < 0) scrollPosition = 0; + if(scrollPosition + visibleLines > this.ackLines.size()) scrollPosition = this.ackLines.size() - visibleLines; + }else { + dragstart = -1; + } + } + +} diff --git a/src/main/java/net/minecraft/src/GuiMemoryErrorScreen.java b/src/main/java/net/minecraft/src/GuiMemoryErrorScreen.java new file mode 100644 index 0000000..96b4006 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiMemoryErrorScreen.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + +public class GuiMemoryErrorScreen extends GuiScreen { + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + StringTranslate var1 = StringTranslate.getInstance(); + this.buttonList.clear(); + this.buttonList.add(new GuiSmallButton(0, this.width / 2 - 155, this.height / 4 + 120 + 12, var1.translateKey("gui.toMenu"))); + this.buttonList.add(new GuiSmallButton(1, this.width / 2 - 155 + 160, this.height / 4 + 120 + 12, var1.translateKey("menu.quit"))); + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.id == 0) { + this.mc.displayGuiScreen(new GuiMainMenu()); + } else if (par1GuiButton.id == 1) { + this.mc.shutdown(); + } + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, "Out of memory!", this.width / 2, this.height / 4 - 60 + 20, 16777215); + this.drawString(this.fontRenderer, "Minecraft has run out of memory.", this.width / 2 - 140, this.height / 4 - 60 + 60 + 0, 10526880); + this.drawString(this.fontRenderer, "This could be caused by a bug in the game or by the", this.width / 2 - 140, this.height / 4 - 60 + 60 + 18, 10526880); + this.drawString(this.fontRenderer, "Java Virtual Machine not being allocated enough", this.width / 2 - 140, this.height / 4 - 60 + 60 + 27, 10526880); + this.drawString(this.fontRenderer, "memory. If you are playing in a web browser, try", this.width / 2 - 140, this.height / 4 - 60 + 60 + 36, 10526880); + this.drawString(this.fontRenderer, "downloading the game and playing it offline.", this.width / 2 - 140, this.height / 4 - 60 + 60 + 45, 10526880); + this.drawString(this.fontRenderer, "To prevent level corruption, the current game has quit.", this.width / 2 - 140, this.height / 4 - 60 + 60 + 63, 10526880); + this.drawString(this.fontRenderer, "We\'ve tried to free up enough memory to let you go back to", this.width / 2 - 140, this.height / 4 - 60 + 60 + 81, 10526880); + this.drawString(this.fontRenderer, "the main menu and back to playing, but this may not have worked.", this.width / 2 - 140, this.height / 4 - 60 + 60 + 90, 10526880); + this.drawString(this.fontRenderer, "Please restart the game if you see this message again.", this.width / 2 - 140, this.height / 4 - 60 + 60 + 99, 10526880); + super.drawScreen(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/GuiMerchant.java b/src/main/java/net/minecraft/src/GuiMerchant.java new file mode 100644 index 0000000..c51f9c9 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiMerchant.java @@ -0,0 +1,170 @@ +package net.minecraft.src; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiMerchant extends GuiContainer { + /** Instance of IMerchant interface. */ + private IMerchant theIMerchant; + private GuiButtonMerchant nextRecipeButtonIndex; + private GuiButtonMerchant previousRecipeButtonIndex; + private int currentRecipeIndex = 0; + private String field_94082_v; + + public GuiMerchant(InventoryPlayer par1, IMerchant par2, World par3World, String par4) { + super(new ContainerMerchant(par1, par2, par3World)); + this.theIMerchant = par2; + this.field_94082_v = par4 != null && par4.length() >= 1 ? par4 : StatCollector.translateToLocal("entity.Villager.name"); + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + super.initGui(); + int var1 = (this.width - this.xSize) / 2; + int var2 = (this.height - this.ySize) / 2; + this.buttonList.add(this.nextRecipeButtonIndex = new GuiButtonMerchant(1, var1 + 120 + 27, var2 + 24 - 1, true)); + this.buttonList.add(this.previousRecipeButtonIndex = new GuiButtonMerchant(2, var1 + 36 - 19, var2 + 24 - 1, false)); + this.nextRecipeButtonIndex.enabled = false; + this.previousRecipeButtonIndex.enabled = false; + } + + /** + * Draw the foreground layer for the GuiContainer (everything in front of the + * items) + */ + protected void drawGuiContainerForegroundLayer(int par1, int par2) { + this.fontRenderer.drawString(this.field_94082_v, this.xSize / 2 - this.fontRenderer.getStringWidth(this.field_94082_v) / 2, 6, 4210752); + this.fontRenderer.drawString(StatCollector.translateToLocal("container.inventory"), 8, this.ySize - 96 + 2, 4210752); + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + super.updateScreen(); + MerchantRecipeList var1 = this.theIMerchant.getRecipes(this.mc.thePlayer); + + if (var1 != null) { + this.nextRecipeButtonIndex.enabled = this.currentRecipeIndex < var1.size() - 1; + this.previousRecipeButtonIndex.enabled = this.currentRecipeIndex > 0; + } + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + boolean var2 = false; + + if (par1GuiButton == this.nextRecipeButtonIndex) { + ++this.currentRecipeIndex; + var2 = true; + } else if (par1GuiButton == this.previousRecipeButtonIndex) { + --this.currentRecipeIndex; + var2 = true; + } + + if (var2) { + ((ContainerMerchant) this.inventorySlots).setCurrentRecipeIndex(this.currentRecipeIndex); + ByteArrayOutputStream var3 = new ByteArrayOutputStream(); + DataOutputStream var4 = new DataOutputStream(var3); + + try { + var4.writeInt(this.currentRecipeIndex); + this.mc.getNetHandler().addToSendQueue(new Packet250CustomPayload("MC|TrSel", var3.toByteArray())); + } catch (Exception var6) { + var6.printStackTrace(); + } + } + } + + private static final TextureLocation tex = new TextureLocation("/gui/trading.png"); + + /** + * Draw the background layer for the GuiContainer (everything behind the items) + */ + protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex.bindTexture(); + int var4 = (this.width - this.xSize) / 2; + int var5 = (this.height - this.ySize) / 2; + this.drawTexturedModalRect(var4, var5, 0, 0, this.xSize, this.ySize); + MerchantRecipeList var6 = this.theIMerchant.getRecipes(this.mc.thePlayer); + + if (var6 != null && !var6.isEmpty()) { + int var7 = this.currentRecipeIndex; + MerchantRecipe var8 = (MerchantRecipe) var6.get(var7); + + if (var8.func_82784_g()) { + tex.bindTexture(); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + this.drawTexturedModalRect(this.guiLeft + 83, this.guiTop + 21, 212, 0, 28, 21); + this.drawTexturedModalRect(this.guiLeft + 83, this.guiTop + 51, 212, 0, 28, 21); + } + } + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + super.drawScreen(par1, par2, par3); + MerchantRecipeList var4 = this.theIMerchant.getRecipes(this.mc.thePlayer); + + if (var4 != null && !var4.isEmpty()) { + int var5 = (this.width - this.xSize) / 2; + int var6 = (this.height - this.ySize) / 2; + int var7 = this.currentRecipeIndex; + MerchantRecipe var8 = (MerchantRecipe) var4.get(var7); + EaglerAdapter.glPushMatrix(); + ItemStack var9 = var8.getItemToBuy(); + ItemStack var10 = var8.getSecondItemToBuy(); + ItemStack var11 = var8.getItemToSell(); + RenderHelper.enableGUIStandardItemLighting(); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + EaglerAdapter.glEnable(EaglerAdapter.GL_COLOR_MATERIAL); + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + itemRenderer.zLevel = 100.0F; + itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, var9, var5 + 36, var6 + 24); + itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, var9, var5 + 36, var6 + 24); + + if (var10 != null) { + itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, var10, var5 + 62, var6 + 24); + itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, var10, var5 + 62, var6 + 24); + } + + itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, var11, var5 + 120, var6 + 24); + itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, var11, var5 + 120, var6 + 24); + itemRenderer.zLevel = 0.0F; + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + + if (this.isPointInRegion(36, 24, 16, 16, par1, par2)) { + this.drawItemStackTooltip(var9, par1, par2); + } else if (var10 != null && this.isPointInRegion(62, 24, 16, 16, par1, par2)) { + this.drawItemStackTooltip(var10, par1, par2); + } else if (this.isPointInRegion(120, 24, 16, 16, par1, par2)) { + this.drawItemStackTooltip(var11, par1, par2); + } + + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + RenderHelper.enableStandardItemLighting(); + } + } + + /** + * Gets the Instance of IMerchant interface. + */ + public IMerchant getIMerchant() { + return this.theIMerchant; + } +} diff --git a/src/main/java/net/minecraft/src/GuiMultiplayer.java b/src/main/java/net/minecraft/src/GuiMultiplayer.java new file mode 100644 index 0000000..0e279d8 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiMultiplayer.java @@ -0,0 +1,460 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.Collections; +import java.util.List; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +public class GuiMultiplayer extends GuiScreen { + /** Number of outstanding ThreadPollServers threads */ + private static int threadsPending = 0; + + /** Lock object for use with synchronized() */ + private static Object lock = new Object(); + + /** + * A reference to the screen object that created this. Used for navigating + * between screens. + */ + private GuiScreen parentScreen; + + /** Slot container for the server list */ + private GuiSlotServer serverSlotContainer; + private ServerList internetServerList; + + /** Index of the currently selected server */ + private int selectedServer = -1; + private GuiButton field_96289_p; + + /** The 'Join Server' button */ + private GuiButton buttonSelect; + + /** The 'Delete' button */ + private GuiButton buttonDelete; + + /** The 'Delete' button was clicked */ + private boolean deleteClicked = false; + + /** The 'Add server' button was clicked */ + private boolean addClicked = false; + + /** The 'Edit' button was clicked */ + private boolean editClicked = false; + + /** The 'Direct Connect' button was clicked */ + private boolean directClicked = false; + + /** This GUI's lag tooltip text or null if no lag icon is being hovered. */ + private String lagTooltip = null; + + /** Instance of ServerData. */ + private ServerData theServerData = null; + + /** How many ticks this Gui is already opened */ + private int ticksOpened; + private boolean field_74024_A; + private List listofLanServers = Collections.emptyList(); + + public GuiMultiplayer(GuiScreen par1GuiScreen) { + this.parentScreen = par1GuiScreen; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + EaglerAdapter.enableRepeatEvents(true); + this.buttonList.clear(); + + if (!this.field_74024_A) { + this.field_74024_A = true; + this.internetServerList = new ServerList(this.mc); + this.internetServerList.loadServerList(); + + + this.serverSlotContainer = new GuiSlotServer(this); + } else { + this.serverSlotContainer.func_77207_a(this.width, this.height, 32, this.height - 64); + } + + this.initGuiControls(); + } + + /** + * Populate the GuiScreen controlList + */ + public void initGuiControls() { + StringTranslate var1 = StringTranslate.getInstance(); + this.buttonList.add(this.field_96289_p = new GuiButton(7, this.width / 2 - 154, this.height - 28, 70, 20, var1.translateKey("selectServer.edit"))); + this.buttonList.add(this.buttonDelete = new GuiButton(2, this.width / 2 - 74, this.height - 28, 70, 20, var1.translateKey("selectServer.delete"))); + this.buttonList.add(this.buttonSelect = new GuiButton(1, this.width / 2 - 154, this.height - 52, 100, 20, var1.translateKey("selectServer.select"))); + this.buttonList.add(new GuiButton(4, this.width / 2 - 50, this.height - 52, 100, 20, var1.translateKey("selectServer.direct"))); + this.buttonList.add(new GuiButton(3, this.width / 2 + 4 + 50, this.height - 52, 100, 20, var1.translateKey("selectServer.add"))); + this.buttonList.add(new GuiButton(8, this.width / 2 + 4, this.height - 28, 70, 20, var1.translateKey("selectServer.refresh"))); + this.buttonList.add(new GuiButton(0, this.width / 2 + 4 + 76, this.height - 28, 75, 20, var1.translateKey("gui.cancel"))); + boolean var2 = this.selectedServer >= 0 && this.selectedServer < this.serverSlotContainer.getSize(); + this.buttonSelect.enabled = var2; + this.field_96289_p.enabled = var2; + this.buttonDelete.enabled = var2; + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + super.updateScreen(); + ++this.ticksOpened; + } + + /** + * Called when the screen is unloaded. Used to disable keyboard repeat events + */ + public void onGuiClosed() { + EaglerAdapter.enableRepeatEvents(false); + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.enabled) { + if (par1GuiButton.id == 2) { + String var2 = this.internetServerList.getServerData(this.selectedServer).serverName; + + if (var2 != null) { + this.deleteClicked = true; + StringTranslate var3 = StringTranslate.getInstance(); + String var4 = var3.translateKey("selectServer.deleteQuestion"); + String var5 = "\'" + var2 + "\' " + var3.translateKey("selectServer.deleteWarning"); + String var6 = var3.translateKey("selectServer.deleteButton"); + String var7 = var3.translateKey("gui.cancel"); + GuiYesNo var8 = new GuiYesNo(this, var4, var5, var6, var7, this.selectedServer); + this.mc.displayGuiScreen(var8); + } + } else if (par1GuiButton.id == 1) { + this.joinServer(this.selectedServer); + } else if (par1GuiButton.id == 4) { + this.directClicked = true; + this.mc.displayGuiScreen(new GuiScreenServerList(this, this.theServerData = new ServerData(StatCollector.translateToLocal("selectServer.defaultName"), ""))); + } else if (par1GuiButton.id == 3) { + this.addClicked = true; + this.mc.displayGuiScreen(new GuiScreenAddServer(this, this.theServerData = new ServerData(StatCollector.translateToLocal("selectServer.defaultName"), ""))); + } else if (par1GuiButton.id == 7) { + this.editClicked = true; + ServerData var9 = this.internetServerList.getServerData(this.selectedServer); + this.theServerData = new ServerData(var9.serverName, var9.serverIP); + this.theServerData.setHideAddress(var9.isHidingAddress()); + this.mc.displayGuiScreen(new GuiScreenAddServer(this, this.theServerData)); + } else if (par1GuiButton.id == 0) { + this.mc.displayGuiScreen(this.parentScreen); + } else if (par1GuiButton.id == 8) { + this.mc.displayGuiScreen(new GuiMultiplayer(this.parentScreen)); + } else { + this.serverSlotContainer.actionPerformed(par1GuiButton); + } + } + } + + public void confirmClicked(boolean par1, int par2) { + if (this.deleteClicked) { + this.deleteClicked = false; + + if (par1) { + this.internetServerList.removeServerData(par2); + this.internetServerList.saveServerList(); + this.selectedServer = -1; + } + + this.mc.displayGuiScreen(this); + } else if (this.directClicked) { + this.directClicked = false; + + if (par1) { + this.connectToServer(this.theServerData); + } else { + this.mc.displayGuiScreen(this); + } + } else if (this.addClicked) { + this.addClicked = false; + + if (par1) { + this.internetServerList.addServerData(this.theServerData); + this.internetServerList.saveServerList(); + this.selectedServer = -1; + } + + this.mc.displayGuiScreen(this); + } else if (this.editClicked) { + this.editClicked = false; + + if (par1) { + ServerData var3 = this.internetServerList.getServerData(this.selectedServer); + var3.serverName = this.theServerData.serverName; + var3.serverIP = this.theServerData.serverIP; + var3.setHideAddress(this.theServerData.isHidingAddress()); + this.internetServerList.saveServerList(); + } + + this.mc.displayGuiScreen(this); + } + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + int var3 = this.selectedServer; + + if (par2 == 59) { + this.mc.gameSettings.hideServerAddress = !this.mc.gameSettings.hideServerAddress; + this.mc.gameSettings.saveOptions(); + } else { + if (isShiftKeyDown() && par2 == 200) { + if (var3 > 0 && var3 < this.internetServerList.countServers()) { + this.internetServerList.swapServers(var3, var3 - 1); + --this.selectedServer; + + if (var3 < this.internetServerList.countServers() - 1) { + this.serverSlotContainer.func_77208_b(-this.serverSlotContainer.slotHeight); + } + } + } else if (isShiftKeyDown() && par2 == 208) { + if (var3 < this.internetServerList.countServers() - 1) { + this.internetServerList.swapServers(var3, var3 + 1); + ++this.selectedServer; + + if (var3 > 0) { + this.serverSlotContainer.func_77208_b(this.serverSlotContainer.slotHeight); + } + } + } else if (par1 == 13) { + this.actionPerformed((GuiButton) this.buttonList.get(2)); + } else { + super.keyTyped(par1, par2); + } + } + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.lagTooltip = null; + StringTranslate var4 = StringTranslate.getInstance(); + this.drawDefaultBackground(); + this.serverSlotContainer.drawScreen(par1, par2, par3); + this.drawCenteredString(this.fontRenderer, var4.translateKey("multiplayer.title"), this.width / 2, 20, 16777215); + super.drawScreen(par1, par2, par3); + + if (this.lagTooltip != null) { + this.func_74007_a(this.lagTooltip, par1, par2); + } + } + + /** + * Join server by slot index + */ + private void joinServer(int par1) { + this.connectToServer(this.internetServerList.getServerData(par1)); + } + + private void connectToServer(ServerData par1ServerData) { + this.mc.displayGuiScreen(new GuiConnecting(this, this.mc, par1ServerData)); + } + + private static void func_74017_b(ServerData par1ServerData) throws IOException { + ServerAddress var1 = ServerAddress.func_78860_a(par1ServerData.serverIP); + Socket var2 = null; + DataInputStream var3 = null; + DataOutputStream var4 = null; + + try { + var2 = new Socket(); + var2.setSoTimeout(3000); + var2.setTcpNoDelay(true); + var2.setTrafficClass(18); + var2.connect(new InetSocketAddress(var1.getIP(), var1.getPort()), 3000); + var3 = new DataInputStream(var2.getInputStream()); + var4 = new DataOutputStream(var2.getOutputStream()); + var4.write(254); + var4.write(1); + + if (var3.read() != 255) { + throw new IOException("Bad message"); + } + + String var5 = Packet.readString(var3, 256); + char[] var6 = var5.toCharArray(); + + for (int var7 = 0; var7 < var6.length; ++var7) { + if (var6[var7] != 167 && var6[var7] != 0 && ChatAllowedCharacters.allowedCharacters.indexOf(var6[var7]) < 0) { + var6[var7] = 63; + } + } + + var5 = new String(var6); + int var8; + int var9; + String[] var26; + + if (var5.startsWith("\u00a7") && var5.length() > 1) { + var26 = var5.substring(1).split("\u0000"); + + if (MathHelper.parseIntWithDefault(var26[0], 0) == 1) { + par1ServerData.serverMOTD = var26[3]; + par1ServerData.field_82821_f = MathHelper.parseIntWithDefault(var26[1], par1ServerData.field_82821_f); + par1ServerData.gameVersion = var26[2]; + var8 = MathHelper.parseIntWithDefault(var26[4], 0); + var9 = MathHelper.parseIntWithDefault(var26[5], 0); + + if (var8 >= 0 && var9 >= 0) { + par1ServerData.populationInfo = EnumChatFormatting.GRAY + "" + var8 + "" + EnumChatFormatting.DARK_GRAY + "/" + EnumChatFormatting.GRAY + var9; + } else { + par1ServerData.populationInfo = "" + EnumChatFormatting.DARK_GRAY + "???"; + } + } else { + par1ServerData.gameVersion = "???"; + par1ServerData.serverMOTD = "" + EnumChatFormatting.DARK_GRAY + "???"; + par1ServerData.field_82821_f = 62; + par1ServerData.populationInfo = "" + EnumChatFormatting.DARK_GRAY + "???"; + } + } else { + var26 = var5.split("\u00a7"); + var5 = var26[0]; + var8 = -1; + var9 = -1; + + try { + var8 = Integer.parseInt(var26[1]); + var9 = Integer.parseInt(var26[2]); + } catch (Exception var24) { + ; + } + + par1ServerData.serverMOTD = EnumChatFormatting.GRAY + var5; + + if (var8 >= 0 && var9 > 0) { + par1ServerData.populationInfo = EnumChatFormatting.GRAY + "" + var8 + "" + EnumChatFormatting.DARK_GRAY + "/" + EnumChatFormatting.GRAY + var9; + } else { + par1ServerData.populationInfo = "" + EnumChatFormatting.DARK_GRAY + "???"; + } + + par1ServerData.gameVersion = "1.3"; + par1ServerData.field_82821_f = 60; + } + } finally { + try { + if (var3 != null) { + var3.close(); + } + } catch (Throwable var23) { + ; + } + + try { + if (var4 != null) { + var4.close(); + } + } catch (Throwable var22) { + ; + } + + try { + if (var2 != null) { + var2.close(); + } + } catch (Throwable var21) { + ; + } + } + } + + protected void func_74007_a(String par1Str, int par2, int par3) { + if (par1Str != null) { + int var4 = par2 + 12; + int var5 = par3 - 12; + int var6 = this.fontRenderer.getStringWidth(par1Str); + this.drawGradientRect(var4 - 3, var5 - 3, var4 + var6 + 3, var5 + 8 + 3, -1073741824, -1073741824); + this.fontRenderer.drawStringWithShadow(par1Str, var4, var5, -1); + } + } + + static ServerList getInternetServerList(GuiMultiplayer par0GuiMultiplayer) { + return par0GuiMultiplayer.internetServerList; + } + + static List getListOfLanServers(GuiMultiplayer par0GuiMultiplayer) { + return par0GuiMultiplayer.listofLanServers; + } + + static int getSelectedServer(GuiMultiplayer par0GuiMultiplayer) { + return par0GuiMultiplayer.selectedServer; + } + + static int getAndSetSelectedServer(GuiMultiplayer par0GuiMultiplayer, int par1) { + return par0GuiMultiplayer.selectedServer = par1; + } + + /** + * Return buttonSelect GuiButton + */ + static GuiButton getButtonSelect(GuiMultiplayer par0GuiMultiplayer) { + return par0GuiMultiplayer.buttonSelect; + } + + /** + * Return buttonEdit GuiButton + */ + static GuiButton getButtonEdit(GuiMultiplayer par0GuiMultiplayer) { + return par0GuiMultiplayer.field_96289_p; + } + + /** + * Return buttonDelete GuiButton + */ + static GuiButton getButtonDelete(GuiMultiplayer par0GuiMultiplayer) { + return par0GuiMultiplayer.buttonDelete; + } + + static void func_74008_b(GuiMultiplayer par0GuiMultiplayer, int par1) { + par0GuiMultiplayer.joinServer(par1); + } + + static int getTicksOpened(GuiMultiplayer par0GuiMultiplayer) { + return par0GuiMultiplayer.ticksOpened; + } + + /** + * Returns the lock object for use with synchronized() + */ + static Object getLock() { + return lock; + } + + static int getThreadsPending() { + return threadsPending; + } + + static int increaseThreadsPending() { + return threadsPending++; + } + + static void func_82291_a(ServerData par0ServerData) throws IOException { + func_74017_b(par0ServerData); + } + + static int decreaseThreadsPending() { + return threadsPending--; + } + + static String getAndSetLagTooltip(GuiMultiplayer par0GuiMultiplayer, String par1Str) { + return par0GuiMultiplayer.lagTooltip = par1Str; + } +} diff --git a/src/main/java/net/minecraft/src/GuiNewChat.java b/src/main/java/net/minecraft/src/GuiNewChat.java new file mode 100644 index 0000000..7fa8975 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiNewChat.java @@ -0,0 +1,330 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +import net.minecraft.client.Minecraft; + +public class GuiNewChat extends Gui { + /** The Minecraft instance. */ + private final Minecraft mc; + + /** A list of messages previously sent through the chat GUI */ + private final List sentMessages = new ArrayList(); + + /** Chat lines to be displayed in the chat box */ + private final List chatLines = new ArrayList(); + private final List field_96134_d = new ArrayList(); + private int field_73768_d = 0; + private boolean field_73769_e = false; + + public GuiNewChat(Minecraft par1Minecraft) { + this.mc = par1Minecraft; + } + + public void drawChat(int par1) { + if (this.mc.gameSettings.chatVisibility != 2) { + int var2 = this.func_96127_i(); + boolean var3 = false; + int var4 = 0; + int var5 = this.field_96134_d.size(); + float var6 = this.mc.gameSettings.chatOpacity * 0.9F + 0.1F; + + if (var5 > 0) { + if (this.getChatOpen()) { + var3 = true; + } + + float var7 = this.func_96131_h(); + int var8 = MathHelper.ceiling_float_int((float) this.func_96126_f() / var7); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(2.0F, 20.0F, 0.0F); + EaglerAdapter.glScalef(var7, var7, 1.0F); + int var9; + int var11; + int var14; + + for (var9 = 0; var9 + this.field_73768_d < this.field_96134_d.size() && var9 < var2; ++var9) { + ChatLine var10 = (ChatLine) this.field_96134_d.get(var9 + this.field_73768_d); + + if (var10 != null) { + var11 = par1 - var10.getUpdatedCounter(); + + if (var11 < 200 || var3) { + double var12 = (double) var11 / 200.0D; + var12 = 1.0D - var12; + var12 *= 10.0D; + + if (var12 < 0.0D) { + var12 = 0.0D; + } + + if (var12 > 1.0D) { + var12 = 1.0D; + } + + var12 *= var12; + var14 = (int) (255.0D * var12); + + if (var3) { + var14 = 255; + } + + var14 = (int) ((float) var14 * var6); + ++var4; + + if (var14 > 3) { + byte var15 = 0; + int var16 = -var9 * 9; + drawRect(var15, var16 - 9, var15 + var8 + 4, var16, var14 / 2 << 24); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + String var17 = var10.getChatLineString(); + + if (!this.mc.gameSettings.chatColours) { + var17 = StringUtils.stripControlCodes(var17); + } + + this.mc.fontRenderer.drawStringWithShadow(var17, var15, var16 - 8, 16777215 + (var14 << 24)); + } + } + } + } + + if (var3) { + var9 = this.mc.fontRenderer.FONT_HEIGHT; + EaglerAdapter.glTranslatef(-3.0F, 0.0F, 0.0F); + int var18 = var5 * var9 + var5; + var11 = var4 * var9 + var4; + int var19 = this.field_73768_d * var11 / var5; + int var13 = var11 * var11 / var18; + + if (var18 != var11) { + var14 = var19 > 0 ? 170 : 96; + int var20 = this.field_73769_e ? 13382451 : 3355562; + drawRect(0, -var19, 2, -var19 - var13, var20 + (var14 << 24)); + drawRect(2, -var19, 1, -var19 - var13, 13421772 + (var14 << 24)); + } + } + + EaglerAdapter.glPopMatrix(); + } + } + } + + /** + * Clears the chat. + */ + public void clearChatMessages() { + this.field_96134_d.clear(); + this.chatLines.clear(); + this.sentMessages.clear(); + } + + /** + * takes a String and prints it to chat + */ + public void printChatMessage(String par1Str) { + this.printChatMessageWithOptionalDeletion(par1Str, 0); + } + + /** + * prints the String to Chat. If the ID is not 0, deletes an existing Chat Line + * of that ID from the GUI + */ + public void printChatMessageWithOptionalDeletion(String par1Str, int par2) { + this.func_96129_a(par1Str, par2, this.mc.ingameGUI.getUpdateCounter(), false); + System.out.println("[CHAT] " + par1Str); + } + + private void func_96129_a(String par1Str, int par2, int par3, boolean par4) { + boolean var5 = this.getChatOpen(); + boolean var6 = true; + + if (par2 != 0) { + this.deleteChatLine(par2); + } + + Iterator var7 = this.mc.fontRenderer.listFormattedStringToWidth(par1Str, MathHelper.floor_float((float) this.func_96126_f() / this.func_96131_h())).iterator(); + + while (var7.hasNext()) { + String var8 = (String) var7.next(); + + if (var5 && this.field_73768_d > 0) { + this.field_73769_e = true; + this.scroll(1); + } + + if (!var6) { + var8 = " " + var8; + } + + var6 = false; + this.field_96134_d.add(0, new ChatLine(par3, var8, par2)); + } + + while (this.field_96134_d.size() > 100) { + this.field_96134_d.remove(this.field_96134_d.size() - 1); + } + + if (!par4) { + this.chatLines.add(0, new ChatLine(par3, par1Str.trim(), par2)); + + while (this.chatLines.size() > 100) { + this.chatLines.remove(this.chatLines.size() - 1); + } + } + } + + public void func_96132_b() { + this.field_96134_d.clear(); + this.resetScroll(); + + for (int var1 = this.chatLines.size() - 1; var1 >= 0; --var1) { + ChatLine var2 = (ChatLine) this.chatLines.get(var1); + this.func_96129_a(var2.getChatLineString(), var2.getChatLineID(), var2.getUpdatedCounter(), true); + } + } + + /** + * Gets the list of messages previously sent through the chat GUI + */ + public List getSentMessages() { + return this.sentMessages; + } + + /** + * Adds this string to the list of sent messages, for recall using the up/down + * arrow keys + */ + public void addToSentMessages(String par1Str) { + if (this.sentMessages.isEmpty() || !((String) this.sentMessages.get(this.sentMessages.size() - 1)).equals(par1Str)) { + this.sentMessages.add(par1Str); + } + } + + /** + * Resets the chat scroll (executed when the GUI is closed) + */ + public void resetScroll() { + this.field_73768_d = 0; + this.field_73769_e = false; + } + + /** + * Scrolls the chat by the given number of lines. + */ + public void scroll(int par1) { + this.field_73768_d += par1; + int var2 = this.field_96134_d.size(); + + if (this.field_73768_d > var2 - this.func_96127_i()) { + this.field_73768_d = var2 - this.func_96127_i(); + } + + if (this.field_73768_d <= 0) { + this.field_73768_d = 0; + this.field_73769_e = false; + } + } + + public ChatClickData func_73766_a(int par1, int par2) { + if (!this.getChatOpen()) { + return null; + } else { + ScaledResolution var3 = new ScaledResolution(this.mc.gameSettings, this.mc.displayWidth, this.mc.displayHeight); + int var4 = var3.getScaleFactor(); + float var5 = this.func_96131_h(); + int var6 = par1 / var4 - 3; + int var7 = par2 / var4 - 25; + var6 = MathHelper.floor_float((float) var6 / var5); + var7 = MathHelper.floor_float((float) var7 / var5); + + if (var6 >= 0 && var7 >= 0) { + int var8 = Math.min(this.func_96127_i(), this.field_96134_d.size()); + + if (var6 <= MathHelper.floor_float((float) this.func_96126_f() / this.func_96131_h()) && var7 < this.mc.fontRenderer.FONT_HEIGHT * var8 + var8) { + int var9 = var7 / (this.mc.fontRenderer.FONT_HEIGHT + 1) + this.field_73768_d; + return new ChatClickData(this.mc.fontRenderer, (ChatLine) this.field_96134_d.get(var9), var6, var7 - (var9 - this.field_73768_d) * this.mc.fontRenderer.FONT_HEIGHT + var9); + } else { + return null; + } + } else { + return null; + } + } + } + + /** + * Adds a message to the chat after translating to the client's locale. + */ + public void addTranslatedMessage(String par1Str, Object... par2ArrayOfObj) { + this.printChatMessage(StringTranslate.getInstance().translateKeyFormat(par1Str, par2ArrayOfObj)); + } + + /** + * @return {@code true} if the chat GUI is open + */ + public boolean getChatOpen() { + return this.mc.currentScreen instanceof GuiChat; + } + + /** + * finds and deletes a Chat line by ID + */ + public void deleteChatLine(int par1) { + Iterator var2 = this.field_96134_d.iterator(); + ChatLine var3; + + do { + if (!var2.hasNext()) { + var2 = this.chatLines.iterator(); + + do { + if (!var2.hasNext()) { + return; + } + + var3 = (ChatLine) var2.next(); + } while (var3.getChatLineID() != par1); + + var2.remove(); + return; + } + + var3 = (ChatLine) var2.next(); + } while (var3.getChatLineID() != par1); + + var2.remove(); + } + + public int func_96126_f() { + return func_96128_a(this.mc.gameSettings.chatWidth); + } + + public int func_96133_g() { + return func_96130_b(this.getChatOpen() ? this.mc.gameSettings.chatHeightFocused : this.mc.gameSettings.chatHeightUnfocused); + } + + public float func_96131_h() { + return this.mc.gameSettings.chatScale; + } + + public static final int func_96128_a(float par0) { + short var1 = 320; + byte var2 = 40; + return MathHelper.floor_float(par0 * (float) (var1 - var2) + (float) var2); + } + + public static final int func_96130_b(float par0) { + short var1 = 180; + byte var2 = 20; + return MathHelper.floor_float(par0 * (float) (var1 - var2) + (float) var2); + } + + public int func_96127_i() { + return this.func_96133_g() / 9; + } +} diff --git a/src/main/java/net/minecraft/src/GuiOptions.java b/src/main/java/net/minecraft/src/GuiOptions.java new file mode 100644 index 0000000..ee04ee0 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiOptions.java @@ -0,0 +1,115 @@ +package net.minecraft.src; + +public class GuiOptions extends GuiScreen { + /** + * An array of options that can be changed directly from the options GUI. + */ + private static final EnumOptions[] relevantOptions = new EnumOptions[] { EnumOptions.MUSIC, EnumOptions.SOUND, EnumOptions.INVERT_MOUSE, EnumOptions.SENSITIVITY, EnumOptions.FOV, EnumOptions.DIFFICULTY, EnumOptions.ANTIALIASING }; + + /** + * A reference to the screen object that created this. Used for navigating + * between screens. + */ + private final GuiScreen parentScreen; + + /** Reference to the GameSettings object. */ + private final GameSettings options; + + /** The title string that is displayed in the top-center of the screen. */ + protected String screenTitle = "Options"; + + public GuiOptions(GuiScreen par1GuiScreen, GameSettings par2GameSettings) { + this.parentScreen = par1GuiScreen; + this.options = par2GameSettings; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + StringTranslate var1 = StringTranslate.getInstance(); + int var2 = 0; + this.screenTitle = var1.translateKey("options.title"); + EnumOptions[] var3 = relevantOptions; + int var4 = var3.length; + + for (int var5 = 0; var5 < var4; ++var5) { + EnumOptions var6 = var3[var5]; + + if (var6.getEnumFloat()) { + this.buttonList.add(new GuiSlider(var6.returnEnumOrdinal(), this.width / 2 - 155 + var2 % 2 * 160, this.height / 6 - 12 + 24 * (var2 >> 1), var6, this.options.getKeyBinding(var6), this.options.getOptionFloatValue(var6))); + } else { + GuiSmallButton var7 = new GuiSmallButton(var6.returnEnumOrdinal(), this.width / 2 - 155 + var2 % 2 * 160, this.height / 6 - 12 + 24 * (var2 >> 1), var6, this.options.getKeyBinding(var6)); + + if (var6 == EnumOptions.DIFFICULTY && this.mc.theWorld != null && this.mc.theWorld.getWorldInfo().isHardcoreModeEnabled()) { + var7.enabled = false; + var7.displayString = StatCollector.translateToLocal("options.difficulty") + ": " + StatCollector.translateToLocal("options.difficulty.hardcore"); + } + + this.buttonList.add(var7); + } + + ++var2; + } + + GuiButton b, b2; + + this.buttonList.add(new GuiButton(101, this.width / 2 - 152, this.height / 6 + 96 - 6, 150, 20, var1.translateKey("options.video"))); + this.buttonList.add(new GuiButton(100, this.width / 2 + 2, this.height / 6 + 96 - 6, 150, 20, var1.translateKey("options.controls"))); + this.buttonList.add(new GuiButton(102, this.width / 2 - 152, this.height / 6 + 120 - 6, 150, 20, var1.translateKey("options.language"))); + this.buttonList.add(new GuiButton(103, this.width / 2 + 2, this.height / 6 + 120 - 6, 150, 20, var1.translateKey("options.multiplayer.title"))); + this.buttonList.add(b = new GuiButton(105, this.width / 2 - 152, this.height / 6 + 144 - 6, 150, 20, var1.translateKey("options.texture.pack"))); + this.buttonList.add(b2 = new GuiButton(104, this.width / 2 + 2, this.height / 6 + 144 - 6, 150, 20, var1.translateKey("options.snooper.view"))); + this.buttonList.add(new GuiButton(200, this.width / 2 - 100, this.height / 6 + 168, var1.translateKey("gui.done"))); + b.enabled = false; + b2.enabled = false; + + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.enabled) { + if (par1GuiButton.id < 100 && par1GuiButton instanceof GuiSmallButton) { + this.options.setOptionValue(((GuiSmallButton) par1GuiButton).returnEnumOptions(), 1); + par1GuiButton.displayString = this.options.getKeyBinding(EnumOptions.getEnumOptions(par1GuiButton.id)); + } + + if (par1GuiButton.id == 101) { + this.mc.gameSettings.saveOptions(); + this.mc.displayGuiScreen(new GuiVideoSettings(this, this.options)); + } + + if (par1GuiButton.id == 100) { + this.mc.gameSettings.saveOptions(); + this.mc.displayGuiScreen(new GuiControls(this, this.options)); + } + + if (par1GuiButton.id == 102) { + this.mc.gameSettings.saveOptions(); + this.mc.displayGuiScreen(new GuiLanguage(this, this.options)); + } + + if (par1GuiButton.id == 103) { + this.mc.gameSettings.saveOptions(); + this.mc.displayGuiScreen(new GuiScreenChatOptions(this, this.options)); + } + + if (par1GuiButton.id == 200) { + this.mc.gameSettings.saveOptions(); + this.mc.displayGuiScreen(this.parentScreen); + } + } + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, 15, 16777215); + super.drawScreen(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/GuiParticle.java b/src/main/java/net/minecraft/src/GuiParticle.java new file mode 100644 index 0000000..818aaba --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiParticle.java @@ -0,0 +1,46 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiParticle extends Gui { + private List particles = new ArrayList(); + private Minecraft mc; + + public GuiParticle(Minecraft par1Minecraft) { + this.mc = par1Minecraft; + } + + public void update() { + for (int var1 = 0; var1 < this.particles.size(); ++var1) { + Particle var2 = (Particle) this.particles.get(var1); + var2.preUpdate(); + var2.update(this); + + if (var2.isDead) { + this.particles.remove(var1--); + } + } + } + + private static final TextureLocation tex_particles = new TextureLocation("/gui/particles.png"); + + public void draw(float par1) { + tex_particles.bindTexture(); + + for (int var2 = 0; var2 < this.particles.size(); ++var2) { + Particle var3 = (Particle) this.particles.get(var2); + int var4 = (int) (var3.prevPosX + (var3.posX - var3.prevPosX) * (double) par1 - 4.0D); + int var5 = (int) (var3.prevPosY + (var3.posY - var3.prevPosY) * (double) par1 - 4.0D); + float var6 = (float) (var3.prevTintAlpha + (var3.tintAlpha - var3.prevTintAlpha) * (double) par1); + float var7 = (float) (var3.prevTintRed + (var3.tintRed - var3.prevTintRed) * (double) par1); + float var8 = (float) (var3.prevTintGreen + (var3.tintGreen - var3.prevTintGreen) * (double) par1); + float var9 = (float) (var3.prevTintBlue + (var3.tintBlue - var3.prevTintBlue) * (double) par1); + EaglerAdapter.glColor4f(var7, var8, var9, var6); + this.drawTexturedModalRect(var4, var5, 40, 0, 8, 8); + } + } +} diff --git a/src/main/java/net/minecraft/src/GuiPlayerInfo.java b/src/main/java/net/minecraft/src/GuiPlayerInfo.java new file mode 100644 index 0000000..08a22c3 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiPlayerInfo.java @@ -0,0 +1,17 @@ +package net.minecraft.src; + +public class GuiPlayerInfo { + /** The string value of the object */ + public final String name; + + /** Player name in lowercase. */ + private final String nameinLowerCase; + + /** Player response time to server in milliseconds */ + public int responseTime; + + public GuiPlayerInfo(String par1Str) { + this.name = par1Str; + this.nameinLowerCase = par1Str.toLowerCase(); + } +} diff --git a/src/main/java/net/minecraft/src/GuiProgress.java b/src/main/java/net/minecraft/src/GuiProgress.java new file mode 100644 index 0000000..12b61de --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiProgress.java @@ -0,0 +1,63 @@ +package net.minecraft.src; + +public class GuiProgress extends GuiScreen implements IProgressUpdate { + private String progressMessage = ""; + private String workingMessage = ""; + private int currentProgress = 0; + private boolean noMoreProgress; + + /** + * "Saving level", or the loading,or downloading equivelent + */ + public void displayProgressMessage(String par1Str) { + this.resetProgressAndMessage(par1Str); + } + + /** + * this string, followed by "working..." and then the "% complete" are the 3 + * lines shown. This resets progress to 0, and the WorkingString to + * "working...". + */ + public void resetProgressAndMessage(String par1Str) { + this.progressMessage = par1Str; + this.resetProgresAndWorkingMessage("Working..."); + } + + /** + * This is called with "Working..." by resetProgressAndMessage + */ + public void resetProgresAndWorkingMessage(String par1Str) { + this.workingMessage = par1Str; + this.setLoadingProgress(0); + } + + /** + * Updates the progress bar on the loading screen to the specified amount. Args: + * loadProgress + */ + public void setLoadingProgress(int par1) { + this.currentProgress = par1; + } + + /** + * called when there is no more progress to be had, both on completion and + * failure + */ + public void onNoMoreProgress() { + this.noMoreProgress = true; + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + if (this.noMoreProgress) { + this.mc.displayGuiScreen((GuiScreen) null); + } else { + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, this.progressMessage, this.width / 2, 70, 16777215); + this.drawCenteredString(this.fontRenderer, this.workingMessage + " " + this.currentProgress + "%", this.width / 2, 90, 16777215); + super.drawScreen(par1, par2, par3); + } + } +} diff --git a/src/main/java/net/minecraft/src/GuiRepair.java b/src/main/java/net/minecraft/src/GuiRepair.java new file mode 100644 index 0000000..934f3f3 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiRepair.java @@ -0,0 +1,165 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiRepair extends GuiContainer implements ICrafting { + private ContainerRepair repairContainer; + private GuiTextField itemNameField; + private InventoryPlayer field_82325_q; + + public GuiRepair(InventoryPlayer par1, World par2World, int par3, int par4, int par5) { + super(new ContainerRepair(par1, par2World, par3, par4, par5, Minecraft.getMinecraft().thePlayer)); + this.field_82325_q = par1; + this.repairContainer = (ContainerRepair) this.inventorySlots; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + super.initGui(); + EaglerAdapter.enableRepeatEvents(true); + int var1 = (this.width - this.xSize) / 2; + int var2 = (this.height - this.ySize) / 2; + this.itemNameField = new GuiTextField(this.fontRenderer, var1 + 62, var2 + 24, 103, 12); + this.itemNameField.setTextColor(-1); + this.itemNameField.setDisabledTextColour(-1); + this.itemNameField.setEnableBackgroundDrawing(false); + this.itemNameField.setMaxStringLength(30); + this.inventorySlots.removeCraftingFromCrafters(this); + this.inventorySlots.addCraftingToCrafters(this); + } + + /** + * Called when the screen is unloaded. Used to disable keyboard repeat events + */ + public void onGuiClosed() { + super.onGuiClosed(); + EaglerAdapter.enableRepeatEvents(false); + this.inventorySlots.removeCraftingFromCrafters(this); + } + + /** + * Draw the foreground layer for the GuiContainer (everything in front of the + * items) + */ + protected void drawGuiContainerForegroundLayer(int par1, int par2) { + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + this.fontRenderer.drawString(StatCollector.translateToLocal("container.repair"), 60, 6, 4210752); + + if (this.repairContainer.maximumCost > 0) { + int var3 = 8453920; + boolean var4 = true; + String var5 = StatCollector.translateToLocalFormatted("container.repair.cost", new Object[] { Integer.valueOf(this.repairContainer.maximumCost) }); + + if (this.repairContainer.maximumCost >= 40 && !this.mc.thePlayer.capabilities.isCreativeMode) { + var5 = StatCollector.translateToLocal("container.repair.expensive"); + var3 = 16736352; + } else if (!this.repairContainer.getSlot(2).getHasStack()) { + var4 = false; + } else if (!this.repairContainer.getSlot(2).canTakeStack(this.field_82325_q.player)) { + var3 = 16736352; + } + + if (var4) { + int var6 = -16777216 | (var3 & 16579836) >> 2 | var3 & -16777216; + int var7 = this.xSize - 8 - this.fontRenderer.getStringWidth(var5); + byte var8 = 67; + + if (this.fontRenderer.getUnicodeFlag()) { + drawRect(var7 - 3, var8 - 2, this.xSize - 7, var8 + 10, -16777216); + drawRect(var7 - 2, var8 - 1, this.xSize - 8, var8 + 9, -12895429); + } else { + this.fontRenderer.drawString(var5, var7, var8 + 1, var6); + this.fontRenderer.drawString(var5, var7 + 1, var8, var6); + this.fontRenderer.drawString(var5, var7 + 1, var8 + 1, var6); + } + + this.fontRenderer.drawString(var5, var7, var8, var3); + } + } + + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + if (this.itemNameField.textboxKeyTyped(par1, par2)) { + this.repairContainer.updateItemName(this.itemNameField.getText()); + this.mc.thePlayer.sendQueue.addToSendQueue(new Packet250CustomPayload("MC|ItemName", this.itemNameField.getText().getBytes())); + } else { + super.keyTyped(par1, par2); + } + } + + /** + * Called when the mouse is clicked. + */ + protected void mouseClicked(int par1, int par2, int par3) { + super.mouseClicked(par1, par2, par3); + this.itemNameField.mouseClicked(par1, par2, par3); + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + super.drawScreen(par1, par2, par3); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + this.itemNameField.drawTextBox(); + } + + private static final TextureLocation tex = new TextureLocation("/gui/repair.png"); + + /** + * Draw the background layer for the GuiContainer (everything behind the items) + */ + protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex.bindTexture(); + int var4 = (this.width - this.xSize) / 2; + int var5 = (this.height - this.ySize) / 2; + this.drawTexturedModalRect(var4, var5, 0, 0, this.xSize, this.ySize); + this.drawTexturedModalRect(var4 + 59, var5 + 20, 0, this.ySize + (this.repairContainer.getSlot(0).getHasStack() ? 0 : 16), 110, 16); + + if ((this.repairContainer.getSlot(0).getHasStack() || this.repairContainer.getSlot(1).getHasStack()) && !this.repairContainer.getSlot(2).getHasStack()) { + this.drawTexturedModalRect(var4 + 99, var5 + 45, this.xSize, 0, 28, 21); + } + } + + public void sendContainerAndContentsToPlayer(Container par1Container, List par2List) { + this.sendSlotContents(par1Container, 0, par1Container.getSlot(0).getStack()); + } + + /** + * Sends the contents of an inventory slot to the client-side Container. This + * doesn't have to match the actual contents of that slot. Args: Container, slot + * number, slot contents + */ + public void sendSlotContents(Container par1Container, int par2, ItemStack par3ItemStack) { + if (par2 == 0) { + this.itemNameField.setText(par3ItemStack == null ? "" : par3ItemStack.getDisplayName()); + this.itemNameField.setEnabled(par3ItemStack != null); + + if (par3ItemStack != null) { + this.repairContainer.updateItemName(this.itemNameField.getText()); + this.mc.thePlayer.sendQueue.addToSendQueue(new Packet250CustomPayload("MC|ItemName", this.itemNameField.getText().getBytes())); + } + } + } + + /** + * Sends two ints to the client-side Container. Used for furnace burning time, + * smelting progress, brewing progress, and enchanting level. Normally the first + * int identifies which variable to update, and the second contains the new + * value. Both are truncated to shorts in non-local SMP. + */ + public void sendProgressBarUpdate(Container par1Container, int par2, int par3) { + } +} diff --git a/src/main/java/net/minecraft/src/GuiScreen.java b/src/main/java/net/minecraft/src/GuiScreen.java new file mode 100644 index 0000000..61e7a7c --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiScreen.java @@ -0,0 +1,260 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class GuiScreen extends Gui { + public static final boolean isMacOs = Minecraft.getOs() == EnumOS.MACOS; + + /** Reference to the Minecraft object. */ + protected Minecraft mc; + + /** The width of the screen object. */ + public int width; + + /** The height of the screen object. */ + public int height; + + /** A list of all the buttons in this container. */ + protected List buttonList = new ArrayList(); + public boolean allowUserInput = false; + + /** The FontRenderer used by GuiScreen */ + protected FontRenderer fontRenderer; + public GuiParticle guiParticles; + + /** The button that was just pressed. */ + private GuiButton selectedButton = null; + private int eventButton = 0; + private long field_85043_c = 0L; + private int field_92018_d = 0; + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + for (int var4 = 0; var4 < this.buttonList.size(); ++var4) { + GuiButton var5 = (GuiButton) this.buttonList.get(var4); + var5.drawButton(this.mc, par1, par2); + } + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + //if (par2 == 1) { + // this.mc.displayGuiScreen((GuiScreen) null); + // this.mc.setIngameFocus(); + //} + } + + /** + * Returns a string stored in the system clipboard. + */ + public static String getClipboardString() { + return ""; + } + + /** + * store a string in the system clipboard + */ + public static void setClipboardString(String par0Str) { + + } + + /** + * Called when the mouse is clicked. + */ + protected void mouseClicked(int par1, int par2, int par3) { + if (par3 == 0) { + for (int var4 = 0; var4 < this.buttonList.size(); ++var4) { + GuiButton var5 = (GuiButton) this.buttonList.get(var4); + + if (var5.mousePressed(this.mc, par1, par2)) { + this.selectedButton = var5; + this.mc.sndManager.playSoundFX("random.click", 1.0F, 1.0F); + this.actionPerformed(var5); + } + } + } + } + + /** + * Called when the mouse is moved or a mouse button is released. Signature: + * (mouseX, mouseY, which) which==-1 is mouseMove, which==0 or which==1 is + * mouseUp + */ + protected void mouseMovedOrUp(int par1, int par2, int par3) { + if (this.selectedButton != null && par3 == 0) { + this.selectedButton.mouseReleased(par1, par2); + this.selectedButton = null; + } + } + + protected void func_85041_a(int par1, int par2, int par3, long par4) { + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + } + + /** + * Causes the screen to lay out its subcomponents again. This is the equivalent + * of the Java call Container.validate() + */ + public void setWorldAndResolution(Minecraft par1Minecraft, int par2, int par3) { + this.guiParticles = new GuiParticle(par1Minecraft); + this.mc = par1Minecraft; + this.fontRenderer = par1Minecraft.fontRenderer; + this.width = par2; + this.height = par3; + this.buttonList.clear(); + this.initGui(); + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + } + + /** + * Delegates mouse and keyboard input. + */ + public void handleInput() { + while (EaglerAdapter.mouseNext()) { + this.handleMouseInput(); + } + + while (EaglerAdapter.keysNext()) { + this.handleKeyboardInput(); + } + } + + /** + * Handles mouse input. + */ + public void handleMouseInput() { + int var1 = EaglerAdapter.mouseGetEventX() * this.width / this.mc.displayWidth; + int var2 = this.height - EaglerAdapter.mouseGetEventY() * this.height / this.mc.displayHeight - 1; + + if (EaglerAdapter.mouseGetEventButtonState()) { + if (this.mc.gameSettings.touchscreen && this.field_92018_d++ > 0) { + return; + } + + this.eventButton = EaglerAdapter.mouseGetEventButton(); + this.field_85043_c = Minecraft.getSystemTime(); + this.mouseClicked(var1, var2, this.eventButton); + } else if (EaglerAdapter.mouseGetEventButton() != -1) { + if (this.mc.gameSettings.touchscreen && --this.field_92018_d > 0) { + return; + } + + this.eventButton = -1; + this.mouseMovedOrUp(var1, var2, EaglerAdapter.mouseGetEventButton()); + } else if (this.eventButton != -1 && this.field_85043_c > 0L) { + long var3 = Minecraft.getSystemTime() - this.field_85043_c; + this.func_85041_a(var1, var2, this.eventButton, var3); + } + } + + /** + * Handles keyboard input. + */ + public void handleKeyboardInput() { + if (EaglerAdapter.getEventKeyState()) { + int var1 = EaglerAdapter.getEventKey(); + char var2 = EaglerAdapter.getEventChar(); + + if (var1 == 87) { + this.mc.toggleFullscreen(); + return; + } + + if (isMacOs && var1 == 28 && var2 == 0) { + var1 = 29; + } + + this.keyTyped(var2, var1); + } + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + } + + /** + * Called when the screen is unloaded. Used to disable keyboard repeat events + */ + public void onGuiClosed() { + } + + /** + * Draws either a gradient over the background screen (when it exists) or a flat + * gradient over background.png + */ + public void drawDefaultBackground() { + this.drawWorldBackground(0); + } + + public void drawWorldBackground(int par1) { + if (this.mc.theWorld != null) { + this.drawGradientRect(0, 0, this.width, this.height, -1072689136, -804253680); + } else { + this.drawBackground(par1); + } + } + + private static final TextureLocation tex_background = new TextureLocation("/gui/background.png"); + + /** + * Draws the background (i is always 0 as of 1.2.2) + */ + public void drawBackground(int par1) { + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glDisable(EaglerAdapter.GL_FOG); + Tessellator var2 = Tessellator.instance; + tex_background.bindTexture(); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + float var3 = 32.0F; + var2.startDrawingQuads(); + var2.setColorOpaque_I(4210752); + var2.addVertexWithUV(0.0D, (double) this.height, 0.0D, 0.0D, (double) ((float) this.height / var3 + (float) par1)); + var2.addVertexWithUV((double) this.width, (double) this.height, 0.0D, (double) ((float) this.width / var3), (double) ((float) this.height / var3 + (float) par1)); + var2.addVertexWithUV((double) this.width, 0.0D, 0.0D, (double) ((float) this.width / var3), (double) par1); + var2.addVertexWithUV(0.0D, 0.0D, 0.0D, 0.0D, (double) par1); + var2.draw(); + } + + /** + * Returns true if this GUI should pause the game when it is displayed in + * single-player + */ + public boolean doesGuiPauseGame() { + return true; + } + + public void confirmClicked(boolean par1, int par2) { + } + + public static boolean isCtrlKeyDown() { + boolean var0 = EaglerAdapter.isKeyDown(28) && EaglerAdapter.getEventChar() == 0; + return EaglerAdapter.isKeyDown(29) || EaglerAdapter.isKeyDown(157) || isMacOs && (var0 || EaglerAdapter.isKeyDown(219) || EaglerAdapter.isKeyDown(220)); + } + + public static boolean isShiftKeyDown() { + return EaglerAdapter.isKeyDown(42) || EaglerAdapter.isKeyDown(54); + } +} diff --git a/src/main/java/net/minecraft/src/GuiScreenAddServer.java b/src/main/java/net/minecraft/src/GuiScreenAddServer.java new file mode 100644 index 0000000..6cab074 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiScreenAddServer.java @@ -0,0 +1,120 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +public class GuiScreenAddServer extends GuiScreen { + /** This GUI's parent GUI. */ + private GuiScreen parentGui; + private GuiTextField serverAddress; + private GuiTextField serverName; + + /** ServerData to be modified by this GUI */ + private ServerData newServerData; + + public GuiScreenAddServer(GuiScreen par1GuiScreen, ServerData par2ServerData) { + this.parentGui = par1GuiScreen; + this.newServerData = par2ServerData; + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + this.serverName.updateCursorCounter(); + this.serverAddress.updateCursorCounter(); + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + StringTranslate var1 = StringTranslate.getInstance(); + EaglerAdapter.enableRepeatEvents(true); + this.buttonList.clear(); + this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + 12, var1.translateKey("addServer.add"))); + this.buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 + 120 + 12, var1.translateKey("gui.cancel"))); + this.buttonList.add(new GuiButton(2, this.width / 2 - 100, 142, var1.translateKey("addServer.hideAddress") + ": " + (this.newServerData.isHidingAddress() ? var1.translateKey("gui.yes") : var1.translateKey("gui.no")))); + this.serverName = new GuiTextField(this.fontRenderer, this.width / 2 - 100, 66, 200, 20); + this.serverName.setFocused(true); + this.serverName.setText(this.newServerData.serverName); + this.serverAddress = new GuiTextField(this.fontRenderer, this.width / 2 - 100, 106, 200, 20); + this.serverAddress.setMaxStringLength(128); + this.serverAddress.setText(this.newServerData.serverIP); + ((GuiButton) this.buttonList.get(0)).enabled = this.serverAddress.getText().length() > 0 && this.serverAddress.getText().split(":").length > 0 && this.serverName.getText().length() > 0; + } + + /** + * Called when the screen is unloaded. Used to disable keyboard repeat events + */ + public void onGuiClosed() { + EaglerAdapter.enableRepeatEvents(false); + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.enabled) { + if (par1GuiButton.id == 1) { + this.parentGui.confirmClicked(false, 0); + } else if (par1GuiButton.id == 0) { + this.newServerData.serverName = this.serverName.getText(); + this.newServerData.serverIP = this.serverAddress.getText(); + this.parentGui.confirmClicked(true, 0); + } else if (par1GuiButton.id == 2) { + StringTranslate var2 = StringTranslate.getInstance(); + this.newServerData.setHideAddress(!this.newServerData.isHidingAddress()); + ((GuiButton) this.buttonList.get(2)).displayString = var2.translateKey("addServer.hideAddress") + ": " + (this.newServerData.isHidingAddress() ? var2.translateKey("gui.yes") : var2.translateKey("gui.no")); + } + } + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + this.serverName.textboxKeyTyped(par1, par2); + this.serverAddress.textboxKeyTyped(par1, par2); + + if (par1 == 9) { + if (this.serverName.isFocused()) { + this.serverName.setFocused(false); + this.serverAddress.setFocused(true); + } else { + this.serverName.setFocused(true); + this.serverAddress.setFocused(false); + } + } + + if (par1 == 13) { + this.actionPerformed((GuiButton) this.buttonList.get(0)); + } + + ((GuiButton) this.buttonList.get(0)).enabled = this.serverAddress.getText().length() > 0 && this.serverAddress.getText().split(":").length > 0 && this.serverName.getText().length() > 0; + } + + /** + * Called when the mouse is clicked. + */ + protected void mouseClicked(int par1, int par2, int par3) { + super.mouseClicked(par1, par2, par3); + this.serverAddress.mouseClicked(par1, par2, par3); + this.serverName.mouseClicked(par1, par2, par3); + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + StringTranslate var4 = StringTranslate.getInstance(); + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, var4.translateKey("addServer.title"), this.width / 2, 17, 16777215); + this.drawString(this.fontRenderer, var4.translateKey("addServer.enterName"), this.width / 2 - 100, 53, 10526880); + this.drawString(this.fontRenderer, var4.translateKey("addServer.enterIp"), this.width / 2 - 100, 94, 10526880); + this.serverName.drawTextBox(); + this.serverAddress.drawTextBox(); + super.drawScreen(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/GuiScreenBook.java b/src/main/java/net/minecraft/src/GuiScreenBook.java new file mode 100644 index 0000000..b2e44d2 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiScreenBook.java @@ -0,0 +1,363 @@ +package net.minecraft.src; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class GuiScreenBook extends GuiScreen { + /** The player editing the book */ + private final EntityPlayer editingPlayer; + private final ItemStack itemstackBook; + + /** Whether the book is signed or can still be edited */ + private final boolean bookIsUnsigned; + private boolean bookModified; + private boolean editingTitle; + + /** Update ticks since the gui was opened */ + private int updateCount; + private int bookImageWidth = 192; + private int bookImageHeight = 192; + private int bookTotalPages = 1; + private int currPage; + private NBTTagList bookPages; + private String bookTitle = ""; + private GuiButtonNextPage buttonNextPage; + private GuiButtonNextPage buttonPreviousPage; + private GuiButton buttonDone; + + /** The GuiButton to sign this book. */ + private GuiButton buttonSign; + private GuiButton buttonFinalize; + private GuiButton buttonCancel; + + public GuiScreenBook(EntityPlayer par1EntityPlayer, ItemStack par2ItemStack, boolean par3) { + this.editingPlayer = par1EntityPlayer; + this.itemstackBook = par2ItemStack; + this.bookIsUnsigned = par3; + + if (par2ItemStack.hasTagCompound()) { + NBTTagCompound var4 = par2ItemStack.getTagCompound(); + this.bookPages = var4.getTagList("pages"); + + if (this.bookPages != null) { + this.bookPages = (NBTTagList) this.bookPages.copy(); + this.bookTotalPages = this.bookPages.tagCount(); + + if (this.bookTotalPages < 1) { + this.bookTotalPages = 1; + } + } + } + + if (this.bookPages == null && par3) { + this.bookPages = new NBTTagList("pages"); + this.bookPages.appendTag(new NBTTagString("1", "")); + this.bookTotalPages = 1; + } + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + super.updateScreen(); + ++this.updateCount; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + this.buttonList.clear(); + EaglerAdapter.enableRepeatEvents(true); + + if (this.bookIsUnsigned) { + this.buttonList.add(this.buttonSign = new GuiButton(3, this.width / 2 - 100, 4 + this.bookImageHeight, 98, 20, StatCollector.translateToLocal("book.signButton"))); + this.buttonList.add(this.buttonDone = new GuiButton(0, this.width / 2 + 2, 4 + this.bookImageHeight, 98, 20, StatCollector.translateToLocal("gui.done"))); + this.buttonList.add(this.buttonFinalize = new GuiButton(5, this.width / 2 - 100, 4 + this.bookImageHeight, 98, 20, StatCollector.translateToLocal("book.finalizeButton"))); + this.buttonList.add(this.buttonCancel = new GuiButton(4, this.width / 2 + 2, 4 + this.bookImageHeight, 98, 20, StatCollector.translateToLocal("gui.cancel"))); + } else { + this.buttonList.add(this.buttonDone = new GuiButton(0, this.width / 2 - 100, 4 + this.bookImageHeight, 200, 20, StatCollector.translateToLocal("gui.done"))); + } + + int var1 = (this.width - this.bookImageWidth) / 2; + byte var2 = 2; + this.buttonList.add(this.buttonNextPage = new GuiButtonNextPage(1, var1 + 120, var2 + 154, true)); + this.buttonList.add(this.buttonPreviousPage = new GuiButtonNextPage(2, var1 + 38, var2 + 154, false)); + this.updateButtons(); + } + + /** + * Called when the screen is unloaded. Used to disable keyboard repeat events + */ + public void onGuiClosed() { + EaglerAdapter.enableRepeatEvents(false); + } + + private void updateButtons() { + this.buttonNextPage.drawButton = !this.editingTitle && (this.currPage < this.bookTotalPages - 1 || this.bookIsUnsigned); + this.buttonPreviousPage.drawButton = !this.editingTitle && this.currPage > 0; + this.buttonDone.drawButton = !this.bookIsUnsigned || !this.editingTitle; + + if (this.bookIsUnsigned) { + this.buttonSign.drawButton = !this.editingTitle; + this.buttonCancel.drawButton = this.editingTitle; + this.buttonFinalize.drawButton = this.editingTitle; + this.buttonFinalize.enabled = this.bookTitle.trim().length() > 0; + } + } + + private void sendBookToServer(boolean par1) { + if (this.bookIsUnsigned && this.bookModified) { + if (this.bookPages != null) { + while (this.bookPages.tagCount() > 1) { + NBTTagString var2 = (NBTTagString) this.bookPages.tagAt(this.bookPages.tagCount() - 1); + + if (var2.data != null && var2.data.length() != 0) { + break; + } + + this.bookPages.removeTag(this.bookPages.tagCount() - 1); + } + + if (this.itemstackBook.hasTagCompound()) { + NBTTagCompound var7 = this.itemstackBook.getTagCompound(); + var7.setTag("pages", this.bookPages); + } else { + this.itemstackBook.setTagInfo("pages", this.bookPages); + } + + String var8 = "MC|BEdit"; + + if (par1) { + var8 = "MC|BSign"; + this.itemstackBook.setTagInfo("author", new NBTTagString("author", this.editingPlayer.username)); + this.itemstackBook.setTagInfo("title", new NBTTagString("title", this.bookTitle.trim())); + this.itemstackBook.itemID = Item.writtenBook.itemID; + } + + ByteArrayOutputStream var3 = new ByteArrayOutputStream(); + DataOutputStream var4 = new DataOutputStream(var3); + + try { + Packet.writeItemStack(this.itemstackBook, var4); + this.mc.getNetHandler().addToSendQueue(new Packet250CustomPayload(var8, var3.toByteArray())); + } catch (Exception var6) { + var6.printStackTrace(); + } + } + } + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.enabled) { + if (par1GuiButton.id == 0) { + this.mc.displayGuiScreen((GuiScreen) null); + this.sendBookToServer(false); + } else if (par1GuiButton.id == 3 && this.bookIsUnsigned) { + this.editingTitle = true; + } else if (par1GuiButton.id == 1) { + if (this.currPage < this.bookTotalPages - 1) { + ++this.currPage; + } else if (this.bookIsUnsigned) { + this.addNewPage(); + + if (this.currPage < this.bookTotalPages - 1) { + ++this.currPage; + } + } + } else if (par1GuiButton.id == 2) { + if (this.currPage > 0) { + --this.currPage; + } + } else if (par1GuiButton.id == 5 && this.editingTitle) { + this.sendBookToServer(true); + this.mc.displayGuiScreen((GuiScreen) null); + } else if (par1GuiButton.id == 4 && this.editingTitle) { + this.editingTitle = false; + } + + this.updateButtons(); + } + } + + private void addNewPage() { + if (this.bookPages != null && this.bookPages.tagCount() < 50) { + this.bookPages.appendTag(new NBTTagString("" + (this.bookTotalPages + 1), "")); + ++this.bookTotalPages; + this.bookModified = true; + } + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + super.keyTyped(par1, par2); + + if (this.bookIsUnsigned) { + if (this.editingTitle) { + this.func_74162_c(par1, par2); + } else { + this.keyTypedInBook(par1, par2); + } + } + } + + /** + * Processes keystrokes when editing the text of a book + */ + private void keyTypedInBook(char par1, int par2) { + switch (par1) { + case 22: + this.func_74160_b(GuiScreen.getClipboardString()); + return; + + default: + switch (par2) { + case 14: + String var3 = this.func_74158_i(); + + if (var3.length() > 0) { + this.func_74159_a(var3.substring(0, var3.length() - 1)); + } + + return; + + case 28: + this.func_74160_b("\n"); + return; + + default: + if (ChatAllowedCharacters.isAllowedCharacter(par1)) { + this.func_74160_b(Character.toString(par1)); + } + } + } + } + + private void func_74162_c(char par1, int par2) { + switch (par2) { + case 14: + if (this.bookTitle.length() > 0) { + this.bookTitle = this.bookTitle.substring(0, this.bookTitle.length() - 1); + this.updateButtons(); + } + + return; + + case 28: + if (this.bookTitle.length() > 0) { + this.sendBookToServer(true); + this.mc.displayGuiScreen((GuiScreen) null); + } + + return; + + default: + if (this.bookTitle.length() < 16 && ChatAllowedCharacters.isAllowedCharacter(par1)) { + this.bookTitle = this.bookTitle + Character.toString(par1); + this.updateButtons(); + this.bookModified = true; + } + } + } + + private String func_74158_i() { + if (this.bookPages != null && this.currPage >= 0 && this.currPage < this.bookPages.tagCount()) { + NBTTagString var1 = (NBTTagString) this.bookPages.tagAt(this.currPage); + return var1.toString(); + } else { + return ""; + } + } + + private void func_74159_a(String par1Str) { + if (this.bookPages != null && this.currPage >= 0 && this.currPage < this.bookPages.tagCount()) { + NBTTagString var2 = (NBTTagString) this.bookPages.tagAt(this.currPage); + var2.data = par1Str; + this.bookModified = true; + } + } + + private void func_74160_b(String par1Str) { + String var2 = this.func_74158_i(); + String var3 = var2 + par1Str; + int var4 = this.fontRenderer.splitStringWidth(var3 + "" + EnumChatFormatting.BLACK + "_", 118); + + if (var4 <= 118 && var3.length() < 256) { + this.func_74159_a(var3); + } + } + + private static final TextureLocation tex = new TextureLocation("/gui/book.png"); + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex.bindTexture(); + int var4 = (this.width - this.bookImageWidth) / 2; + byte var5 = 2; + this.drawTexturedModalRect(var4, var5, 0, 0, this.bookImageWidth, this.bookImageHeight); + String var6; + String var7; + int var8; + + if (this.editingTitle) { + var6 = this.bookTitle; + + if (this.bookIsUnsigned) { + if (this.updateCount / 6 % 2 == 0) { + var6 = var6 + "" + EnumChatFormatting.BLACK + "_"; + } else { + var6 = var6 + "" + EnumChatFormatting.GRAY + "_"; + } + } + + var7 = StatCollector.translateToLocal("book.editTitle"); + var8 = this.fontRenderer.getStringWidth(var7); + this.fontRenderer.drawString(var7, var4 + 36 + (116 - var8) / 2, var5 + 16 + 16, 0); + int var9 = this.fontRenderer.getStringWidth(var6); + this.fontRenderer.drawString(var6, var4 + 36 + (116 - var9) / 2, var5 + 48, 0); + String var10 = String.format(StatCollector.translateToLocal("book.byAuthor"), new Object[] { this.editingPlayer.username }); + int var11 = this.fontRenderer.getStringWidth(var10); + this.fontRenderer.drawString(EnumChatFormatting.DARK_GRAY + var10, var4 + 36 + (116 - var11) / 2, var5 + 48 + 10, 0); + String var12 = StatCollector.translateToLocal("book.finalizeWarning"); + this.fontRenderer.drawSplitString(var12, var4 + 36, var5 + 80, 116, 0); + } else { + var6 = String.format(StatCollector.translateToLocal("book.pageIndicator"), new Object[] { Integer.valueOf(this.currPage + 1), Integer.valueOf(this.bookTotalPages) }); + var7 = ""; + + if (this.bookPages != null && this.currPage >= 0 && this.currPage < this.bookPages.tagCount()) { + NBTTagString var13 = (NBTTagString) this.bookPages.tagAt(this.currPage); + var7 = var13.toString(); + } + + if (this.bookIsUnsigned) { + if (this.fontRenderer.getBidiFlag()) { + var7 = var7 + "_"; + } else if (this.updateCount / 6 % 2 == 0) { + var7 = var7 + "" + EnumChatFormatting.BLACK + "_"; + } else { + var7 = var7 + "" + EnumChatFormatting.GRAY + "_"; + } + } + + var8 = this.fontRenderer.getStringWidth(var6); + this.fontRenderer.drawString(var6, var4 - var8 + this.bookImageWidth - 44, var5 + 16, 0); + this.fontRenderer.drawSplitString(var7, var4 + 36, var5 + 16 + 16, 116, 0); + } + + super.drawScreen(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/GuiScreenChatOptions.java b/src/main/java/net/minecraft/src/GuiScreenChatOptions.java new file mode 100644 index 0000000..1cbabd1 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiScreenChatOptions.java @@ -0,0 +1,99 @@ +package net.minecraft.src; + +public class GuiScreenChatOptions extends GuiScreen { + /** An array of all EnumOptions which are to do with chat. */ + private static final EnumOptions[] allScreenChatOptions = new EnumOptions[] { EnumOptions.CHAT_VISIBILITY, EnumOptions.CHAT_COLOR, EnumOptions.CHAT_LINKS, EnumOptions.CHAT_OPACITY, EnumOptions.CHAT_LINKS_PROMPT, EnumOptions.CHAT_SCALE, + EnumOptions.CHAT_HEIGHT_FOCUSED, EnumOptions.CHAT_HEIGHT_UNFOCUSED, EnumOptions.CHAT_WIDTH }; + private static final EnumOptions[] allMultiplayerOptions = new EnumOptions[] { EnumOptions.SHOW_CAPE }; + + /** Instance of GuiScreen. */ + private final GuiScreen theGuiScreen; + + /** Instance of GameSettings file. */ + private final GameSettings theSettings; + private String theChatOptions; + private String field_82268_n; + private int field_82269_o = 0; + + public GuiScreenChatOptions(GuiScreen par1GuiScreen, GameSettings par2GameSettings) { + this.theGuiScreen = par1GuiScreen; + this.theSettings = par2GameSettings; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + StringTranslate var1 = StringTranslate.getInstance(); + int var2 = 0; + this.theChatOptions = var1.translateKey("options.chat.title"); + this.field_82268_n = var1.translateKey("options.multiplayer.title"); + EnumOptions[] var3 = allScreenChatOptions; + int var4 = var3.length; + int var5; + EnumOptions var6; + + for (var5 = 0; var5 < var4; ++var5) { + var6 = var3[var5]; + + if (var6.getEnumFloat()) { + this.buttonList.add(new GuiSlider(var6.returnEnumOrdinal(), this.width / 2 - 155 + var2 % 2 * 160, this.height / 6 + 24 * (var2 >> 1), var6, this.theSettings.getKeyBinding(var6), this.theSettings.getOptionFloatValue(var6))); + } else { + this.buttonList.add(new GuiSmallButton(var6.returnEnumOrdinal(), this.width / 2 - 155 + var2 % 2 * 160, this.height / 6 + 24 * (var2 >> 1), var6, this.theSettings.getKeyBinding(var6))); + } + + ++var2; + } + + if (var2 % 2 == 1) { + ++var2; + } + + this.field_82269_o = this.height / 6 + 24 * (var2 >> 1); + var2 += 2; + var3 = allMultiplayerOptions; + var4 = var3.length; + + for (var5 = 0; var5 < var4; ++var5) { + var6 = var3[var5]; + + if (var6.getEnumFloat()) { + this.buttonList.add(new GuiSlider(var6.returnEnumOrdinal(), this.width / 2 - 155 + var2 % 2 * 160, this.height / 6 + 24 * (var2 >> 1), var6, this.theSettings.getKeyBinding(var6), this.theSettings.getOptionFloatValue(var6))); + } else { + this.buttonList.add(new GuiSmallButton(var6.returnEnumOrdinal(), this.width / 2 - 155 + var2 % 2 * 160, this.height / 6 + 24 * (var2 >> 1), var6, this.theSettings.getKeyBinding(var6))); + } + + ++var2; + } + + this.buttonList.add(new GuiButton(200, this.width / 2 - 100, this.height / 6 + 168, var1.translateKey("gui.done"))); + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.enabled) { + if (par1GuiButton.id < 100 && par1GuiButton instanceof GuiSmallButton) { + this.theSettings.setOptionValue(((GuiSmallButton) par1GuiButton).returnEnumOptions(), 1); + par1GuiButton.displayString = this.theSettings.getKeyBinding(EnumOptions.getEnumOptions(par1GuiButton.id)); + } + + if (par1GuiButton.id == 200) { + this.mc.gameSettings.saveOptions(); + this.mc.displayGuiScreen(this.theGuiScreen); + } + } + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, this.theChatOptions, this.width / 2, 20, 16777215); + this.drawCenteredString(this.fontRenderer, this.field_82268_n, this.width / 2, this.field_82269_o + 7, 16777215); + super.drawScreen(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/GuiScreenConfirmation.java b/src/main/java/net/minecraft/src/GuiScreenConfirmation.java new file mode 100644 index 0000000..1abab5e --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiScreenConfirmation.java @@ -0,0 +1,26 @@ +package net.minecraft.src; + +public class GuiScreenConfirmation extends GuiYesNo { + private String field_96288_n; + + public GuiScreenConfirmation(GuiScreen par1GuiScreen, String par2Str, String par3Str, String par4Str, int par5) { + super(par1GuiScreen, par2Str, par3Str, par5); + this.field_96288_n = par4Str; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + this.buttonList.add(new GuiSmallButton(0, this.width / 2 - 155, this.height / 6 + 112, this.buttonText1)); + this.buttonList.add(new GuiSmallButton(1, this.width / 2 - 155 + 160, this.height / 6 + 112, this.buttonText2)); + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + super.drawScreen(par1, par2, par3); + this.drawCenteredString(this.fontRenderer, this.field_96288_n, this.width / 2, 110, 16777215); + } +} diff --git a/src/main/java/net/minecraft/src/GuiScreenServerList.java b/src/main/java/net/minecraft/src/GuiScreenServerList.java new file mode 100644 index 0000000..0bc2a37 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiScreenServerList.java @@ -0,0 +1,96 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +public class GuiScreenServerList extends GuiScreen { + /** Needed a change as a local variable was conflicting on construct */ + private final GuiScreen guiScreen; + + /** Instance of ServerData. */ + private final ServerData theServerData; + private GuiTextField serverTextField; + + public GuiScreenServerList(GuiScreen par1GuiScreen, ServerData par2ServerData) { + this.guiScreen = par1GuiScreen; + this.theServerData = par2ServerData; + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + this.serverTextField.updateCursorCounter(); + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + StringTranslate var1 = StringTranslate.getInstance(); + EaglerAdapter.enableRepeatEvents(true); + this.buttonList.clear(); + this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + 12, var1.translateKey("selectServer.select"))); + this.buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 + 120 + 12, var1.translateKey("gui.cancel"))); + this.serverTextField = new GuiTextField(this.fontRenderer, this.width / 2 - 100, 116, 200, 20); + this.serverTextField.setMaxStringLength(128); + this.serverTextField.setFocused(true); + this.serverTextField.setText(this.mc.gameSettings.lastServer); + ((GuiButton) this.buttonList.get(0)).enabled = this.serverTextField.getText().length() > 0 && this.serverTextField.getText().split(":").length > 0; + } + + /** + * Called when the screen is unloaded. Used to disable keyboard repeat events + */ + public void onGuiClosed() { + EaglerAdapter.enableRepeatEvents(false); + this.mc.gameSettings.lastServer = this.serverTextField.getText(); + this.mc.gameSettings.saveOptions(); + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.enabled) { + if (par1GuiButton.id == 1) { + this.guiScreen.confirmClicked(false, 0); + } else if (par1GuiButton.id == 0) { + this.theServerData.serverIP = this.serverTextField.getText(); + this.guiScreen.confirmClicked(true, 0); + } + } + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + if (this.serverTextField.textboxKeyTyped(par1, par2)) { + ((GuiButton) this.buttonList.get(0)).enabled = this.serverTextField.getText().length() > 0 && this.serverTextField.getText().split(":").length > 0; + } else if (par2 == 28) { + this.actionPerformed((GuiButton) this.buttonList.get(0)); + } + } + + /** + * Called when the mouse is clicked. + */ + protected void mouseClicked(int par1, int par2, int par3) { + super.mouseClicked(par1, par2, par3); + this.serverTextField.mouseClicked(par1, par2, par3); + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + StringTranslate var4 = StringTranslate.getInstance(); + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, var4.translateKey("selectServer.direct"), this.width / 2, this.height / 4 - 60 + 20, 16777215); + this.drawString(this.fontRenderer, var4.translateKey("addServer.enterIp"), this.width / 2 - 100, 100, 10526880); + this.serverTextField.drawTextBox(); + super.drawScreen(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/GuiSleepMP.java b/src/main/java/net/minecraft/src/GuiSleepMP.java new file mode 100644 index 0000000..b781981 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiSleepMP.java @@ -0,0 +1,53 @@ +package net.minecraft.src; + +public class GuiSleepMP extends GuiChat { + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + super.initGui(); + StringTranslate var1 = StringTranslate.getInstance(); + this.buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height - 40, var1.translateKey("multiplayer.stopSleeping"))); + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + if (par2 == 1) { + this.wakeEntity(); + } else if (par2 == 28) { + String var3 = this.inputField.getText().trim(); + + if (var3.length() > 0) { + this.mc.thePlayer.sendChatMessage(var3); + } + + this.inputField.setText(""); + this.mc.ingameGUI.getChatGUI().resetScroll(); + } else { + super.keyTyped(par1, par2); + } + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.id == 1) { + this.wakeEntity(); + } else { + super.actionPerformed(par1GuiButton); + } + } + + /** + * Wakes the entity from the bed + */ + private void wakeEntity() { + NetClientHandler var1 = this.mc.thePlayer.sendQueue; + var1.addToSendQueue(new Packet19EntityAction(this.mc.thePlayer, 3)); + } +} diff --git a/src/main/java/net/minecraft/src/GuiSlider.java b/src/main/java/net/minecraft/src/GuiSlider.java new file mode 100644 index 0000000..fd4cd68 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiSlider.java @@ -0,0 +1,89 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.minecraft.client.Minecraft; + +public class GuiSlider extends GuiButton { + /** The value of this slider control. */ + public float sliderValue = 1.0F; + + /** Is this slider control being dragged. */ + public boolean dragging = false; + + /** Additional ID for this slider control. */ + private EnumOptions idFloat = null; + + public GuiSlider(int par1, int par2, int par3, EnumOptions par4EnumOptions, String par5Str, float par6) { + super(par1, par2, par3, 150, 20, par5Str); + this.idFloat = par4EnumOptions; + this.sliderValue = par6; + } + + /** + * Returns 0 if the button is disabled, 1 if the mouse is NOT hovering over this + * button and 2 if it IS hovering over this button. + */ + protected int getHoverState(boolean par1) { + return 0; + } + + /** + * Fired when the mouse button is dragged. Equivalent of + * MouseListener.mouseDragged(MouseEvent e). + */ + protected void mouseDragged(Minecraft par1Minecraft, int par2, int par3) { + if (this.drawButton) { + if (this.dragging) { + this.sliderValue = (float) (par2 - (this.xPosition + 4)) / (float) (this.width - 8); + + if (this.sliderValue < 0.0F) { + this.sliderValue = 0.0F; + } + + if (this.sliderValue > 1.0F) { + this.sliderValue = 1.0F; + } + + par1Minecraft.gameSettings.setOptionFloatValue(this.idFloat, this.sliderValue); + this.displayString = par1Minecraft.gameSettings.getKeyBinding(this.idFloat); + } + + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.drawTexturedModalRect(this.xPosition + (int) (this.sliderValue * (float) (this.width - 8)), this.yPosition, 0, 66, 4, 20); + this.drawTexturedModalRect(this.xPosition + (int) (this.sliderValue * (float) (this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20); + } + } + + /** + * Returns true if the mouse has been pressed on this control. Equivalent of + * MouseListener.mousePressed(MouseEvent e). + */ + public boolean mousePressed(Minecraft par1Minecraft, int par2, int par3) { + if (super.mousePressed(par1Minecraft, par2, par3)) { + this.sliderValue = (float) (par2 - (this.xPosition + 4)) / (float) (this.width - 8); + + if (this.sliderValue < 0.0F) { + this.sliderValue = 0.0F; + } + + if (this.sliderValue > 1.0F) { + this.sliderValue = 1.0F; + } + + par1Minecraft.gameSettings.setOptionFloatValue(this.idFloat, this.sliderValue); + this.displayString = par1Minecraft.gameSettings.getKeyBinding(this.idFloat); + this.dragging = true; + return true; + } else { + return false; + } + } + + /** + * Fired when the mouse button is released. Equivalent of + * MouseListener.mouseReleased(MouseEvent e). + */ + public void mouseReleased(int par1, int par2) { + this.dragging = false; + } +} diff --git a/src/main/java/net/minecraft/src/GuiSlider2.java b/src/main/java/net/minecraft/src/GuiSlider2.java new file mode 100644 index 0000000..4353ad1 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiSlider2.java @@ -0,0 +1,87 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.minecraft.client.Minecraft; + +public class GuiSlider2 extends GuiButton { + /** The value of this slider control. */ + public float sliderValue = 1.0F; + public float sliderMax = 1.0F; + + /** Is this slider control being dragged. */ + public boolean dragging = false; + + public GuiSlider2(int par1, int par2, int par3, int par4, int par5, float par6, float par7) { + super(par1, par2, par3, par4, par5, (int)(par6 * par7 * 100.0F) + "%"); + this.sliderValue = par6; + this.sliderMax = par7; + } + + /** + * Returns 0 if the button is disabled, 1 if the mouse is NOT hovering over this + * button and 2 if it IS hovering over this button. + */ + protected int getHoverState(boolean par1) { + return 0; + } + + /** + * Fired when the mouse button is dragged. Equivalent of + * MouseListener.mouseDragged(MouseEvent e). + */ + protected void mouseDragged(Minecraft par1Minecraft, int par2, int par3) { + if (this.drawButton) { + if (this.dragging) { + this.sliderValue = (float) (par2 - (this.xPosition + 4)) / (float) (this.width - 8); + + if (this.sliderValue < 0.0F) { + this.sliderValue = 0.0F; + } + + if (this.sliderValue > 1.0F) { + this.sliderValue = 1.0F; + } + + this.displayString = (int)(this.sliderValue * this.sliderMax * 100.0F) + "%"; + } + + if(this.enabled) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.drawTexturedModalRect(this.xPosition + (int) (this.sliderValue * (float) (this.width - 8)), this.yPosition, 0, 66, 4, 20); + this.drawTexturedModalRect(this.xPosition + (int) (this.sliderValue * (float) (this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20); + } + } + } + + /** + * Returns true if the mouse has been pressed on this control. Equivalent of + * MouseListener.mousePressed(MouseEvent e). + */ + public boolean mousePressed(Minecraft par1Minecraft, int par2, int par3) { + if (super.mousePressed(par1Minecraft, par2, par3)) { + this.sliderValue = (float) (par2 - (this.xPosition + 4)) / (float) (this.width - 8); + + if (this.sliderValue < 0.0F) { + this.sliderValue = 0.0F; + } + + if (this.sliderValue > 1.0F) { + this.sliderValue = 1.0F; + } + + this.displayString = (int)(this.sliderValue * this.sliderMax * 100.0F) + "%"; + this.dragging = true; + return true; + } else { + return false; + } + } + + /** + * Fired when the mouse button is released. Equivalent of + * MouseListener.mouseReleased(MouseEvent e). + */ + public void mouseReleased(int par1, int par2) { + this.dragging = false; + } +} diff --git a/src/main/java/net/minecraft/src/GuiSlot.java b/src/main/java/net/minecraft/src/GuiSlot.java new file mode 100644 index 0000000..7772101 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiSlot.java @@ -0,0 +1,437 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public abstract class GuiSlot { + private final Minecraft mc; + + /** + * The width of the GuiScreen. Affects the container rendering, but not the + * overlays. + */ + private int width; + + /** + * The height of the GuiScreen. Affects the container rendering, but not the + * overlays or the scrolling. + */ + private int height; + + /** The top of the slot container. Affects the overlays and scrolling. */ + protected int top; + + /** The bottom of the slot container. Affects the overlays and scrolling. */ + protected int bottom; + private int right; + private int left; + + /** The height of a slot. */ + protected final int slotHeight; + + /** button id of the button used to scroll up */ + private int scrollUpButtonID; + + /** the buttonID of the button used to scroll down */ + private int scrollDownButtonID; + + /** X axis position of the mouse */ + protected int mouseX; + + /** Y axis position of the mouse */ + protected int mouseY; + + /** where the mouse was in the window when you first clicked to scroll */ + private float initialClickY = -2.0F; + + /** + * what to multiply the amount you moved your mouse by(used for slowing down + * scrolling when over the items and no on scroll bar) + */ + private float scrollMultiplier; + + /** how far down this slot has been scrolled */ + private float amountScrolled; + + /** the element in the list that was selected */ + private int selectedElement = -1; + + /** the time when this button was last clicked. */ + private long lastClicked = 0L; + + /** true if a selected element in this gui will show an outline box */ + private boolean showSelectionBox = true; + private boolean field_77243_s; + private int field_77242_t; + + public GuiSlot(Minecraft par1Minecraft, int par2, int par3, int par4, int par5, int par6) { + this.mc = par1Minecraft; + this.width = par2; + this.height = par3; + this.top = par4; + this.bottom = par5; + this.slotHeight = par6; + this.left = 0; + this.right = par2; + } + + public void func_77207_a(int par1, int par2, int par3, int par4) { + this.width = par1; + this.height = par2; + this.top = par3; + this.bottom = par4; + this.left = 0; + this.right = par1; + } + + public void setShowSelectionBox(boolean par1) { + this.showSelectionBox = par1; + } + + protected void func_77223_a(boolean par1, int par2) { + this.field_77243_s = par1; + this.field_77242_t = par2; + + if (!par1) { + this.field_77242_t = 0; + } + } + + /** + * Gets the size of the current slot list. + */ + protected abstract int getSize(); + + /** + * the element in the slot that was clicked, boolean for wether it was double + * clicked or not + */ + protected abstract void elementClicked(int var1, boolean var2); + + /** + * returns true if the element passed in is currently selected + */ + protected abstract boolean isSelected(int var1); + + /** + * return the height of the content being scrolled + */ + protected int getContentHeight() { + return this.getSize() * this.slotHeight + this.field_77242_t; + } + + protected abstract void drawBackground(); + + protected abstract void drawSlot(int var1, int var2, int var3, int var4, Tessellator var5); + + protected void func_77222_a(int par1, int par2, Tessellator par3Tessellator) { + } + + protected void func_77224_a(int par1, int par2) { + } + + protected void func_77215_b(int par1, int par2) { + } + + public int func_77210_c(int par1, int par2) { + int var3 = this.width / 2 - 110; + int var4 = this.width / 2 + 110; + int var5 = par2 - this.top - this.field_77242_t + (int) this.amountScrolled - 4; + int var6 = var5 / this.slotHeight; + return par1 >= var3 && par1 <= var4 && var6 >= 0 && var5 >= 0 && var6 < this.getSize() ? var6 : -1; + } + + /** + * Registers the IDs that can be used for the scrollbar's buttons. + */ + public void registerScrollButtons(List par1List, int par2, int par3) { + this.scrollUpButtonID = par2; + this.scrollDownButtonID = par3; + } + + /** + * stop the thing from scrolling out of bounds + */ + private void bindAmountScrolled() { + int var1 = this.func_77209_d(); + + if (var1 < 0) { + var1 /= 2; + } + + if (this.amountScrolled < 0.0F) { + this.amountScrolled = 0.0F; + } + + if (this.amountScrolled > (float) var1) { + this.amountScrolled = (float) var1; + } + } + + public int func_77209_d() { + return this.getContentHeight() - (this.bottom - this.top - 4); + } + + public void func_77208_b(int par1) { + this.amountScrolled += (float) par1; + this.bindAmountScrolled(); + this.initialClickY = -2.0F; + } + + public void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.enabled) { + if (par1GuiButton.id == this.scrollUpButtonID) { + this.amountScrolled -= (float) (this.slotHeight * 2 / 3); + this.initialClickY = -2.0F; + this.bindAmountScrolled(); + } else if (par1GuiButton.id == this.scrollDownButtonID) { + this.amountScrolled += (float) (this.slotHeight * 2 / 3); + this.initialClickY = -2.0F; + this.bindAmountScrolled(); + } + } + } + + private static final TextureLocation tex = new TextureLocation("/gui/background.png"); + + /** + * draws the slot to the screen, pass in mouse's current x and y and partial + * ticks + */ + public void drawScreen(int par1, int par2, float par3) { + this.mouseX = par1; + this.mouseY = par2; + this.drawBackground(); + int var4 = this.getSize(); + int var5 = this.getScrollBarX(); + int var6 = var5 + 6; + int var9; + int var10; + int var11; + int var13; + int var20; + + if (EaglerAdapter.mouseIsButtonDown(0)) { + if (this.initialClickY == -1.0F) { + boolean var7 = true; + + if (par2 >= this.top && par2 <= this.bottom) { + int var8 = this.width / 2 - 110; + var9 = this.width / 2 + 110; + var10 = par2 - this.top - this.field_77242_t + (int) this.amountScrolled - 4; + var11 = var10 / this.slotHeight; + + if (par1 >= var8 && par1 <= var9 && var11 >= 0 && var10 >= 0 && var11 < var4) { + boolean var12 = var11 == this.selectedElement && Minecraft.getSystemTime() - this.lastClicked < 250L; + this.elementClicked(var11, var12); + this.selectedElement = var11; + this.lastClicked = Minecraft.getSystemTime(); + } else if (par1 >= var8 && par1 <= var9 && var10 < 0) { + this.func_77224_a(par1 - var8, par2 - this.top + (int) this.amountScrolled - 4); + var7 = false; + } + + if (par1 >= var5 && par1 <= var6) { + this.scrollMultiplier = -1.0F; + var20 = this.func_77209_d(); + + if (var20 < 1) { + var20 = 1; + } + + var13 = (int) ((float) ((this.bottom - this.top) * (this.bottom - this.top)) / (float) this.getContentHeight()); + + if (var13 < 32) { + var13 = 32; + } + + if (var13 > this.bottom - this.top - 8) { + var13 = this.bottom - this.top - 8; + } + + this.scrollMultiplier /= (float) (this.bottom - this.top - var13) / (float) var20; + } else { + this.scrollMultiplier = 1.0F; + } + + if (var7) { + this.initialClickY = (float) par2; + } else { + this.initialClickY = -2.0F; + } + } else { + this.initialClickY = -2.0F; + } + } else if (this.initialClickY >= 0.0F) { + this.amountScrolled -= ((float) par2 - this.initialClickY) * this.scrollMultiplier; + this.initialClickY = (float) par2; + } + } else { + while (!this.mc.gameSettings.touchscreen && EaglerAdapter.mouseNext()) { + int var16 = EaglerAdapter.mouseGetEventDWheel(); + + if (var16 != 0) { + if (var16 > 0) { + var16 = -1; + } else if (var16 < 0) { + var16 = 1; + } + + this.amountScrolled += (float) (var16 * this.slotHeight / 2); + } + } + + this.initialClickY = -1.0F; + } + + this.bindAmountScrolled(); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glDisable(EaglerAdapter.GL_FOG); + Tessellator var18 = Tessellator.instance; + tex.bindTexture(); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + float var17 = 32.0F; + var18.startDrawingQuads(); + var18.setColorOpaque_I(2105376); + var18.addVertexWithUV((double) this.left, (double) this.bottom, 0.0D, (double) ((float) this.left / var17), (double) ((float) (this.bottom + (int) this.amountScrolled) / var17)); + var18.addVertexWithUV((double) this.right, (double) this.bottom, 0.0D, (double) ((float) this.right / var17), (double) ((float) (this.bottom + (int) this.amountScrolled) / var17)); + var18.addVertexWithUV((double) this.right, (double) this.top, 0.0D, (double) ((float) this.right / var17), (double) ((float) (this.top + (int) this.amountScrolled) / var17)); + var18.addVertexWithUV((double) this.left, (double) this.top, 0.0D, (double) ((float) this.left / var17), (double) ((float) (this.top + (int) this.amountScrolled) / var17)); + var18.draw(); + var9 = this.width / 2 - 92 - 16; + var10 = this.top + 4 - (int) this.amountScrolled; + + if (this.field_77243_s) { + this.func_77222_a(var9, var10, var18); + } + + int var14; + + for (var11 = 0; var11 < var4; ++var11) { + var20 = var10 + var11 * this.slotHeight + this.field_77242_t; + var13 = this.slotHeight - 4; + + if (var20 <= this.bottom && var20 + var13 >= this.top) { + if (this.showSelectionBox && this.isSelected(var11)) { + var14 = this.width / 2 - 110; + int var15 = this.width / 2 + 110; + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + var18.startDrawingQuads(); + var18.setColorOpaque_I(8421504); + var18.addVertexWithUV((double) var14, (double) (var20 + var13 + 2), 0.0D, 0.0D, 1.0D); + var18.addVertexWithUV((double) var15, (double) (var20 + var13 + 2), 0.0D, 1.0D, 1.0D); + var18.addVertexWithUV((double) var15, (double) (var20 - 2), 0.0D, 1.0D, 0.0D); + var18.addVertexWithUV((double) var14, (double) (var20 - 2), 0.0D, 0.0D, 0.0D); + var18.setColorOpaque_I(0); + var18.addVertexWithUV((double) (var14 + 1), (double) (var20 + var13 + 1), 0.0D, 0.0D, 1.0D); + var18.addVertexWithUV((double) (var15 - 1), (double) (var20 + var13 + 1), 0.0D, 1.0D, 1.0D); + var18.addVertexWithUV((double) (var15 - 1), (double) (var20 - 1), 0.0D, 1.0D, 0.0D); + var18.addVertexWithUV((double) (var14 + 1), (double) (var20 - 1), 0.0D, 0.0D, 0.0D); + var18.draw(); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + } + + this.drawSlot(var11, var9, var20, var13, var18); + } + } + + EaglerAdapter.glDisable(EaglerAdapter.GL_DEPTH_TEST); + byte var19 = 4; + this.overlayBackground(0, this.top, 255, 255); + this.overlayBackground(this.bottom, this.height, 255, 255); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glShadeModel(EaglerAdapter.GL_SMOOTH); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + var18.startDrawingQuads(); + var18.setColorRGBA_I(0, 0); + var18.addVertexWithUV((double) this.left, (double) (this.top + var19), 0.0D, 0.0D, 1.0D); + var18.addVertexWithUV((double) this.right, (double) (this.top + var19), 0.0D, 1.0D, 1.0D); + var18.setColorRGBA_I(0, 255); + var18.addVertexWithUV((double) this.right, (double) this.top, 0.0D, 1.0D, 0.0D); + var18.addVertexWithUV((double) this.left, (double) this.top, 0.0D, 0.0D, 0.0D); + var18.draw(); + var18.startDrawingQuads(); + var18.setColorRGBA_I(0, 255); + var18.addVertexWithUV((double) this.left, (double) this.bottom, 0.0D, 0.0D, 1.0D); + var18.addVertexWithUV((double) this.right, (double) this.bottom, 0.0D, 1.0D, 1.0D); + var18.setColorRGBA_I(0, 0); + var18.addVertexWithUV((double) this.right, (double) (this.bottom - var19), 0.0D, 1.0D, 0.0D); + var18.addVertexWithUV((double) this.left, (double) (this.bottom - var19), 0.0D, 0.0D, 0.0D); + var18.draw(); + var20 = this.func_77209_d(); + + if (var20 > 0) { + var13 = (this.bottom - this.top) * (this.bottom - this.top) / this.getContentHeight(); + + if (var13 < 32) { + var13 = 32; + } + + if (var13 > this.bottom - this.top - 8) { + var13 = this.bottom - this.top - 8; + } + + var14 = (int) this.amountScrolled * (this.bottom - this.top - var13) / var20 + this.top; + + if (var14 < this.top) { + var14 = this.top; + } + + var18.startDrawingQuads(); + var18.setColorRGBA_I(0, 255); + var18.addVertexWithUV((double) var5, (double) this.bottom, 0.0D, 0.0D, 1.0D); + var18.addVertexWithUV((double) var6, (double) this.bottom, 0.0D, 1.0D, 1.0D); + var18.addVertexWithUV((double) var6, (double) this.top, 0.0D, 1.0D, 0.0D); + var18.addVertexWithUV((double) var5, (double) this.top, 0.0D, 0.0D, 0.0D); + var18.draw(); + var18.startDrawingQuads(); + var18.setColorRGBA_I(8421504, 255); + var18.addVertexWithUV((double) var5, (double) (var14 + var13), 0.0D, 0.0D, 1.0D); + var18.addVertexWithUV((double) var6, (double) (var14 + var13), 0.0D, 1.0D, 1.0D); + var18.addVertexWithUV((double) var6, (double) var14, 0.0D, 1.0D, 0.0D); + var18.addVertexWithUV((double) var5, (double) var14, 0.0D, 0.0D, 0.0D); + var18.draw(); + var18.startDrawingQuads(); + var18.setColorRGBA_I(12632256, 255); + var18.addVertexWithUV((double) var5, (double) (var14 + var13 - 1), 0.0D, 0.0D, 1.0D); + var18.addVertexWithUV((double) (var6 - 1), (double) (var14 + var13 - 1), 0.0D, 1.0D, 1.0D); + var18.addVertexWithUV((double) (var6 - 1), (double) var14, 0.0D, 1.0D, 0.0D); + var18.addVertexWithUV((double) var5, (double) var14, 0.0D, 0.0D, 0.0D); + var18.draw(); + } + + this.func_77215_b(par1, par2); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glShadeModel(EaglerAdapter.GL_FLAT); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + } + + protected int getScrollBarX() { + return this.width / 2 + 124; + } + + /** + * Overlays the background to hide scrolled items + */ + private void overlayBackground(int par1, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + tex.bindTexture(); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + float var6 = 32.0F; + var5.startDrawingQuads(); + var5.setColorRGBA_I(4210752, par4); + var5.addVertexWithUV(0.0D, (double) par2, 0.0D, 0.0D, (double) ((float) par2 / var6)); + var5.addVertexWithUV((double) this.width, (double) par2, 0.0D, (double) ((float) this.width / var6), (double) ((float) par2 / var6)); + var5.setColorRGBA_I(4210752, par3); + var5.addVertexWithUV((double) this.width, (double) par1, 0.0D, (double) ((float) this.width / var6), (double) ((float) par1 / var6)); + var5.addVertexWithUV(0.0D, (double) par1, 0.0D, 0.0D, (double) ((float) par1 / var6)); + var5.draw(); + } +} diff --git a/src/main/java/net/minecraft/src/GuiSlotLanguage.java b/src/main/java/net/minecraft/src/GuiSlotLanguage.java new file mode 100644 index 0000000..e764459 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiSlotLanguage.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.TreeMap; + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +class GuiSlotLanguage extends GuiSlot { + private ArrayList field_77251_g; + private TreeMap field_77253_h; + + final GuiLanguage languageGui; + + public GuiSlotLanguage(GuiLanguage par1GuiLanguage) { + super(par1GuiLanguage.mc, par1GuiLanguage.width, par1GuiLanguage.height, 32, par1GuiLanguage.height - 65 + 4, 18); + this.languageGui = par1GuiLanguage; + this.field_77253_h = StringTranslate.getInstance().getLanguageList(); + this.field_77251_g = new ArrayList(); + Iterator var2 = this.field_77253_h.keySet().iterator(); + + while (var2.hasNext()) { + String var3 = (String) var2.next(); + this.field_77251_g.add(var3); + } + } + + /** + * Gets the size of the current slot list. + */ + protected int getSize() { + return this.field_77251_g.size(); + } + + /** + * the element in the slot that was clicked, boolean for wether it was double + * clicked or not + */ + protected void elementClicked(int par1, boolean par2) { + StringTranslate.getInstance().setLanguage((String) this.field_77251_g.get(par1), false); + this.languageGui.mc.fontRenderer.setUnicodeFlag(StringTranslate.getInstance().isUnicode()); + GuiLanguage.getGameSettings(this.languageGui).language = (String) this.field_77251_g.get(par1); + this.languageGui.fontRenderer.setBidiFlag(StringTranslate.isBidirectional(GuiLanguage.getGameSettings(this.languageGui).language)); + GuiLanguage.getDoneButton(this.languageGui).displayString = StringTranslate.getInstance().translateKey("gui.done"); + GuiLanguage.getGameSettings(this.languageGui).saveOptions(); + } + + /** + * returns true if the element passed in is currently selected + */ + protected boolean isSelected(int par1) { + return ((String) this.field_77251_g.get(par1)).equals(StringTranslate.getInstance().getCurrentLanguage()); + } + + /** + * return the height of the content being scrolled + */ + protected int getContentHeight() { + return this.getSize() * 18; + } + + protected void drawBackground() { + this.languageGui.drawDefaultBackground(); + } + + protected void drawSlot(int par1, int par2, int par3, int par4, Tessellator par5Tessellator) { + this.languageGui.fontRenderer.setBidiFlag(true); + this.languageGui.drawCenteredString(this.languageGui.fontRenderer, (String) this.field_77253_h.get(this.field_77251_g.get(par1)), this.languageGui.width / 2, par3 + 1, 16777215); + this.languageGui.fontRenderer.setBidiFlag(StringTranslate.isBidirectional(GuiLanguage.getGameSettings(this.languageGui).language)); + } +} diff --git a/src/main/java/net/minecraft/src/GuiSlotServer.java b/src/main/java/net/minecraft/src/GuiSlotServer.java new file mode 100644 index 0000000..28b7dd5 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiSlotServer.java @@ -0,0 +1,142 @@ +package net.minecraft.src; + +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +class GuiSlotServer extends GuiSlot { + /** Instance to the GUI this list is on. */ + final GuiMultiplayer parentGui; + + public GuiSlotServer(GuiMultiplayer par1GuiMultiplayer) { + super(par1GuiMultiplayer.mc, par1GuiMultiplayer.width, par1GuiMultiplayer.height, 32, par1GuiMultiplayer.height - 64, 36); + this.parentGui = par1GuiMultiplayer; + } + + /** + * Gets the size of the current slot list. + */ + protected int getSize() { + return GuiMultiplayer.getInternetServerList(this.parentGui).countServers() + GuiMultiplayer.getListOfLanServers(this.parentGui).size() + 1; + } + + /** + * the element in the slot that was clicked, boolean for wether it was double + * clicked or not + */ + protected void elementClicked(int par1, boolean par2) { + if (par1 < GuiMultiplayer.getInternetServerList(this.parentGui).countServers() + GuiMultiplayer.getListOfLanServers(this.parentGui).size()) { + int var3 = GuiMultiplayer.getSelectedServer(this.parentGui); + GuiMultiplayer.getAndSetSelectedServer(this.parentGui, par1); + ServerData var4 = GuiMultiplayer.getInternetServerList(this.parentGui).countServers() > par1 ? GuiMultiplayer.getInternetServerList(this.parentGui).getServerData(par1) : null; + boolean var5 = GuiMultiplayer.getSelectedServer(this.parentGui) >= 0 && GuiMultiplayer.getSelectedServer(this.parentGui) < this.getSize() && (var4 == null || var4.field_82821_f == 61); + boolean var6 = GuiMultiplayer.getSelectedServer(this.parentGui) < GuiMultiplayer.getInternetServerList(this.parentGui).countServers(); + GuiMultiplayer.getButtonSelect(this.parentGui).enabled = var5; + GuiMultiplayer.getButtonEdit(this.parentGui).enabled = var6; + GuiMultiplayer.getButtonDelete(this.parentGui).enabled = var6; + + if (par2 && var5) { + GuiMultiplayer.func_74008_b(this.parentGui, par1); + } else if (var6 && GuiScreen.isShiftKeyDown() && var3 >= 0 && var3 < GuiMultiplayer.getInternetServerList(this.parentGui).countServers()) { + GuiMultiplayer.getInternetServerList(this.parentGui).swapServers(var3, GuiMultiplayer.getSelectedServer(this.parentGui)); + } + } + } + + /** + * returns true if the element passed in is currently selected + */ + protected boolean isSelected(int par1) { + return par1 == GuiMultiplayer.getSelectedServer(this.parentGui); + } + + /** + * return the height of the content being scrolled + */ + protected int getContentHeight() { + return this.getSize() * 36; + } + + protected void drawBackground() { + this.parentGui.drawDefaultBackground(); + } + + protected void drawSlot(int par1, int par2, int par3, int par4, Tessellator par5Tessellator) { + if (par1 < GuiMultiplayer.getInternetServerList(this.parentGui).countServers()) { + this.func_77247_d(par1, par2, par3, par4, par5Tessellator); + } + } + + private static final TextureLocation icons = new TextureLocation("/gui/icons.png"); + + private void func_77247_d(int par1, int par2, int par3, int par4, Tessellator par5Tessellator) { + ServerData var6 = GuiMultiplayer.getInternetServerList(this.parentGui).getServerData(par1); + + boolean var7 = var6.field_82821_f > 61; + boolean var8 = var6.field_82821_f < 61; + boolean var9 = var7 || var8; + this.parentGui.drawString(this.parentGui.fontRenderer, var6.serverName, par2 + 2, par3 + 1, 16777215); + this.parentGui.drawString(this.parentGui.fontRenderer, var6.serverMOTD, par2 + 2, par3 + 12, 8421504); + this.parentGui.drawString(this.parentGui.fontRenderer, var6.populationInfo, par2 + 215 - this.parentGui.fontRenderer.getStringWidth(var6.populationInfo), par3 + 12, 8421504); + + if (var9) { + String var10 = EnumChatFormatting.DARK_RED + var6.gameVersion; + this.parentGui.drawString(this.parentGui.fontRenderer, var10, par2 + 200 - this.parentGui.fontRenderer.getStringWidth(var10), par3 + 1, 8421504); + } + + if (!this.parentGui.mc.gameSettings.hideServerAddress && !var6.isHidingAddress()) { + this.parentGui.drawString(this.parentGui.fontRenderer, var6.serverIP, par2 + 2, par3 + 12 + 11, 3158064); + } else { + this.parentGui.drawString(this.parentGui.fontRenderer, StatCollector.translateToLocal("selectServer.hiddenAddress"), par2 + 2, par3 + 12 + 11, 3158064); + } + + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + icons.bindTexture(); + byte var15 = 0; + boolean var11 = false; + String var12 = ""; + int var16; + + if (var9) { + var12 = var7 ? "Client out of date!" : "Server out of date!"; + var16 = 5; + } else if (var6.field_78841_f && var6.pingToServer != -2L) { + if (var6.pingToServer < 0L) { + var16 = 5; + } else if (var6.pingToServer < 150L) { + var16 = 0; + } else if (var6.pingToServer < 300L) { + var16 = 1; + } else if (var6.pingToServer < 600L) { + var16 = 2; + } else if (var6.pingToServer < 1000L) { + var16 = 3; + } else { + var16 = 4; + } + + if (var6.pingToServer < 0L) { + var12 = "(no connection)"; + } else { + var12 = "default"; //var6.pingToServer + "ms"; + } + } else { + var15 = 1; + var16 = (int) (Minecraft.getSystemTime() / 100L + (long) (par1 * 2) & 7L); + + if (var16 > 4) { + var16 = 8 - var16; + } + + var12 = "3rd party"; + } + + this.parentGui.drawTexturedModalRect(par2 + 205, par3, 0 + var15 * 10, 176 + var16 * 8, 10, 8); + byte var13 = 4; + + if (this.mouseX >= par2 + 205 - var13 && this.mouseY >= par3 - var13 && this.mouseX <= par2 + 205 + 10 + var13 && this.mouseY <= par3 + 8 + var13) { + GuiMultiplayer.getAndSetLagTooltip(this.parentGui, var12); + } + } +} diff --git a/src/main/java/net/minecraft/src/GuiSmallButton.java b/src/main/java/net/minecraft/src/GuiSmallButton.java new file mode 100644 index 0000000..e29bff7 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiSmallButton.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +public class GuiSmallButton extends GuiButton { + private final EnumOptions enumOptions; + + public GuiSmallButton(int par1, int par2, int par3, String par4Str) { + this(par1, par2, par3, (EnumOptions) null, par4Str); + } + + public GuiSmallButton(int par1, int par2, int par3, int par4, int par5, String par6Str) { + super(par1, par2, par3, par4, par5, par6Str); + this.enumOptions = null; + } + + public GuiSmallButton(int par1, int par2, int par3, EnumOptions par4EnumOptions, String par5Str) { + super(par1, par2, par3, 150, 20, par5Str); + this.enumOptions = par4EnumOptions; + } + + public EnumOptions returnEnumOptions() { + return this.enumOptions; + } +} diff --git a/src/main/java/net/minecraft/src/GuiTextField.java b/src/main/java/net/minecraft/src/GuiTextField.java new file mode 100644 index 0000000..bdb496f --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiTextField.java @@ -0,0 +1,634 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class GuiTextField extends Gui { + /** + * Have the font renderer from GuiScreen to render the textbox text into the + * screen. + */ + private final FontRenderer fontRenderer; + private final int xPos; + private final int yPos; + + /** The width of this text field. */ + private final int width; + private final int height; + + /** Have the current text beign edited on the textbox. */ + private String text = ""; + private int maxStringLength = 32; + private int cursorCounter; + private boolean enableBackgroundDrawing = true; + + /** + * if true the textbox can lose focus by clicking elsewhere on the screen + */ + private boolean canLoseFocus = true; + + /** + * If this value is true along isEnabled, keyTyped will process the keys. + */ + private boolean isFocused = false; + + /** + * If this value is true along isFocused, keyTyped will process the keys. + */ + private boolean isEnabled = true; + + /** + * The current character index that should be used as start of the rendered + * text. + */ + private int lineScrollOffset = 0; + private int cursorPosition = 0; + + /** other selection position, maybe the same as the cursor */ + private int selectionEnd = 0; + private int enabledColor = 14737632; + private int disabledColor = 7368816; + + /** True if this textbox is visible */ + private boolean visible = true; + + public GuiTextField(FontRenderer par1FontRenderer, int par2, int par3, int par4, int par5) { + this.fontRenderer = par1FontRenderer; + this.xPos = par2; + this.yPos = par3; + this.width = par4; + this.height = par5; + } + + /** + * Increments the cursor counter + */ + public void updateCursorCounter() { + ++this.cursorCounter; + } + + /** + * Sets the text of the textbox. + */ + public void setText(String par1Str) { + if (par1Str.length() > this.maxStringLength) { + this.text = par1Str.substring(0, this.maxStringLength); + } else { + this.text = par1Str; + } + + this.setCursorPositionEnd(); + } + + /** + * Returns the text beign edited on the textbox. + */ + public String getText() { + return this.text; + } + + /** + * @return returns the text between the cursor and selectionEnd + */ + public String getSelectedtext() { + int var1 = this.cursorPosition < this.selectionEnd ? this.cursorPosition : this.selectionEnd; + int var2 = this.cursorPosition < this.selectionEnd ? this.selectionEnd : this.cursorPosition; + return this.text.substring(var1, var2); + } + + /** + * replaces selected text, or inserts text at the position on the cursor + */ + public void writeText(String par1Str) { + String var2 = ""; + String var3 = ChatAllowedCharacters.filerAllowedCharacters(par1Str); + int var4 = this.cursorPosition < this.selectionEnd ? this.cursorPosition : this.selectionEnd; + int var5 = this.cursorPosition < this.selectionEnd ? this.selectionEnd : this.cursorPosition; + int var6 = this.maxStringLength - this.text.length() - (var4 - this.selectionEnd); + boolean var7 = false; + + if (this.text.length() > 0) { + var2 = var2 + this.text.substring(0, var4); + } + + int var8; + + if (var6 < var3.length()) { + var2 = var2 + var3.substring(0, var6); + var8 = var6; + } else { + var2 = var2 + var3; + var8 = var3.length(); + } + + if (this.text.length() > 0 && var5 < this.text.length()) { + var2 = var2 + this.text.substring(var5); + } + + this.text = var2; + this.moveCursorBy(var4 - this.selectionEnd + var8); + } + + /** + * Deletes the specified number of words starting at the cursor position. + * Negative numbers will delete words left of the cursor. + */ + public void deleteWords(int par1) { + if (this.text.length() != 0) { + if (this.selectionEnd != this.cursorPosition) { + this.writeText(""); + } else { + this.deleteFromCursor(this.getNthWordFromCursor(par1) - this.cursorPosition); + } + } + } + + /** + * delete the selected text, otherwsie deletes characters from either side of + * the cursor. params: delete num + */ + public void deleteFromCursor(int par1) { + if (this.text.length() != 0) { + if (this.selectionEnd != this.cursorPosition) { + this.writeText(""); + } else { + boolean var2 = par1 < 0; + int var3 = var2 ? this.cursorPosition + par1 : this.cursorPosition; + int var4 = var2 ? this.cursorPosition : this.cursorPosition + par1; + String var5 = ""; + + if (var3 >= 0) { + var5 = this.text.substring(0, var3); + } + + if (var4 < this.text.length()) { + var5 = var5 + this.text.substring(var4); + } + + this.text = var5; + + if (var2) { + this.moveCursorBy(par1); + } + } + } + } + + /** + * see @getNthNextWordFromPos() params: N, position + */ + public int getNthWordFromCursor(int par1) { + return this.getNthWordFromPos(par1, this.getCursorPosition()); + } + + /** + * gets the position of the nth word. N may be negative, then it looks + * backwards. params: N, position + */ + public int getNthWordFromPos(int par1, int par2) { + return this.func_73798_a(par1, this.getCursorPosition(), true); + } + + public int func_73798_a(int par1, int par2, boolean par3) { + int var4 = par2; + boolean var5 = par1 < 0; + int var6 = Math.abs(par1); + + for (int var7 = 0; var7 < var6; ++var7) { + if (var5) { + while (par3 && var4 > 0 && this.text.charAt(var4 - 1) == 32) { + --var4; + } + + while (var4 > 0 && this.text.charAt(var4 - 1) != 32) { + --var4; + } + } else { + int var8 = this.text.length(); + var4 = this.text.indexOf(32, var4); + + if (var4 == -1) { + var4 = var8; + } else { + while (par3 && var4 < var8 && this.text.charAt(var4) == 32) { + ++var4; + } + } + } + } + + return var4; + } + + /** + * Moves the text cursor by a specified number of characters and clears the + * selection + */ + public void moveCursorBy(int par1) { + this.setCursorPosition(this.selectionEnd + par1); + } + + /** + * sets the position of the cursor to the provided index + */ + public void setCursorPosition(int par1) { + this.cursorPosition = par1; + int var2 = this.text.length(); + + if (this.cursorPosition < 0) { + this.cursorPosition = 0; + } + + if (this.cursorPosition > var2) { + this.cursorPosition = var2; + } + + this.setSelectionPos(this.cursorPosition); + } + + /** + * sets the cursors position to the beginning + */ + public void setCursorPositionZero() { + this.setCursorPosition(0); + } + + /** + * sets the cursors position to after the text + */ + public void setCursorPositionEnd() { + this.setCursorPosition(this.text.length()); + } + + /** + * Call this method from you GuiScreen to process the keys into textbox. + */ + public boolean textboxKeyTyped(char par1, int par2) { + if (this.isEnabled && this.isFocused) { + switch (par1) { + case 1: + this.setCursorPositionEnd(); + this.setSelectionPos(0); + return true; + + case 3: + GuiScreen.setClipboardString(this.getSelectedtext()); + return true; + + case 22: + this.writeText(GuiScreen.getClipboardString()); + return true; + + case 24: + GuiScreen.setClipboardString(this.getSelectedtext()); + this.writeText(""); + return true; + + default: + switch (par2) { + case 14: + if (GuiScreen.isCtrlKeyDown()) { + this.deleteWords(-1); + } else { + this.deleteFromCursor(-1); + } + + return true; + + case 199: + if (GuiScreen.isShiftKeyDown()) { + this.setSelectionPos(0); + } else { + this.setCursorPositionZero(); + } + + return true; + + case 203: + if (GuiScreen.isShiftKeyDown()) { + if (GuiScreen.isCtrlKeyDown()) { + this.setSelectionPos(this.getNthWordFromPos(-1, this.getSelectionEnd())); + } else { + this.setSelectionPos(this.getSelectionEnd() - 1); + } + } else if (GuiScreen.isCtrlKeyDown()) { + this.setCursorPosition(this.getNthWordFromCursor(-1)); + } else { + this.moveCursorBy(-1); + } + + return true; + + case 205: + if (GuiScreen.isShiftKeyDown()) { + if (GuiScreen.isCtrlKeyDown()) { + this.setSelectionPos(this.getNthWordFromPos(1, this.getSelectionEnd())); + } else { + this.setSelectionPos(this.getSelectionEnd() + 1); + } + } else if (GuiScreen.isCtrlKeyDown()) { + this.setCursorPosition(this.getNthWordFromCursor(1)); + } else { + this.moveCursorBy(1); + } + + return true; + + case 207: + if (GuiScreen.isShiftKeyDown()) { + this.setSelectionPos(this.text.length()); + } else { + this.setCursorPositionEnd(); + } + + return true; + + case 211: + if (GuiScreen.isCtrlKeyDown()) { + this.deleteWords(1); + } else { + this.deleteFromCursor(1); + } + + return true; + + default: + if (ChatAllowedCharacters.isAllowedCharacter(par1)) { + this.writeText(Character.toString(par1)); + return true; + } else { + return false; + } + } + } + } else { + return false; + } + } + + /** + * Args: x, y, buttonClicked + */ + public void mouseClicked(int par1, int par2, int par3) { + boolean var4 = par1 >= this.xPos && par1 < this.xPos + this.width && par2 >= this.yPos && par2 < this.yPos + this.height; + + if (this.canLoseFocus) { + this.setFocused(this.isEnabled && var4); + } + + if (this.isFocused && par3 == 0) { + int var5 = par1 - this.xPos; + + if (this.enableBackgroundDrawing) { + var5 -= 4; + } + + String var6 = this.fontRenderer.trimStringToWidth(this.text.substring(this.lineScrollOffset), this.getWidth()); + this.setCursorPosition(this.fontRenderer.trimStringToWidth(var6, var5).length() + this.lineScrollOffset); + } + } + + /** + * Draws the textbox + */ + public void drawTextBox() { + if (this.getVisible()) { + if (this.getEnableBackgroundDrawing()) { + drawRect(this.xPos - 1, this.yPos - 1, this.xPos + this.width + 1, this.yPos + this.height + 1, -6250336); + drawRect(this.xPos, this.yPos, this.xPos + this.width, this.yPos + this.height, -16777216); + } + + int var1 = this.isEnabled ? this.enabledColor : this.disabledColor; + int var2 = this.cursorPosition - this.lineScrollOffset; + int var3 = this.selectionEnd - this.lineScrollOffset; + String var4 = this.fontRenderer.trimStringToWidth(this.text.substring(this.lineScrollOffset), this.getWidth()); + boolean var5 = var2 >= 0 && var2 <= var4.length(); + boolean var6 = this.isFocused && this.cursorCounter / 6 % 2 == 0 && var5; + int var7 = this.enableBackgroundDrawing ? this.xPos + 4 : this.xPos; + int var8 = this.enableBackgroundDrawing ? this.yPos + (this.height - 8) / 2 : this.yPos; + int var9 = var7; + + if (var3 > var4.length()) { + var3 = var4.length(); + } + + if (var4.length() > 0) { + String var10 = var5 ? var4.substring(0, var2) : var4; + var9 = this.fontRenderer.drawStringWithShadow(var10, var7, var8, var1); + } + + boolean var13 = this.cursorPosition < this.text.length() || this.text.length() >= this.getMaxStringLength(); + int var11 = var9; + + if (!var5) { + var11 = var2 > 0 ? var7 + this.width : var7; + } else if (var13) { + var11 = var9 - 1; + --var9; + } + + if (var4.length() > 0 && var5 && var2 < var4.length()) { + this.fontRenderer.drawStringWithShadow(var4.substring(var2), var9, var8, var1); + } + + if (var6) { + if (var13) { + Gui.drawRect(var11, var8 - 1, var11 + 1, var8 + 1 + this.fontRenderer.FONT_HEIGHT, -3092272); + } else { + this.fontRenderer.drawStringWithShadow("_", var11, var8, var1); + } + } + + if (var3 != var2) { + int var12 = var7 + this.fontRenderer.getStringWidth(var4.substring(0, var3)); + this.drawCursorVertical(var11, var8 - 1, var12 - 1, var8 + 1 + this.fontRenderer.FONT_HEIGHT); + } + } + } + + /** + * draws the vertical line cursor in the textbox + */ + private void drawCursorVertical(int par1, int par2, int par3, int par4) { + int var5; + + if (par1 < par3) { + var5 = par1; + par1 = par3; + par3 = var5; + } + + if (par2 < par4) { + var5 = par2; + par2 = par4; + par4 = var5; + } + + Tessellator var6 = Tessellator.instance; + EaglerAdapter.glColor4f(0.0F, 0.0F, 255.0F, 255.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glEnable(EaglerAdapter.GL_COLOR_LOGIC_OP); + EaglerAdapter.glLogicOp(EaglerAdapter.GL_OR_REVERSE); + var6.startDrawingQuads(); + var6.addVertex((double) par1, (double) par4, 0.0D); + var6.addVertex((double) par3, (double) par4, 0.0D); + var6.addVertex((double) par3, (double) par2, 0.0D); + var6.addVertex((double) par1, (double) par2, 0.0D); + var6.draw(); + EaglerAdapter.glDisable(EaglerAdapter.GL_COLOR_LOGIC_OP); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + } + + public void setMaxStringLength(int par1) { + this.maxStringLength = par1; + + if (this.text.length() > par1) { + this.text = this.text.substring(0, par1); + } + } + + /** + * returns the maximum number of character that can be contained in this textbox + */ + public int getMaxStringLength() { + return this.maxStringLength; + } + + /** + * returns the current position of the cursor + */ + public int getCursorPosition() { + return this.cursorPosition; + } + + /** + * get enable drawing background and outline + */ + public boolean getEnableBackgroundDrawing() { + return this.enableBackgroundDrawing; + } + + /** + * enable drawing background and outline + */ + public void setEnableBackgroundDrawing(boolean par1) { + this.enableBackgroundDrawing = par1; + } + + /** + * Sets the text colour for this textbox (disabled text will not use this + * colour) + */ + public void setTextColor(int par1) { + this.enabledColor = par1; + } + + public void setDisabledTextColour(int par1) { + this.disabledColor = par1; + } + + /** + * setter for the focused field + */ + public void setFocused(boolean par1) { + if (par1 && !this.isFocused) { + this.cursorCounter = 0; + } + + this.isFocused = par1; + } + + /** + * getter for the focused field + */ + public boolean isFocused() { + return this.isFocused; + } + + public void setEnabled(boolean par1) { + this.isEnabled = par1; + } + + /** + * the side of the selection that is not the cursor, maye be the same as the + * cursor + */ + public int getSelectionEnd() { + return this.selectionEnd; + } + + /** + * returns the width of the textbox depending on if the the box is enabled + */ + public int getWidth() { + return this.getEnableBackgroundDrawing() ? this.width - 8 : this.width; + } + + /** + * Sets the position of the selection anchor (i.e. position the selection was + * started at) + */ + public void setSelectionPos(int par1) { + int var2 = this.text.length(); + + if (par1 > var2) { + par1 = var2; + } + + if (par1 < 0) { + par1 = 0; + } + + this.selectionEnd = par1; + + if (this.fontRenderer != null) { + if (this.lineScrollOffset > var2) { + this.lineScrollOffset = var2; + } + + int var3 = this.getWidth(); + String var4 = this.fontRenderer.trimStringToWidth(this.text.substring(this.lineScrollOffset), var3); + int var5 = var4.length() + this.lineScrollOffset; + + if (par1 == this.lineScrollOffset) { + this.lineScrollOffset -= this.fontRenderer.trimStringToWidth(this.text, var3, true).length(); + } + + if (par1 > var5) { + this.lineScrollOffset += par1 - var5; + } else if (par1 <= this.lineScrollOffset) { + this.lineScrollOffset -= this.lineScrollOffset - par1; + } + + if (this.lineScrollOffset < 0) { + this.lineScrollOffset = 0; + } + + if (this.lineScrollOffset > var2) { + this.lineScrollOffset = var2; + } + } + } + + /** + * if true the textbox can lose focus by clicking elsewhere on the screen + */ + public void setCanLoseFocus(boolean par1) { + this.canLoseFocus = par1; + } + + /** + * @return {@code true} if this textbox is visible + */ + public boolean getVisible() { + return this.visible; + } + + /** + * Sets whether or not this textbox is visible + */ + public void setVisible(boolean par1) { + this.visible = par1; + } +} diff --git a/src/main/java/net/minecraft/src/GuiTexturePackSlot.java b/src/main/java/net/minecraft/src/GuiTexturePackSlot.java new file mode 100644 index 0000000..e02ad7d --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiTexturePackSlot.java @@ -0,0 +1,85 @@ +package net.minecraft.src; + +import java.util.List; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +class GuiTexturePackSlot extends GuiSlot { + final GuiTexturePacks parentTexturePackGui; + + public GuiTexturePackSlot(GuiTexturePacks par1GuiTexturePacks) { + super(GuiTexturePacks.func_73950_a(par1GuiTexturePacks), par1GuiTexturePacks.width, par1GuiTexturePacks.height, 32, par1GuiTexturePacks.height - 55 + 4, 36); + this.parentTexturePackGui = par1GuiTexturePacks; + } + + /** + * Gets the size of the current slot list. + */ + protected int getSize() { + return GuiTexturePacks.func_73955_b(this.parentTexturePackGui).texturePackList.availableTexturePacks().size(); + } + + /** + * the element in the slot that was clicked, boolean for wether it was double + * clicked or not + */ + protected void elementClicked(int par1, boolean par2) { + List var3 = GuiTexturePacks.func_73958_c(this.parentTexturePackGui).texturePackList.availableTexturePacks(); + + try { + GuiTexturePacks.func_73951_d(this.parentTexturePackGui).texturePackList.setTexturePack((ITexturePack) var3.get(par1)); + GuiTexturePacks.func_73952_e(this.parentTexturePackGui).renderEngine.refreshTextures(); + GuiTexturePacks.func_73962_f(this.parentTexturePackGui).renderGlobal.loadRenderers(); + } catch (Exception var5) { + GuiTexturePacks.func_73959_g(this.parentTexturePackGui).texturePackList.setTexturePack((ITexturePack) var3.get(0)); + GuiTexturePacks.func_73957_h(this.parentTexturePackGui).renderEngine.refreshTextures(); + GuiTexturePacks.func_73956_i(this.parentTexturePackGui).renderGlobal.loadRenderers(); + } + } + + /** + * returns true if the element passed in is currently selected + */ + protected boolean isSelected(int par1) { + List var2 = GuiTexturePacks.func_73953_j(this.parentTexturePackGui).texturePackList.availableTexturePacks(); + return GuiTexturePacks.func_73961_k(this.parentTexturePackGui).texturePackList.getSelectedTexturePack() == var2.get(par1); + } + + /** + * return the height of the content being scrolled + */ + protected int getContentHeight() { + return this.getSize() * 36; + } + + protected void drawBackground() { + this.parentTexturePackGui.drawDefaultBackground(); + } + + protected void drawSlot(int par1, int par2, int par3, int par4, Tessellator par5Tessellator) { + ITexturePack var6 = (ITexturePack) GuiTexturePacks.func_96143_l(this.parentTexturePackGui).texturePackList.availableTexturePacks().get(par1); + var6.bindThumbnailTexture(GuiTexturePacks.func_96142_m(this.parentTexturePackGui).renderEngine); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + par5Tessellator.startDrawingQuads(); + par5Tessellator.setColorOpaque_I(16777215); + par5Tessellator.addVertexWithUV((double) par2, (double) (par3 + par4), 0.0D, 0.0D, 1.0D); + par5Tessellator.addVertexWithUV((double) (par2 + 32), (double) (par3 + par4), 0.0D, 1.0D, 1.0D); + par5Tessellator.addVertexWithUV((double) (par2 + 32), (double) par3, 0.0D, 1.0D, 0.0D); + par5Tessellator.addVertexWithUV((double) par2, (double) par3, 0.0D, 0.0D, 0.0D); + par5Tessellator.draw(); + String var7 = var6.getTexturePackFileName(); + + if (!var6.isCompatible()) { + var7 = EnumChatFormatting.DARK_RED + StatCollector.translateToLocal("texturePack.incompatible") + " - " + var7; + } + + if (var7.length() > 32) { + var7 = var7.substring(0, 32).trim() + "..."; + } + + this.parentTexturePackGui.drawString(GuiTexturePacks.func_73954_n(this.parentTexturePackGui), var7, par2 + 32 + 2, par3 + 1, 16777215); + this.parentTexturePackGui.drawString(GuiTexturePacks.func_96145_o(this.parentTexturePackGui), var6.getFirstDescriptionLine(), par2 + 32 + 2, par3 + 12, 8421504); + this.parentTexturePackGui.drawString(GuiTexturePacks.func_96144_p(this.parentTexturePackGui), var6.getSecondDescriptionLine(), par2 + 32 + 2, par3 + 12 + 10, 8421504); + } +} diff --git a/src/main/java/net/minecraft/src/GuiTexturePacks.java b/src/main/java/net/minecraft/src/GuiTexturePacks.java new file mode 100644 index 0000000..fe8a810 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiTexturePacks.java @@ -0,0 +1,153 @@ +package net.minecraft.src; + +import net.minecraft.client.Minecraft; + +public class GuiTexturePacks extends GuiScreen { + protected GuiScreen guiScreen; + private int refreshTimer = -1; + + /** the absolute location of this texture pack */ + private String fileLocation = ""; + + /** + * the GuiTexturePackSlot that contains all the texture packs and their + * descriptions + */ + private GuiTexturePackSlot guiTexturePackSlot; + private GameSettings field_96146_n; + + public GuiTexturePacks(GuiScreen par1, GameSettings par2) { + this.guiScreen = par1; + this.field_96146_n = par2; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + StringTranslate var1 = StringTranslate.getInstance(); + GuiSmallButton b; + this.buttonList.add(b = new GuiSmallButton(5, this.width / 2 - 154, this.height - 48, var1.translateKey("texturePack.openFolder"))); + b.enabled = false; + this.buttonList.add(new GuiSmallButton(6, this.width / 2 + 4, this.height - 48, var1.translateKey("gui.done"))); + this.mc.texturePackList.updateAvaliableTexturePacks(); + //this.fileLocation = (new File("texturepacks")).getAbsolutePath(); + this.guiTexturePackSlot = new GuiTexturePackSlot(this); + this.guiTexturePackSlot.registerScrollButtons(this.buttonList, 7, 8); + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.enabled) { + + } + } + + /** + * Called when the mouse is clicked. + */ + protected void mouseClicked(int par1, int par2, int par3) { + super.mouseClicked(par1, par2, par3); + } + + /** + * Called when the mouse is moved or a mouse button is released. Signature: + * (mouseX, mouseY, which) which==-1 is mouseMove, which==0 or which==1 is + * mouseUp + */ + protected void mouseMovedOrUp(int par1, int par2, int par3) { + super.mouseMovedOrUp(par1, par2, par3); + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.guiTexturePackSlot.drawScreen(par1, par2, par3); + + if (this.refreshTimer <= 0) { + this.mc.texturePackList.updateAvaliableTexturePacks(); + this.refreshTimer += 20; + } + + StringTranslate var4 = StringTranslate.getInstance(); + this.drawCenteredString(this.fontRenderer, var4.translateKey("texturePack.title"), this.width / 2, 16, 16777215); + this.drawCenteredString(this.fontRenderer, var4.translateKey("texturePack.folderInfo"), this.width / 2 - 77, this.height - 26, 8421504); + super.drawScreen(par1, par2, par3); + } + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + super.updateScreen(); + --this.refreshTimer; + } + + static Minecraft func_73950_a(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.mc; + } + + static Minecraft func_73955_b(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.mc; + } + + static Minecraft func_73958_c(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.mc; + } + + static Minecraft func_73951_d(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.mc; + } + + static Minecraft func_73952_e(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.mc; + } + + static Minecraft func_73962_f(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.mc; + } + + static Minecraft func_73959_g(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.mc; + } + + static Minecraft func_73957_h(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.mc; + } + + static Minecraft func_73956_i(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.mc; + } + + static Minecraft func_73953_j(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.mc; + } + + static Minecraft func_73961_k(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.mc; + } + + static Minecraft func_96143_l(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.mc; + } + + static Minecraft func_96142_m(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.mc; + } + + static FontRenderer func_73954_n(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.fontRenderer; + } + + static FontRenderer func_96145_o(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.fontRenderer; + } + + static FontRenderer func_96144_p(GuiTexturePacks par0GuiTexturePacks) { + return par0GuiTexturePacks.fontRenderer; + } +} diff --git a/src/main/java/net/minecraft/src/GuiVideoSettings.java b/src/main/java/net/minecraft/src/GuiVideoSettings.java new file mode 100644 index 0000000..4e32033 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiVideoSettings.java @@ -0,0 +1,111 @@ +package net.minecraft.src; + +public class GuiVideoSettings extends GuiScreen { + private GuiScreen parentGuiScreen; + + /** The title string that is displayed in the top-center of the screen. */ + protected String screenTitle = "Video Settings"; + + /** GUI game settings */ + private GameSettings guiGameSettings; + + /** + * True if the system is 64-bit (using a simple indexOf test on a system + * property) + */ + private boolean is64bit = false; + + /** An array of all of EnumOption's video options. */ + private static EnumOptions[] videoOptions = new EnumOptions[] { EnumOptions.GRAPHICS, EnumOptions.RENDER_DISTANCE, EnumOptions.AMBIENT_OCCLUSION, EnumOptions.FRAMERATE_LIMIT, EnumOptions.ANAGLYPH, EnumOptions.VIEW_BOBBING, + EnumOptions.GUI_SCALE, EnumOptions.GAMMA, EnumOptions.RENDER_CLOUDS, EnumOptions.ENABLE_FOG, EnumOptions.PARTICLES, EnumOptions.ENABLE_VSYNC }; + + public GuiVideoSettings(GuiScreen par1GuiScreen, GameSettings par2GameSettings) { + this.parentGuiScreen = par1GuiScreen; + this.guiGameSettings = par2GameSettings; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + StringTranslate var1 = StringTranslate.getInstance(); + this.screenTitle = var1.translateKey("options.videoTitle"); + this.buttonList.clear(); + this.buttonList.add(new GuiButton(200, this.width / 2 - 100, this.height / 6 + 168, var1.translateKey("gui.done"))); + this.is64bit = true; + /* + String[] var2 = new String[] { "sun.arch.data.model", "com.ibm.vm.bitmode", "os.arch" }; + String[] var3 = var2; + int var4 = var2.length; + + for (int var5 = 0; var5 < var4; ++var5) { + String var6 = var3[var5]; + String var7 = System.getProperty(var6); + + if (var7 != null && var7.contains("64")) { + this.is64bit = true; + break; + } + } + */ + + int var9 = 0; + EnumOptions[] var10 = videoOptions; + int var11 = var10.length; + + for (int var12 = 0; var12 < var11; ++var12) { + EnumOptions var8 = var10[var12]; + + if (var8.getEnumFloat()) { + this.buttonList.add(new GuiSlider(var8.returnEnumOrdinal(), this.width / 2 - 155 + var9 % 2 * 160, this.height / 7 + 24 * (var9 >> 1), var8, this.guiGameSettings.getKeyBinding(var8), + this.guiGameSettings.getOptionFloatValue(var8))); + } else { + this.buttonList.add(new GuiSmallButton(var8.returnEnumOrdinal(), this.width / 2 - 155 + var9 % 2 * 160, this.height / 7 + 24 * (var9 >> 1), var8, this.guiGameSettings.getKeyBinding(var8))); + } + + ++var9; + } + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + if (par1GuiButton.enabled) { + int var2 = this.guiGameSettings.guiScale; + + if (par1GuiButton.id < 100 && par1GuiButton instanceof GuiSmallButton) { + this.guiGameSettings.setOptionValue(((GuiSmallButton) par1GuiButton).returnEnumOptions(), 1); + par1GuiButton.displayString = this.guiGameSettings.getKeyBinding(EnumOptions.getEnumOptions(par1GuiButton.id)); + } + + if (par1GuiButton.id == 200) { + this.mc.gameSettings.saveOptions(); + this.mc.displayGuiScreen(this.parentGuiScreen); + } + + if (this.guiGameSettings.guiScale != var2) { + ScaledResolution var3 = new ScaledResolution(this.mc.gameSettings, this.mc.displayWidth, this.mc.displayHeight); + int var4 = var3.getScaledWidth(); + int var5 = var3.getScaledHeight(); + this.setWorldAndResolution(this.mc, var4, var5); + } + } + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, this.is64bit ? 20 : 5, 16777215); + + if (!this.is64bit && this.guiGameSettings.renderDistance == 0) { + this.drawCenteredString(this.fontRenderer, StatCollector.translateToLocal("options.farWarning1"), this.width / 2, this.height / 6 + 144 + 1, 11468800); + this.drawCenteredString(this.fontRenderer, StatCollector.translateToLocal("options.farWarning2"), this.width / 2, this.height / 6 + 144 + 13, 11468800); + } + + super.drawScreen(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/GuiWinGame.java b/src/main/java/net/minecraft/src/GuiWinGame.java new file mode 100644 index 0000000..ee25683 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiWinGame.java @@ -0,0 +1,200 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.EaglerProfile; +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class GuiWinGame extends GuiScreen { + /** Counts the number of screen updates. */ + private int updateCounter = 0; + + /** List of lines on the ending poem and credits. */ + private List lines; + private int field_73989_c = 0; + private float field_73987_d = 0.5F; + + /** + * Called from the main game loop to update the screen. + */ + public void updateScreen() { + ++this.updateCounter; + float var1 = (float) (this.field_73989_c + this.height + this.height + 24) / this.field_73987_d; + + if ((float) this.updateCounter > var1) { + this.respawnPlayer(); + } + } + + /** + * Fired when a key is typed. This is the equivalent of + * KeyListener.keyTyped(KeyEvent e). + */ + protected void keyTyped(char par1, int par2) { + if (par2 == 1) { + this.respawnPlayer(); + } + } + + /** + * Respawns the player. + */ + private void respawnPlayer() { + this.mc.thePlayer.sendQueue.addToSendQueue(new Packet205ClientCommand(1)); + this.mc.displayGuiScreen((GuiScreen) null); + } + + /** + * Returns true if this GUI should pause the game when it is displayed in + * single-player + */ + public boolean doesGuiPauseGame() { + return true; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + if (this.lines == null) { + this.lines = new ArrayList(); + + try { + String var1 = ""; + String var2 = "" + EnumChatFormatting.WHITE + EnumChatFormatting.OBFUSCATED + EnumChatFormatting.GREEN + EnumChatFormatting.AQUA; + short var3 = 274; + Random var5 = new Random(8124371L); + int var6; + + for(String str : EaglerAdapter.fileContentsLines("/title/win.txt")) { + String var7; + String var8; + + for (var1 = var1.replaceAll("PLAYERNAME", EaglerProfile.username); var1.contains(var2); var1 = var7 + EnumChatFormatting.WHITE + EnumChatFormatting.OBFUSCATED + "XXXXXXXX".substring(0, var5.nextInt(4) + 3) + var8) { + var6 = var1.indexOf(var2); + var7 = var1.substring(0, var6); + var8 = var1.substring(var6 + var2.length()); + } + + this.lines.addAll(this.mc.fontRenderer.listFormattedStringToWidth(var1, var3)); + this.lines.add(""); + } + + for (var6 = 0; var6 < 8; ++var6) { + this.lines.add(""); + } + + for(String str : EaglerAdapter.fileContentsLines("/title/credits.txt")) { + var1 = var1.replaceAll("PLAYERNAME", EaglerProfile.username); + var1 = var1.replaceAll("\t", " "); + this.lines.addAll(this.mc.fontRenderer.listFormattedStringToWidth(var1, var3)); + this.lines.add(""); + } + + this.field_73989_c = this.lines.size() * 12; + } catch (Exception var9) { + var9.printStackTrace(); + } + } + } + + private static final TextureLocation bk = new TextureLocation("%blur%/gui/background.png"); + + private void func_73986_b(int par1, int par2, float par3) { + Tessellator var4 = Tessellator.instance; + bk.bindTexture(); + var4.startDrawingQuads(); + var4.setColorRGBA_F(1.0F, 1.0F, 1.0F, 1.0F); + int var5 = this.width; + float var6 = 0.0F - ((float) this.updateCounter + par3) * 0.5F * this.field_73987_d; + float var7 = (float) this.height - ((float) this.updateCounter + par3) * 0.5F * this.field_73987_d; + float var8 = 0.015625F; + float var9 = ((float) this.updateCounter + par3 - 0.0F) * 0.02F; + float var10 = (float) (this.field_73989_c + this.height + this.height + 24) / this.field_73987_d; + float var11 = (var10 - 20.0F - ((float) this.updateCounter + par3)) * 0.005F; + + if (var11 < var9) { + var9 = var11; + } + + if (var9 > 1.0F) { + var9 = 1.0F; + } + + var9 *= var9; + var9 = var9 * 96.0F / 255.0F; + var4.setColorOpaque_F(var9, var9, var9); + var4.addVertexWithUV(0.0D, (double) this.height, (double) this.zLevel, 0.0D, (double) (var6 * var8)); + var4.addVertexWithUV((double) var5, (double) this.height, (double) this.zLevel, (double) ((float) var5 * var8), (double) (var6 * var8)); + var4.addVertexWithUV((double) var5, 0.0D, (double) this.zLevel, (double) ((float) var5 * var8), (double) (var7 * var8)); + var4.addVertexWithUV(0.0D, 0.0D, (double) this.zLevel, 0.0D, (double) (var7 * var8)); + var4.draw(); + } + + private static final TextureLocation mclogo = new TextureLocation("/title/mclogo.png"); + private static final TextureLocation vigg = new TextureLocation("%blur%/misc/vignette.png"); + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.func_73986_b(par1, par2, par3); + Tessellator var4 = Tessellator.instance; + short var5 = 274; + int var6 = this.width / 2 - var5 / 2; + int var7 = this.height + 50; + float var8 = -((float) this.updateCounter + par3) * this.field_73987_d; + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(0.0F, var8, 0.0F); + mclogo.bindTexture(); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.drawTexturedModalRect(var6, var7, 0, 0, 155, 44); + this.drawTexturedModalRect(var6 + 155, var7, 0, 45, 155, 44); + var4.setColorOpaque_I(16777215); + int var9 = var7 + 200; + int var10; + + for (var10 = 0; var10 < this.lines.size(); ++var10) { + if (var10 == this.lines.size() - 1) { + float var11 = (float) var9 + var8 - (float) (this.height / 2 - 6); + + if (var11 < 0.0F) { + EaglerAdapter.glTranslatef(0.0F, -var11, 0.0F); + } + } + + if ((float) var9 + var8 + 12.0F + 8.0F > 0.0F && (float) var9 + var8 < (float) this.height) { + String var12 = (String) this.lines.get(var10); + + if (var12.startsWith("[C]")) { + this.fontRenderer.drawStringWithShadow(var12.substring(3), var6 + (var5 - this.fontRenderer.getStringWidth(var12.substring(3))) / 2, var9, 16777215); + } else { + this.fontRenderer.fontRandom.setSeed((long) var10 * 4238972211L + (long) (this.updateCounter / 4)); + this.fontRenderer.drawStringWithShadow(var12, var6, var9, 16777215); + } + } + + var9 += 12; + } + + EaglerAdapter.glPopMatrix(); + vigg.bindTexture(); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_ZERO, EaglerAdapter.GL_ONE_MINUS_SRC_COLOR); + var4.startDrawingQuads(); + var4.setColorRGBA_F(1.0F, 1.0F, 1.0F, 1.0F); + var10 = this.width; + int var13 = this.height; + var4.addVertexWithUV(0.0D, (double) var13, (double) this.zLevel, 0.0D, 1.0D); + var4.addVertexWithUV((double) var10, (double) var13, (double) this.zLevel, 1.0D, 1.0D); + var4.addVertexWithUV((double) var10, 0.0D, (double) this.zLevel, 1.0D, 0.0D); + var4.addVertexWithUV(0.0D, 0.0D, (double) this.zLevel, 0.0D, 0.0D); + var4.draw(); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + super.drawScreen(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/GuiYesNo.java b/src/main/java/net/minecraft/src/GuiYesNo.java new file mode 100644 index 0000000..8e36b36 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiYesNo.java @@ -0,0 +1,69 @@ +package net.minecraft.src; + +public class GuiYesNo extends GuiScreen { + /** + * A reference to the screen object that created this. Used for navigating + * between screens. + */ + protected GuiScreen parentScreen; + + /** First line of text. */ + protected String message1; + + /** Second line of text. */ + private String message2; + + /** The text shown for the first button in GuiYesNo */ + protected String buttonText1; + + /** The text shown for the second button in GuiYesNo */ + protected String buttonText2; + + /** World number to be deleted. */ + protected int worldNumber; + + public GuiYesNo(GuiScreen par1GuiScreen, String par2Str, String par3Str, int par4) { + this.parentScreen = par1GuiScreen; + this.message1 = par2Str; + this.message2 = par3Str; + this.worldNumber = par4; + StringTranslate var5 = StringTranslate.getInstance(); + this.buttonText1 = var5.translateKey("gui.yes"); + this.buttonText2 = var5.translateKey("gui.no"); + } + + public GuiYesNo(GuiScreen par1GuiScreen, String par2Str, String par3Str, String par4Str, String par5Str, int par6) { + this.parentScreen = par1GuiScreen; + this.message1 = par2Str; + this.message2 = par3Str; + this.buttonText1 = par4Str; + this.buttonText2 = par5Str; + this.worldNumber = par6; + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + this.buttonList.add(new GuiSmallButton(0, this.width / 2 - 155, this.height / 6 + 96, this.buttonText1)); + this.buttonList.add(new GuiSmallButton(1, this.width / 2 - 155 + 160, this.height / 6 + 96, this.buttonText2)); + } + + /** + * Fired when a control is clicked. This is the equivalent of + * ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) { + this.parentScreen.confirmClicked(par1GuiButton.id == 0, this.worldNumber); + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, this.message1, this.width / 2, 70, 16777215); + this.drawCenteredString(this.fontRenderer, this.message2, this.width / 2, 90, 16777215); + super.drawScreen(par1, par2, par3); + } +} diff --git a/src/main/java/net/minecraft/src/Hopper.java b/src/main/java/net/minecraft/src/Hopper.java new file mode 100644 index 0000000..2037caf --- /dev/null +++ b/src/main/java/net/minecraft/src/Hopper.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +public interface Hopper extends IInventory { + /** + * Returns the worldObj for this tileEntity. + */ + World getWorldObj(); + + /** + * Gets the world X position for this hopper entity. + */ + double getXPos(); + + /** + * Gets the world Y position for this hopper entity. + */ + double getYPos(); + + /** + * Gets the world Z position for this hopper entity. + */ + double getZPos(); +} diff --git a/src/main/java/net/minecraft/src/IAdminCommand.java b/src/main/java/net/minecraft/src/IAdminCommand.java new file mode 100644 index 0000000..a2a9da8 --- /dev/null +++ b/src/main/java/net/minecraft/src/IAdminCommand.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +public interface IAdminCommand { + /** + * Sends a message to the admins of the server from a given CommandSender with + * the given resource string and given extra srings. If the int par2 is even or + * zero, the original sender is also notified. + */ + void notifyAdmins(ICommandSender var1, int var2, String var3, Object... var4); +} diff --git a/src/main/java/net/minecraft/src/IAnimals.java b/src/main/java/net/minecraft/src/IAnimals.java new file mode 100644 index 0000000..8592735 --- /dev/null +++ b/src/main/java/net/minecraft/src/IAnimals.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +public interface IAnimals { +} diff --git a/src/main/java/net/minecraft/src/IBehaviorDispenseItem.java b/src/main/java/net/minecraft/src/IBehaviorDispenseItem.java new file mode 100644 index 0000000..3d8e839 --- /dev/null +++ b/src/main/java/net/minecraft/src/IBehaviorDispenseItem.java @@ -0,0 +1,9 @@ +package net.minecraft.src; + +public interface IBehaviorDispenseItem { + + /** + * Dispenses the specified ItemStack from a dispenser. + */ + ItemStack dispense(IBlockSource var1, ItemStack var2); +} diff --git a/src/main/java/net/minecraft/src/IBlockAccess.java b/src/main/java/net/minecraft/src/IBlockAccess.java new file mode 100644 index 0000000..4618f34 --- /dev/null +++ b/src/main/java/net/minecraft/src/IBlockAccess.java @@ -0,0 +1,85 @@ +package net.minecraft.src; + +public interface IBlockAccess { + /** + * Returns the block ID at coords x,y,z + */ + int getBlockId(int var1, int var2, int var3); + + /** + * Returns the TileEntity associated with a given block in X,Y,Z coordinates, or + * null if no TileEntity exists + */ + TileEntity getBlockTileEntity(int var1, int var2, int var3); + + /** + * Any Light rendered on a 1.8 Block goes through here + */ + int getLightBrightnessForSkyBlocks(int var1, int var2, int var3, int var4); + + float getBrightness(int var1, int var2, int var3, int var4); + + /** + * Returns how bright the block is shown as which is the block's light value + * looked up in a lookup table (light values aren't linear for brightness). + * Args: x, y, z + */ + float getLightBrightness(int var1, int var2, int var3); + + /** + * Returns the block metadata at coords x,y,z + */ + int getBlockMetadata(int var1, int var2, int var3); + + /** + * Returns the block's material. + */ + Material getBlockMaterial(int var1, int var2, int var3); + + /** + * Returns true if the block at the specified coordinates is an opaque cube. + * Args: x, y, z + */ + boolean isBlockOpaqueCube(int var1, int var2, int var3); + + /** + * Indicate if a material is a normal solid opaque cube. + */ + boolean isBlockNormalCube(int var1, int var2, int var3); + + /** + * Returns true if the block at the specified coordinates is empty + */ + boolean isAirBlock(int var1, int var2, int var3); + + /** + * Gets the biome for a given set of x/z coordinates + */ + BiomeGenBase getBiomeGenForCoords(int var1, int var2); + + /** + * Returns current world height. + */ + int getHeight(); + + /** + * set by !chunk.getAreLevelsEmpty + */ + boolean extendedLevelsInChunkCache(); + + /** + * Returns true if the block at the given coordinate has a solid (buildable) top + * surface. + */ + boolean doesBlockHaveSolidTopSurface(int var1, int var2, int var3); + + /** + * Return the Vec3Pool object for this world. + */ + Vec3Pool getWorldVec3Pool(); + + /** + * Is this block powering in the specified direction Args: x, y, z, direction + */ + int isBlockProvidingPowerTo(int var1, int var2, int var3, int var4); +} diff --git a/src/main/java/net/minecraft/src/IBlockSource.java b/src/main/java/net/minecraft/src/IBlockSource.java new file mode 100644 index 0000000..5a025c8 --- /dev/null +++ b/src/main/java/net/minecraft/src/IBlockSource.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +public interface IBlockSource extends ILocatableSource { + double getX(); + + double getY(); + + double getZ(); + + int getXInt(); + + int getYInt(); + + int getZInt(); + + int getBlockMetadata(); + + TileEntity getBlockTileEntity(); +} diff --git a/src/main/java/net/minecraft/src/IBossDisplayData.java b/src/main/java/net/minecraft/src/IBossDisplayData.java new file mode 100644 index 0000000..a6149da --- /dev/null +++ b/src/main/java/net/minecraft/src/IBossDisplayData.java @@ -0,0 +1,15 @@ +package net.minecraft.src; + +public interface IBossDisplayData { + int getMaxHealth(); + + /** + * Returns the health points of the dragon. + */ + int getBossHealth(); + + /** + * Gets the username of the entity. + */ + String getEntityName(); +} diff --git a/src/main/java/net/minecraft/src/ICamera.java b/src/main/java/net/minecraft/src/ICamera.java new file mode 100644 index 0000000..25ed334 --- /dev/null +++ b/src/main/java/net/minecraft/src/ICamera.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +public interface ICamera { + /** + * Returns true if the bounding box is inside all 6 clipping planes, otherwise + * returns false. + */ + boolean isBoundingBoxInFrustum(AxisAlignedBB var1); + + void setPosition(double var1, double var3, double var5); +} diff --git a/src/main/java/net/minecraft/src/IChunkLoader.java b/src/main/java/net/minecraft/src/IChunkLoader.java new file mode 100644 index 0000000..179197f --- /dev/null +++ b/src/main/java/net/minecraft/src/IChunkLoader.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public interface IChunkLoader { + /** + * Loads the specified(XZ) chunk into the specified world. + */ + Chunk loadChunk(World var1, int var2, int var3); + + void saveChunk(World var1, Chunk var2); + + /** + * Save extra data associated with this Chunk not normally saved during + * autosave, only during chunk unload. Currently unused. + */ + void saveExtraChunkData(World var1, Chunk var2); + + /** + * Called every World.tick() + */ + void chunkTick(); + + /** + * Save extra data not associated with any Chunk. Not saved during autosave, + * only during world unload. Currently unused. + */ + void saveExtraData(); +} diff --git a/src/main/java/net/minecraft/src/IChunkProvider.java b/src/main/java/net/minecraft/src/IChunkProvider.java new file mode 100644 index 0000000..1e81f72 --- /dev/null +++ b/src/main/java/net/minecraft/src/IChunkProvider.java @@ -0,0 +1,67 @@ +package net.minecraft.src; + +import java.util.List; + +public interface IChunkProvider { + /** + * Checks to see if a chunk exists at x, y + */ + boolean chunkExists(int var1, int var2); + + /** + * Will return back a chunk, if it doesn't exist and its not a MP client it will + * generates all the blocks for the specified chunk from the map seed and chunk + * seed + */ + Chunk provideChunk(int var1, int var2); + + /** + * loads or generates the chunk at the chunk location specified + */ + Chunk loadChunk(int var1, int var2); + + /** + * Populates chunk with ores etc etc + */ + void populate(IChunkProvider var1, int var2, int var3); + + /** + * Two modes of operation: if passed true, save all Chunks in one go. If passed + * false, save up to two chunks. Return true if all chunks have been saved. + */ + boolean saveChunks(boolean var1, IProgressUpdate var2); + + /** + * Unloads chunks that are marked to be unloaded. This is not guaranteed to + * unload every such chunk. + */ + boolean unloadQueuedChunks(); + + /** + * Returns if the IChunkProvider supports saving. + */ + boolean canSave(); + + /** + * Converts the instance data to a readable string. + */ + String makeString(); + + /** + * Returns a list of creatures of the specified type that can spawn at the given + * location. + */ + List getPossibleCreatures(EnumCreatureType var1, int var2, int var3, int var4); + + /** + * Returns the location of the closest structure of the specified type. If not + * found returns null. + */ + ChunkPosition findClosestStructure(World var1, String var2, int var3, int var4, int var5); + + int getLoadedChunkCount(); + + void recreateStructures(int var1, int var2); + + void func_104112_b(); +} diff --git a/src/main/java/net/minecraft/src/ICommand.java b/src/main/java/net/minecraft/src/ICommand.java new file mode 100644 index 0000000..958294d --- /dev/null +++ b/src/main/java/net/minecraft/src/ICommand.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +import java.util.List; + +public interface ICommand extends Comparable { + String getCommandName(); + + String getCommandUsage(ICommandSender var1); + + List getCommandAliases(); + + void processCommand(ICommandSender var1, String[] var2); + + /** + * Returns true if the given command sender is allowed to use this command. + */ + boolean canCommandSenderUseCommand(ICommandSender var1); + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + List addTabCompletionOptions(ICommandSender var1, String[] var2); + + /** + * Return whether the specified command parameter index is a username parameter. + */ + boolean isUsernameIndex(String[] var1, int var2); +} diff --git a/src/main/java/net/minecraft/src/ICommandManager.java b/src/main/java/net/minecraft/src/ICommandManager.java new file mode 100644 index 0000000..180350a --- /dev/null +++ b/src/main/java/net/minecraft/src/ICommandManager.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Map; + +public interface ICommandManager { + int executeCommand(ICommandSender var1, String var2); + + /** + * Performs a "begins with" string match on each token in par2. Only returns + * commands that par1 can use. + */ + List getPossibleCommands(ICommandSender var1, String var2); + + /** + * returns all commands that the commandSender can use + */ + List getPossibleCommands(ICommandSender var1); + + /** + * returns a map of string to commads. All commands are returned, not just ones + * which someone has permission to use. + */ + Map getCommands(); +} diff --git a/src/main/java/net/minecraft/src/ICommandSender.java b/src/main/java/net/minecraft/src/ICommandSender.java new file mode 100644 index 0000000..b32ae4e --- /dev/null +++ b/src/main/java/net/minecraft/src/ICommandSender.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +public interface ICommandSender { + /** + * Gets the name of this command sender (usually username, but possibly "Rcon") + */ + String getCommandSenderName(); + + void sendChatToPlayer(String var1); + + /** + * Returns true if the command sender is allowed to use the given command. + */ + boolean canCommandSenderUseCommand(int var1, String var2); + + /** + * Translates and formats the given string key with the given arguments. + */ + String translateString(String var1, Object... var2); + + /** + * Return the position for this command sender. + */ + ChunkCoordinates getPlayerCoordinates(); +} diff --git a/src/main/java/net/minecraft/src/ICrafting.java b/src/main/java/net/minecraft/src/ICrafting.java new file mode 100644 index 0000000..99eefee --- /dev/null +++ b/src/main/java/net/minecraft/src/ICrafting.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +import java.util.List; + +public interface ICrafting { + void sendContainerAndContentsToPlayer(Container var1, List var2); + + /** + * Sends the contents of an inventory slot to the client-side Container. This + * doesn't have to match the actual contents of that slot. Args: Container, slot + * number, slot contents + */ + void sendSlotContents(Container var1, int var2, ItemStack var3); + + /** + * Sends two ints to the client-side Container. Used for furnace burning time, + * smelting progress, brewing progress, and enchanting level. Normally the first + * int identifies which variable to update, and the second contains the new + * value. Both are truncated to shorts in non-local SMP. + */ + void sendProgressBarUpdate(Container var1, int var2, int var3); +} diff --git a/src/main/java/net/minecraft/src/IEnchantmentModifier.java b/src/main/java/net/minecraft/src/IEnchantmentModifier.java new file mode 100644 index 0000000..1601bd5 --- /dev/null +++ b/src/main/java/net/minecraft/src/IEnchantmentModifier.java @@ -0,0 +1,9 @@ +package net.minecraft.src; + +interface IEnchantmentModifier { + /** + * Generic method use to calculate modifiers of offensive or defensive + * enchantment values. + */ + void calculateModifier(Enchantment var1, int var2); +} diff --git a/src/main/java/net/minecraft/src/IEntityMultiPart.java b/src/main/java/net/minecraft/src/IEntityMultiPart.java new file mode 100644 index 0000000..17cc747 --- /dev/null +++ b/src/main/java/net/minecraft/src/IEntityMultiPart.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +public interface IEntityMultiPart { + World func_82194_d(); + + boolean attackEntityFromPart(EntityDragonPart var1, DamageSource var2, int var3); +} diff --git a/src/main/java/net/minecraft/src/IEntitySelector.java b/src/main/java/net/minecraft/src/IEntitySelector.java new file mode 100644 index 0000000..3e9263d --- /dev/null +++ b/src/main/java/net/minecraft/src/IEntitySelector.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +public interface IEntitySelector { + IEntitySelector selectAnything = new EntitySelectorAlive(); + IEntitySelector selectInventories = new EntitySelectorInventory(); + + /** + * Return whether the specified entity is applicable to this filter. + */ + boolean isEntityApplicable(Entity var1); +} diff --git a/src/main/java/net/minecraft/src/IInvBasic.java b/src/main/java/net/minecraft/src/IInvBasic.java new file mode 100644 index 0000000..30e637c --- /dev/null +++ b/src/main/java/net/minecraft/src/IInvBasic.java @@ -0,0 +1,9 @@ +package net.minecraft.src; + +public interface IInvBasic { + /** + * Called by InventoryBasic.onInventoryChanged() on a array that is never + * filled. + */ + void onInventoryChanged(InventoryBasic var1); +} diff --git a/src/main/java/net/minecraft/src/IInventory.java b/src/main/java/net/minecraft/src/IInventory.java new file mode 100644 index 0000000..2d8f8b1 --- /dev/null +++ b/src/main/java/net/minecraft/src/IInventory.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +public interface IInventory { + /** + * Returns the number of slots in the inventory. + */ + int getSizeInventory(); + + /** + * Returns the stack in slot i + */ + ItemStack getStackInSlot(int var1); + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + ItemStack decrStackSize(int var1, int var2); + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + ItemStack getStackInSlotOnClosing(int var1); + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + void setInventorySlotContents(int var1, ItemStack var2); + + /** + * Returns the name of the inventory. + */ + String getInvName(); + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + boolean isInvNameLocalized(); + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + int getInventoryStackLimit(); + + /** + * Called when an the contents of an Inventory change, usually + */ + void onInventoryChanged(); + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + boolean isUseableByPlayer(EntityPlayer var1); + + void openChest(); + + void closeChest(); + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + boolean isStackValidForSlot(int var1, ItemStack var2); +} diff --git a/src/main/java/net/minecraft/src/ILocatableSource.java b/src/main/java/net/minecraft/src/ILocatableSource.java new file mode 100644 index 0000000..154fcc3 --- /dev/null +++ b/src/main/java/net/minecraft/src/ILocatableSource.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +public interface ILocatableSource extends ILocation { +} diff --git a/src/main/java/net/minecraft/src/ILocation.java b/src/main/java/net/minecraft/src/ILocation.java new file mode 100644 index 0000000..a77439b --- /dev/null +++ b/src/main/java/net/minecraft/src/ILocation.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public interface ILocation extends IPosition { + World getWorld(); +} diff --git a/src/main/java/net/minecraft/src/ILogAgent.java b/src/main/java/net/minecraft/src/ILogAgent.java new file mode 100644 index 0000000..d65036e --- /dev/null +++ b/src/main/java/net/minecraft/src/ILogAgent.java @@ -0,0 +1,17 @@ +package net.minecraft.src; + +public interface ILogAgent { + void logInfo(String var1); + + void logWarning(String var1); + + void logWarningFormatted(String var1, Object... var2); + + void logWarningException(String var1, Throwable var2); + + void logSevere(String var1); + + void logSevereException(String var1, Throwable var2); + + void logFine(String var1); +} diff --git a/src/main/java/net/minecraft/src/IMerchant.java b/src/main/java/net/minecraft/src/IMerchant.java new file mode 100644 index 0000000..91b9982 --- /dev/null +++ b/src/main/java/net/minecraft/src/IMerchant.java @@ -0,0 +1,13 @@ +package net.minecraft.src; + +public interface IMerchant { + void setCustomer(EntityPlayer var1); + + EntityPlayer getCustomer(); + + MerchantRecipeList getRecipes(EntityPlayer var1); + + void setRecipes(MerchantRecipeList var1); + + void useRecipe(MerchantRecipe var1); +} diff --git a/src/main/java/net/minecraft/src/IMob.java b/src/main/java/net/minecraft/src/IMob.java new file mode 100644 index 0000000..374c63b --- /dev/null +++ b/src/main/java/net/minecraft/src/IMob.java @@ -0,0 +1,6 @@ +package net.minecraft.src; + +public interface IMob extends IAnimals { + /** Entity selector for IMob types. */ + IEntitySelector mobSelector = new FilterIMob(); +} diff --git a/src/main/java/net/minecraft/src/INetworkManager.java b/src/main/java/net/minecraft/src/INetworkManager.java new file mode 100644 index 0000000..b9c8079 --- /dev/null +++ b/src/main/java/net/minecraft/src/INetworkManager.java @@ -0,0 +1,42 @@ +package net.minecraft.src; + +public interface INetworkManager { + /** + * Sets the NetHandler for this NetworkManager. Server-only. + */ + public void setNetHandler(NetHandler var1); + + /** + * Adds the packet to the correct send queue (chunk data packets go to a + * separate queue). + */ + public void addToSendQueue(Packet var1); + + /** + * Wakes reader and writer threads + */ + public void wakeThreads(); + + /** + * Checks timeouts and processes all pending read packets. + */ + public void processReadPackets(); + + /** + * Shuts down the server. (Only actually used on the server) + */ + public void serverShutdown(); + + /** + * returns 0 for memoryConnections + */ + public int packetSize(); + + /** + * Shuts down the network with the specified reason. Closes all streams and + * sockets, spawns NetworkMasterThread to stop reading and writing threads. + */ + public void networkShutdown(String var1, Object... var2); + + public void closeConnections(); +} diff --git a/src/main/java/net/minecraft/src/INpc.java b/src/main/java/net/minecraft/src/INpc.java new file mode 100644 index 0000000..0848d78 --- /dev/null +++ b/src/main/java/net/minecraft/src/INpc.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +public interface INpc extends IAnimals { +} diff --git a/src/main/java/net/minecraft/src/IPlayerFileData.java b/src/main/java/net/minecraft/src/IPlayerFileData.java new file mode 100644 index 0000000..72784a6 --- /dev/null +++ b/src/main/java/net/minecraft/src/IPlayerFileData.java @@ -0,0 +1,18 @@ +package net.minecraft.src; + +public interface IPlayerFileData { + /** + * Writes the player data to disk from the specified PlayerEntityMP. + */ + void writePlayerData(EntityPlayer var1); + + /** + * Reads the player data from disk into the specified PlayerEntityMP. + */ + NBTTagCompound readPlayerData(EntityPlayer var1); + + /** + * Returns an array of usernames for which player.dat exists for. + */ + String[] getAvailablePlayerDat(); +} diff --git a/src/main/java/net/minecraft/src/IPosition.java b/src/main/java/net/minecraft/src/IPosition.java new file mode 100644 index 0000000..51c3a39 --- /dev/null +++ b/src/main/java/net/minecraft/src/IPosition.java @@ -0,0 +1,9 @@ +package net.minecraft.src; + +public interface IPosition { + double getX(); + + double getY(); + + double getZ(); +} diff --git a/src/main/java/net/minecraft/src/IProgressUpdate.java b/src/main/java/net/minecraft/src/IProgressUpdate.java new file mode 100644 index 0000000..d19d8a4 --- /dev/null +++ b/src/main/java/net/minecraft/src/IProgressUpdate.java @@ -0,0 +1,32 @@ +package net.minecraft.src; + +public interface IProgressUpdate { + /** + * "Saving level", or the loading,or downloading equivelent + */ + void displayProgressMessage(String var1); + + /** + * this string, followed by "working..." and then the "% complete" are the 3 + * lines shown. This resets progress to 0, and the WorkingString to + * "working...". + */ + void resetProgressAndMessage(String var1); + + /** + * This is called with "Working..." by resetProgressAndMessage + */ + void resetProgresAndWorkingMessage(String var1); + + /** + * Updates the progress bar on the loading screen to the specified amount. Args: + * loadProgress + */ + void setLoadingProgress(int var1); + + /** + * called when there is no more progress to be had, both on completion and + * failure + */ + void onNoMoreProgress(); +} diff --git a/src/main/java/net/minecraft/src/IProjectile.java b/src/main/java/net/minecraft/src/IProjectile.java new file mode 100644 index 0000000..4135bea --- /dev/null +++ b/src/main/java/net/minecraft/src/IProjectile.java @@ -0,0 +1,9 @@ +package net.minecraft.src; + +public interface IProjectile { + /** + * Similar to setArrowHeading, it's point the throwable entity to a x, y, z + * direction. + */ + void setThrowableHeading(double var1, double var3, double var5, float var7, float var8); +} diff --git a/src/main/java/net/minecraft/src/IRangedAttackMob.java b/src/main/java/net/minecraft/src/IRangedAttackMob.java new file mode 100644 index 0000000..97f473d --- /dev/null +++ b/src/main/java/net/minecraft/src/IRangedAttackMob.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public interface IRangedAttackMob { + /** + * Attack the specified entity using a ranged attack. + */ + void attackEntityWithRangedAttack(EntityLiving var1, float var2); +} diff --git a/src/main/java/net/minecraft/src/IRecipe.java b/src/main/java/net/minecraft/src/IRecipe.java new file mode 100644 index 0000000..cfec198 --- /dev/null +++ b/src/main/java/net/minecraft/src/IRecipe.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +public interface IRecipe { + /** + * Used to check if a recipe matches current crafting inventory + */ + boolean matches(InventoryCrafting var1, World var2); + + /** + * Returns an Item that is the result of this recipe + */ + ItemStack getCraftingResult(InventoryCrafting var1); + + /** + * Returns the size of the recipe area + */ + int getRecipeSize(); + + ItemStack getRecipeOutput(); +} diff --git a/src/main/java/net/minecraft/src/IRegistry.java b/src/main/java/net/minecraft/src/IRegistry.java new file mode 100644 index 0000000..2f4c6d3 --- /dev/null +++ b/src/main/java/net/minecraft/src/IRegistry.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +public interface IRegistry { + Object func_82594_a(Object var1); + + /** + * Register an object on this registry. + */ + void putObject(Object var1, Object var2); +} diff --git a/src/main/java/net/minecraft/src/IServer.java b/src/main/java/net/minecraft/src/IServer.java new file mode 100644 index 0000000..7ffc726 --- /dev/null +++ b/src/main/java/net/minecraft/src/IServer.java @@ -0,0 +1,99 @@ +package net.minecraft.src; + +public interface IServer { + /** + * Gets an integer property. If it does not exist, set it to the specified + * value. + */ + int getIntProperty(String var1, int var2); + + /** + * Gets a string property. If it does not exist, set it to the specified value. + */ + String getStringProperty(String var1, String var2); + + /** + * Saves an Object with the given property name. + */ + void setProperty(String var1, Object var2); + + /** + * Saves all of the server properties to the properties file. + */ + void saveProperties(); + + /** + * Returns the filename where server properties are stored + */ + String getSettingsFilename(); + + /** + * Returns the server's hostname. + */ + String getHostname(); + + /** + * Never used, but "getServerPort" is already taken. + */ + int getPort(); + + /** + * Returns the server message of the day + */ + String getServerMOTD(); + + /** + * Returns the server's Minecraft version as string. + */ + String getMinecraftVersion(); + + /** + * Returns the number of players currently on the server. + */ + int getCurrentPlayerCount(); + + /** + * Returns the maximum number of players allowed on the server. + */ + int getMaxPlayers(); + + /** + * Returns an array of the usernames of all the connected players. + */ + String[] getAllUsernames(); + + String getFolderName(); + + /** + * Used by RCon's Query in the form of "MajorServerMod 1.2.3: MyPlugin 1.3; + * AnotherPlugin 2.1; AndSoForth 1.0". + */ + String getPlugins(); + + String executeCommand(String var1); + + /** + * Returns true if debugging is enabled, false otherwise. + */ + boolean isDebuggingEnabled(); + + /** + * Logs the message with a level of INFO. + */ + void logInfo(String var1); + + /** + * Logs the message with a level of WARN. + */ + void logWarning(String var1); + + /** + * Logs the error message with a level of SEVERE. + */ + void logSevere(String var1); + + /** + * If isDebuggingEnabled(), logs the message with a level of INFO. + */ + void logDebug(String var1); +} diff --git a/src/main/java/net/minecraft/src/ISidedInventory.java b/src/main/java/net/minecraft/src/ISidedInventory.java new file mode 100644 index 0000000..c64dd58 --- /dev/null +++ b/src/main/java/net/minecraft/src/ISidedInventory.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +public interface ISidedInventory extends IInventory { + /** + * Returns an array containing the indices of the slots that can be accessed by + * automation on the given side of this block. + */ + int[] getAccessibleSlotsFromSide(int var1); + + /** + * Returns true if automation can insert the given item in the given slot from + * the given side. Args: Slot, item, side + */ + boolean canInsertItem(int var1, ItemStack var2, int var3); + + /** + * Returns true if automation can extract the given item in the given slot from + * the given side. Args: Slot, item, side + */ + boolean canExtractItem(int var1, ItemStack var2, int var3); +} diff --git a/src/main/java/net/minecraft/src/IStatStringFormat.java b/src/main/java/net/minecraft/src/IStatStringFormat.java new file mode 100644 index 0000000..7111d92 --- /dev/null +++ b/src/main/java/net/minecraft/src/IStatStringFormat.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public interface IStatStringFormat { + /** + * Formats the strings based on 'IStatStringFormat' interface. + */ + String formatString(String var1); +} diff --git a/src/main/java/net/minecraft/src/IStatType.java b/src/main/java/net/minecraft/src/IStatType.java new file mode 100644 index 0000000..e6f41a5 --- /dev/null +++ b/src/main/java/net/minecraft/src/IStatType.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public interface IStatType { + /** + * Formats a given stat for human consumption. + */ + String format(int var1); +} diff --git a/src/main/java/net/minecraft/src/ITexturePack.java b/src/main/java/net/minecraft/src/ITexturePack.java new file mode 100644 index 0000000..0696877 --- /dev/null +++ b/src/main/java/net/minecraft/src/ITexturePack.java @@ -0,0 +1,52 @@ +package net.minecraft.src; + +import java.io.InputStream; + +public interface ITexturePack { + /** + * Delete the OpenGL texture id of the pack's thumbnail image, and close the zip + * file in case of TexturePackCustom. + */ + void deleteTexturePack(RenderEngine var1); + + /** + * Bind the texture id of the pack's thumbnail image, loading it if necessary. + */ + void bindThumbnailTexture(RenderEngine var1); + + InputStream func_98137_a(String var1, boolean var2); + + /** + * Gives a texture resource as InputStream. + */ + InputStream getResourceAsStream(String var1); + + /** + * Get the texture pack ID + */ + String getTexturePackID(); + + /** + * Get the file name of the texture pack, or Default if not from a custom + * texture pack + */ + String getTexturePackFileName(); + + /** + * Get the first line of the texture pack description (read from the pack.txt + * file) + */ + String getFirstDescriptionLine(); + + /** + * Get the second line of the texture pack description (read from the pack.txt + * file) + */ + String getSecondDescriptionLine(); + + boolean func_98138_b(String var1, boolean var2); + + boolean isCompatible(); + + byte[] getResourceAsBytes(String par1Str); +} diff --git a/src/main/java/net/minecraft/src/IThreadedFileIO.java b/src/main/java/net/minecraft/src/IThreadedFileIO.java new file mode 100644 index 0000000..b0d3d18 --- /dev/null +++ b/src/main/java/net/minecraft/src/IThreadedFileIO.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public interface IThreadedFileIO { + /** + * Returns a boolean stating if the write was unsuccessful. + */ + boolean writeNextIO(); +} diff --git a/src/main/java/net/minecraft/src/ITileEntityProvider.java b/src/main/java/net/minecraft/src/ITileEntityProvider.java new file mode 100644 index 0000000..5fa82b6 --- /dev/null +++ b/src/main/java/net/minecraft/src/ITileEntityProvider.java @@ -0,0 +1,9 @@ +package net.minecraft.src; + +public interface ITileEntityProvider { + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + TileEntity createNewTileEntity(World var1); +} diff --git a/src/main/java/net/minecraft/src/IUpdatePlayerListBox.java b/src/main/java/net/minecraft/src/IUpdatePlayerListBox.java new file mode 100644 index 0000000..33d1e85 --- /dev/null +++ b/src/main/java/net/minecraft/src/IUpdatePlayerListBox.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public interface IUpdatePlayerListBox { + /** + * Updates the JList with a new model. + */ + void update(); +} diff --git a/src/main/java/net/minecraft/src/IWorldAccess.java b/src/main/java/net/minecraft/src/IWorldAccess.java new file mode 100644 index 0000000..837dd7f --- /dev/null +++ b/src/main/java/net/minecraft/src/IWorldAccess.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +public interface IWorldAccess { + /** + * On the client, re-renders the block. On the server, sends the block to the + * client (which will re-render it), including the tile entity description + * packet if applicable. Args: x, y, z + */ + void markBlockForUpdate(int var1, int var2, int var3); + + /** + * On the client, re-renders this block. On the server, does nothing. Used for + * lighting updates. + */ + void markBlockForRenderUpdate(int var1, int var2, int var3); + + /** + * On the client, re-renders all blocks in this range, inclusive. On the server, + * does nothing. Args: min x, min y, min z, max x, max y, max z + */ + void markBlockRangeForRenderUpdate(int var1, int var2, int var3, int var4, int var5, int var6); + + /** + * Plays the specified sound. Arg: soundName, x, y, z, volume, pitch + */ + void playSound(String var1, double var2, double var4, double var6, float var8, float var9); + + /** + * Plays sound to all near players except the player reference given + */ + void playSoundToNearExcept(EntityPlayer var1, String var2, double var3, double var5, double var7, float var9, float var10); + + /** + * Spawns a particle. Arg: particleType, x, y, z, velX, velY, velZ + */ + void spawnParticle(String var1, double var2, double var4, double var6, double var8, double var10, double var12); + + /** + * Called on all IWorldAccesses when an entity is created or loaded. On client + * worlds, starts downloading any necessary textures. On server worlds, adds the + * entity to the entity tracker. + */ + void onEntityCreate(Entity var1); + + /** + * Called on all IWorldAccesses when an entity is unloaded or destroyed. On + * client worlds, releases any downloaded textures. On server worlds, removes + * the entity from the entity tracker. + */ + void onEntityDestroy(Entity var1); + + /** + * Plays the specified record. Arg: recordName, x, y, z + */ + void playRecord(String var1, int var2, int var3, int var4); + + void broadcastSound(int var1, int var2, int var3, int var4, int var5); + + /** + * Plays a pre-canned sound effect along with potentially auxiliary data-driven + * one-shot behaviour (particles, etc). + */ + void playAuxSFX(EntityPlayer var1, int var2, int var3, int var4, int var5, int var6); + + /** + * Starts (or continues) destroying a block with given ID at the given + * coordinates for the given partially destroyed value + */ + void destroyBlockPartially(int var1, int var2, int var3, int var4, int var5); +} diff --git a/src/main/java/net/minecraft/src/Icon.java b/src/main/java/net/minecraft/src/Icon.java new file mode 100644 index 0000000..a494454 --- /dev/null +++ b/src/main/java/net/minecraft/src/Icon.java @@ -0,0 +1,57 @@ +package net.minecraft.src; + +public interface Icon { + /** + * Returns the X position of this icon on its texture sheet, in pixels. + */ + int getOriginX(); + + /** + * Returns the Y position of this icon on its texture sheet, in pixels. + */ + int getOriginY(); + + /** + * Returns the minimum U coordinate to use when rendering with this icon. + */ + float getMinU(); + + /** + * Returns the maximum U coordinate to use when rendering with this icon. + */ + float getMaxU(); + + /** + * Gets a U coordinate on the icon. 0 returns uMin and 16 returns uMax. Other + * arguments return in-between values. + */ + float getInterpolatedU(double var1); + + /** + * Returns the minimum V coordinate to use when rendering with this icon. + */ + float getMinV(); + + /** + * Returns the maximum V coordinate to use when rendering with this icon. + */ + float getMaxV(); + + /** + * Gets a V coordinate on the icon. 0 returns vMin and 16 returns vMax. Other + * arguments return in-between values. + */ + float getInterpolatedV(double var1); + + String getIconName(); + + /** + * Returns the width of the texture sheet this icon is on, in pixels. + */ + int getSheetWidth(); + + /** + * Returns the height of the texture sheet this icon is on, in pixels. + */ + int getSheetHeight(); +} diff --git a/src/main/java/net/minecraft/src/IconFlipped.java b/src/main/java/net/minecraft/src/IconFlipped.java new file mode 100644 index 0000000..a81ecf4 --- /dev/null +++ b/src/main/java/net/minecraft/src/IconFlipped.java @@ -0,0 +1,91 @@ +package net.minecraft.src; + +public class IconFlipped implements Icon { + private final Icon baseIcon; + private final boolean flipU; + private final boolean flipV; + + public IconFlipped(Icon par1Icon, boolean par2, boolean par3) { + this.baseIcon = par1Icon; + this.flipU = par2; + this.flipV = par3; + } + + /** + * Returns the X position of this icon on its texture sheet, in pixels. + */ + public int getOriginX() { + return this.baseIcon.getOriginX(); + } + + /** + * Returns the Y position of this icon on its texture sheet, in pixels. + */ + public int getOriginY() { + return this.baseIcon.getOriginY(); + } + + /** + * Returns the minimum U coordinate to use when rendering with this icon. + */ + public float getMinU() { + return this.flipU ? this.baseIcon.getMaxU() : this.baseIcon.getMinU(); + } + + /** + * Returns the maximum U coordinate to use when rendering with this icon. + */ + public float getMaxU() { + return this.flipU ? this.baseIcon.getMinU() : this.baseIcon.getMaxU(); + } + + /** + * Gets a U coordinate on the icon. 0 returns uMin and 16 returns uMax. Other + * arguments return in-between values. + */ + public float getInterpolatedU(double par1) { + float var3 = this.getMaxU() - this.getMinU(); + return this.getMinU() + var3 * ((float) par1 / 16.0F); + } + + /** + * Returns the minimum V coordinate to use when rendering with this icon. + */ + public float getMinV() { + return this.flipV ? this.baseIcon.getMinV() : this.baseIcon.getMinV(); + } + + /** + * Returns the maximum V coordinate to use when rendering with this icon. + */ + public float getMaxV() { + return this.flipV ? this.baseIcon.getMinV() : this.baseIcon.getMaxV(); + } + + /** + * Gets a V coordinate on the icon. 0 returns vMin and 16 returns vMax. Other + * arguments return in-between values. + */ + public float getInterpolatedV(double par1) { + float var3 = this.getMaxV() - this.getMinV(); + return this.getMinV() + var3 * ((float) par1 / 16.0F); + } + + public String getIconName() { + return this.baseIcon.getIconName(); + } + + /** + * Returns the width of the texture sheet this icon is on, in pixels. + */ + public int getSheetWidth() { + return this.baseIcon.getSheetWidth(); + } + + /** + * Returns the height of the texture sheet this icon is on, in pixels. + */ + public int getSheetHeight() { + return this.baseIcon.getSheetHeight(); + } +} diff --git a/src/main/java/net/minecraft/src/IconRegister.java b/src/main/java/net/minecraft/src/IconRegister.java new file mode 100644 index 0000000..ee530c2 --- /dev/null +++ b/src/main/java/net/minecraft/src/IconRegister.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public interface IconRegister { + Icon registerIcon(String var1); +} diff --git a/src/main/java/net/minecraft/src/IntHashMap.java b/src/main/java/net/minecraft/src/IntHashMap.java new file mode 100644 index 0000000..a859836 --- /dev/null +++ b/src/main/java/net/minecraft/src/IntHashMap.java @@ -0,0 +1,218 @@ +package net.minecraft.src; + +import java.util.HashSet; +import java.util.Set; + +public class IntHashMap { + /** An array of HashEntries representing the heads of hash slot lists */ + private transient IntHashMapEntry[] slots = new IntHashMapEntry[16]; + + /** The number of items stored in this map */ + private transient int count; + + /** The grow threshold */ + private int threshold = 12; + + /** The scale factor used to determine when to grow the table */ + private final float growFactor = 0.75F; + + /** A serial stamp used to mark changes */ + private transient volatile int versionStamp; + + /** The set of all the keys stored in this MCHash object */ + private Set keySet = new HashSet(); + + /** + * Makes the passed in integer suitable for hashing by a number of shifts + */ + private static int computeHash(int par0) { + par0 ^= par0 >>> 20 ^ par0 >>> 12; + return par0 ^ par0 >>> 7 ^ par0 >>> 4; + } + + /** + * Computes the index of the slot for the hash and slot count passed in. + */ + private static int getSlotIndex(int par0, int par1) { + return par0 & par1 - 1; + } + + /** + * Returns the object associated to a key + */ + public Object lookup(int par1) { + int var2 = computeHash(par1); + + for (IntHashMapEntry var3 = this.slots[getSlotIndex(var2, this.slots.length)]; var3 != null; var3 = var3.nextEntry) { + if (var3.hashEntry == par1) { + return var3.valueEntry; + } + } + + return null; + } + + /** + * Return true if an object is associated with the given key + */ + public boolean containsItem(int par1) { + return this.lookupEntry(par1) != null; + } + + /** + * Returns the key/object mapping for a given key as a MCHashEntry + */ + final IntHashMapEntry lookupEntry(int par1) { + int var2 = computeHash(par1); + + for (IntHashMapEntry var3 = this.slots[getSlotIndex(var2, this.slots.length)]; var3 != null; var3 = var3.nextEntry) { + if (var3.hashEntry == par1) { + return var3; + } + } + + return null; + } + + /** + * Adds a key and associated value to this map + */ + public void addKey(int par1, Object par2Obj) { + this.keySet.add(Integer.valueOf(par1)); + int var3 = computeHash(par1); + int var4 = getSlotIndex(var3, this.slots.length); + + for (IntHashMapEntry var5 = this.slots[var4]; var5 != null; var5 = var5.nextEntry) { + if (var5.hashEntry == par1) { + var5.valueEntry = par2Obj; + return; + } + } + + ++this.versionStamp; + this.insert(var3, par1, par2Obj, var4); + } + + /** + * Increases the number of hash slots + */ + private void grow(int par1) { + IntHashMapEntry[] var2 = this.slots; + int var3 = var2.length; + + if (var3 == 1073741824) { + this.threshold = Integer.MAX_VALUE; + } else { + IntHashMapEntry[] var4 = new IntHashMapEntry[par1]; + this.copyTo(var4); + this.slots = var4; + this.threshold = (int) ((float) par1 * this.growFactor); + } + } + + /** + * Copies the hash slots to a new array + */ + private void copyTo(IntHashMapEntry[] par1ArrayOfIntHashMapEntry) { + IntHashMapEntry[] var2 = this.slots; + int var3 = par1ArrayOfIntHashMapEntry.length; + + for (int var4 = 0; var4 < var2.length; ++var4) { + IntHashMapEntry var5 = var2[var4]; + + if (var5 != null) { + var2[var4] = null; + IntHashMapEntry var6; + + do { + var6 = var5.nextEntry; + int var7 = getSlotIndex(var5.slotHash, var3); + var5.nextEntry = par1ArrayOfIntHashMapEntry[var7]; + par1ArrayOfIntHashMapEntry[var7] = var5; + var5 = var6; + } while (var6 != null); + } + } + } + + /** + * Removes the specified object from the map and returns it + */ + public Object removeObject(int par1) { + this.keySet.remove(Integer.valueOf(par1)); + IntHashMapEntry var2 = this.removeEntry(par1); + return var2 == null ? null : var2.valueEntry; + } + + /** + * Removes the specified entry from the map and returns it + */ + final IntHashMapEntry removeEntry(int par1) { + int var2 = computeHash(par1); + int var3 = getSlotIndex(var2, this.slots.length); + IntHashMapEntry var4 = this.slots[var3]; + IntHashMapEntry var5; + IntHashMapEntry var6; + + for (var5 = var4; var5 != null; var5 = var6) { + var6 = var5.nextEntry; + + if (var5.hashEntry == par1) { + ++this.versionStamp; + --this.count; + + if (var4 == var5) { + this.slots[var3] = var6; + } else { + var4.nextEntry = var6; + } + + return var5; + } + + var4 = var5; + } + + return var5; + } + + /** + * Removes all entries from the map + */ + public void clearMap() { + ++this.versionStamp; + IntHashMapEntry[] var1 = this.slots; + + for (int var2 = 0; var2 < var1.length; ++var2) { + var1[var2] = null; + } + + this.count = 0; + } + + /** + * Adds an object to a slot + */ + private void insert(int par1, int par2, Object par3Obj, int par4) { + IntHashMapEntry var5 = this.slots[par4]; + this.slots[par4] = new IntHashMapEntry(par1, par2, par3Obj, var5); + + if (this.count++ >= this.threshold) { + this.grow(2 * this.slots.length); + } + } + + /** + * Return the Set of all keys stored in this MCHash object + */ + public Set getKeySet() { + return this.keySet; + } + + /** + * Returns the hash code for a key + */ + static int getHash(int par0) { + return computeHash(par0); + } +} diff --git a/src/main/java/net/minecraft/src/IntHashMapEntry.java b/src/main/java/net/minecraft/src/IntHashMapEntry.java new file mode 100644 index 0000000..9a4831d --- /dev/null +++ b/src/main/java/net/minecraft/src/IntHashMapEntry.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +class IntHashMapEntry { + /** The hash code of this entry */ + final int hashEntry; + + /** The object stored in this entry */ + Object valueEntry; + + /** The next entry in this slot */ + IntHashMapEntry nextEntry; + + /** The id of the hash slot computed from the hash */ + final int slotHash; + + IntHashMapEntry(int par1, int par2, Object par3Obj, IntHashMapEntry par4IntHashMapEntry) { + this.valueEntry = par3Obj; + this.nextEntry = par4IntHashMapEntry; + this.hashEntry = par2; + this.slotHash = par1; + } + + /** + * Returns the hash code for this entry + */ + public final int getHash() { + return this.hashEntry; + } + + /** + * Returns the object stored in this entry + */ + public final Object getValue() { + return this.valueEntry; + } + + public final boolean equals(Object par1Obj) { + if (!(par1Obj instanceof IntHashMapEntry)) { + return false; + } else { + IntHashMapEntry var2 = (IntHashMapEntry) par1Obj; + Integer var3 = Integer.valueOf(this.getHash()); + Integer var4 = Integer.valueOf(var2.getHash()); + + if (var3 == var4 || var3 != null && var3.equals(var4)) { + Object var5 = this.getValue(); + Object var6 = var2.getValue(); + + if (var5 == var6 || var5 != null && var5.equals(var6)) { + return true; + } + } + + return false; + } + } + + public final int hashCode() { + return IntHashMap.getHash(this.hashEntry); + } + + public final String toString() { + return this.getHash() + "=" + this.getValue(); + } +} diff --git a/src/main/java/net/minecraft/src/InventoryBasic.java b/src/main/java/net/minecraft/src/InventoryBasic.java new file mode 100644 index 0000000..610365c --- /dev/null +++ b/src/main/java/net/minecraft/src/InventoryBasic.java @@ -0,0 +1,145 @@ +package net.minecraft.src; + +import java.util.List; + +public class InventoryBasic implements IInventory { + private String inventoryTitle; + private int slotsCount; + private ItemStack[] inventoryContents; + private List field_70480_d; + private boolean field_94051_e; + + public InventoryBasic(String par1Str, boolean par2, int par3) { + this.inventoryTitle = par1Str; + this.field_94051_e = par2; + this.slotsCount = par3; + this.inventoryContents = new ItemStack[par3]; + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return this.inventoryContents[par1]; + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (this.inventoryContents[par1] != null) { + ItemStack var3; + + if (this.inventoryContents[par1].stackSize <= par2) { + var3 = this.inventoryContents[par1]; + this.inventoryContents[par1] = null; + this.onInventoryChanged(); + return var3; + } else { + var3 = this.inventoryContents[par1].splitStack(par2); + + if (this.inventoryContents[par1].stackSize == 0) { + this.inventoryContents[par1] = null; + } + + this.onInventoryChanged(); + return var3; + } + } else { + return null; + } + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (this.inventoryContents[par1] != null) { + ItemStack var2 = this.inventoryContents[par1]; + this.inventoryContents[par1] = null; + return var2; + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + this.inventoryContents[par1] = par2ItemStack; + + if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) { + par2ItemStack.stackSize = this.getInventoryStackLimit(); + } + + this.onInventoryChanged(); + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return this.slotsCount; + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return this.inventoryTitle; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return this.field_94051_e; + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + if (this.field_70480_d != null) { + for (int var1 = 0; var1 < this.field_70480_d.size(); ++var1) { + ((IInvBasic) this.field_70480_d.get(var1)).onInventoryChanged(this); + } + } + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return true; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/InventoryCraftResult.java b/src/main/java/net/minecraft/src/InventoryCraftResult.java new file mode 100644 index 0000000..930b4c1 --- /dev/null +++ b/src/main/java/net/minecraft/src/InventoryCraftResult.java @@ -0,0 +1,108 @@ +package net.minecraft.src; + +public class InventoryCraftResult implements IInventory { + /** A list of one item containing the result of the crafting formula */ + private ItemStack[] stackResult = new ItemStack[1]; + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return 1; + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return this.stackResult[0]; + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return "Result"; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return false; + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (this.stackResult[0] != null) { + ItemStack var3 = this.stackResult[0]; + this.stackResult[0] = null; + return var3; + } else { + return null; + } + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (this.stackResult[0] != null) { + ItemStack var2 = this.stackResult[0]; + this.stackResult[0] = null; + return var2; + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + this.stackResult[0] = par2ItemStack; + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return true; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/InventoryCrafting.java b/src/main/java/net/minecraft/src/InventoryCrafting.java new file mode 100644 index 0000000..7a7a54f --- /dev/null +++ b/src/main/java/net/minecraft/src/InventoryCrafting.java @@ -0,0 +1,152 @@ +package net.minecraft.src; + +public class InventoryCrafting implements IInventory { + /** List of the stacks in the crafting matrix. */ + private ItemStack[] stackList; + + /** the width of the crafting inventory */ + private int inventoryWidth; + + /** + * Class containing the callbacks for the events on_GUIClosed and + * on_CraftMaxtrixChanged. + */ + private Container eventHandler; + + public InventoryCrafting(Container par1Container, int par2, int par3) { + int var4 = par2 * par3; + this.stackList = new ItemStack[var4]; + this.eventHandler = par1Container; + this.inventoryWidth = par2; + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return this.stackList.length; + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return par1 >= this.getSizeInventory() ? null : this.stackList[par1]; + } + + /** + * Returns the itemstack in the slot specified (Top left is 0, 0). Args: row, + * column + */ + public ItemStack getStackInRowAndColumn(int par1, int par2) { + if (par1 >= 0 && par1 < this.inventoryWidth) { + int var3 = par1 + par2 * this.inventoryWidth; + return this.getStackInSlot(var3); + } else { + return null; + } + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return "container.crafting"; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return false; + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (this.stackList[par1] != null) { + ItemStack var2 = this.stackList[par1]; + this.stackList[par1] = null; + return var2; + } else { + return null; + } + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (this.stackList[par1] != null) { + ItemStack var3; + + if (this.stackList[par1].stackSize <= par2) { + var3 = this.stackList[par1]; + this.stackList[par1] = null; + this.eventHandler.onCraftMatrixChanged(this); + return var3; + } else { + var3 = this.stackList[par1].splitStack(par2); + + if (this.stackList[par1].stackSize == 0) { + this.stackList[par1] = null; + } + + this.eventHandler.onCraftMatrixChanged(this); + return var3; + } + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + this.stackList[par1] = par2ItemStack; + this.eventHandler.onCraftMatrixChanged(this); + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return true; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/InventoryEffectRenderer.java b/src/main/java/net/minecraft/src/InventoryEffectRenderer.java new file mode 100644 index 0000000..633daf2 --- /dev/null +++ b/src/main/java/net/minecraft/src/InventoryEffectRenderer.java @@ -0,0 +1,86 @@ +package net.minecraft.src; + +import java.util.Collection; +import java.util.Iterator; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public abstract class InventoryEffectRenderer extends GuiContainer { + private boolean field_74222_o; + + public InventoryEffectRenderer(Container par1Container) { + super(par1Container); + } + + /** + * Adds the buttons (and other controls) to the screen in question. + */ + public void initGui() { + super.initGui(); + + if (!this.mc.thePlayer.getActivePotionEffects().isEmpty()) { + this.guiLeft = 160 + (this.width - this.xSize - 200) / 2; + this.field_74222_o = true; + } + } + + /** + * Draws the screen and all the components in it. + */ + public void drawScreen(int par1, int par2, float par3) { + super.drawScreen(par1, par2, par3); + + if (this.field_74222_o) { + this.displayDebuffEffects(); + } + } + + private static final TextureLocation tex_inventory = new TextureLocation("/gui/inventory.png"); + + /** + * Displays debuff/potion effects that are currently being applied to the player + */ + private void displayDebuffEffects() { + int var1 = this.guiLeft - 124; + int var2 = this.guiTop; + Collection var4 = this.mc.thePlayer.getActivePotionEffects(); + + if (!var4.isEmpty()) { + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + int var5 = 33; + + if (var4.size() > 5) { + var5 = 132 / (var4.size() - 1); + } + + for (Iterator var6 = this.mc.thePlayer.getActivePotionEffects().iterator(); var6.hasNext(); var2 += var5) { + PotionEffect var7 = (PotionEffect) var6.next(); + Potion var8 = Potion.potionTypes[var7.getPotionID()]; + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tex_inventory.bindTexture(); + this.drawTexturedModalRect(var1, var2, 0, 166, 140, 32); + + if (var8.hasStatusIcon()) { + int var9 = var8.getStatusIconIndex(); + this.drawTexturedModalRect(var1 + 6, var2 + 7, 0 + var9 % 8 * 18, 198 + var9 / 8 * 18, 18, 18); + } + + String var11 = StatCollector.translateToLocal(var8.getName()); + + if (var7.getAmplifier() == 1) { + var11 = var11 + " II"; + } else if (var7.getAmplifier() == 2) { + var11 = var11 + " III"; + } else if (var7.getAmplifier() == 3) { + var11 = var11 + " IV"; + } + + this.fontRenderer.drawStringWithShadow(var11, var1 + 10 + 18, var2 + 6, 16777215); + String var10 = Potion.getDurationString(var7); + this.fontRenderer.drawStringWithShadow(var10, var1 + 10 + 18, var2 + 6 + 10, 8355711); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/InventoryEnderChest.java b/src/main/java/net/minecraft/src/InventoryEnderChest.java new file mode 100644 index 0000000..f262574 --- /dev/null +++ b/src/main/java/net/minecraft/src/InventoryEnderChest.java @@ -0,0 +1,80 @@ +package net.minecraft.src; + +public class InventoryEnderChest extends InventoryBasic { + private TileEntityEnderChest associatedChest; + + public InventoryEnderChest() { + super("container.enderchest", false, 27); + } + + public void setAssociatedChest(TileEntityEnderChest par1TileEntityEnderChest) { + this.associatedChest = par1TileEntityEnderChest; + } + + public void loadInventoryFromNBT(NBTTagList par1NBTTagList) { + int var2; + + for (var2 = 0; var2 < this.getSizeInventory(); ++var2) { + this.setInventorySlotContents(var2, (ItemStack) null); + } + + for (var2 = 0; var2 < par1NBTTagList.tagCount(); ++var2) { + NBTTagCompound var3 = (NBTTagCompound) par1NBTTagList.tagAt(var2); + int var4 = var3.getByte("Slot") & 255; + + if (var4 >= 0 && var4 < this.getSizeInventory()) { + this.setInventorySlotContents(var4, ItemStack.loadItemStackFromNBT(var3)); + } + } + } + + public NBTTagList saveInventoryToNBT() { + NBTTagList var1 = new NBTTagList("EnderItems"); + + for (int var2 = 0; var2 < this.getSizeInventory(); ++var2) { + ItemStack var3 = this.getStackInSlot(var2); + + if (var3 != null) { + NBTTagCompound var4 = new NBTTagCompound(); + var4.setByte("Slot", (byte) var2); + var3.writeToNBT(var4); + var1.appendTag(var4); + } + } + + return var1; + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.associatedChest != null && !this.associatedChest.isUseableByPlayer(par1EntityPlayer) ? false : super.isUseableByPlayer(par1EntityPlayer); + } + + public void openChest() { + if (this.associatedChest != null) { + this.associatedChest.openChest(); + } + + super.openChest(); + } + + public void closeChest() { + if (this.associatedChest != null) { + this.associatedChest.closeChest(); + } + + super.closeChest(); + this.associatedChest = null; + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/InventoryLargeChest.java b/src/main/java/net/minecraft/src/InventoryLargeChest.java new file mode 100644 index 0000000..857e8b6 --- /dev/null +++ b/src/main/java/net/minecraft/src/InventoryLargeChest.java @@ -0,0 +1,134 @@ +package net.minecraft.src; + +public class InventoryLargeChest implements IInventory { + /** Name of the chest. */ + private String name; + + /** Inventory object corresponding to double chest upper part */ + private IInventory upperChest; + + /** Inventory object corresponding to double chest lower part */ + private IInventory lowerChest; + + public InventoryLargeChest(String par1Str, IInventory par2IInventory, IInventory par3IInventory) { + this.name = par1Str; + + if (par2IInventory == null) { + par2IInventory = par3IInventory; + } + + if (par3IInventory == null) { + par3IInventory = par2IInventory; + } + + this.upperChest = par2IInventory; + this.lowerChest = par3IInventory; + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return this.upperChest.getSizeInventory() + this.lowerChest.getSizeInventory(); + } + + /** + * Return whether the given inventory is part of this large chest. + */ + public boolean isPartOfLargeChest(IInventory par1IInventory) { + return this.upperChest == par1IInventory || this.lowerChest == par1IInventory; + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return this.upperChest.isInvNameLocalized() ? this.upperChest.getInvName() : (this.lowerChest.isInvNameLocalized() ? this.lowerChest.getInvName() : this.name); + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return this.upperChest.isInvNameLocalized() || this.lowerChest.isInvNameLocalized(); + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return par1 >= this.upperChest.getSizeInventory() ? this.lowerChest.getStackInSlot(par1 - this.upperChest.getSizeInventory()) : this.upperChest.getStackInSlot(par1); + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + return par1 >= this.upperChest.getSizeInventory() ? this.lowerChest.decrStackSize(par1 - this.upperChest.getSizeInventory(), par2) : this.upperChest.decrStackSize(par1, par2); + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + return par1 >= this.upperChest.getSizeInventory() ? this.lowerChest.getStackInSlotOnClosing(par1 - this.upperChest.getSizeInventory()) : this.upperChest.getStackInSlotOnClosing(par1); + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + if (par1 >= this.upperChest.getSizeInventory()) { + this.lowerChest.setInventorySlotContents(par1 - this.upperChest.getSizeInventory(), par2ItemStack); + } else { + this.upperChest.setInventorySlotContents(par1, par2ItemStack); + } + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return this.upperChest.getInventoryStackLimit(); + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + this.upperChest.onInventoryChanged(); + this.lowerChest.onInventoryChanged(); + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.upperChest.isUseableByPlayer(par1EntityPlayer) && this.lowerChest.isUseableByPlayer(par1EntityPlayer); + } + + public void openChest() { + this.upperChest.openChest(); + this.lowerChest.openChest(); + } + + public void closeChest() { + this.upperChest.closeChest(); + this.lowerChest.closeChest(); + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/InventoryMerchant.java b/src/main/java/net/minecraft/src/InventoryMerchant.java new file mode 100644 index 0000000..b6193b2 --- /dev/null +++ b/src/main/java/net/minecraft/src/InventoryMerchant.java @@ -0,0 +1,203 @@ +package net.minecraft.src; + +public class InventoryMerchant implements IInventory { + private final IMerchant theMerchant; + private ItemStack[] theInventory = new ItemStack[3]; + private final EntityPlayer thePlayer; + private MerchantRecipe currentRecipe; + private int currentRecipeIndex; + + public InventoryMerchant(EntityPlayer par1EntityPlayer, IMerchant par2IMerchant) { + this.thePlayer = par1EntityPlayer; + this.theMerchant = par2IMerchant; + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return this.theInventory.length; + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return this.theInventory[par1]; + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (this.theInventory[par1] != null) { + ItemStack var3; + + if (par1 == 2) { + var3 = this.theInventory[par1]; + this.theInventory[par1] = null; + return var3; + } else if (this.theInventory[par1].stackSize <= par2) { + var3 = this.theInventory[par1]; + this.theInventory[par1] = null; + + if (this.inventoryResetNeededOnSlotChange(par1)) { + this.resetRecipeAndSlots(); + } + + return var3; + } else { + var3 = this.theInventory[par1].splitStack(par2); + + if (this.theInventory[par1].stackSize == 0) { + this.theInventory[par1] = null; + } + + if (this.inventoryResetNeededOnSlotChange(par1)) { + this.resetRecipeAndSlots(); + } + + return var3; + } + } else { + return null; + } + } + + /** + * if par1 slot has changed, does resetRecipeAndSlots need to be called? + */ + private boolean inventoryResetNeededOnSlotChange(int par1) { + return par1 == 0 || par1 == 1; + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (this.theInventory[par1] != null) { + ItemStack var2 = this.theInventory[par1]; + this.theInventory[par1] = null; + return var2; + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + this.theInventory[par1] = par2ItemStack; + + if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) { + par2ItemStack.stackSize = this.getInventoryStackLimit(); + } + + if (this.inventoryResetNeededOnSlotChange(par1)) { + this.resetRecipeAndSlots(); + } + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return "mob.villager"; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return false; + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.theMerchant.getCustomer() == par1EntityPlayer; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + this.resetRecipeAndSlots(); + } + + public void resetRecipeAndSlots() { + this.currentRecipe = null; + ItemStack var1 = this.theInventory[0]; + ItemStack var2 = this.theInventory[1]; + + if (var1 == null) { + var1 = var2; + var2 = null; + } + + if (var1 == null) { + this.setInventorySlotContents(2, (ItemStack) null); + } else { + MerchantRecipeList var3 = this.theMerchant.getRecipes(this.thePlayer); + + if (var3 != null) { + MerchantRecipe var4 = var3.canRecipeBeUsed(var1, var2, this.currentRecipeIndex); + + if (var4 != null && !var4.func_82784_g()) { + this.currentRecipe = var4; + this.setInventorySlotContents(2, var4.getItemToSell().copy()); + } else if (var2 != null) { + var4 = var3.canRecipeBeUsed(var2, var1, this.currentRecipeIndex); + + if (var4 != null && !var4.func_82784_g()) { + this.currentRecipe = var4; + this.setInventorySlotContents(2, var4.getItemToSell().copy()); + } else { + this.setInventorySlotContents(2, (ItemStack) null); + } + } else { + this.setInventorySlotContents(2, (ItemStack) null); + } + } + } + } + + public MerchantRecipe getCurrentRecipe() { + return this.currentRecipe; + } + + public void setCurrentRecipeIndex(int par1) { + this.currentRecipeIndex = par1; + this.resetRecipeAndSlots(); + } +} diff --git a/src/main/java/net/minecraft/src/InventoryPlayer.java b/src/main/java/net/minecraft/src/InventoryPlayer.java new file mode 100644 index 0000000..fa558f0 --- /dev/null +++ b/src/main/java/net/minecraft/src/InventoryPlayer.java @@ -0,0 +1,677 @@ +package net.minecraft.src; + +public class InventoryPlayer implements IInventory { + /** + * An array of 36 item stacks indicating the main player inventory (including + * the visible bar). + */ + public ItemStack[] mainInventory = new ItemStack[36]; + + /** An array of 4 item stacks containing the currently worn armor pieces. */ + public ItemStack[] armorInventory = new ItemStack[4]; + + /** The index of the currently held item (0-8). */ + public int currentItem = 0; + + /** The current ItemStack. */ + private ItemStack currentItemStack; + + /** The player whose inventory this is. */ + public EntityPlayer player; + private ItemStack itemStack; + + /** + * Set true whenever the inventory changes. Nothing sets it false so you will + * have to write your own code to check it and reset the value. + */ + public boolean inventoryChanged = false; + + public InventoryPlayer(EntityPlayer par1EntityPlayer) { + this.player = par1EntityPlayer; + } + + /** + * Returns the item stack currently held by the player. + */ + public ItemStack getCurrentItem() { + return this.currentItem < 9 && this.currentItem >= 0 ? this.mainInventory[this.currentItem] : null; + } + + /** + * Get the size of the player hotbar inventory + */ + public static int getHotbarSize() { + return 9; + } + + /** + * Returns a slot index in main inventory containing a specific itemID + */ + private int getInventorySlotContainItem(int par1) { + for (int var2 = 0; var2 < this.mainInventory.length; ++var2) { + if (this.mainInventory[var2] != null && this.mainInventory[var2].itemID == par1) { + return var2; + } + } + + return -1; + } + + private int getInventorySlotContainItemAndDamage(int par1, int par2) { + for (int var3 = 0; var3 < this.mainInventory.length; ++var3) { + if (this.mainInventory[var3] != null && this.mainInventory[var3].itemID == par1 && this.mainInventory[var3].getItemDamage() == par2) { + return var3; + } + } + + return -1; + } + + /** + * stores an itemstack in the users inventory + */ + private int storeItemStack(ItemStack par1ItemStack) { + for (int var2 = 0; var2 < this.mainInventory.length; ++var2) { + if (this.mainInventory[var2] != null && this.mainInventory[var2].itemID == par1ItemStack.itemID && this.mainInventory[var2].isStackable() && this.mainInventory[var2].stackSize < this.mainInventory[var2].getMaxStackSize() + && this.mainInventory[var2].stackSize < this.getInventoryStackLimit() && (!this.mainInventory[var2].getHasSubtypes() || this.mainInventory[var2].getItemDamage() == par1ItemStack.getItemDamage()) + && ItemStack.areItemStackTagsEqual(this.mainInventory[var2], par1ItemStack)) { + return var2; + } + } + + return -1; + } + + /** + * Returns the first item stack that is empty. + */ + public int getFirstEmptyStack() { + for (int var1 = 0; var1 < this.mainInventory.length; ++var1) { + if (this.mainInventory[var1] == null) { + return var1; + } + } + + return -1; + } + + /** + * Sets a specific itemID as the current item being held (only if it exists on + * the hotbar) + */ + public void setCurrentItem(int par1, int par2, boolean par3, boolean par4) { + boolean var5 = true; + this.currentItemStack = this.getCurrentItem(); + int var7; + + if (par3) { + var7 = this.getInventorySlotContainItemAndDamage(par1, par2); + } else { + var7 = this.getInventorySlotContainItem(par1); + } + + if (var7 >= 0 && var7 < 9) { + this.currentItem = var7; + } else { + if (par4 && par1 > 0) { + int var6 = this.getFirstEmptyStack(); + + if (var6 >= 0 && var6 < 9) { + this.currentItem = var6; + } + + this.func_70439_a(Item.itemsList[par1], par2); + } + } + } + + /** + * Switch the current item to the next one or the previous one + */ + public void changeCurrentItem(int par1) { + if (par1 > 0) { + par1 = 1; + } + + if (par1 < 0) { + par1 = -1; + } + + for (this.currentItem -= par1; this.currentItem < 0; this.currentItem += 9) { + ; + } + + while (this.currentItem >= 9) { + this.currentItem -= 9; + } + } + + /** + * Clear this player's inventory, using the specified ID and metadata as filters + * or -1 for no filter. + */ + public int clearInventory(int par1, int par2) { + int var3 = 0; + int var4; + ItemStack var5; + + for (var4 = 0; var4 < this.mainInventory.length; ++var4) { + var5 = this.mainInventory[var4]; + + if (var5 != null && (par1 <= -1 || var5.itemID == par1) && (par2 <= -1 || var5.getItemDamage() == par2)) { + var3 += var5.stackSize; + this.mainInventory[var4] = null; + } + } + + for (var4 = 0; var4 < this.armorInventory.length; ++var4) { + var5 = this.armorInventory[var4]; + + if (var5 != null && (par1 <= -1 || var5.itemID == par1) && (par2 <= -1 || var5.getItemDamage() == par2)) { + var3 += var5.stackSize; + this.armorInventory[var4] = null; + } + } + + return var3; + } + + public void func_70439_a(Item par1Item, int par2) { + if (par1Item != null) { + int var3 = this.getInventorySlotContainItemAndDamage(par1Item.itemID, par2); + + if (var3 >= 0) { + this.mainInventory[var3] = this.mainInventory[this.currentItem]; + } + + if (this.currentItemStack != null && this.currentItemStack.isItemEnchantable() && this.getInventorySlotContainItemAndDamage(this.currentItemStack.itemID, this.currentItemStack.getItemDamageForDisplay()) == this.currentItem) { + return; + } + + this.mainInventory[this.currentItem] = new ItemStack(Item.itemsList[par1Item.itemID], 1, par2); + } + } + + /** + * This function stores as many items of an ItemStack as possible in a matching + * slot and returns the quantity of left over items. + */ + private int storePartialItemStack(ItemStack par1ItemStack) { + int var2 = par1ItemStack.itemID; + int var3 = par1ItemStack.stackSize; + int var4; + + if (par1ItemStack.getMaxStackSize() == 1) { + var4 = this.getFirstEmptyStack(); + + if (var4 < 0) { + return var3; + } else { + if (this.mainInventory[var4] == null) { + this.mainInventory[var4] = ItemStack.copyItemStack(par1ItemStack); + } + + return 0; + } + } else { + var4 = this.storeItemStack(par1ItemStack); + + if (var4 < 0) { + var4 = this.getFirstEmptyStack(); + } + + if (var4 < 0) { + return var3; + } else { + if (this.mainInventory[var4] == null) { + this.mainInventory[var4] = new ItemStack(var2, 0, par1ItemStack.getItemDamage()); + + if (par1ItemStack.hasTagCompound()) { + this.mainInventory[var4].setTagCompound((NBTTagCompound) par1ItemStack.getTagCompound().copy()); + } + } + + int var5 = var3; + + if (var3 > this.mainInventory[var4].getMaxStackSize() - this.mainInventory[var4].stackSize) { + var5 = this.mainInventory[var4].getMaxStackSize() - this.mainInventory[var4].stackSize; + } + + if (var5 > this.getInventoryStackLimit() - this.mainInventory[var4].stackSize) { + var5 = this.getInventoryStackLimit() - this.mainInventory[var4].stackSize; + } + + if (var5 == 0) { + return var3; + } else { + var3 -= var5; + this.mainInventory[var4].stackSize += var5; + this.mainInventory[var4].animationsToGo = 5; + return var3; + } + } + } + } + + /** + * Decrement the number of animations remaining. Only called on client side. + * This is used to handle the animation of receiving a block. + */ + public void decrementAnimations() { + for (int var1 = 0; var1 < this.mainInventory.length; ++var1) { + if (this.mainInventory[var1] != null) { + this.mainInventory[var1].updateAnimation(this.player.worldObj, this.player, var1, this.currentItem == var1); + } + } + } + + /** + * removed one item of specified itemID from inventory (if it is in a stack, the + * stack size will reduce with 1) + */ + public boolean consumeInventoryItem(int par1) { + int var2 = this.getInventorySlotContainItem(par1); + + if (var2 < 0) { + return false; + } else { + if (--this.mainInventory[var2].stackSize <= 0) { + this.mainInventory[var2] = null; + } + + return true; + } + } + + /** + * Get if a specifiied item id is inside the inventory. + */ + public boolean hasItem(int par1) { + int var2 = this.getInventorySlotContainItem(par1); + return var2 >= 0; + } + + /** + * Adds the item stack to the inventory, returns false if it is impossible. + */ + public boolean addItemStackToInventory(ItemStack par1ItemStack) { + if (par1ItemStack == null) { + return false; + } else { + int var2; + + if (par1ItemStack.isItemDamaged()) { + var2 = this.getFirstEmptyStack(); + + if (var2 >= 0) { + this.mainInventory[var2] = ItemStack.copyItemStack(par1ItemStack); + this.mainInventory[var2].animationsToGo = 5; + par1ItemStack.stackSize = 0; + return true; + } else if (this.player.capabilities.isCreativeMode) { + par1ItemStack.stackSize = 0; + return true; + } else { + return false; + } + } else { + do { + var2 = par1ItemStack.stackSize; + par1ItemStack.stackSize = this.storePartialItemStack(par1ItemStack); + } while (par1ItemStack.stackSize > 0 && par1ItemStack.stackSize < var2); + + if (par1ItemStack.stackSize == var2 && this.player.capabilities.isCreativeMode) { + par1ItemStack.stackSize = 0; + return true; + } else { + return par1ItemStack.stackSize < var2; + } + } + } + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + ItemStack[] var3 = this.mainInventory; + + if (par1 >= this.mainInventory.length) { + var3 = this.armorInventory; + par1 -= this.mainInventory.length; + } + + if (var3[par1] != null) { + ItemStack var4; + + if (var3[par1].stackSize <= par2) { + var4 = var3[par1]; + var3[par1] = null; + return var4; + } else { + var4 = var3[par1].splitStack(par2); + + if (var3[par1].stackSize == 0) { + var3[par1] = null; + } + + return var4; + } + } else { + return null; + } + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + ItemStack[] var2 = this.mainInventory; + + if (par1 >= this.mainInventory.length) { + var2 = this.armorInventory; + par1 -= this.mainInventory.length; + } + + if (var2[par1] != null) { + ItemStack var3 = var2[par1]; + var2[par1] = null; + return var3; + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + ItemStack[] var3 = this.mainInventory; + + if (par1 >= var3.length) { + par1 -= var3.length; + var3 = this.armorInventory; + } + + var3[par1] = par2ItemStack; + } + + /** + * Gets the strength of the current item (tool) against the specified block, + * 1.0f if not holding anything. + */ + public float getStrVsBlock(Block par1Block) { + float var2 = 1.0F; + + if (this.mainInventory[this.currentItem] != null) { + var2 *= this.mainInventory[this.currentItem].getStrVsBlock(par1Block); + } + + return var2; + } + + /** + * Writes the inventory out as a list of compound tags. This is where the slot + * indices are used (+100 for armor, +80 for crafting). + */ + public NBTTagList writeToNBT(NBTTagList par1NBTTagList) { + int var2; + NBTTagCompound var3; + + for (var2 = 0; var2 < this.mainInventory.length; ++var2) { + if (this.mainInventory[var2] != null) { + var3 = new NBTTagCompound(); + var3.setByte("Slot", (byte) var2); + this.mainInventory[var2].writeToNBT(var3); + par1NBTTagList.appendTag(var3); + } + } + + for (var2 = 0; var2 < this.armorInventory.length; ++var2) { + if (this.armorInventory[var2] != null) { + var3 = new NBTTagCompound(); + var3.setByte("Slot", (byte) (var2 + 100)); + this.armorInventory[var2].writeToNBT(var3); + par1NBTTagList.appendTag(var3); + } + } + + return par1NBTTagList; + } + + /** + * Reads from the given tag list and fills the slots in the inventory with the + * correct items. + */ + public void readFromNBT(NBTTagList par1NBTTagList) { + this.mainInventory = new ItemStack[36]; + this.armorInventory = new ItemStack[4]; + + for (int var2 = 0; var2 < par1NBTTagList.tagCount(); ++var2) { + NBTTagCompound var3 = (NBTTagCompound) par1NBTTagList.tagAt(var2); + int var4 = var3.getByte("Slot") & 255; + ItemStack var5 = ItemStack.loadItemStackFromNBT(var3); + + if (var5 != null) { + if (var4 >= 0 && var4 < this.mainInventory.length) { + this.mainInventory[var4] = var5; + } + + if (var4 >= 100 && var4 < this.armorInventory.length + 100) { + this.armorInventory[var4 - 100] = var5; + } + } + } + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return this.mainInventory.length + 4; + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + ItemStack[] var2 = this.mainInventory; + + if (par1 >= var2.length) { + par1 -= var2.length; + var2 = this.armorInventory; + } + + return var2[par1]; + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return "container.inventory"; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return false; + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Return damage vs an entity done by the current held weapon, or 1 if nothing + * is held + */ + public int getDamageVsEntity(Entity par1Entity) { + ItemStack var2 = this.getStackInSlot(this.currentItem); + return var2 != null ? var2.getDamageVsEntity(par1Entity) : 1; + } + + /** + * Returns whether the current item (tool) can harvest from the specified block + * (actually get a result). + */ + public boolean canHarvestBlock(Block par1Block) { + if (par1Block.blockMaterial.isToolNotRequired()) { + return true; + } else { + ItemStack var2 = this.getStackInSlot(this.currentItem); + return var2 != null ? var2.canHarvestBlock(par1Block) : false; + } + } + + /** + * returns a player armor item (as itemstack) contained in specified armor slot. + */ + public ItemStack armorItemInSlot(int par1) { + return this.armorInventory[par1]; + } + + /** + * Based on the damage values and maximum damage values of each armor item, + * returns the current armor value. + */ + public int getTotalArmorValue() { + int var1 = 0; + + for (int var2 = 0; var2 < this.armorInventory.length; ++var2) { + if (this.armorInventory[var2] != null && this.armorInventory[var2].getItem() instanceof ItemArmor) { + int var3 = ((ItemArmor) this.armorInventory[var2].getItem()).damageReduceAmount; + var1 += var3; + } + } + + return var1; + } + + /** + * Damages armor in each slot by the specified amount. + */ + public void damageArmor(int par1) { + par1 /= 4; + + if (par1 < 1) { + par1 = 1; + } + + for (int var2 = 0; var2 < this.armorInventory.length; ++var2) { + if (this.armorInventory[var2] != null && this.armorInventory[var2].getItem() instanceof ItemArmor) { + this.armorInventory[var2].damageItem(par1, this.player); + + if (this.armorInventory[var2].stackSize == 0) { + this.armorInventory[var2] = null; + } + } + } + } + + /** + * Drop all armor and main inventory items. + */ + public void dropAllItems() { + int var1; + + for (var1 = 0; var1 < this.mainInventory.length; ++var1) { + if (this.mainInventory[var1] != null) { + this.player.dropPlayerItemWithRandomChoice(this.mainInventory[var1], true); + this.mainInventory[var1] = null; + } + } + + for (var1 = 0; var1 < this.armorInventory.length; ++var1) { + if (this.armorInventory[var1] != null) { + this.player.dropPlayerItemWithRandomChoice(this.armorInventory[var1], true); + this.armorInventory[var1] = null; + } + } + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + this.inventoryChanged = true; + } + + public void setItemStack(ItemStack par1ItemStack) { + this.itemStack = par1ItemStack; + } + + public ItemStack getItemStack() { + return this.itemStack; + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.player.isDead ? false : par1EntityPlayer.getDistanceSqToEntity(this.player) <= 64.0D; + } + + /** + * Returns true if the specified ItemStack exists in the inventory. + */ + public boolean hasItemStack(ItemStack par1ItemStack) { + int var2; + + for (var2 = 0; var2 < this.armorInventory.length; ++var2) { + if (this.armorInventory[var2] != null && this.armorInventory[var2].isItemEqual(par1ItemStack)) { + return true; + } + } + + for (var2 = 0; var2 < this.mainInventory.length; ++var2) { + if (this.mainInventory[var2] != null && this.mainInventory[var2].isItemEqual(par1ItemStack)) { + return true; + } + } + + return false; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } + + /** + * Copy the ItemStack contents from another InventoryPlayer instance + */ + public void copyInventory(InventoryPlayer par1InventoryPlayer) { + int var2; + + for (var2 = 0; var2 < this.mainInventory.length; ++var2) { + this.mainInventory[var2] = ItemStack.copyItemStack(par1InventoryPlayer.mainInventory[var2]); + } + + for (var2 = 0; var2 < this.armorInventory.length; ++var2) { + this.armorInventory[var2] = ItemStack.copyItemStack(par1InventoryPlayer.armorInventory[var2]); + } + + this.currentItem = par1InventoryPlayer.currentItem; + } +} diff --git a/src/main/java/net/minecraft/src/InventoryRepair.java b/src/main/java/net/minecraft/src/InventoryRepair.java new file mode 100644 index 0000000..7047024 --- /dev/null +++ b/src/main/java/net/minecraft/src/InventoryRepair.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +class InventoryRepair extends InventoryBasic { + /** Container of this anvil's block. */ + final ContainerRepair theContainer; + + InventoryRepair(ContainerRepair par1ContainerRepair, String par2Str, boolean par3, int par4) { + super(par2Str, par3, par4); + this.theContainer = par1ContainerRepair; + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + super.onInventoryChanged(); + this.theContainer.onCraftMatrixChanged(this); + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/Item.java b/src/main/java/net/minecraft/src/Item.java new file mode 100644 index 0000000..2493fe5 --- /dev/null +++ b/src/main/java/net/minecraft/src/Item.java @@ -0,0 +1,632 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + + + +public class Item { + private CreativeTabs tabToDisplayOn = null; + + /** The RNG used by the Item subclasses. */ + protected static Random itemRand = new Random(); + + /** A 32000 elements Item array. */ + public static Item[] itemsList = new Item[32000]; + public static Item shovelIron = (new ItemSpade(0, EnumToolMaterial.IRON)).setUnlocalizedName("shovelIron"); + public static Item pickaxeIron = (new ItemPickaxe(1, EnumToolMaterial.IRON)).setUnlocalizedName("pickaxeIron"); + public static Item axeIron = (new ItemAxe(2, EnumToolMaterial.IRON)).setUnlocalizedName("hatchetIron"); + public static Item flintAndSteel = (new ItemFlintAndSteel(3)).setUnlocalizedName("flintAndSteel"); + public static Item appleRed = (new ItemFood(4, 4, 0.3F, false)).setUnlocalizedName("apple"); + public static ItemBow bow = (ItemBow) (new ItemBow(5)).setUnlocalizedName("bow"); + public static Item arrow = (new Item(6)).setUnlocalizedName("arrow").setCreativeTab(CreativeTabs.tabCombat); + public static Item coal = (new ItemCoal(7)).setUnlocalizedName("coal"); + public static Item diamond = (new Item(8)).setUnlocalizedName("diamond").setCreativeTab(CreativeTabs.tabMaterials); + public static Item ingotIron = (new Item(9)).setUnlocalizedName("ingotIron").setCreativeTab(CreativeTabs.tabMaterials); + public static Item ingotGold = (new Item(10)).setUnlocalizedName("ingotGold").setCreativeTab(CreativeTabs.tabMaterials); + public static Item swordIron = (new ItemSword(11, EnumToolMaterial.IRON)).setUnlocalizedName("swordIron"); + public static Item swordWood = (new ItemSword(12, EnumToolMaterial.WOOD)).setUnlocalizedName("swordWood"); + public static Item shovelWood = (new ItemSpade(13, EnumToolMaterial.WOOD)).setUnlocalizedName("shovelWood"); + public static Item pickaxeWood = (new ItemPickaxe(14, EnumToolMaterial.WOOD)).setUnlocalizedName("pickaxeWood"); + public static Item axeWood = (new ItemAxe(15, EnumToolMaterial.WOOD)).setUnlocalizedName("hatchetWood"); + public static Item swordStone = (new ItemSword(16, EnumToolMaterial.STONE)).setUnlocalizedName("swordStone"); + public static Item shovelStone = (new ItemSpade(17, EnumToolMaterial.STONE)).setUnlocalizedName("shovelStone"); + public static Item pickaxeStone = (new ItemPickaxe(18, EnumToolMaterial.STONE)).setUnlocalizedName("pickaxeStone"); + public static Item axeStone = (new ItemAxe(19, EnumToolMaterial.STONE)).setUnlocalizedName("hatchetStone"); + public static Item swordDiamond = (new ItemSword(20, EnumToolMaterial.EMERALD)).setUnlocalizedName("swordDiamond"); + public static Item shovelDiamond = (new ItemSpade(21, EnumToolMaterial.EMERALD)).setUnlocalizedName("shovelDiamond"); + public static Item pickaxeDiamond = (new ItemPickaxe(22, EnumToolMaterial.EMERALD)).setUnlocalizedName("pickaxeDiamond"); + public static Item axeDiamond = (new ItemAxe(23, EnumToolMaterial.EMERALD)).setUnlocalizedName("hatchetDiamond"); + public static Item stick = (new Item(24)).setFull3D().setUnlocalizedName("stick").setCreativeTab(CreativeTabs.tabMaterials); + public static Item bowlEmpty = (new Item(25)).setUnlocalizedName("bowl").setCreativeTab(CreativeTabs.tabMaterials); + public static Item bowlSoup = (new ItemSoup(26, 6)).setUnlocalizedName("mushroomStew"); + public static Item swordGold = (new ItemSword(27, EnumToolMaterial.GOLD)).setUnlocalizedName("swordGold"); + public static Item shovelGold = (new ItemSpade(28, EnumToolMaterial.GOLD)).setUnlocalizedName("shovelGold"); + public static Item pickaxeGold = (new ItemPickaxe(29, EnumToolMaterial.GOLD)).setUnlocalizedName("pickaxeGold"); + public static Item axeGold = (new ItemAxe(30, EnumToolMaterial.GOLD)).setUnlocalizedName("hatchetGold"); + public static Item silk = (new ItemReed(31, Block.tripWire)).setUnlocalizedName("string").setCreativeTab(CreativeTabs.tabMaterials); + public static Item feather = (new Item(32)).setUnlocalizedName("feather").setCreativeTab(CreativeTabs.tabMaterials); + public static Item gunpowder = (new Item(33)).setUnlocalizedName("sulphur").setPotionEffect(PotionHelper.gunpowderEffect).setCreativeTab(CreativeTabs.tabMaterials); + public static Item hoeWood = (new ItemHoe(34, EnumToolMaterial.WOOD)).setUnlocalizedName("hoeWood"); + public static Item hoeStone = (new ItemHoe(35, EnumToolMaterial.STONE)).setUnlocalizedName("hoeStone"); + public static Item hoeIron = (new ItemHoe(36, EnumToolMaterial.IRON)).setUnlocalizedName("hoeIron"); + public static Item hoeDiamond = (new ItemHoe(37, EnumToolMaterial.EMERALD)).setUnlocalizedName("hoeDiamond"); + public static Item hoeGold = (new ItemHoe(38, EnumToolMaterial.GOLD)).setUnlocalizedName("hoeGold"); + public static Item seeds = (new ItemSeeds(39, Block.crops.blockID, Block.tilledField.blockID)).setUnlocalizedName("seeds"); + public static Item wheat = (new Item(40)).setUnlocalizedName("wheat").setCreativeTab(CreativeTabs.tabMaterials); + public static Item bread = (new ItemFood(41, 5, 0.6F, false)).setUnlocalizedName("bread"); + public static ItemArmor helmetLeather = (ItemArmor) (new ItemArmor(42, EnumArmorMaterial.CLOTH, 0, 0)).setUnlocalizedName("helmetCloth"); + public static ItemArmor plateLeather = (ItemArmor) (new ItemArmor(43, EnumArmorMaterial.CLOTH, 0, 1)).setUnlocalizedName("chestplateCloth"); + public static ItemArmor legsLeather = (ItemArmor) (new ItemArmor(44, EnumArmorMaterial.CLOTH, 0, 2)).setUnlocalizedName("leggingsCloth"); + public static ItemArmor bootsLeather = (ItemArmor) (new ItemArmor(45, EnumArmorMaterial.CLOTH, 0, 3)).setUnlocalizedName("bootsCloth"); + public static ItemArmor helmetChain = (ItemArmor) (new ItemArmor(46, EnumArmorMaterial.CHAIN, 1, 0)).setUnlocalizedName("helmetChain"); + public static ItemArmor plateChain = (ItemArmor) (new ItemArmor(47, EnumArmorMaterial.CHAIN, 1, 1)).setUnlocalizedName("chestplateChain"); + public static ItemArmor legsChain = (ItemArmor) (new ItemArmor(48, EnumArmorMaterial.CHAIN, 1, 2)).setUnlocalizedName("leggingsChain"); + public static ItemArmor bootsChain = (ItemArmor) (new ItemArmor(49, EnumArmorMaterial.CHAIN, 1, 3)).setUnlocalizedName("bootsChain"); + public static ItemArmor helmetIron = (ItemArmor) (new ItemArmor(50, EnumArmorMaterial.IRON, 2, 0)).setUnlocalizedName("helmetIron"); + public static ItemArmor plateIron = (ItemArmor) (new ItemArmor(51, EnumArmorMaterial.IRON, 2, 1)).setUnlocalizedName("chestplateIron"); + public static ItemArmor legsIron = (ItemArmor) (new ItemArmor(52, EnumArmorMaterial.IRON, 2, 2)).setUnlocalizedName("leggingsIron"); + public static ItemArmor bootsIron = (ItemArmor) (new ItemArmor(53, EnumArmorMaterial.IRON, 2, 3)).setUnlocalizedName("bootsIron"); + public static ItemArmor helmetDiamond = (ItemArmor) (new ItemArmor(54, EnumArmorMaterial.DIAMOND, 3, 0)).setUnlocalizedName("helmetDiamond"); + public static ItemArmor plateDiamond = (ItemArmor) (new ItemArmor(55, EnumArmorMaterial.DIAMOND, 3, 1)).setUnlocalizedName("chestplateDiamond"); + public static ItemArmor legsDiamond = (ItemArmor) (new ItemArmor(56, EnumArmorMaterial.DIAMOND, 3, 2)).setUnlocalizedName("leggingsDiamond"); + public static ItemArmor bootsDiamond = (ItemArmor) (new ItemArmor(57, EnumArmorMaterial.DIAMOND, 3, 3)).setUnlocalizedName("bootsDiamond"); + public static ItemArmor helmetGold = (ItemArmor) (new ItemArmor(58, EnumArmorMaterial.GOLD, 4, 0)).setUnlocalizedName("helmetGold"); + public static ItemArmor plateGold = (ItemArmor) (new ItemArmor(59, EnumArmorMaterial.GOLD, 4, 1)).setUnlocalizedName("chestplateGold"); + public static ItemArmor legsGold = (ItemArmor) (new ItemArmor(60, EnumArmorMaterial.GOLD, 4, 2)).setUnlocalizedName("leggingsGold"); + public static ItemArmor bootsGold = (ItemArmor) (new ItemArmor(61, EnumArmorMaterial.GOLD, 4, 3)).setUnlocalizedName("bootsGold"); + public static Item flint = (new Item(62)).setUnlocalizedName("flint").setCreativeTab(CreativeTabs.tabMaterials); + public static Item porkRaw = (new ItemFood(63, 3, 0.3F, true)).setUnlocalizedName("porkchopRaw"); + public static Item porkCooked = (new ItemFood(64, 8, 0.8F, true)).setUnlocalizedName("porkchopCooked"); + public static Item painting = (new ItemHangingEntity(65, EntityPainting.class)).setUnlocalizedName("painting"); + public static Item appleGold = (new ItemAppleGold(66, 4, 1.2F, false)).setAlwaysEdible().setPotionEffect(Potion.regeneration.id, 5, 0, 1.0F).setUnlocalizedName("appleGold"); + public static Item sign = (new ItemSign(67)).setUnlocalizedName("sign"); + public static Item doorWood = (new ItemDoor(68, Material.wood)).setUnlocalizedName("doorWood"); + public static Item bucketEmpty = (new ItemBucket(69, 0)).setUnlocalizedName("bucket").setMaxStackSize(16); + public static Item bucketWater = (new ItemBucket(70, Block.waterMoving.blockID)).setUnlocalizedName("bucketWater").setContainerItem(bucketEmpty); + public static Item bucketLava = (new ItemBucket(71, Block.lavaMoving.blockID)).setUnlocalizedName("bucketLava").setContainerItem(bucketEmpty); + public static Item minecartEmpty = (new ItemMinecart(72, 0)).setUnlocalizedName("minecart"); + public static Item saddle = (new ItemSaddle(73)).setUnlocalizedName("saddle"); + public static Item doorIron = (new ItemDoor(74, Material.iron)).setUnlocalizedName("doorIron"); + public static Item redstone = (new ItemRedstone(75)).setUnlocalizedName("redstone").setPotionEffect(PotionHelper.redstoneEffect); + public static Item snowball = (new ItemSnowball(76)).setUnlocalizedName("snowball"); + public static Item boat = (new ItemBoat(77)).setUnlocalizedName("boat"); + public static Item leather = (new Item(78)).setUnlocalizedName("leather").setCreativeTab(CreativeTabs.tabMaterials); + public static Item bucketMilk = (new ItemBucketMilk(79)).setUnlocalizedName("milk").setContainerItem(bucketEmpty); + public static Item brick = (new Item(80)).setUnlocalizedName("brick").setCreativeTab(CreativeTabs.tabMaterials); + public static Item clay = (new Item(81)).setUnlocalizedName("clay").setCreativeTab(CreativeTabs.tabMaterials); + public static Item reed = (new ItemReed(82, Block.reed)).setUnlocalizedName("reeds").setCreativeTab(CreativeTabs.tabMaterials); + public static Item paper = (new Item(83)).setUnlocalizedName("paper").setCreativeTab(CreativeTabs.tabMisc); + public static Item book = (new ItemBook(84)).setUnlocalizedName("book").setCreativeTab(CreativeTabs.tabMisc); + public static Item slimeBall = (new Item(85)).setUnlocalizedName("slimeball").setCreativeTab(CreativeTabs.tabMisc); + public static Item minecartCrate = (new ItemMinecart(86, 1)).setUnlocalizedName("minecartChest"); + public static Item minecartPowered = (new ItemMinecart(87, 2)).setUnlocalizedName("minecartFurnace"); + public static Item egg = (new ItemEgg(88)).setUnlocalizedName("egg"); + public static Item compass = (new Item(89)).setUnlocalizedName("compass").setCreativeTab(CreativeTabs.tabTools); + public static ItemFishingRod fishingRod = (ItemFishingRod) (new ItemFishingRod(90)).setUnlocalizedName("fishingRod"); + public static Item pocketSundial = (new Item(91)).setUnlocalizedName("clock").setCreativeTab(CreativeTabs.tabTools); + public static Item lightStoneDust = (new Item(92)).setUnlocalizedName("yellowDust").setPotionEffect(PotionHelper.glowstoneEffect).setCreativeTab(CreativeTabs.tabMaterials); + public static Item fishRaw = (new ItemFood(93, 2, 0.3F, false)).setUnlocalizedName("fishRaw"); + public static Item fishCooked = (new ItemFood(94, 5, 0.6F, false)).setUnlocalizedName("fishCooked"); + public static Item dyePowder = (new ItemDye(95)).setUnlocalizedName("dyePowder"); + public static Item bone = (new Item(96)).setUnlocalizedName("bone").setFull3D().setCreativeTab(CreativeTabs.tabMisc); + public static Item sugar = (new Item(97)).setUnlocalizedName("sugar").setPotionEffect(PotionHelper.sugarEffect).setCreativeTab(CreativeTabs.tabMaterials); + public static Item cake = (new ItemReed(98, Block.cake)).setMaxStackSize(1).setUnlocalizedName("cake").setCreativeTab(CreativeTabs.tabFood); + public static Item bed = (new ItemBed(99)).setMaxStackSize(1).setUnlocalizedName("bed"); + public static Item redstoneRepeater = (new ItemReed(100, Block.redstoneRepeaterIdle)).setUnlocalizedName("diode").setCreativeTab(CreativeTabs.tabRedstone); + public static Item cookie = (new ItemFood(101, 2, 0.1F, false)).setUnlocalizedName("cookie"); + public static ItemMap map = (ItemMap) (new ItemMap(102)).setUnlocalizedName("map"); + + /** + * Item introduced on 1.7 version, is a shear to cut leaves (you can keep the + * block) or get wool from sheeps. + */ + public static ItemShears shears = (ItemShears) (new ItemShears(103)).setUnlocalizedName("shears"); + public static Item melon = (new ItemFood(104, 2, 0.3F, false)).setUnlocalizedName("melon"); + public static Item pumpkinSeeds = (new ItemSeeds(105, Block.pumpkinStem.blockID, Block.tilledField.blockID)).setUnlocalizedName("seeds_pumpkin"); + public static Item melonSeeds = (new ItemSeeds(106, Block.melonStem.blockID, Block.tilledField.blockID)).setUnlocalizedName("seeds_melon"); + public static Item beefRaw = (new ItemFood(107, 3, 0.3F, true)).setUnlocalizedName("beefRaw"); + public static Item beefCooked = (new ItemFood(108, 8, 0.8F, true)).setUnlocalizedName("beefCooked"); + public static Item chickenRaw = (new ItemFood(109, 2, 0.3F, true)).setPotionEffect(Potion.hunger.id, 30, 0, 0.3F).setUnlocalizedName("chickenRaw"); + public static Item chickenCooked = (new ItemFood(110, 6, 0.6F, true)).setUnlocalizedName("chickenCooked"); + public static Item rottenFlesh = (new ItemFood(111, 4, 0.1F, true)).setPotionEffect(Potion.hunger.id, 30, 0, 0.8F).setUnlocalizedName("rottenFlesh"); + public static Item enderPearl = (new ItemEnderPearl(112)).setUnlocalizedName("enderPearl"); + public static Item blazeRod = (new Item(113)).setUnlocalizedName("blazeRod").setCreativeTab(CreativeTabs.tabMaterials); + public static Item ghastTear = (new Item(114)).setUnlocalizedName("ghastTear").setPotionEffect(PotionHelper.ghastTearEffect).setCreativeTab(CreativeTabs.tabBrewing); + public static Item goldNugget = (new Item(115)).setUnlocalizedName("goldNugget").setCreativeTab(CreativeTabs.tabMaterials); + public static Item netherStalkSeeds = (new ItemSeeds(116, Block.netherStalk.blockID, Block.slowSand.blockID)).setUnlocalizedName("netherStalkSeeds").setPotionEffect("+4"); + public static ItemPotion potion = (ItemPotion) (new ItemPotion(117)).setUnlocalizedName("potion"); + public static Item glassBottle = (new ItemGlassBottle(118)).setUnlocalizedName("glassBottle"); + public static Item spiderEye = (new ItemFood(119, 2, 0.8F, false)).setPotionEffect(Potion.poison.id, 5, 0, 1.0F).setUnlocalizedName("spiderEye").setPotionEffect(PotionHelper.spiderEyeEffect); + public static Item fermentedSpiderEye = (new Item(120)).setUnlocalizedName("fermentedSpiderEye").setPotionEffect(PotionHelper.fermentedSpiderEyeEffect).setCreativeTab(CreativeTabs.tabBrewing); + public static Item blazePowder = (new Item(121)).setUnlocalizedName("blazePowder").setPotionEffect(PotionHelper.blazePowderEffect).setCreativeTab(CreativeTabs.tabBrewing); + public static Item magmaCream = (new Item(122)).setUnlocalizedName("magmaCream").setPotionEffect(PotionHelper.magmaCreamEffect).setCreativeTab(CreativeTabs.tabBrewing); + public static Item brewingStand = (new ItemReed(123, Block.brewingStand)).setUnlocalizedName("brewingStand").setCreativeTab(CreativeTabs.tabBrewing); + public static Item cauldron = (new ItemReed(124, Block.cauldron)).setUnlocalizedName("cauldron").setCreativeTab(CreativeTabs.tabBrewing); + public static Item eyeOfEnder = (new ItemEnderEye(125)).setUnlocalizedName("eyeOfEnder"); + public static Item speckledMelon = (new Item(126)).setUnlocalizedName("speckledMelon").setPotionEffect(PotionHelper.speckledMelonEffect).setCreativeTab(CreativeTabs.tabBrewing); + public static Item monsterPlacer = (new ItemMonsterPlacer(127)).setUnlocalizedName("monsterPlacer"); + + /** + * Bottle o' Enchanting. Drops between 1 and 3 experience orbs when thrown. + */ + public static Item expBottle = (new ItemExpBottle(128)).setUnlocalizedName("expBottle"); + + /** + * Fire Charge. When used in a dispenser it fires a fireball similiar to a + * Ghast's. + */ + public static Item fireballCharge = (new ItemFireball(129)).setUnlocalizedName("fireball"); + public static Item writableBook = (new ItemWritableBook(130)).setUnlocalizedName("writingBook").setCreativeTab(CreativeTabs.tabMisc); + public static Item writtenBook = (new ItemEditableBook(131)).setUnlocalizedName("writtenBook"); + public static Item emerald = (new Item(132)).setUnlocalizedName("emerald").setCreativeTab(CreativeTabs.tabMaterials); + public static Item itemFrame = (new ItemHangingEntity(133, EntityItemFrame.class)).setUnlocalizedName("frame"); + public static Item flowerPot = (new ItemReed(134, Block.flowerPot)).setUnlocalizedName("flowerPot").setCreativeTab(CreativeTabs.tabDecorations); + public static Item carrot = (new ItemSeedFood(135, 4, 0.6F, Block.carrot.blockID, Block.tilledField.blockID)).setUnlocalizedName("carrots"); + public static Item potato = (new ItemSeedFood(136, 1, 0.3F, Block.potato.blockID, Block.tilledField.blockID)).setUnlocalizedName("potato"); + public static Item bakedPotato = (new ItemFood(137, 6, 0.6F, false)).setUnlocalizedName("potatoBaked"); + public static Item poisonousPotato = (new ItemFood(138, 2, 0.3F, false)).setPotionEffect(Potion.poison.id, 5, 0, 0.6F).setUnlocalizedName("potatoPoisonous"); + public static ItemEmptyMap emptyMap = (ItemEmptyMap) (new ItemEmptyMap(139)).setUnlocalizedName("emptyMap"); + public static Item goldenCarrot = (new ItemFood(140, 6, 1.2F, false)).setUnlocalizedName("carrotGolden").setPotionEffect(PotionHelper.goldenCarrotEffect); + public static Item skull = (new ItemSkull(141)).setUnlocalizedName("skull"); + public static Item carrotOnAStick = (new ItemCarrotOnAStick(142)).setUnlocalizedName("carrotOnAStick"); + public static Item netherStar = (new ItemSimpleFoiled(143)).setUnlocalizedName("netherStar").setCreativeTab(CreativeTabs.tabMaterials); + public static Item pumpkinPie = (new ItemFood(144, 8, 0.3F, false)).setUnlocalizedName("pumpkinPie").setCreativeTab(CreativeTabs.tabFood); + public static Item firework = (new ItemFirework(145)).setUnlocalizedName("fireworks"); + public static Item fireworkCharge = (new ItemFireworkCharge(146)).setUnlocalizedName("fireworksCharge").setCreativeTab(CreativeTabs.tabMisc); + public static ItemEnchantedBook enchantedBook = (ItemEnchantedBook) (new ItemEnchantedBook(147)).setMaxStackSize(1).setUnlocalizedName("enchantedBook"); + public static Item comparator = (new ItemReed(148, Block.redstoneComparatorIdle)).setUnlocalizedName("comparator").setCreativeTab(CreativeTabs.tabRedstone); + public static Item netherrackBrick = (new Item(149)).setUnlocalizedName("netherbrick").setCreativeTab(CreativeTabs.tabMaterials); + public static Item netherQuartz = (new Item(150)).setUnlocalizedName("netherquartz").setCreativeTab(CreativeTabs.tabMaterials); + public static Item minecartTnt = (new ItemMinecart(151, 3)).setUnlocalizedName("minecartTnt"); + public static Item minecartHopper = (new ItemMinecart(152, 5)).setUnlocalizedName("minecartHopper"); + public static Item record13 = (new ItemRecord(2000, "13")).setUnlocalizedName("record"); + public static Item recordCat = (new ItemRecord(2001, "cat")).setUnlocalizedName("record"); + public static Item recordBlocks = (new ItemRecord(2002, "blocks")).setUnlocalizedName("record"); + public static Item recordChirp = (new ItemRecord(2003, "chirp")).setUnlocalizedName("record"); + public static Item recordFar = (new ItemRecord(2004, "far")).setUnlocalizedName("record"); + public static Item recordMall = (new ItemRecord(2005, "mall")).setUnlocalizedName("record"); + public static Item recordMellohi = (new ItemRecord(2006, "mellohi")).setUnlocalizedName("record"); + public static Item recordStal = (new ItemRecord(2007, "stal")).setUnlocalizedName("record"); + public static Item recordStrad = (new ItemRecord(2008, "strad")).setUnlocalizedName("record"); + public static Item recordWard = (new ItemRecord(2009, "ward")).setUnlocalizedName("record"); + public static Item record11 = (new ItemRecord(2010, "11")).setUnlocalizedName("record"); + public static Item recordWait = (new ItemRecord(2011, "wait")).setUnlocalizedName("record"); + + /** The ID of this item. */ + public final int itemID; + + /** Maximum size of the stack. */ + protected int maxStackSize = 64; + + /** Maximum damage an item can handle. */ + private int maxDamage = 0; + + /** If true, render the object in full 3D, like weapons and tools. */ + protected boolean bFull3D = false; + + /** + * Some items (like dyes) have multiple subtypes on same item, this is field + * define this behavior + */ + protected boolean hasSubtypes = false; + private Item containerItem = null; + private String potionEffect = null; + + /** The unlocalized name of this item. */ + private String unlocalizedName; + + /** Icon index in the icons table. */ + protected Icon itemIcon; + + protected Item(int par1) { + this.itemID = 256 + par1; + + if (itemsList[256 + par1] != null) { + System.out.println("CONFLICT @ " + par1); + } + + itemsList[256 + par1] = this; + } + + public Item setMaxStackSize(int par1) { + this.maxStackSize = par1; + return this; + } + + /** + * Returns 0 for /terrain.png, 1 for /gui/items.png + */ + public int getSpriteNumber() { + return 1; + } + + /** + * Gets an icon index based on an item's damage value + */ + public Icon getIconFromDamage(int par1) { + return this.itemIcon; + } + + /** + * Returns the icon index of the stack given as argument. + */ + public final Icon getIconIndex(ItemStack par1ItemStack) { + return this.getIconFromDamage(par1ItemStack.getItemDamage()); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + return false; + } + + /** + * Returns the strength of the stack against a given block. 1.0F base, + * (Quality+1)*2 if correct blocktype, 1.5F if sword + */ + public float getStrVsBlock(ItemStack par1ItemStack, Block par2Block) { + return 1.0F; + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + return par1ItemStack; + } + + public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + return par1ItemStack; + } + + /** + * Returns the maximum size of the stack for a specific item. *Isn't this more a + * Set than a Get?* + */ + public int getItemStackLimit() { + return this.maxStackSize; + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return 0; + } + + public boolean getHasSubtypes() { + return this.hasSubtypes; + } + + protected Item setHasSubtypes(boolean par1) { + this.hasSubtypes = par1; + return this; + } + + /** + * Returns the maximum damage an item can take. + */ + public int getMaxDamage() { + return this.maxDamage; + } + + /** + * set max damage of an Item + */ + protected Item setMaxDamage(int par1) { + this.maxDamage = par1; + return this; + } + + public boolean isDamageable() { + return this.maxDamage > 0 && !this.hasSubtypes; + } + + /** + * Current implementations of this method in child classes do not use the entry + * argument beside ev. They just raise the damage on the stack. + */ + public boolean hitEntity(ItemStack par1ItemStack, EntityLiving par2EntityLiving, EntityLiving par3EntityLiving) { + return false; + } + + public boolean onBlockDestroyed(ItemStack par1ItemStack, World par2World, int par3, int par4, int par5, int par6, EntityLiving par7EntityLiving) { + return false; + } + + /** + * Returns the damage against a given entity. + */ + public int getDamageVsEntity(Entity par1Entity) { + return 1; + } + + /** + * Returns if the item (tool) can harvest results from the block type. + */ + public boolean canHarvestBlock(Block par1Block) { + return false; + } + + /** + * Called when a player right clicks an entity with an item. + */ + public boolean itemInteractionForEntity(ItemStack par1ItemStack, EntityLiving par2EntityLiving) { + return false; + } + + /** + * Sets bFull3D to True and return the object. + */ + public Item setFull3D() { + this.bFull3D = true; + return this; + } + + /** + * Returns True is the item is renderer in full 3D when hold. + */ + public boolean isFull3D() { + return this.bFull3D; + } + + /** + * Returns true if this item should be rotated by 180 degrees around the Y axis + * when being held in an entities hands. + */ + public boolean shouldRotateAroundWhenRendering() { + return false; + } + + /** + * Sets the unlocalized name of this item to the string passed as the parameter, + * prefixed by "item." + */ + public Item setUnlocalizedName(String par1Str) { + this.unlocalizedName = par1Str; + return this; + } + + /** + * Gets the localized name of the given item stack. + */ + public String getLocalizedName(ItemStack par1ItemStack) { + String var2 = this.getUnlocalizedName(par1ItemStack); + return var2 == null ? "" : StatCollector.translateToLocal(var2); + } + + /** + * Returns the unlocalized name of this item. + */ + public String getUnlocalizedName() { + return "item." + this.unlocalizedName; + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + return "item." + this.unlocalizedName; + } + + public Item setContainerItem(Item par1Item) { + this.containerItem = par1Item; + return this; + } + + /** + * If this returns true, after a recipe involving this item is crafted the + * container item will be added to the player's inventory instead of remaining + * in the crafting grid. + */ + public boolean doesContainerItemLeaveCraftingGrid(ItemStack par1ItemStack) { + return true; + } + + /** + * If this function returns true (or the item is damageable), the ItemStack's + * NBT tag will be sent to the client. + */ + public boolean getShareTag() { + return true; + } + + public Item getContainerItem() { + return this.containerItem; + } + + /** + * True if this Item has a container item (a.k.a. crafting result) + */ + public boolean hasContainerItem() { + return this.containerItem != null; + } + + public String getStatName() { + return StatCollector.translateToLocal(this.getUnlocalizedName() + ".name"); + } + + public String func_77653_i(ItemStack par1ItemStack) { + return StatCollector.translateToLocal(this.getUnlocalizedName(par1ItemStack) + ".name"); + } + + public int getColorFromItemStack(ItemStack par1ItemStack, int par2) { + return 16777215; + } + + /** + * Called each tick as long the item is on a player inventory. Uses by maps to + * check if is on a player hand and update it's contents. + */ + public void onUpdate(ItemStack par1ItemStack, World par2World, Entity par3Entity, int par4, boolean par5) { + } + + /** + * Called when item is crafted/smelted. Used only by maps so far. + */ + public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + } + + /** + * false for all Items except sub-classes of ItemMapBase + */ + public boolean isMap() { + return false; + } + + /** + * returns the action that specifies what animation to play when the items is + * being used + */ + public EnumAction getItemUseAction(ItemStack par1ItemStack) { + return EnumAction.none; + } + + /** + * How long it takes to use or consume an item + */ + public int getMaxItemUseDuration(ItemStack par1ItemStack) { + return 0; + } + + /** + * called when the player releases the use item button. Args: itemstack, world, + * entityplayer, itemInUseCount + */ + public void onPlayerStoppedUsing(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer, int par4) { + } + + /** + * Sets the string representing this item's effect on a potion when used as an + * ingredient. + */ + protected Item setPotionEffect(String par1Str) { + this.potionEffect = par1Str; + return this; + } + + /** + * Returns a string representing what this item does to a potion. + */ + public String getPotionEffect() { + return this.potionEffect; + } + + /** + * Returns true if this item serves as a potion ingredient (its ingredient + * information is not null). + */ + public boolean isPotionIngredient() { + return this.potionEffect != null; + } + + /** + * allows items to add custom lines of information to the mouseover description + */ + public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { + } + + public String getItemDisplayName(ItemStack par1ItemStack) { + return ("" + StringTranslate.getInstance().translateNamedKey(this.getLocalizedName(par1ItemStack))).trim(); + } + + public boolean hasEffect(ItemStack par1ItemStack) { + return par1ItemStack.isItemEnchanted(); + } + + /** + * Return an item rarity from EnumRarity + */ + public EnumRarity getRarity(ItemStack par1ItemStack) { + return par1ItemStack.isItemEnchanted() ? EnumRarity.rare : EnumRarity.common; + } + + /** + * Checks isDamagable and if it cannot be stacked + */ + public boolean isItemTool(ItemStack par1ItemStack) { + return this.getItemStackLimit() == 1 && this.isDamageable(); + } + + protected MovingObjectPosition getMovingObjectPositionFromPlayer(World par1World, EntityPlayer par2EntityPlayer, boolean par3) { + float var4 = 1.0F; + float var5 = par2EntityPlayer.prevRotationPitch + (par2EntityPlayer.rotationPitch - par2EntityPlayer.prevRotationPitch) * var4; + float var6 = par2EntityPlayer.prevRotationYaw + (par2EntityPlayer.rotationYaw - par2EntityPlayer.prevRotationYaw) * var4; + double var7 = par2EntityPlayer.prevPosX + (par2EntityPlayer.posX - par2EntityPlayer.prevPosX) * (double) var4; + double var9 = par2EntityPlayer.prevPosY + (par2EntityPlayer.posY - par2EntityPlayer.prevPosY) * (double) var4 + 1.62D - (double) par2EntityPlayer.yOffset; + double var11 = par2EntityPlayer.prevPosZ + (par2EntityPlayer.posZ - par2EntityPlayer.prevPosZ) * (double) var4; + Vec3 var13 = par1World.getWorldVec3Pool().getVecFromPool(var7, var9, var11); + float var14 = MathHelper.cos(-var6 * 0.017453292F - (float) Math.PI); + float var15 = MathHelper.sin(-var6 * 0.017453292F - (float) Math.PI); + float var16 = -MathHelper.cos(-var5 * 0.017453292F); + float var17 = MathHelper.sin(-var5 * 0.017453292F); + float var18 = var15 * var16; + float var20 = var14 * var16; + double var21 = 5.0D; + Vec3 var23 = var13.addVector((double) var18 * var21, (double) var17 * var21, (double) var20 * var21); + return par1World.rayTraceBlocks_do_do(var13, var23, par3, !par3); + } + + /** + * Return the enchantability factor of the item, most of the time is based on + * material. + */ + public int getItemEnchantability() { + return 0; + } + + public boolean requiresMultipleRenderPasses() { + return false; + } + + /** + * Gets an icon index based on an item's damage value and the given render pass + */ + public Icon getIconFromDamageForRenderPass(int par1, int par2) { + return this.getIconFromDamage(par1); + } + + /** + * returns a list of items with the same ID, but different meta (eg: dye returns + * 16 items) + */ + public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List) { + par3List.add(new ItemStack(par1, 1, 0)); + } + + /** + * gets the CreativeTab this item is displayed on + */ + public CreativeTabs getCreativeTab() { + return this.tabToDisplayOn; + } + + /** + * returns this; + */ + public Item setCreativeTab(CreativeTabs par1CreativeTabs) { + this.tabToDisplayOn = par1CreativeTabs; + return this; + } + + public boolean func_82788_x() { + return true; + } + + /** + * Return whether this item is repairable in an anvil. + */ + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) { + return false; + } + + public void registerIcons(IconRegister par1IconRegister) { + this.itemIcon = par1IconRegister.registerIcon(this.unlocalizedName); + } +} diff --git a/src/main/java/net/minecraft/src/ItemAnvilBlock.java b/src/main/java/net/minecraft/src/ItemAnvilBlock.java new file mode 100644 index 0000000..9072d32 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemAnvilBlock.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +public class ItemAnvilBlock extends ItemMultiTextureTile { + public ItemAnvilBlock(Block par1Block) { + super(par1Block.blockID - 256, par1Block, BlockAnvil.statuses); + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1 << 2; + } +} diff --git a/src/main/java/net/minecraft/src/ItemAppleGold.java b/src/main/java/net/minecraft/src/ItemAppleGold.java new file mode 100644 index 0000000..60dcefb --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemAppleGold.java @@ -0,0 +1,42 @@ +package net.minecraft.src; + +import java.util.List; + +public class ItemAppleGold extends ItemFood { + public ItemAppleGold(int par1, int par2, float par3, boolean par4) { + super(par1, par2, par3, par4); + this.setHasSubtypes(true); + } + + public boolean hasEffect(ItemStack par1ItemStack) { + return par1ItemStack.getItemDamage() > 0; + } + + /** + * Return an item rarity from EnumRarity + */ + public EnumRarity getRarity(ItemStack par1ItemStack) { + return par1ItemStack.getItemDamage() == 0 ? EnumRarity.rare : EnumRarity.epic; + } + + protected void onFoodEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (par1ItemStack.getItemDamage() > 0) { + if (!par2World.isRemote) { + par3EntityPlayer.addPotionEffect(new PotionEffect(Potion.regeneration.id, 600, 3)); + par3EntityPlayer.addPotionEffect(new PotionEffect(Potion.resistance.id, 6000, 0)); + par3EntityPlayer.addPotionEffect(new PotionEffect(Potion.fireResistance.id, 6000, 0)); + } + } else { + super.onFoodEaten(par1ItemStack, par2World, par3EntityPlayer); + } + } + + /** + * returns a list of items with the same ID, but different meta (eg: dye returns + * 16 items) + */ + public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List) { + par3List.add(new ItemStack(par1, 1, 0)); + par3List.add(new ItemStack(par1, 1, 1)); + } +} diff --git a/src/main/java/net/minecraft/src/ItemArmor.java b/src/main/java/net/minecraft/src/ItemArmor.java new file mode 100644 index 0000000..5d6d1e1 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemArmor.java @@ -0,0 +1,202 @@ +package net.minecraft.src; + +public class ItemArmor extends Item { + /** Holds the 'base' maxDamage that each armorType have. */ + private static final int[] maxDamageArray = new int[] { 11, 16, 15, 13 }; + private static final String[] field_94606_cu = new String[] { "helmetCloth_overlay", "chestplateCloth_overlay", "leggingsCloth_overlay", "bootsCloth_overlay" }; + public static final String[] field_94603_a = new String[] { "slot_empty_helmet", "slot_empty_chestplate", "slot_empty_leggings", "slot_empty_boots" }; + + /** + * Stores the armor type: 0 is helmet, 1 is plate, 2 is legs and 3 is boots + */ + public final int armorType; + + /** Holds the amount of damage that the armor reduces at full durability. */ + public final int damageReduceAmount; + + /** + * Used on RenderPlayer to select the correspondent armor to be rendered on the + * player: 0 is cloth, 1 is chain, 2 is iron, 3 is diamond and 4 is gold. + */ + public final int renderIndex; + + /** The EnumArmorMaterial used for this ItemArmor */ + private final EnumArmorMaterial material; + private Icon field_94605_cw; + private Icon field_94604_cx; + + public ItemArmor(int par1, EnumArmorMaterial par2EnumArmorMaterial, int par3, int par4) { + super(par1); + this.material = par2EnumArmorMaterial; + this.armorType = par4; + this.renderIndex = par3; + this.damageReduceAmount = par2EnumArmorMaterial.getDamageReductionAmount(par4); + this.setMaxDamage(par2EnumArmorMaterial.getDurability(par4)); + this.maxStackSize = 1; + this.setCreativeTab(CreativeTabs.tabCombat); + } + + public int getColorFromItemStack(ItemStack par1ItemStack, int par2) { + if (par2 > 0) { + return 16777215; + } else { + int var3 = this.getColor(par1ItemStack); + + if (var3 < 0) { + var3 = 16777215; + } + + return var3; + } + } + + public boolean requiresMultipleRenderPasses() { + return this.material == EnumArmorMaterial.CLOTH; + } + + /** + * Return the enchantability factor of the item, most of the time is based on + * material. + */ + public int getItemEnchantability() { + return this.material.getEnchantability(); + } + + /** + * Return the armor material for this armor item. + */ + public EnumArmorMaterial getArmorMaterial() { + return this.material; + } + + /** + * Return whether the specified armor ItemStack has a color. + */ + public boolean hasColor(ItemStack par1ItemStack) { + return this.material != EnumArmorMaterial.CLOTH ? false + : (!par1ItemStack.hasTagCompound() ? false : (!par1ItemStack.getTagCompound().hasKey("display") ? false : par1ItemStack.getTagCompound().getCompoundTag("display").hasKey("color"))); + } + + /** + * Return the color for the specified armor ItemStack. + */ + public int getColor(ItemStack par1ItemStack) { + if (this.material != EnumArmorMaterial.CLOTH) { + return -1; + } else { + NBTTagCompound var2 = par1ItemStack.getTagCompound(); + + if (var2 == null) { + return 10511680; + } else { + NBTTagCompound var3 = var2.getCompoundTag("display"); + return var3 == null ? 10511680 : (var3.hasKey("color") ? var3.getInteger("color") : 10511680); + } + } + } + + /** + * Gets an icon index based on an item's damage value and the given render pass + */ + public Icon getIconFromDamageForRenderPass(int par1, int par2) { + return par2 == 1 ? this.field_94605_cw : super.getIconFromDamageForRenderPass(par1, par2); + } + + /** + * Remove the color from the specified armor ItemStack. + */ + public void removeColor(ItemStack par1ItemStack) { + if (this.material == EnumArmorMaterial.CLOTH) { + NBTTagCompound var2 = par1ItemStack.getTagCompound(); + + if (var2 != null) { + NBTTagCompound var3 = var2.getCompoundTag("display"); + + if (var3.hasKey("color")) { + var3.removeTag("color"); + } + } + } + } + + public void func_82813_b(ItemStack par1ItemStack, int par2) { + if (this.material != EnumArmorMaterial.CLOTH) { + throw new UnsupportedOperationException("Can\'t dye non-leather!"); + } else { + NBTTagCompound var3 = par1ItemStack.getTagCompound(); + + if (var3 == null) { + var3 = new NBTTagCompound(); + par1ItemStack.setTagCompound(var3); + } + + NBTTagCompound var4 = var3.getCompoundTag("display"); + + if (!var3.hasKey("display")) { + var3.setCompoundTag("display", var4); + } + + var4.setInteger("color", par2); + } + } + + /** + * Return whether this item is repairable in an anvil. + */ + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) { + return this.material.getArmorCraftingMaterial() == par2ItemStack.itemID ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); + } + + public void registerIcons(IconRegister par1IconRegister) { + super.registerIcons(par1IconRegister); + + if (this.material == EnumArmorMaterial.CLOTH) { + this.field_94605_cw = par1IconRegister.registerIcon(field_94606_cu[this.armorType]); + } + + this.field_94604_cx = par1IconRegister.registerIcon(field_94603_a[this.armorType]); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + int var4 = EntityLiving.getArmorPosition(par1ItemStack) - 1; + ItemStack var5 = par3EntityPlayer.getCurrentArmor(var4); + + if (var5 == null) { + par3EntityPlayer.setCurrentItemOrArmor(var4, par1ItemStack.copy()); + par1ItemStack.stackSize = 0; + } + + return par1ItemStack; + } + + public static Icon func_94602_b(int par0) { + switch (par0) { + case 0: + return Item.helmetDiamond.field_94604_cx; + + case 1: + return Item.plateDiamond.field_94604_cx; + + case 2: + return Item.legsDiamond.field_94604_cx; + + case 3: + return Item.bootsDiamond.field_94604_cx; + + default: + return null; + } + } + + /** + * Returns the 'max damage' factor array for the armor, each piece of armor have + * a durability factor (that gets multiplied by armor material factor) + */ + static int[] getMaxDamageArray() { + return maxDamageArray; + } +} diff --git a/src/main/java/net/minecraft/src/ItemAxe.java b/src/main/java/net/minecraft/src/ItemAxe.java new file mode 100644 index 0000000..763969e --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemAxe.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +public class ItemAxe extends ItemTool { + /** an array of the blocks this axe is effective against */ + private static Block[] blocksEffectiveAgainst = new Block[] { Block.planks, Block.bookShelf, Block.wood, Block.chest, Block.stoneDoubleSlab, Block.stoneSingleSlab, Block.pumpkin, Block.pumpkinLantern }; + + protected ItemAxe(int par1, EnumToolMaterial par2EnumToolMaterial) { + super(par1, 3, par2EnumToolMaterial, blocksEffectiveAgainst); + } + + /** + * Returns the strength of the stack against a given block. 1.0F base, + * (Quality+1)*2 if correct blocktype, 1.5F if sword + */ + public float getStrVsBlock(ItemStack par1ItemStack, Block par2Block) { + return par2Block != null && (par2Block.blockMaterial == Material.wood || par2Block.blockMaterial == Material.plants || par2Block.blockMaterial == Material.vine) ? this.efficiencyOnProperMaterial + : super.getStrVsBlock(par1ItemStack, par2Block); + } +} diff --git a/src/main/java/net/minecraft/src/ItemBed.java b/src/main/java/net/minecraft/src/ItemBed.java new file mode 100644 index 0000000..fbecbca --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemBed.java @@ -0,0 +1,61 @@ +package net.minecraft.src; + +public class ItemBed extends Item { + public ItemBed(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (par3World.isRemote) { + return true; + } else if (par7 != 1) { + return false; + } else { + ++par5; + BlockBed var11 = (BlockBed) Block.bed; + int var12 = MathHelper.floor_double((double) (par2EntityPlayer.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + byte var13 = 0; + byte var14 = 0; + + if (var12 == 0) { + var14 = 1; + } + + if (var12 == 1) { + var13 = -1; + } + + if (var12 == 2) { + var14 = -1; + } + + if (var12 == 3) { + var13 = 1; + } + + if (par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack) && par2EntityPlayer.canPlayerEdit(par4 + var13, par5, par6 + var14, par7, par1ItemStack)) { + if (par3World.isAirBlock(par4, par5, par6) && par3World.isAirBlock(par4 + var13, par5, par6 + var14) && par3World.doesBlockHaveSolidTopSurface(par4, par5 - 1, par6) + && par3World.doesBlockHaveSolidTopSurface(par4 + var13, par5 - 1, par6 + var14)) { + par3World.setBlock(par4, par5, par6, var11.blockID, var12, 3); + + if (par3World.getBlockId(par4, par5, par6) == var11.blockID) { + par3World.setBlock(par4 + var13, par5, par6 + var14, var11.blockID, var12 + 8, 3); + } + + --par1ItemStack.stackSize; + return true; + } else { + return false; + } + } else { + return false; + } + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemBlock.java b/src/main/java/net/minecraft/src/ItemBlock.java new file mode 100644 index 0000000..4bb605b --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemBlock.java @@ -0,0 +1,175 @@ +package net.minecraft.src; + +import java.util.List; + +public class ItemBlock extends Item { + /** The block ID of the Block associated with this ItemBlock */ + private int blockID; + private Icon field_94588_b; + + public ItemBlock(int par1) { + super(par1); + this.blockID = par1 + 256; + } + + /** + * Returns the blockID for this Item + */ + public int getBlockID() { + return this.blockID; + } + + /** + * Returns 0 for /terrain.png, 1 for /gui/items.png + */ + public int getSpriteNumber() { + return Block.blocksList[this.blockID].getItemIconName() != null ? 1 : 0; + } + + /** + * Gets an icon index based on an item's damage value + */ + public Icon getIconFromDamage(int par1) { + return this.field_94588_b != null ? this.field_94588_b : Block.blocksList[this.blockID].getBlockTextureFromSide(1); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (var11 == Block.snow.blockID && (par3World.getBlockMetadata(par4, par5, par6) & 7) < 1) { + par7 = 1; + } else if (var11 != Block.vine.blockID && var11 != Block.tallGrass.blockID && var11 != Block.deadBush.blockID) { + if (par7 == 0) { + --par5; + } + + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + } + + if (par1ItemStack.stackSize == 0) { + return false; + } else if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else if (par5 == 255 && Block.blocksList[this.blockID].blockMaterial.isSolid()) { + return false; + } else if (par3World.canPlaceEntityOnSide(this.blockID, par4, par5, par6, false, par7, par2EntityPlayer, par1ItemStack)) { + Block var12 = Block.blocksList[this.blockID]; + int var13 = this.getMetadata(par1ItemStack.getItemDamage()); + int var14 = Block.blocksList[this.blockID].onBlockPlaced(par3World, par4, par5, par6, par7, par8, par9, par10, var13); + + if (par3World.setBlock(par4, par5, par6, this.blockID, var14, 3)) { + if (par3World.getBlockId(par4, par5, par6) == this.blockID) { + Block.blocksList[this.blockID].onBlockPlacedBy(par3World, par4, par5, par6, par2EntityPlayer, par1ItemStack); + Block.blocksList[this.blockID].onPostBlockPlaced(par3World, par4, par5, par6, var14); + } + + par3World.playSoundEffect((double) ((float) par4 + 0.5F), (double) ((float) par5 + 0.5F), (double) ((float) par6 + 0.5F), var12.stepSound.getPlaceSound(), (var12.stepSound.getVolume() + 1.0F) / 2.0F, + var12.stepSound.getPitch() * 0.8F); + --par1ItemStack.stackSize; + } + + return true; + } else { + return false; + } + } + + /** + * Returns true if the given ItemBlock can be placed on the given side of the + * given block position. + */ + public boolean canPlaceItemBlockOnSide(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer, ItemStack par7ItemStack) { + int var8 = par1World.getBlockId(par2, par3, par4); + + if (var8 == Block.snow.blockID) { + par5 = 1; + } else if (var8 != Block.vine.blockID && var8 != Block.tallGrass.blockID && var8 != Block.deadBush.blockID) { + if (par5 == 0) { + --par3; + } + + if (par5 == 1) { + ++par3; + } + + if (par5 == 2) { + --par4; + } + + if (par5 == 3) { + ++par4; + } + + if (par5 == 4) { + --par2; + } + + if (par5 == 5) { + ++par2; + } + } + + return par1World.canPlaceEntityOnSide(this.getBlockID(), par2, par3, par4, false, par5, (Entity) null, par7ItemStack); + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + return Block.blocksList[this.blockID].getUnlocalizedName(); + } + + /** + * Returns the unlocalized name of this item. + */ + public String getUnlocalizedName() { + return Block.blocksList[this.blockID].getUnlocalizedName(); + } + + /** + * gets the CreativeTab this item is displayed on + */ + public CreativeTabs getCreativeTab() { + return Block.blocksList[this.blockID].getCreativeTabToDisplayOn(); + } + + /** + * returns a list of items with the same ID, but different meta (eg: dye returns + * 16 items) + */ + public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List) { + Block.blocksList[this.blockID].getSubBlocks(par1, par2CreativeTabs, par3List); + } + + public void registerIcons(IconRegister par1IconRegister) { + String var2 = Block.blocksList[this.blockID].getItemIconName(); + + if (var2 != null) { + this.field_94588_b = par1IconRegister.registerIcon(var2); + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemBlockWithMetadata.java b/src/main/java/net/minecraft/src/ItemBlockWithMetadata.java new file mode 100644 index 0000000..e5eae7a --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemBlockWithMetadata.java @@ -0,0 +1,26 @@ +package net.minecraft.src; + +public class ItemBlockWithMetadata extends ItemBlock { + private Block theBlock; + + public ItemBlockWithMetadata(int par1, Block par2Block) { + super(par1); + this.theBlock = par2Block; + this.setMaxDamage(0); + this.setHasSubtypes(true); + } + + /** + * Gets an icon index based on an item's damage value + */ + public Icon getIconFromDamage(int par1) { + return this.theBlock.getIcon(2, par1); + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1; + } +} diff --git a/src/main/java/net/minecraft/src/ItemBoat.java b/src/main/java/net/minecraft/src/ItemBoat.java new file mode 100644 index 0000000..b3a5ab8 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemBoat.java @@ -0,0 +1,91 @@ +package net.minecraft.src; + +import java.util.List; + + + +public class ItemBoat extends Item { + public ItemBoat(int par1) { + super(par1); + this.maxStackSize = 1; + this.setCreativeTab(CreativeTabs.tabTransport); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + float var4 = 1.0F; + float var5 = par3EntityPlayer.prevRotationPitch + (par3EntityPlayer.rotationPitch - par3EntityPlayer.prevRotationPitch) * var4; + float var6 = par3EntityPlayer.prevRotationYaw + (par3EntityPlayer.rotationYaw - par3EntityPlayer.prevRotationYaw) * var4; + double var7 = par3EntityPlayer.prevPosX + (par3EntityPlayer.posX - par3EntityPlayer.prevPosX) * (double) var4; + double var9 = par3EntityPlayer.prevPosY + (par3EntityPlayer.posY - par3EntityPlayer.prevPosY) * (double) var4 + 1.62D - (double) par3EntityPlayer.yOffset; + double var11 = par3EntityPlayer.prevPosZ + (par3EntityPlayer.posZ - par3EntityPlayer.prevPosZ) * (double) var4; + Vec3 var13 = par2World.getWorldVec3Pool().getVecFromPool(var7, var9, var11); + float var14 = MathHelper.cos(-var6 * 0.017453292F - (float) Math.PI); + float var15 = MathHelper.sin(-var6 * 0.017453292F - (float) Math.PI); + float var16 = -MathHelper.cos(-var5 * 0.017453292F); + float var17 = MathHelper.sin(-var5 * 0.017453292F); + float var18 = var15 * var16; + float var20 = var14 * var16; + double var21 = 5.0D; + Vec3 var23 = var13.addVector((double) var18 * var21, (double) var17 * var21, (double) var20 * var21); + MovingObjectPosition var24 = par2World.rayTraceBlocks_do(var13, var23, true); + + if (var24 == null) { + return par1ItemStack; + } else { + Vec3 var25 = par3EntityPlayer.getLook(var4); + boolean var26 = false; + float var27 = 1.0F; + List var28 = par2World.getEntitiesWithinAABBExcludingEntity(par3EntityPlayer, + par3EntityPlayer.boundingBox.addCoord(var25.xCoord * var21, var25.yCoord * var21, var25.zCoord * var21).expand((double) var27, (double) var27, (double) var27)); + int var29; + + for (var29 = 0; var29 < var28.size(); ++var29) { + Entity var30 = (Entity) var28.get(var29); + + if (var30.canBeCollidedWith()) { + float var31 = var30.getCollisionBorderSize(); + AxisAlignedBB var32 = var30.boundingBox.expand((double) var31, (double) var31, (double) var31); + + if (var32.isVecInside(var13)) { + var26 = true; + } + } + } + + if (var26) { + return par1ItemStack; + } else { + if (var24.typeOfHit == EnumMovingObjectType.TILE) { + var29 = var24.blockX; + int var33 = var24.blockY; + int var34 = var24.blockZ; + + if (par2World.getBlockId(var29, var33, var34) == Block.snow.blockID) { + --var33; + } + + EntityBoat var35 = new EntityBoat(par2World, (double) ((float) var29 + 0.5F), (double) ((float) var33 + 1.0F), (double) ((float) var34 + 0.5F)); + var35.rotationYaw = (float) (((MathHelper.floor_double((double) (par3EntityPlayer.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) - 1) * 90); + + if (!par2World.getCollidingBoundingBoxes(var35, var35.boundingBox.expand(-0.1D, -0.1D, -0.1D)).isEmpty()) { + return par1ItemStack; + } + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(var35); + } + + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + } + + return par1ItemStack; + } + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemBook.java b/src/main/java/net/minecraft/src/ItemBook.java new file mode 100644 index 0000000..ff309fd --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemBook.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +public class ItemBook extends Item { + public ItemBook(int par1) { + super(par1); + } + + /** + * Checks isDamagable and if it cannot be stacked + */ + public boolean isItemTool(ItemStack par1ItemStack) { + return par1ItemStack.stackSize == 1; + } + + /** + * Return the enchantability factor of the item, most of the time is based on + * material. + */ + public int getItemEnchantability() { + return 1; + } +} diff --git a/src/main/java/net/minecraft/src/ItemBow.java b/src/main/java/net/minecraft/src/ItemBow.java new file mode 100644 index 0000000..d97c953 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemBow.java @@ -0,0 +1,125 @@ +package net.minecraft.src; + +public class ItemBow extends Item { + public static final String[] bowPullIconNameArray = new String[] { "bow_pull_0", "bow_pull_1", "bow_pull_2" }; + private Icon[] iconArray; + + public ItemBow(int par1) { + super(par1); + this.maxStackSize = 1; + this.setMaxDamage(384); + this.setCreativeTab(CreativeTabs.tabCombat); + } + + /** + * called when the player releases the use item button. Args: itemstack, world, + * entityplayer, itemInUseCount + */ + public void onPlayerStoppedUsing(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer, int par4) { + boolean var5 = par3EntityPlayer.capabilities.isCreativeMode || EnchantmentHelper.getEnchantmentLevel(Enchantment.infinity.effectId, par1ItemStack) > 0; + + if (var5 || par3EntityPlayer.inventory.hasItem(Item.arrow.itemID)) { + int var6 = this.getMaxItemUseDuration(par1ItemStack) - par4; + float var7 = (float) var6 / 20.0F; + var7 = (var7 * var7 + var7 * 2.0F) / 3.0F; + + if ((double) var7 < 0.1D) { + return; + } + + if (var7 > 1.0F) { + var7 = 1.0F; + } + + EntityArrow var8 = new EntityArrow(par2World, par3EntityPlayer, var7 * 2.0F); + + if (var7 == 1.0F) { + var8.setIsCritical(true); + } + + int var9 = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, par1ItemStack); + + if (var9 > 0) { + var8.setDamage(var8.getDamage() + (double) var9 * 0.5D + 0.5D); + } + + int var10 = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, par1ItemStack); + + if (var10 > 0) { + var8.setKnockbackStrength(var10); + } + + if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, par1ItemStack) > 0) { + var8.setFire(100); + } + + par1ItemStack.damageItem(1, par3EntityPlayer); + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + var7 * 0.5F); + + if (var5) { + var8.canBePickedUp = 2; + } else { + par3EntityPlayer.inventory.consumeInventoryItem(Item.arrow.itemID); + } + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(var8); + } + } + } + + public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + return par1ItemStack; + } + + /** + * How long it takes to use or consume an item + */ + public int getMaxItemUseDuration(ItemStack par1ItemStack) { + return 72000; + } + + /** + * returns the action that specifies what animation to play when the items is + * being used + */ + public EnumAction getItemUseAction(ItemStack par1ItemStack) { + return EnumAction.bow; + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (par3EntityPlayer.capabilities.isCreativeMode || par3EntityPlayer.inventory.hasItem(Item.arrow.itemID)) { + par3EntityPlayer.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); + } + + return par1ItemStack; + } + + /** + * Return the enchantability factor of the item, most of the time is based on + * material. + */ + public int getItemEnchantability() { + return 1; + } + + public void registerIcons(IconRegister par1IconRegister) { + super.registerIcons(par1IconRegister); + this.iconArray = new Icon[bowPullIconNameArray.length]; + + for (int var2 = 0; var2 < this.iconArray.length; ++var2) { + this.iconArray[var2] = par1IconRegister.registerIcon(bowPullIconNameArray[var2]); + } + } + + /** + * used to cycle through icons based on their used duration, i.e. for the bow + */ + public Icon getItemIconForUseDuration(int par1) { + return this.iconArray[par1]; + } +} diff --git a/src/main/java/net/minecraft/src/ItemBucket.java b/src/main/java/net/minecraft/src/ItemBucket.java new file mode 100644 index 0000000..d5e3249 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemBucket.java @@ -0,0 +1,147 @@ +package net.minecraft.src; + + + +public class ItemBucket extends Item { + /** field for checking if the bucket has been filled. */ + private int isFull; + + public ItemBucket(int par1, int par2) { + super(par1); + this.maxStackSize = 1; + this.isFull = par2; + this.setCreativeTab(CreativeTabs.tabMisc); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + float var4 = 1.0F; + double var5 = par3EntityPlayer.prevPosX + (par3EntityPlayer.posX - par3EntityPlayer.prevPosX) * (double) var4; + double var7 = par3EntityPlayer.prevPosY + (par3EntityPlayer.posY - par3EntityPlayer.prevPosY) * (double) var4 + 1.62D - (double) par3EntityPlayer.yOffset; + double var9 = par3EntityPlayer.prevPosZ + (par3EntityPlayer.posZ - par3EntityPlayer.prevPosZ) * (double) var4; + boolean var11 = this.isFull == 0; + MovingObjectPosition var12 = this.getMovingObjectPositionFromPlayer(par2World, par3EntityPlayer, var11); + + if (var12 == null) { + return par1ItemStack; + } else { + if (var12.typeOfHit == EnumMovingObjectType.TILE) { + int var13 = var12.blockX; + int var14 = var12.blockY; + int var15 = var12.blockZ; + + if (!par2World.canMineBlock(par3EntityPlayer, var13, var14, var15)) { + return par1ItemStack; + } + + if (this.isFull == 0) { + if (!par3EntityPlayer.canPlayerEdit(var13, var14, var15, var12.sideHit, par1ItemStack)) { + return par1ItemStack; + } + + if (par2World.getBlockMaterial(var13, var14, var15) == Material.water && par2World.getBlockMetadata(var13, var14, var15) == 0) { + par2World.setBlockToAir(var13, var14, var15); + + if (par3EntityPlayer.capabilities.isCreativeMode) { + return par1ItemStack; + } + + if (--par1ItemStack.stackSize <= 0) { + return new ItemStack(Item.bucketWater); + } + + if (!par3EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Item.bucketWater))) { + par3EntityPlayer.dropPlayerItem(new ItemStack(Item.bucketWater.itemID, 1, 0)); + } + + return par1ItemStack; + } + + if (par2World.getBlockMaterial(var13, var14, var15) == Material.lava && par2World.getBlockMetadata(var13, var14, var15) == 0) { + par2World.setBlockToAir(var13, var14, var15); + + if (par3EntityPlayer.capabilities.isCreativeMode) { + return par1ItemStack; + } + + if (--par1ItemStack.stackSize <= 0) { + return new ItemStack(Item.bucketLava); + } + + if (!par3EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Item.bucketLava))) { + par3EntityPlayer.dropPlayerItem(new ItemStack(Item.bucketLava.itemID, 1, 0)); + } + + return par1ItemStack; + } + } else { + if (this.isFull < 0) { + return new ItemStack(Item.bucketEmpty); + } + + if (var12.sideHit == 0) { + --var14; + } + + if (var12.sideHit == 1) { + ++var14; + } + + if (var12.sideHit == 2) { + --var15; + } + + if (var12.sideHit == 3) { + ++var15; + } + + if (var12.sideHit == 4) { + --var13; + } + + if (var12.sideHit == 5) { + ++var13; + } + + if (!par3EntityPlayer.canPlayerEdit(var13, var14, var15, var12.sideHit, par1ItemStack)) { + return par1ItemStack; + } + + if (this.tryPlaceContainedLiquid(par2World, var5, var7, var9, var13, var14, var15) && !par3EntityPlayer.capabilities.isCreativeMode) { + return new ItemStack(Item.bucketEmpty); + } + } + } else if (this.isFull == 0 && var12.entityHit instanceof EntityCow) { + return new ItemStack(Item.bucketMilk); + } + + return par1ItemStack; + } + } + + /** + * Attempts to place the liquid contained inside the bucket. + */ + public boolean tryPlaceContainedLiquid(World par1World, double par2, double par4, double par6, int par8, int par9, int par10) { + if (this.isFull <= 0) { + return false; + } else if (!par1World.isAirBlock(par8, par9, par10) && par1World.getBlockMaterial(par8, par9, par10).isSolid()) { + return false; + } else { + if (par1World.provider.isHellWorld && this.isFull == Block.waterMoving.blockID) { + par1World.playSoundEffect(par2 + 0.5D, par4 + 0.5D, par6 + 0.5D, "random.fizz", 0.5F, 2.6F + (par1World.rand.nextFloat() - par1World.rand.nextFloat()) * 0.8F); + + for (int var11 = 0; var11 < 8; ++var11) { + par1World.spawnParticle("largesmoke", (double) par8 + Math.random(), (double) par9 + Math.random(), (double) par10 + Math.random(), 0.0D, 0.0D, 0.0D); + } + } else { + par1World.setBlock(par8, par9, par10, this.isFull, 0, 3); + } + + return true; + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemBucketMilk.java b/src/main/java/net/minecraft/src/ItemBucketMilk.java new file mode 100644 index 0000000..a771ae2 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemBucketMilk.java @@ -0,0 +1,45 @@ +package net.minecraft.src; + +public class ItemBucketMilk extends Item { + public ItemBucketMilk(int par1) { + super(par1); + this.setMaxStackSize(1); + this.setCreativeTab(CreativeTabs.tabMisc); + } + + public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + if (!par2World.isRemote) { + par3EntityPlayer.clearActivePotions(); + } + + return par1ItemStack.stackSize <= 0 ? new ItemStack(Item.bucketEmpty) : par1ItemStack; + } + + /** + * How long it takes to use or consume an item + */ + public int getMaxItemUseDuration(ItemStack par1ItemStack) { + return 32; + } + + /** + * returns the action that specifies what animation to play when the items is + * being used + */ + public EnumAction getItemUseAction(ItemStack par1ItemStack) { + return EnumAction.drink; + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + par3EntityPlayer.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); + return par1ItemStack; + } +} diff --git a/src/main/java/net/minecraft/src/ItemCarrotOnAStick.java b/src/main/java/net/minecraft/src/ItemCarrotOnAStick.java new file mode 100644 index 0000000..6c9cc03 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemCarrotOnAStick.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +public class ItemCarrotOnAStick extends Item { + public ItemCarrotOnAStick(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabTransport); + this.setMaxStackSize(1); + this.setMaxDamage(25); + } + + /** + * Returns True is the item is renderer in full 3D when hold. + */ + public boolean isFull3D() { + return true; + } + + /** + * Returns true if this item should be rotated by 180 degrees around the Y axis + * when being held in an entities hands. + */ + public boolean shouldRotateAroundWhenRendering() { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/ItemCloth.java b/src/main/java/net/minecraft/src/ItemCloth.java new file mode 100644 index 0000000..9fea12d --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemCloth.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class ItemCloth extends ItemBlock { + public ItemCloth(int par1) { + super(par1); + this.setMaxDamage(0); + this.setHasSubtypes(true); + } + + /** + * Gets an icon index based on an item's damage value + */ + public Icon getIconFromDamage(int par1) { + return Block.cloth.getIcon(2, BlockCloth.getBlockFromDye(par1)); + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1; + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + return super.getUnlocalizedName() + "." + ItemDye.dyeColorNames[BlockCloth.getBlockFromDye(par1ItemStack.getItemDamage())]; + } +} diff --git a/src/main/java/net/minecraft/src/ItemCoal.java b/src/main/java/net/minecraft/src/ItemCoal.java new file mode 100644 index 0000000..6463644 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemCoal.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +import java.util.List; + +public class ItemCoal extends Item { + public ItemCoal(int par1) { + super(par1); + this.setHasSubtypes(true); + this.setMaxDamage(0); + this.setCreativeTab(CreativeTabs.tabMaterials); + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + return par1ItemStack.getItemDamage() == 1 ? "item.charcoal" : "item.coal"; + } + + /** + * returns a list of items with the same ID, but different meta (eg: dye returns + * 16 items) + */ + public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List) { + par3List.add(new ItemStack(par1, 1, 0)); + par3List.add(new ItemStack(par1, 1, 1)); + } +} diff --git a/src/main/java/net/minecraft/src/ItemColored.java b/src/main/java/net/minecraft/src/ItemColored.java new file mode 100644 index 0000000..a59d65c --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemColored.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +public class ItemColored extends ItemBlock { + private final Block blockRef; + private String[] blockNames; + + public ItemColored(int par1, boolean par2) { + super(par1); + this.blockRef = Block.blocksList[this.getBlockID()]; + + if (par2) { + this.setMaxDamage(0); + this.setHasSubtypes(true); + } + } + + public int getColorFromItemStack(ItemStack par1ItemStack, int par2) { + return this.blockRef.getRenderColor(par1ItemStack.getItemDamage()); + } + + /** + * Gets an icon index based on an item's damage value + */ + public Icon getIconFromDamage(int par1) { + return this.blockRef.getIcon(0, par1); + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1; + } + + /** + * Sets the array of strings to be used for name lookups from item damage to + * metadata + */ + public ItemColored setBlockNames(String[] par1ArrayOfStr) { + this.blockNames = par1ArrayOfStr; + return this; + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + if (this.blockNames == null) { + return super.getUnlocalizedName(par1ItemStack); + } else { + int var2 = par1ItemStack.getItemDamage(); + return var2 >= 0 && var2 < this.blockNames.length ? super.getUnlocalizedName(par1ItemStack) + "." + this.blockNames[var2] : super.getUnlocalizedName(par1ItemStack); + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemDoor.java b/src/main/java/net/minecraft/src/ItemDoor.java new file mode 100644 index 0000000..ae4ae66 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemDoor.java @@ -0,0 +1,83 @@ +package net.minecraft.src; + +public class ItemDoor extends Item { + private Material doorMaterial; + + public ItemDoor(int par1, Material par2Material) { + super(par1); + this.doorMaterial = par2Material; + this.maxStackSize = 1; + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (par7 != 1) { + return false; + } else { + ++par5; + Block var11; + + if (this.doorMaterial == Material.wood) { + var11 = Block.doorWood; + } else { + var11 = Block.doorIron; + } + + if (par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack) && par2EntityPlayer.canPlayerEdit(par4, par5 + 1, par6, par7, par1ItemStack)) { + if (!var11.canPlaceBlockAt(par3World, par4, par5, par6)) { + return false; + } else { + int var12 = MathHelper.floor_double((double) ((par2EntityPlayer.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3; + placeDoorBlock(par3World, par4, par5, par6, var12, var11); + --par1ItemStack.stackSize; + return true; + } + } else { + return false; + } + } + } + + public static void placeDoorBlock(World par0World, int par1, int par2, int par3, int par4, Block par5Block) { + byte var6 = 0; + byte var7 = 0; + + if (par4 == 0) { + var7 = 1; + } + + if (par4 == 1) { + var6 = -1; + } + + if (par4 == 2) { + var7 = -1; + } + + if (par4 == 3) { + var6 = 1; + } + + int var8 = (par0World.isBlockNormalCube(par1 - var6, par2, par3 - var7) ? 1 : 0) + (par0World.isBlockNormalCube(par1 - var6, par2 + 1, par3 - var7) ? 1 : 0); + int var9 = (par0World.isBlockNormalCube(par1 + var6, par2, par3 + var7) ? 1 : 0) + (par0World.isBlockNormalCube(par1 + var6, par2 + 1, par3 + var7) ? 1 : 0); + boolean var10 = par0World.getBlockId(par1 - var6, par2, par3 - var7) == par5Block.blockID || par0World.getBlockId(par1 - var6, par2 + 1, par3 - var7) == par5Block.blockID; + boolean var11 = par0World.getBlockId(par1 + var6, par2, par3 + var7) == par5Block.blockID || par0World.getBlockId(par1 + var6, par2 + 1, par3 + var7) == par5Block.blockID; + boolean var12 = false; + + if (var10 && !var11) { + var12 = true; + } else if (var9 > var8) { + var12 = true; + } + + par0World.setBlock(par1, par2, par3, par5Block.blockID, par4, 2); + par0World.setBlock(par1, par2 + 1, par3, par5Block.blockID, 8 | (var12 ? 1 : 0), 2); + par0World.notifyBlocksOfNeighborChange(par1, par2, par3, par5Block.blockID); + par0World.notifyBlocksOfNeighborChange(par1, par2 + 1, par3, par5Block.blockID); + } +} diff --git a/src/main/java/net/minecraft/src/ItemDye.java b/src/main/java/net/minecraft/src/ItemDye.java new file mode 100644 index 0000000..a92093a --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemDye.java @@ -0,0 +1,263 @@ +package net.minecraft.src; + +import java.util.List; + +public class ItemDye extends Item { + /** List of dye color names */ + public static final String[] dyeColorNames = new String[] { "black", "red", "green", "brown", "blue", "purple", "cyan", "silver", "gray", "pink", "lime", "yellow", "lightBlue", "magenta", "orange", "white" }; + public static final String[] field_94595_b = new String[] { "dyePowder_black", "dyePowder_red", "dyePowder_green", "dyePowder_brown", "dyePowder_blue", "dyePowder_purple", "dyePowder_cyan", "dyePowder_silver", "dyePowder_gray", + "dyePowder_pink", "dyePowder_lime", "dyePowder_yellow", "dyePowder_lightBlue", "dyePowder_magenta", "dyePowder_orange", "dyePowder_white" }; + public static final int[] dyeColors = new int[] { 1973019, 11743532, 3887386, 5320730, 2437522, 8073150, 2651799, 11250603, 4408131, 14188952, 4312372, 14602026, 6719955, 12801229, 15435844, 15790320 }; + private Icon[] field_94594_d; + + public ItemDye(int par1) { + super(par1); + this.setHasSubtypes(true); + this.setMaxDamage(0); + this.setCreativeTab(CreativeTabs.tabMaterials); + } + + /** + * Gets an icon index based on an item's damage value + */ + public Icon getIconFromDamage(int par1) { + int var2 = MathHelper.clamp_int(par1, 0, 15); + return this.field_94594_d[var2]; + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + int var2 = MathHelper.clamp_int(par1ItemStack.getItemDamage(), 0, 15); + return super.getUnlocalizedName() + "." + dyeColorNames[var2]; + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + if (par1ItemStack.getItemDamage() == 15) { + if (func_96604_a(par1ItemStack, par3World, par4, par5, par6)) { + if (!par3World.isRemote) { + par3World.playAuxSFX(2005, par4, par5, par6, 0); + } + + return true; + } + } else if (par1ItemStack.getItemDamage() == 3) { + int var11 = par3World.getBlockId(par4, par5, par6); + int var12 = par3World.getBlockMetadata(par4, par5, par6); + + if (var11 == Block.wood.blockID && BlockLog.limitToValidMetadata(var12) == 3) { + if (par7 == 0) { + return false; + } + + if (par7 == 1) { + return false; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + + if (par3World.isAirBlock(par4, par5, par6)) { + int var13 = Block.blocksList[Block.cocoaPlant.blockID].onBlockPlaced(par3World, par4, par5, par6, par7, par8, par9, par10, 0); + par3World.setBlock(par4, par5, par6, Block.cocoaPlant.blockID, var13, 2); + + if (!par2EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + } + + return true; + } + } + + return false; + } + } + + public static boolean func_96604_a(ItemStack par0ItemStack, World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockId(par2, par3, par4); + + if (var5 == Block.sapling.blockID) { + if (!par1World.isRemote) { + + --par0ItemStack.stackSize; + } + + return true; + } else if (var5 != Block.mushroomBrown.blockID && var5 != Block.mushroomRed.blockID) { + if (var5 != Block.melonStem.blockID && var5 != Block.pumpkinStem.blockID) { + if (var5 > 0 && Block.blocksList[var5] instanceof BlockCrops) { + if (par1World.getBlockMetadata(par2, par3, par4) == 7) { + return false; + } else { + if (!par1World.isRemote) { + ((BlockCrops) Block.blocksList[var5]).fertilize(par1World, par2, par3, par4); + --par0ItemStack.stackSize; + } + + return true; + } + } else { + int var6; + int var7; + int var8; + + if (var5 == Block.cocoaPlant.blockID) { + var6 = par1World.getBlockMetadata(par2, par3, par4); + var7 = BlockDirectional.getDirection(var6); + var8 = BlockCocoa.func_72219_c(var6); + + if (var8 >= 2) { + return false; + } else { + if (!par1World.isRemote) { + ++var8; + par1World.setBlockMetadataWithNotify(par2, par3, par4, var8 << 2 | var7, 2); + --par0ItemStack.stackSize; + } + + return true; + } + } else if (var5 != Block.grass.blockID) { + return false; + } else { + if (!par1World.isRemote) { + --par0ItemStack.stackSize; + label102: + + for (var6 = 0; var6 < 128; ++var6) { + var7 = par2; + var8 = par3 + 1; + int var9 = par4; + + for (int var10 = 0; var10 < var6 / 16; ++var10) { + var7 += itemRand.nextInt(3) - 1; + var8 += (itemRand.nextInt(3) - 1) * itemRand.nextInt(3) / 2; + var9 += itemRand.nextInt(3) - 1; + + if (par1World.getBlockId(var7, var8 - 1, var9) != Block.grass.blockID || par1World.isBlockNormalCube(var7, var8, var9)) { + continue label102; + } + } + + if (par1World.getBlockId(var7, var8, var9) == 0) { + if (itemRand.nextInt(10) != 0) { + if (Block.tallGrass.canBlockStay(par1World, var7, var8, var9)) { + par1World.setBlock(var7, var8, var9, Block.tallGrass.blockID, 1, 3); + } + } else if (itemRand.nextInt(3) != 0) { + if (Block.plantYellow.canBlockStay(par1World, var7, var8, var9)) { + par1World.setBlock(var7, var8, var9, Block.plantYellow.blockID); + } + } else if (Block.plantRed.canBlockStay(par1World, var7, var8, var9)) { + par1World.setBlock(var7, var8, var9, Block.plantRed.blockID); + } + } + } + } + + return true; + } + } + } else if (par1World.getBlockMetadata(par2, par3, par4) == 7) { + return false; + } else { + if (!par1World.isRemote) { + ((BlockStem) Block.blocksList[var5]).fertilizeStem(par1World, par2, par3, par4); + --par0ItemStack.stackSize; + } + + return true; + } + } else { + if (!par1World.isRemote) { + + --par0ItemStack.stackSize; + } + + return true; + } + } + + public static void func_96603_a(World par0World, int par1, int par2, int par3, int par4) { + int var5 = par0World.getBlockId(par1, par2, par3); + + if (par4 == 0) { + par4 = 15; + } + + Block var6 = var5 > 0 && var5 < Block.blocksList.length ? Block.blocksList[var5] : null; + + if (var6 != null) { + var6.setBlockBoundsBasedOnState(par0World, par1, par2, par3); + + for (int var7 = 0; var7 < par4; ++var7) { + double var8 = itemRand.nextGaussian() * 0.02D; + double var10 = itemRand.nextGaussian() * 0.02D; + double var12 = itemRand.nextGaussian() * 0.02D; + par0World.spawnParticle("happyVillager", (double) ((float) par1 + itemRand.nextFloat()), (double) par2 + (double) itemRand.nextFloat() * var6.getBlockBoundsMaxY(), (double) ((float) par3 + itemRand.nextFloat()), var8, var10, + var12); + } + } + } + + /** + * Called when a player right clicks an entity with an item. + */ + public boolean itemInteractionForEntity(ItemStack par1ItemStack, EntityLiving par2EntityLiving) { + if (par2EntityLiving instanceof EntitySheep) { + EntitySheep var3 = (EntitySheep) par2EntityLiving; + int var4 = BlockCloth.getBlockFromDye(par1ItemStack.getItemDamage()); + + if (!var3.getSheared() && var3.getFleeceColor() != var4) { + var3.setFleeceColor(var4); + --par1ItemStack.stackSize; + } + + return true; + } else { + return false; + } + } + + /** + * returns a list of items with the same ID, but different meta (eg: dye returns + * 16 items) + */ + public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List) { + for (int var4 = 0; var4 < 16; ++var4) { + par3List.add(new ItemStack(par1, 1, var4)); + } + } + + public void registerIcons(IconRegister par1IconRegister) { + this.field_94594_d = new Icon[field_94595_b.length]; + + for (int var2 = 0; var2 < field_94595_b.length; ++var2) { + this.field_94594_d[var2] = par1IconRegister.registerIcon(field_94595_b[var2]); + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemEditableBook.java b/src/main/java/net/minecraft/src/ItemEditableBook.java new file mode 100644 index 0000000..8389a14 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemEditableBook.java @@ -0,0 +1,69 @@ +package net.minecraft.src; + +import java.util.List; + +public class ItemEditableBook extends Item { + public ItemEditableBook(int par1) { + super(par1); + this.setMaxStackSize(1); + } + + public static boolean validBookTagContents(NBTTagCompound par0NBTTagCompound) { + if (!ItemWritableBook.validBookTagPages(par0NBTTagCompound)) { + return false; + } else if (!par0NBTTagCompound.hasKey("title")) { + return false; + } else { + String var1 = par0NBTTagCompound.getString("title"); + return var1 != null && var1.length() <= 16 ? par0NBTTagCompound.hasKey("author") : false; + } + } + + public String getItemDisplayName(ItemStack par1ItemStack) { + if (par1ItemStack.hasTagCompound()) { + NBTTagCompound var2 = par1ItemStack.getTagCompound(); + NBTTagString var3 = (NBTTagString) var2.getTag("title"); + + if (var3 != null) { + return var3.toString(); + } + } + + return super.getItemDisplayName(par1ItemStack); + } + + /** + * allows items to add custom lines of information to the mouseover description + */ + public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { + if (par1ItemStack.hasTagCompound()) { + NBTTagCompound var5 = par1ItemStack.getTagCompound(); + NBTTagString var6 = (NBTTagString) var5.getTag("author"); + + if (var6 != null) { + par3List.add(EnumChatFormatting.GRAY + String.format(StatCollector.translateToLocalFormatted("book.byAuthor", new Object[] { var6.data }), new Object[0])); + } + } + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + par3EntityPlayer.displayGUIBook(par1ItemStack); + return par1ItemStack; + } + + /** + * If this function returns true (or the item is damageable), the ItemStack's + * NBT tag will be sent to the client. + */ + public boolean getShareTag() { + return true; + } + + public boolean hasEffect(ItemStack par1ItemStack) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/ItemEgg.java b/src/main/java/net/minecraft/src/ItemEgg.java new file mode 100644 index 0000000..55243d5 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemEgg.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class ItemEgg extends Item { + public ItemEgg(int par1) { + super(par1); + this.maxStackSize = 16; + this.setCreativeTab(CreativeTabs.tabMaterials); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(new EntityEgg(par2World, par3EntityPlayer)); + } + + return par1ItemStack; + } +} diff --git a/src/main/java/net/minecraft/src/ItemEmptyMap.java b/src/main/java/net/minecraft/src/ItemEmptyMap.java new file mode 100644 index 0000000..3854c3e --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemEmptyMap.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + + + +public class ItemEmptyMap extends ItemMapBase { + protected ItemEmptyMap(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabMisc); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + ItemStack var4 = new ItemStack(Item.map, 1, par2World.getUniqueDataId("map")); + String var5 = "map_" + var4.getItemDamage(); + MapData var6 = new MapData(var5); + par2World.setItemData(var5, var6); + var6.scale = 0; + int var7 = 128 * (1 << var6.scale); + var6.xCenter = (int) (Math.round(par3EntityPlayer.posX / (double) var7) * (long) var7); + var6.zCenter = (int) (Math.round(par3EntityPlayer.posZ / (double) var7) * (long) var7); + var6.dimension = (byte) par2World.provider.dimensionId; + var6.markDirty(); + --par1ItemStack.stackSize; + + if (par1ItemStack.stackSize <= 0) { + return var4; + } else { + if (!par3EntityPlayer.inventory.addItemStackToInventory(var4.copy())) { + par3EntityPlayer.dropPlayerItem(var4); + } + + return par1ItemStack; + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemEnchantedBook.java b/src/main/java/net/minecraft/src/ItemEnchantedBook.java new file mode 100644 index 0000000..b6417c9 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemEnchantedBook.java @@ -0,0 +1,102 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ItemEnchantedBook extends Item { + public ItemEnchantedBook(int par1) { + super(par1); + } + + public boolean hasEffect(ItemStack par1ItemStack) { + return true; + } + + /** + * Checks isDamagable and if it cannot be stacked + */ + public boolean isItemTool(ItemStack par1ItemStack) { + return false; + } + + /** + * Return an item rarity from EnumRarity + */ + public EnumRarity getRarity(ItemStack par1ItemStack) { + return this.func_92110_g(par1ItemStack).tagCount() > 0 ? EnumRarity.uncommon : super.getRarity(par1ItemStack); + } + + public NBTTagList func_92110_g(ItemStack par1ItemStack) { + return par1ItemStack.stackTagCompound != null && par1ItemStack.stackTagCompound.hasKey("StoredEnchantments") ? (NBTTagList) par1ItemStack.stackTagCompound.getTag("StoredEnchantments") : new NBTTagList(); + } + + /** + * allows items to add custom lines of information to the mouseover description + */ + public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { + super.addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); + NBTTagList var5 = this.func_92110_g(par1ItemStack); + + if (var5 != null) { + for (int var6 = 0; var6 < var5.tagCount(); ++var6) { + short var7 = ((NBTTagCompound) var5.tagAt(var6)).getShort("id"); + short var8 = ((NBTTagCompound) var5.tagAt(var6)).getShort("lvl"); + + if (Enchantment.enchantmentsList[var7] != null) { + par3List.add(Enchantment.enchantmentsList[var7].getTranslatedName(var8)); + } + } + } + } + + public void func_92115_a(ItemStack par1ItemStack, EnchantmentData par2EnchantmentData) { + NBTTagList var3 = this.func_92110_g(par1ItemStack); + boolean var4 = true; + + for (int var5 = 0; var5 < var3.tagCount(); ++var5) { + NBTTagCompound var6 = (NBTTagCompound) var3.tagAt(var5); + + if (var6.getShort("id") == par2EnchantmentData.enchantmentobj.effectId) { + if (var6.getShort("lvl") < par2EnchantmentData.enchantmentLevel) { + var6.setShort("lvl", (short) par2EnchantmentData.enchantmentLevel); + } + + var4 = false; + break; + } + } + + if (var4) { + NBTTagCompound var7 = new NBTTagCompound(); + var7.setShort("id", (short) par2EnchantmentData.enchantmentobj.effectId); + var7.setShort("lvl", (short) par2EnchantmentData.enchantmentLevel); + var3.appendTag(var7); + } + + if (!par1ItemStack.hasTagCompound()) { + par1ItemStack.setTagCompound(new NBTTagCompound()); + } + + par1ItemStack.getTagCompound().setTag("StoredEnchantments", var3); + } + + public ItemStack func_92111_a(EnchantmentData par1EnchantmentData) { + ItemStack var2 = new ItemStack(this); + this.func_92115_a(var2, par1EnchantmentData); + return var2; + } + + public void func_92113_a(Enchantment par1Enchantment, List par2List) { + for (int var3 = par1Enchantment.getMinLevel(); var3 <= par1Enchantment.getMaxLevel(); ++var3) { + par2List.add(this.func_92111_a(new EnchantmentData(par1Enchantment, var3))); + } + } + + public ItemStack func_92109_a(Random par1Random) { + Enchantment var2 = Enchantment.field_92090_c[par1Random.nextInt(Enchantment.field_92090_c.length)]; + ItemStack var3 = new ItemStack(this.itemID, 1, 0); + int var4 = MathHelper.getRandomIntegerInRange(par1Random, var2.getMinLevel(), var2.getMaxLevel()); + this.func_92115_a(var3, new EnchantmentData(var2, var4)); + return var3; + } +} diff --git a/src/main/java/net/minecraft/src/ItemEnderEye.java b/src/main/java/net/minecraft/src/ItemEnderEye.java new file mode 100644 index 0000000..9e6ed67 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemEnderEye.java @@ -0,0 +1,154 @@ +package net.minecraft.src; + +public class ItemEnderEye extends Item { + public ItemEnderEye(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabMisc); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + int var11 = par3World.getBlockId(par4, par5, par6); + int var12 = par3World.getBlockMetadata(par4, par5, par6); + + if (par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack) && var11 == Block.endPortalFrame.blockID && !BlockEndPortalFrame.isEnderEyeInserted(var12)) { + if (par3World.isRemote) { + return true; + } else { + par3World.setBlockMetadataWithNotify(par4, par5, par6, var12 + 4, 2); + --par1ItemStack.stackSize; + int var13; + + for (var13 = 0; var13 < 16; ++var13) { + double var14 = (double) ((float) par4 + (5.0F + itemRand.nextFloat() * 6.0F) / 16.0F); + double var16 = (double) ((float) par5 + 0.8125F); + double var18 = (double) ((float) par6 + (5.0F + itemRand.nextFloat() * 6.0F) / 16.0F); + double var20 = 0.0D; + double var22 = 0.0D; + double var24 = 0.0D; + par3World.spawnParticle("smoke", var14, var16, var18, var20, var22, var24); + } + + var13 = var12 & 3; + int var26 = 0; + int var15 = 0; + boolean var27 = false; + boolean var17 = true; + int var28 = Direction.rotateRight[var13]; + int var19; + int var21; + int var23; + int var29; + int var30; + + for (var19 = -2; var19 <= 2; ++var19) { + var29 = par4 + Direction.offsetX[var28] * var19; + var21 = par6 + Direction.offsetZ[var28] * var19; + var30 = par3World.getBlockId(var29, par5, var21); + + if (var30 == Block.endPortalFrame.blockID) { + var23 = par3World.getBlockMetadata(var29, par5, var21); + + if (!BlockEndPortalFrame.isEnderEyeInserted(var23)) { + var17 = false; + break; + } + + var15 = var19; + + if (!var27) { + var26 = var19; + var27 = true; + } + } + } + + if (var17 && var15 == var26 + 2) { + for (var19 = var26; var19 <= var15; ++var19) { + var29 = par4 + Direction.offsetX[var28] * var19; + var21 = par6 + Direction.offsetZ[var28] * var19; + var29 += Direction.offsetX[var13] * 4; + var21 += Direction.offsetZ[var13] * 4; + var30 = par3World.getBlockId(var29, par5, var21); + var23 = par3World.getBlockMetadata(var29, par5, var21); + + if (var30 != Block.endPortalFrame.blockID || !BlockEndPortalFrame.isEnderEyeInserted(var23)) { + var17 = false; + break; + } + } + + for (var19 = var26 - 1; var19 <= var15 + 1; var19 += 4) { + for (var29 = 1; var29 <= 3; ++var29) { + var21 = par4 + Direction.offsetX[var28] * var19; + var30 = par6 + Direction.offsetZ[var28] * var19; + var21 += Direction.offsetX[var13] * var29; + var30 += Direction.offsetZ[var13] * var29; + var23 = par3World.getBlockId(var21, par5, var30); + int var31 = par3World.getBlockMetadata(var21, par5, var30); + + if (var23 != Block.endPortalFrame.blockID || !BlockEndPortalFrame.isEnderEyeInserted(var31)) { + var17 = false; + break; + } + } + } + + if (var17) { + for (var19 = var26; var19 <= var15; ++var19) { + for (var29 = 1; var29 <= 3; ++var29) { + var21 = par4 + Direction.offsetX[var28] * var19; + var30 = par6 + Direction.offsetZ[var28] * var19; + var21 += Direction.offsetX[var13] * var29; + var30 += Direction.offsetZ[var13] * var29; + par3World.setBlock(var21, par5, var30, Block.endPortal.blockID, 0, 2); + } + } + } + } + + return true; + } + } else { + return false; + } + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + MovingObjectPosition var4 = this.getMovingObjectPositionFromPlayer(par2World, par3EntityPlayer, false); + + if (var4 != null && var4.typeOfHit == EnumMovingObjectType.TILE) { + int var5 = par2World.getBlockId(var4.blockX, var4.blockY, var4.blockZ); + + if (var5 == Block.endPortalFrame.blockID) { + return par1ItemStack; + } + } + + if (!par2World.isRemote) { + ChunkPosition var7 = par2World.findClosestStructure("Stronghold", (int) par3EntityPlayer.posX, (int) par3EntityPlayer.posY, (int) par3EntityPlayer.posZ); + + if (var7 != null) { + EntityEnderEye var6 = new EntityEnderEye(par2World, par3EntityPlayer.posX, par3EntityPlayer.posY + 1.62D - (double) par3EntityPlayer.yOffset, par3EntityPlayer.posZ); + var6.moveTowards((double) var7.x, var7.y, (double) var7.z); + par2World.spawnEntityInWorld(var6); + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + par2World.playAuxSFXAtEntity((EntityPlayer) null, 1002, (int) par3EntityPlayer.posX, (int) par3EntityPlayer.posY, (int) par3EntityPlayer.posZ, 0); + + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + } + } + + return par1ItemStack; + } +} diff --git a/src/main/java/net/minecraft/src/ItemEnderPearl.java b/src/main/java/net/minecraft/src/ItemEnderPearl.java new file mode 100644 index 0000000..fbb38ca --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemEnderPearl.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +public class ItemEnderPearl extends Item { + public ItemEnderPearl(int par1) { + super(par1); + this.maxStackSize = 16; + this.setCreativeTab(CreativeTabs.tabMisc); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (par3EntityPlayer.capabilities.isCreativeMode) { + return par1ItemStack; + } else if (par3EntityPlayer.ridingEntity != null) { + return par1ItemStack; + } else { + --par1ItemStack.stackSize; + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(new EntityEnderPearl(par2World, par3EntityPlayer)); + } + + return par1ItemStack; + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemExpBottle.java b/src/main/java/net/minecraft/src/ItemExpBottle.java new file mode 100644 index 0000000..4d8be50 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemExpBottle.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +public class ItemExpBottle extends Item { + public ItemExpBottle(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabMisc); + } + + public boolean hasEffect(ItemStack par1ItemStack) { + return true; + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(new EntityExpBottle(par2World, par3EntityPlayer)); + } + + return par1ItemStack; + } +} diff --git a/src/main/java/net/minecraft/src/ItemFireball.java b/src/main/java/net/minecraft/src/ItemFireball.java new file mode 100644 index 0000000..0141c65 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemFireball.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +public class ItemFireball extends Item { + public ItemFireball(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabMisc); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (par3World.isRemote) { + return true; + } else { + if (par7 == 0) { + --par5; + } + + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (var11 == 0) { + par3World.playSoundEffect((double) par4 + 0.5D, (double) par5 + 0.5D, (double) par6 + 0.5D, "fire.ignite", 1.0F, itemRand.nextFloat() * 0.4F + 0.8F); + par3World.setBlock(par4, par5, par6, Block.fire.blockID); + } + + if (!par2EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + return true; + } + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemFirework.java b/src/main/java/net/minecraft/src/ItemFirework.java new file mode 100644 index 0000000..41cad57 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemFirework.java @@ -0,0 +1,63 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +public class ItemFirework extends Item { + public ItemFirework(int par1) { + super(par1); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (!par3World.isRemote) { + EntityFireworkRocket var11 = new EntityFireworkRocket(par3World, (double) ((float) par4 + par8), (double) ((float) par5 + par9), (double) ((float) par6 + par10), par1ItemStack); + par3World.spawnEntityInWorld(var11); + + if (!par2EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + return true; + } else { + return false; + } + } + + /** + * allows items to add custom lines of information to the mouseover description + */ + public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { + if (par1ItemStack.hasTagCompound()) { + NBTTagCompound var5 = par1ItemStack.getTagCompound().getCompoundTag("Fireworks"); + + if (var5 != null) { + if (var5.hasKey("Flight")) { + par3List.add(StatCollector.translateToLocal("item.fireworks.flight") + " " + var5.getByte("Flight")); + } + + NBTTagList var6 = var5.getTagList("Explosions"); + + if (var6 != null && var6.tagCount() > 0) { + for (int var7 = 0; var7 < var6.tagCount(); ++var7) { + NBTTagCompound var8 = (NBTTagCompound) var6.tagAt(var7); + ArrayList var9 = new ArrayList(); + ItemFireworkCharge.func_92107_a(var8, var9); + + if (var9.size() > 0) { + for (int var10 = 1; var10 < var9.size(); ++var10) { + var9.set(var10, " " + (String) var9.get(var10)); + } + + par3List.addAll(var9); + } + } + } + } + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemFireworkCharge.java b/src/main/java/net/minecraft/src/ItemFireworkCharge.java new file mode 100644 index 0000000..f9b4eda --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemFireworkCharge.java @@ -0,0 +1,181 @@ +package net.minecraft.src; + +import java.util.List; + +public class ItemFireworkCharge extends Item { + private Icon theIcon; + + public ItemFireworkCharge(int par1) { + super(par1); + } + + /** + * Gets an icon index based on an item's damage value and the given render pass + */ + public Icon getIconFromDamageForRenderPass(int par1, int par2) { + return par2 > 0 ? this.theIcon : super.getIconFromDamageForRenderPass(par1, par2); + } + + public int getColorFromItemStack(ItemStack par1ItemStack, int par2) { + if (par2 != 1) { + return super.getColorFromItemStack(par1ItemStack, par2); + } else { + NBTBase var3 = func_92108_a(par1ItemStack, "Colors"); + + if (var3 == null) { + return 9079434; + } else { + NBTTagIntArray var4 = (NBTTagIntArray) var3; + + if (var4.intArray.length == 1) { + return var4.intArray[0]; + } else { + int var5 = 0; + int var6 = 0; + int var7 = 0; + int[] var8 = var4.intArray; + int var9 = var8.length; + + for (int var10 = 0; var10 < var9; ++var10) { + int var11 = var8[var10]; + var5 += (var11 & 16711680) >> 16; + var6 += (var11 & 65280) >> 8; + var7 += (var11 & 255) >> 0; + } + + var5 /= var4.intArray.length; + var6 /= var4.intArray.length; + var7 /= var4.intArray.length; + return var5 << 16 | var6 << 8 | var7; + } + } + } + } + + public boolean requiresMultipleRenderPasses() { + return true; + } + + public static NBTBase func_92108_a(ItemStack par0ItemStack, String par1Str) { + if (par0ItemStack.hasTagCompound()) { + NBTTagCompound var2 = par0ItemStack.getTagCompound().getCompoundTag("Explosion"); + + if (var2 != null) { + return var2.getTag(par1Str); + } + } + + return null; + } + + /** + * allows items to add custom lines of information to the mouseover description + */ + public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { + if (par1ItemStack.hasTagCompound()) { + NBTTagCompound var5 = par1ItemStack.getTagCompound().getCompoundTag("Explosion"); + + if (var5 != null) { + func_92107_a(var5, par3List); + } + } + } + + public static void func_92107_a(NBTTagCompound par0NBTTagCompound, List par1List) { + byte var2 = par0NBTTagCompound.getByte("Type"); + + if (var2 >= 0 && var2 <= 4) { + par1List.add(StatCollector.translateToLocal("item.fireworksCharge.type." + var2).trim()); + } else { + par1List.add(StatCollector.translateToLocal("item.fireworksCharge.type").trim()); + } + + int[] var3 = par0NBTTagCompound.getIntArray("Colors"); + int var8; + int var9; + + if (var3.length > 0) { + boolean var4 = true; + String var5 = ""; + int[] var6 = var3; + int var7 = var3.length; + + for (var8 = 0; var8 < var7; ++var8) { + var9 = var6[var8]; + + if (!var4) { + var5 = var5 + ", "; + } + + var4 = false; + boolean var10 = false; + + for (int var11 = 0; var11 < 16; ++var11) { + if (var9 == ItemDye.dyeColors[var11]) { + var10 = true; + var5 = var5 + StatCollector.translateToLocal("item.fireworksCharge." + ItemDye.dyeColorNames[var11]); + break; + } + } + + if (!var10) { + var5 = var5 + StatCollector.translateToLocal("item.fireworksCharge.customColor"); + } + } + + par1List.add(var5); + } + + int[] var13 = par0NBTTagCompound.getIntArray("FadeColors"); + boolean var15; + + if (var13.length > 0) { + var15 = true; + String var14 = StatCollector.translateToLocal("item.fireworksCharge.fadeTo") + " "; + int[] var16 = var13; + var8 = var13.length; + + for (var9 = 0; var9 < var8; ++var9) { + int var18 = var16[var9]; + + if (!var15) { + var14 = var14 + ", "; + } + + var15 = false; + boolean var19 = false; + + for (int var12 = 0; var12 < 16; ++var12) { + if (var18 == ItemDye.dyeColors[var12]) { + var19 = true; + var14 = var14 + StatCollector.translateToLocal("item.fireworksCharge." + ItemDye.dyeColorNames[var12]); + break; + } + } + + if (!var19) { + var14 = var14 + StatCollector.translateToLocal("item.fireworksCharge.customColor"); + } + } + + par1List.add(var14); + } + + var15 = par0NBTTagCompound.getBoolean("Trail"); + + if (var15) { + par1List.add(StatCollector.translateToLocal("item.fireworksCharge.trail")); + } + + boolean var17 = par0NBTTagCompound.getBoolean("Flicker"); + + if (var17) { + par1List.add(StatCollector.translateToLocal("item.fireworksCharge.flicker")); + } + } + + public void registerIcons(IconRegister par1IconRegister) { + super.registerIcons(par1IconRegister); + this.theIcon = par1IconRegister.registerIcon("fireworksCharge_overlay"); + } +} diff --git a/src/main/java/net/minecraft/src/ItemFishingRod.java b/src/main/java/net/minecraft/src/ItemFishingRod.java new file mode 100644 index 0000000..ec57aba --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemFishingRod.java @@ -0,0 +1,58 @@ +package net.minecraft.src; + +public class ItemFishingRod extends Item { + private Icon theIcon; + + public ItemFishingRod(int par1) { + super(par1); + this.setMaxDamage(64); + this.setMaxStackSize(1); + this.setCreativeTab(CreativeTabs.tabTools); + } + + /** + * Returns True is the item is renderer in full 3D when hold. + */ + public boolean isFull3D() { + return true; + } + + /** + * Returns true if this item should be rotated by 180 degrees around the Y axis + * when being held in an entities hands. + */ + public boolean shouldRotateAroundWhenRendering() { + return true; + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (par3EntityPlayer.fishEntity != null) { + int var4 = par3EntityPlayer.fishEntity.catchFish(); + par1ItemStack.damageItem(var4, par3EntityPlayer); + par3EntityPlayer.swingItem(); + } else { + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(new EntityFishHook(par2World, par3EntityPlayer)); + } + + par3EntityPlayer.swingItem(); + } + + return par1ItemStack; + } + + public void registerIcons(IconRegister par1IconRegister) { + super.registerIcons(par1IconRegister); + this.theIcon = par1IconRegister.registerIcon("fishingRod_empty"); + } + + public Icon func_94597_g() { + return this.theIcon; + } +} diff --git a/src/main/java/net/minecraft/src/ItemFlintAndSteel.java b/src/main/java/net/minecraft/src/ItemFlintAndSteel.java new file mode 100644 index 0000000..1cf9fc0 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemFlintAndSteel.java @@ -0,0 +1,55 @@ +package net.minecraft.src; + +public class ItemFlintAndSteel extends Item { + public ItemFlintAndSteel(int par1) { + super(par1); + this.maxStackSize = 1; + this.setMaxDamage(64); + this.setCreativeTab(CreativeTabs.tabTools); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (par7 == 0) { + --par5; + } + + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (var11 == 0) { + par3World.playSoundEffect((double) par4 + 0.5D, (double) par5 + 0.5D, (double) par6 + 0.5D, "fire.ignite", 1.0F, itemRand.nextFloat() * 0.4F + 0.8F); + par3World.setBlock(par4, par5, par6, Block.fire.blockID); + } + + par1ItemStack.damageItem(1, par2EntityPlayer); + return true; + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemFood.java b/src/main/java/net/minecraft/src/ItemFood.java new file mode 100644 index 0000000..e69a018 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemFood.java @@ -0,0 +1,127 @@ +package net.minecraft.src; + +public class ItemFood extends Item { + /** Number of ticks to run while 'EnumAction'ing until result. */ + public final int itemUseDuration; + + /** The amount this food item heals the player. */ + private final int healAmount; + private final float saturationModifier; + + /** Whether wolves like this food (true for raw and cooked porkchop). */ + private final boolean isWolfsFavoriteMeat; + + /** + * If this field is true, the food can be consumed even if the player don't need + * to eat. + */ + private boolean alwaysEdible; + + /** + * represents the potion effect that will occurr upon eating this food. Set by + * setPotionEffect + */ + private int potionId; + + /** set by setPotionEffect */ + private int potionDuration; + + /** set by setPotionEffect */ + private int potionAmplifier; + + /** probably of the set potion effect occurring */ + private float potionEffectProbability; + + public ItemFood(int par1, int par2, float par3, boolean par4) { + super(par1); + this.itemUseDuration = 32; + this.healAmount = par2; + this.isWolfsFavoriteMeat = par4; + this.saturationModifier = par3; + this.setCreativeTab(CreativeTabs.tabFood); + } + + public ItemFood(int par1, int par2, boolean par3) { + this(par1, par2, 0.6F, par3); + } + + public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + --par1ItemStack.stackSize; + par3EntityPlayer.getFoodStats().addStats(this); + par2World.playSoundAtEntity(par3EntityPlayer, "random.burp", 0.5F, par2World.rand.nextFloat() * 0.1F + 0.9F); + this.onFoodEaten(par1ItemStack, par2World, par3EntityPlayer); + return par1ItemStack; + } + + protected void onFoodEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (!par2World.isRemote && this.potionId > 0 && par2World.rand.nextFloat() < this.potionEffectProbability) { + par3EntityPlayer.addPotionEffect(new PotionEffect(this.potionId, this.potionDuration * 20, this.potionAmplifier)); + } + } + + /** + * How long it takes to use or consume an item + */ + public int getMaxItemUseDuration(ItemStack par1ItemStack) { + return 32; + } + + /** + * returns the action that specifies what animation to play when the items is + * being used + */ + public EnumAction getItemUseAction(ItemStack par1ItemStack) { + return EnumAction.eat; + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (par3EntityPlayer.canEat(this.alwaysEdible)) { + par3EntityPlayer.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); + } + + return par1ItemStack; + } + + public int getHealAmount() { + return this.healAmount; + } + + /** + * gets the saturationModifier of the ItemFood + */ + public float getSaturationModifier() { + return this.saturationModifier; + } + + /** + * Whether wolves like this food (true for raw and cooked porkchop). + */ + public boolean isWolfsFavoriteMeat() { + return this.isWolfsFavoriteMeat; + } + + /** + * sets a potion effect on the item. Args: int potionId, int duration (will be + * multiplied by 20), int amplifier, float probability of effect happening + */ + public ItemFood setPotionEffect(int par1, int par2, int par3, float par4) { + this.potionId = par1; + this.potionDuration = par2; + this.potionAmplifier = par3; + this.potionEffectProbability = par4; + return this; + } + + /** + * Set the field 'alwaysEdible' to true, and make the food edible even if the + * player don't need to eat. + */ + public ItemFood setAlwaysEdible() { + this.alwaysEdible = true; + return this; + } +} diff --git a/src/main/java/net/minecraft/src/ItemGlassBottle.java b/src/main/java/net/minecraft/src/ItemGlassBottle.java new file mode 100644 index 0000000..cc6cc93 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemGlassBottle.java @@ -0,0 +1,58 @@ +package net.minecraft.src; + +public class ItemGlassBottle extends Item { + public ItemGlassBottle(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabBrewing); + } + + /** + * Gets an icon index based on an item's damage value + */ + public Icon getIconFromDamage(int par1) { + return Item.potion.getIconFromDamage(0); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + MovingObjectPosition var4 = this.getMovingObjectPositionFromPlayer(par2World, par3EntityPlayer, true); + + if (var4 == null) { + return par1ItemStack; + } else { + if (var4.typeOfHit == EnumMovingObjectType.TILE) { + int var5 = var4.blockX; + int var6 = var4.blockY; + int var7 = var4.blockZ; + + if (!par2World.canMineBlock(par3EntityPlayer, var5, var6, var7)) { + return par1ItemStack; + } + + if (!par3EntityPlayer.canPlayerEdit(var5, var6, var7, var4.sideHit, par1ItemStack)) { + return par1ItemStack; + } + + if (par2World.getBlockMaterial(var5, var6, var7) == Material.water) { + --par1ItemStack.stackSize; + + if (par1ItemStack.stackSize <= 0) { + return new ItemStack(Item.potion); + } + + if (!par3EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Item.potion))) { + par3EntityPlayer.dropPlayerItem(new ItemStack(Item.potion.itemID, 1, 0)); + } + } + } + + return par1ItemStack; + } + } + + public void registerIcons(IconRegister par1IconRegister) { + } +} diff --git a/src/main/java/net/minecraft/src/ItemHangingEntity.java b/src/main/java/net/minecraft/src/ItemHangingEntity.java new file mode 100644 index 0000000..2f0cbae --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemHangingEntity.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + +public class ItemHangingEntity extends Item { + private final Class hangingEntityClass; + + public ItemHangingEntity(int par1, Class par2Class) { + super(par1); + this.hangingEntityClass = par2Class; + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (par7 == 0) { + return false; + } else if (par7 == 1) { + return false; + } else { + int var11 = Direction.facingToDirection[par7]; + EntityHanging var12 = this.createHangingEntity(par3World, par4, par5, par6, var11); + + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + if (var12 != null && var12.onValidSurface()) { + if (!par3World.isRemote) { + par3World.spawnEntityInWorld(var12); + } + + --par1ItemStack.stackSize; + } + + return true; + } + } + } + + /** + * Create the hanging entity associated to this item. + */ + private EntityHanging createHangingEntity(World par1World, int par2, int par3, int par4, int par5) { + return (EntityHanging) (this.hangingEntityClass == EntityPainting.class ? new EntityPainting(par1World, par2, par3, par4, par5) + : (this.hangingEntityClass == EntityItemFrame.class ? new EntityItemFrame(par1World, par2, par3, par4, par5) : null)); + } +} diff --git a/src/main/java/net/minecraft/src/ItemHoe.java b/src/main/java/net/minecraft/src/ItemHoe.java new file mode 100644 index 0000000..2e24f6f --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemHoe.java @@ -0,0 +1,58 @@ +package net.minecraft.src; + +public class ItemHoe extends Item { + protected EnumToolMaterial theToolMaterial; + + public ItemHoe(int par1, EnumToolMaterial par2EnumToolMaterial) { + super(par1); + this.theToolMaterial = par2EnumToolMaterial; + this.maxStackSize = 1; + this.setMaxDamage(par2EnumToolMaterial.getMaxUses()); + this.setCreativeTab(CreativeTabs.tabTools); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + int var11 = par3World.getBlockId(par4, par5, par6); + int var12 = par3World.getBlockId(par4, par5 + 1, par6); + + if ((par7 == 0 || var12 != 0 || var11 != Block.grass.blockID) && var11 != Block.dirt.blockID) { + return false; + } else { + Block var13 = Block.tilledField; + par3World.playSoundEffect((double) ((float) par4 + 0.5F), (double) ((float) par5 + 0.5F), (double) ((float) par6 + 0.5F), var13.stepSound.getStepSound(), (var13.stepSound.getVolume() + 1.0F) / 2.0F, + var13.stepSound.getPitch() * 0.8F); + + if (par3World.isRemote) { + return true; + } else { + par3World.setBlock(par4, par5, par6, var13.blockID); + par1ItemStack.damageItem(1, par2EntityPlayer); + return true; + } + } + } + } + + /** + * Returns True is the item is renderer in full 3D when hold. + */ + public boolean isFull3D() { + return true; + } + + /** + * Returns the name of the material this tool is made from as it is declared in + * EnumToolMaterial (meaning diamond would return "EMERALD") + */ + public String getMaterialName() { + return this.theToolMaterial.toString(); + } +} diff --git a/src/main/java/net/minecraft/src/ItemLeaves.java b/src/main/java/net/minecraft/src/ItemLeaves.java new file mode 100644 index 0000000..e2e0e6a --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemLeaves.java @@ -0,0 +1,42 @@ +package net.minecraft.src; + +public class ItemLeaves extends ItemBlock { + public ItemLeaves(int par1) { + super(par1); + this.setMaxDamage(0); + this.setHasSubtypes(true); + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1 | 4; + } + + /** + * Gets an icon index based on an item's damage value + */ + public Icon getIconFromDamage(int par1) { + return Block.leaves.getIcon(0, par1); + } + + public int getColorFromItemStack(ItemStack par1ItemStack, int par2) { + int var3 = par1ItemStack.getItemDamage(); + return (var3 & 1) == 1 ? ColorizerFoliage.getFoliageColorPine() : ((var3 & 2) == 2 ? ColorizerFoliage.getFoliageColorBirch() : ColorizerFoliage.getFoliageColorBasic()); + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + int var2 = par1ItemStack.getItemDamage(); + + if (var2 < 0 || var2 >= BlockLeaves.LEAF_TYPES.length) { + var2 = 0; + } + + return super.getUnlocalizedName() + "." + BlockLeaves.LEAF_TYPES[var2]; + } +} diff --git a/src/main/java/net/minecraft/src/ItemLilyPad.java b/src/main/java/net/minecraft/src/ItemLilyPad.java new file mode 100644 index 0000000..8e9c03a --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemLilyPad.java @@ -0,0 +1,47 @@ +package net.minecraft.src; + +public class ItemLilyPad extends ItemColored { + public ItemLilyPad(int par1) { + super(par1, false); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + MovingObjectPosition var4 = this.getMovingObjectPositionFromPlayer(par2World, par3EntityPlayer, true); + + if (var4 == null) { + return par1ItemStack; + } else { + if (var4.typeOfHit == EnumMovingObjectType.TILE) { + int var5 = var4.blockX; + int var6 = var4.blockY; + int var7 = var4.blockZ; + + if (!par2World.canMineBlock(par3EntityPlayer, var5, var6, var7)) { + return par1ItemStack; + } + + if (!par3EntityPlayer.canPlayerEdit(var5, var6, var7, var4.sideHit, par1ItemStack)) { + return par1ItemStack; + } + + if (par2World.getBlockMaterial(var5, var6, var7) == Material.water && par2World.getBlockMetadata(var5, var6, var7) == 0 && par2World.isAirBlock(var5, var6 + 1, var7)) { + par2World.setBlock(var5, var6 + 1, var7, Block.waterlily.blockID); + + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + } + } + + return par1ItemStack; + } + } + + public int getColorFromItemStack(ItemStack par1ItemStack, int par2) { + return Block.waterlily.getRenderColor(par1ItemStack.getItemDamage()); + } +} diff --git a/src/main/java/net/minecraft/src/ItemMap.java b/src/main/java/net/minecraft/src/ItemMap.java new file mode 100644 index 0000000..80645a7 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemMap.java @@ -0,0 +1,285 @@ +package net.minecraft.src; + +import java.util.List; + + + +public class ItemMap extends ItemMapBase { + protected ItemMap(int par1) { + super(par1); + this.setHasSubtypes(true); + } + + public static MapData getMPMapData(short par0, World par1World) { + String var2 = "map_" + par0; + MapData var3 = (MapData) par1World.loadItemData(MapData.class, var2); + + if (var3 == null) { + var3 = new MapData(var2); + par1World.setItemData(var2, var3); + } + + return var3; + } + + public MapData getMapData(ItemStack par1ItemStack, World par2World) { + String var3 = "map_" + par1ItemStack.getItemDamage(); + MapData var4 = (MapData) par2World.loadItemData(MapData.class, var3); + + if (var4 == null && !par2World.isRemote) { + par1ItemStack.setItemDamage(par2World.getUniqueDataId("map")); + var3 = "map_" + par1ItemStack.getItemDamage(); + var4 = new MapData(var3); + var4.scale = 3; + int var5 = 128 * (1 << var4.scale); + var4.xCenter = Math.round((float) par2World.getWorldInfo().getSpawnX() / (float) var5) * var5; + var4.zCenter = Math.round((float) (par2World.getWorldInfo().getSpawnZ() / var5)) * var5; + var4.dimension = (byte) par2World.provider.dimensionId; + var4.markDirty(); + par2World.setItemData(var3, var4); + } + + return var4; + } + + public void updateMapData(World par1World, Entity par2Entity, MapData par3MapData) { + if (par1World.provider.dimensionId == par3MapData.dimension && par2Entity instanceof EntityPlayer) { + short var4 = 128; + short var5 = 128; + int var6 = 1 << par3MapData.scale; + int var7 = par3MapData.xCenter; + int var8 = par3MapData.zCenter; + int var9 = MathHelper.floor_double(par2Entity.posX - (double) var7) / var6 + var4 / 2; + int var10 = MathHelper.floor_double(par2Entity.posZ - (double) var8) / var6 + var5 / 2; + int var11 = 128 / var6; + + if (par1World.provider.hasNoSky) { + var11 /= 2; + } + + MapInfo var12 = par3MapData.func_82568_a((EntityPlayer) par2Entity); + ++var12.field_82569_d; + + for (int var13 = var9 - var11 + 1; var13 < var9 + var11; ++var13) { + if ((var13 & 15) == (var12.field_82569_d & 15)) { + int var14 = 255; + int var15 = 0; + double var16 = 0.0D; + + for (int var18 = var10 - var11 - 1; var18 < var10 + var11; ++var18) { + if (var13 >= 0 && var18 >= -1 && var13 < var4 && var18 < var5) { + int var19 = var13 - var9; + int var20 = var18 - var10; + boolean var21 = var19 * var19 + var20 * var20 > (var11 - 2) * (var11 - 2); + int var22 = (var7 / var6 + var13 - var4 / 2) * var6; + int var23 = (var8 / var6 + var18 - var5 / 2) * var6; + int[] var24 = new int[256]; + Chunk var25 = par1World.getChunkFromBlockCoords(var22, var23); + + if (!var25.isEmpty()) { + int var26 = var22 & 15; + int var27 = var23 & 15; + int var28 = 0; + double var29 = 0.0D; + int var31; + int var32; + int var33; + int var36; + + if (par1World.provider.hasNoSky) { + var31 = var22 + var23 * 231871; + var31 = var31 * var31 * 31287121 + var31 * 11; + + if ((var31 >> 20 & 1) == 0) { + var24[Block.dirt.blockID] += 10; + } else { + var24[Block.stone.blockID] += 10; + } + + var29 = 100.0D; + } else { + for (var31 = 0; var31 < var6; ++var31) { + for (var32 = 0; var32 < var6; ++var32) { + var33 = var25.getHeightValue(var31 + var26, var32 + var27) + 1; + int var34 = 0; + + if (var33 > 1) { + boolean var35; + + do { + var35 = true; + var34 = var25.getBlockID(var31 + var26, var33 - 1, var32 + var27); + + if (var34 == 0) { + var35 = false; + } else if (var33 > 0 && var34 > 0 && Block.blocksList[var34].blockMaterial.materialMapColor == MapColor.airColor) { + var35 = false; + } + + if (!var35) { + --var33; + + if (var33 <= 0) { + break; + } + + var34 = var25.getBlockID(var31 + var26, var33 - 1, var32 + var27); + } + } while (var33 > 0 && !var35); + + if (var33 > 0 && var34 != 0 && Block.blocksList[var34].blockMaterial.isLiquid()) { + var36 = var33 - 1; + boolean var37 = false; + int var41; + + do { + var41 = var25.getBlockID(var31 + var26, var36--, var32 + var27); + ++var28; + } while (var36 > 0 && var41 != 0 && Block.blocksList[var41].blockMaterial.isLiquid()); + } + } + + var29 += (double) var33 / (double) (var6 * var6); + ++var24[var34]; + } + } + } + + var28 /= var6 * var6; + var31 = 0; + var32 = 0; + + for (var33 = 0; var33 < 256; ++var33) { + if (var24[var33] > var31) { + var32 = var33; + var31 = var24[var33]; + } + } + + double var39 = (var29 - var16) * 4.0D / (double) (var6 + 4) + ((double) (var13 + var18 & 1) - 0.5D) * 0.4D; + byte var40 = 1; + + if (var39 > 0.6D) { + var40 = 2; + } + + if (var39 < -0.6D) { + var40 = 0; + } + + var36 = 0; + + if (var32 > 0) { + MapColor var42 = Block.blocksList[var32].blockMaterial.materialMapColor; + + if (var42 == MapColor.waterColor) { + var39 = (double) var28 * 0.1D + (double) (var13 + var18 & 1) * 0.2D; + var40 = 1; + + if (var39 < 0.5D) { + var40 = 2; + } + + if (var39 > 0.9D) { + var40 = 0; + } + } + + var36 = var42.colorIndex; + } + + var16 = var29; + + if (var18 >= 0 && var19 * var19 + var20 * var20 < var11 * var11 && (!var21 || (var13 + var18 & 1) != 0)) { + byte var43 = par3MapData.colors[var13 + var18 * var4]; + byte var38 = (byte) (var36 * 4 + var40); + + if (var43 != var38) { + if (var14 > var18) { + var14 = var18; + } + + if (var15 < var18) { + var15 = var18; + } + + par3MapData.colors[var13 + var18 * var4] = var38; + } + } + } + } + } + + if (var14 <= var15) { + par3MapData.setColumnDirty(var13, var14, var15); + } + } + } + } + } + + /** + * Called each tick as long the item is on a player inventory. Uses by maps to + * check if is on a player hand and update it's contents. + */ + public void onUpdate(ItemStack par1ItemStack, World par2World, Entity par3Entity, int par4, boolean par5) { + if (!par2World.isRemote) { + MapData var6 = this.getMapData(par1ItemStack, par2World); + + if (par3Entity instanceof EntityPlayer) { + EntityPlayer var7 = (EntityPlayer) par3Entity; + var6.updateVisiblePlayers(var7, par1ItemStack); + } + + if (par5) { + this.updateMapData(par2World, par3Entity, var6); + } + } + } + + /** + * returns null if no update is to be sent + */ + public Packet createMapDataPacket(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + byte[] var4 = this.getMapData(par1ItemStack, par2World).getUpdatePacketData(par1ItemStack, par2World, par3EntityPlayer); + return var4 == null ? null : new Packet131MapData((short) Item.map.itemID, (short) par1ItemStack.getItemDamage(), var4); + } + + /** + * Called when item is crafted/smelted. Used only by maps so far. + */ + public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (par1ItemStack.hasTagCompound() && par1ItemStack.getTagCompound().getBoolean("map_is_scaling")) { + MapData var4 = Item.map.getMapData(par1ItemStack, par2World); + par1ItemStack.setItemDamage(par2World.getUniqueDataId("map")); + MapData var5 = new MapData("map_" + par1ItemStack.getItemDamage()); + var5.scale = (byte) (var4.scale + 1); + + if (var5.scale > 4) { + var5.scale = 4; + } + + var5.xCenter = var4.xCenter; + var5.zCenter = var4.zCenter; + var5.dimension = var4.dimension; + var5.markDirty(); + par2World.setItemData("map_" + par1ItemStack.getItemDamage(), var5); + } + } + + /** + * allows items to add custom lines of information to the mouseover description + */ + public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { + MapData var5 = this.getMapData(par1ItemStack, par2EntityPlayer.worldObj); + + if (par4) { + if (var5 == null) { + par3List.add("Unknown map"); + } else { + par3List.add("Scaling at 1:" + (1 << var5.scale)); + par3List.add("(Level " + var5.scale + "/" + 4 + ")"); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemMapBase.java b/src/main/java/net/minecraft/src/ItemMapBase.java new file mode 100644 index 0000000..1b6472f --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemMapBase.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +public class ItemMapBase extends Item { + protected ItemMapBase(int par1) { + super(par1); + } + + /** + * false for all Items except sub-classes of ItemMapBase + */ + public boolean isMap() { + return true; + } + + /** + * returns null if no update is to be sent + */ + public Packet createMapDataPacket(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + return null; + } +} diff --git a/src/main/java/net/minecraft/src/ItemMinecart.java b/src/main/java/net/minecraft/src/ItemMinecart.java new file mode 100644 index 0000000..33a2cf6 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemMinecart.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + +public class ItemMinecart extends Item { + public int minecartType; + + public ItemMinecart(int par1, int par2) { + super(par1); + this.maxStackSize = 1; + this.minecartType = par2; + this.setCreativeTab(CreativeTabs.tabTransport); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (BlockRailBase.isRailBlock(var11)) { + if (!par3World.isRemote) { + EntityMinecart var12 = EntityMinecart.createMinecart(par3World, (double) ((float) par4 + 0.5F), (double) ((float) par5 + 0.5F), (double) ((float) par6 + 0.5F), this.minecartType); + + if (par1ItemStack.hasDisplayName()) { + var12.func_96094_a(par1ItemStack.getDisplayName()); + } + + par3World.spawnEntityInWorld(var12); + } + + --par1ItemStack.stackSize; + return true; + } else { + return false; + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemMonsterPlacer.java b/src/main/java/net/minecraft/src/ItemMonsterPlacer.java new file mode 100644 index 0000000..19ef3ec --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemMonsterPlacer.java @@ -0,0 +1,123 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class ItemMonsterPlacer extends Item { + private Icon theIcon; + + public ItemMonsterPlacer(int par1) { + super(par1); + this.setHasSubtypes(true); + this.setCreativeTab(CreativeTabs.tabMisc); + } + + public String getItemDisplayName(ItemStack par1ItemStack) { + String var2 = ("" + StatCollector.translateToLocal(this.getUnlocalizedName() + ".name")).trim(); + String var3 = EntityList.getStringFromID(par1ItemStack.getItemDamage()); + + if (var3 != null) { + var2 = var2 + " " + StatCollector.translateToLocal("entity." + var3 + ".name"); + } + + return var2; + } + + public int getColorFromItemStack(ItemStack par1ItemStack, int par2) { + EntityEggInfo var3 = (EntityEggInfo) EntityList.entityEggs.get(Integer.valueOf(par1ItemStack.getItemDamage())); + return var3 != null ? (par2 == 0 ? var3.primaryColor : var3.secondaryColor) : 16777215; + } + + public boolean requiresMultipleRenderPasses() { + return true; + } + + /** + * Gets an icon index based on an item's damage value and the given render pass + */ + public Icon getIconFromDamageForRenderPass(int par1, int par2) { + return par2 > 0 ? this.theIcon : super.getIconFromDamageForRenderPass(par1, par2); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (par3World.isRemote) { + return true; + } else { + int var11 = par3World.getBlockId(par4, par5, par6); + par4 += Facing.offsetsXForSide[par7]; + par5 += Facing.offsetsYForSide[par7]; + par6 += Facing.offsetsZForSide[par7]; + double var12 = 0.0D; + + if (par7 == 1 && Block.blocksList[var11] != null && Block.blocksList[var11].getRenderType() == 11) { + var12 = 0.5D; + } + + Entity var14 = spawnCreature(par3World, par1ItemStack.getItemDamage(), (double) par4 + 0.5D, (double) par5 + var12, (double) par6 + 0.5D); + + if (var14 != null) { + if (var14 instanceof EntityLiving && par1ItemStack.hasDisplayName()) { + ((EntityLiving) var14).func_94058_c(par1ItemStack.getDisplayName()); + } + + if (!par2EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + } + + return true; + } + } + + /** + * Spawns the creature specified by the egg's type in the location specified by + * the last three parameters. Parameters: world, entityID, x, y, z. + */ + public static Entity spawnCreature(World par0World, int par1, double par2, double par4, double par6) { + if (!EntityList.entityEggs.containsKey(Integer.valueOf(par1))) { + return null; + } else { + Entity var8 = null; + + for (int var9 = 0; var9 < 1; ++var9) { + var8 = EntityList.createEntityByID(par1, par0World); + + if (var8 != null && var8 instanceof EntityLiving) { + EntityLiving var10 = (EntityLiving) var8; + var10.setWorld(par0World); + var8.setLocationAndAngles(par2, par4, par6, MathHelper.wrapAngleTo180_float(par0World.rand.nextFloat() * 360.0F), 0.0F); + var10.rotationYawHead = var10.rotationYaw; + var10.renderYawOffset = var10.rotationYaw; + var10.initCreature(); + par0World.spawnEntityInWorld(var8); + var10.playLivingSound(); + } + } + + return var8; + } + } + + /** + * returns a list of items with the same ID, but different meta (eg: dye returns + * 16 items) + */ + public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List) { + Iterator var4 = EntityList.entityEggs.values().iterator(); + + while (var4.hasNext()) { + EntityEggInfo var5 = (EntityEggInfo) var4.next(); + par3List.add(new ItemStack(par1, 1, var5.spawnedID)); + } + } + + public void registerIcons(IconRegister par1IconRegister) { + super.registerIcons(par1IconRegister); + this.theIcon = par1IconRegister.registerIcon("monsterPlacer_overlay"); + } +} diff --git a/src/main/java/net/minecraft/src/ItemMultiTextureTile.java b/src/main/java/net/minecraft/src/ItemMultiTextureTile.java new file mode 100644 index 0000000..ffda8b4 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemMultiTextureTile.java @@ -0,0 +1,42 @@ +package net.minecraft.src; + +public class ItemMultiTextureTile extends ItemBlock { + private final Block theBlock; + private final String[] field_82804_b; + + public ItemMultiTextureTile(int par1, Block par2Block, String[] par3ArrayOfStr) { + super(par1); + this.theBlock = par2Block; + this.field_82804_b = par3ArrayOfStr; + this.setMaxDamage(0); + this.setHasSubtypes(true); + } + + /** + * Gets an icon index based on an item's damage value + */ + public Icon getIconFromDamage(int par1) { + return this.theBlock.getIcon(2, par1); + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1; + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + int var2 = par1ItemStack.getItemDamage(); + + if (var2 < 0 || var2 >= this.field_82804_b.length) { + var2 = 0; + } + + return super.getUnlocalizedName() + "." + this.field_82804_b[var2]; + } +} diff --git a/src/main/java/net/minecraft/src/ItemPickaxe.java b/src/main/java/net/minecraft/src/ItemPickaxe.java new file mode 100644 index 0000000..cc48422 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemPickaxe.java @@ -0,0 +1,37 @@ +package net.minecraft.src; + +public class ItemPickaxe extends ItemTool { + /** an array of the blocks this pickaxe is effective against */ + private static Block[] blocksEffectiveAgainst = new Block[] { Block.cobblestone, Block.stoneDoubleSlab, Block.stoneSingleSlab, Block.stone, Block.sandStone, Block.cobblestoneMossy, Block.oreIron, Block.blockIron, Block.oreCoal, + Block.blockGold, Block.oreGold, Block.oreDiamond, Block.blockDiamond, Block.ice, Block.netherrack, Block.oreLapis, Block.blockLapis, Block.oreRedstone, Block.oreRedstoneGlowing, Block.rail, Block.railDetector, Block.railPowered, + Block.railActivator }; + + protected ItemPickaxe(int par1, EnumToolMaterial par2EnumToolMaterial) { + super(par1, 2, par2EnumToolMaterial, blocksEffectiveAgainst); + } + + /** + * Returns if the item (tool) can harvest results from the block type. + */ + public boolean canHarvestBlock(Block par1Block) { + return par1Block == Block.obsidian ? this.toolMaterial.getHarvestLevel() == 3 + : (par1Block != Block.blockDiamond && par1Block != Block.oreDiamond + ? (par1Block != Block.oreEmerald && par1Block != Block.blockEmerald + ? (par1Block != Block.blockGold && par1Block != Block.oreGold ? (par1Block != Block.blockIron && par1Block != Block.oreIron ? (par1Block != Block.blockLapis && par1Block != Block.oreLapis + ? (par1Block != Block.oreRedstone && par1Block != Block.oreRedstoneGlowing + ? (par1Block.blockMaterial == Material.rock ? true : (par1Block.blockMaterial == Material.iron ? true : par1Block.blockMaterial == Material.anvil)) + : this.toolMaterial.getHarvestLevel() >= 2) + : this.toolMaterial.getHarvestLevel() >= 1) : this.toolMaterial.getHarvestLevel() >= 1) : this.toolMaterial.getHarvestLevel() >= 2) + : this.toolMaterial.getHarvestLevel() >= 2) + : this.toolMaterial.getHarvestLevel() >= 2); + } + + /** + * Returns the strength of the stack against a given block. 1.0F base, + * (Quality+1)*2 if correct blocktype, 1.5F if sword + */ + public float getStrVsBlock(ItemStack par1ItemStack, Block par2Block) { + return par2Block != null && (par2Block.blockMaterial == Material.iron || par2Block.blockMaterial == Material.anvil || par2Block.blockMaterial == Material.rock) ? this.efficiencyOnProperMaterial + : super.getStrVsBlock(par1ItemStack, par2Block); + } +} diff --git a/src/main/java/net/minecraft/src/ItemPiston.java b/src/main/java/net/minecraft/src/ItemPiston.java new file mode 100644 index 0000000..5bb7ad0 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemPiston.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +public class ItemPiston extends ItemBlock { + public ItemPiston(int par1) { + super(par1); + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return 7; + } +} diff --git a/src/main/java/net/minecraft/src/ItemPotion.java b/src/main/java/net/minecraft/src/ItemPotion.java new file mode 100644 index 0000000..1b92a8a --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemPotion.java @@ -0,0 +1,318 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class ItemPotion extends Item { + /** maps potion damage values to lists of effect names */ + private HashMap effectCache = new HashMap(); + private static final Map field_77835_b = new LinkedHashMap(); + private Icon field_94591_c; + private Icon field_94590_d; + private Icon field_94592_ct; + + public ItemPotion(int par1) { + super(par1); + this.setMaxStackSize(1); + this.setHasSubtypes(true); + this.setMaxDamage(0); + this.setCreativeTab(CreativeTabs.tabBrewing); + } + + /** + * Returns a list of potion effects for the specified itemstack. + */ + public List getEffects(ItemStack par1ItemStack) { + if (par1ItemStack.hasTagCompound() && par1ItemStack.getTagCompound().hasKey("CustomPotionEffects")) { + ArrayList var6 = new ArrayList(); + NBTTagList var3 = par1ItemStack.getTagCompound().getTagList("CustomPotionEffects"); + + for (int var4 = 0; var4 < var3.tagCount(); ++var4) { + NBTTagCompound var5 = (NBTTagCompound) var3.tagAt(var4); + var6.add(PotionEffect.readCustomPotionEffectFromNBT(var5)); + } + + return var6; + } else { + List var2 = (List) this.effectCache.get(Integer.valueOf(par1ItemStack.getItemDamage())); + + if (var2 == null) { + var2 = PotionHelper.getPotionEffects(par1ItemStack.getItemDamage(), false); + this.effectCache.put(Integer.valueOf(par1ItemStack.getItemDamage()), var2); + } + + return var2; + } + } + + /** + * Returns a list of effects for the specified potion damage value. + */ + public List getEffects(int par1) { + List var2 = (List) this.effectCache.get(Integer.valueOf(par1)); + + if (var2 == null) { + var2 = PotionHelper.getPotionEffects(par1, false); + this.effectCache.put(Integer.valueOf(par1), var2); + } + + return var2; + } + + public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + if (!par2World.isRemote) { + List var4 = this.getEffects(par1ItemStack); + + if (var4 != null) { + Iterator var5 = var4.iterator(); + + while (var5.hasNext()) { + PotionEffect var6 = (PotionEffect) var5.next(); + par3EntityPlayer.addPotionEffect(new PotionEffect(var6)); + } + } + } + + if (!par3EntityPlayer.capabilities.isCreativeMode) { + if (par1ItemStack.stackSize <= 0) { + return new ItemStack(Item.glassBottle); + } + + par3EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Item.glassBottle)); + } + + return par1ItemStack; + } + + /** + * How long it takes to use or consume an item + */ + public int getMaxItemUseDuration(ItemStack par1ItemStack) { + return 32; + } + + /** + * returns the action that specifies what animation to play when the items is + * being used + */ + public EnumAction getItemUseAction(ItemStack par1ItemStack) { + return EnumAction.drink; + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (isSplash(par1ItemStack.getItemDamage())) { + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(new EntityPotion(par2World, par3EntityPlayer, par1ItemStack)); + } + + return par1ItemStack; + } else { + par3EntityPlayer.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); + return par1ItemStack; + } + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + return false; + } + + /** + * Gets an icon index based on an item's damage value + */ + public Icon getIconFromDamage(int par1) { + return isSplash(par1) ? this.field_94591_c : this.field_94590_d; + } + + /** + * Gets an icon index based on an item's damage value and the given render pass + */ + public Icon getIconFromDamageForRenderPass(int par1, int par2) { + return par2 == 0 ? this.field_94592_ct : super.getIconFromDamageForRenderPass(par1, par2); + } + + /** + * returns wether or not a potion is a throwable splash potion based on damage + * value + */ + public static boolean isSplash(int par0) { + return (par0 & 16384) != 0; + } + + public int getColorFromDamage(int par1) { + return PotionHelper.func_77915_a(par1, false); + } + + public int getColorFromItemStack(ItemStack par1ItemStack, int par2) { + return par2 > 0 ? 16777215 : this.getColorFromDamage(par1ItemStack.getItemDamage()); + } + + public boolean requiresMultipleRenderPasses() { + return true; + } + + public boolean isEffectInstant(int par1) { + List var2 = this.getEffects(par1); + + if (var2 != null && !var2.isEmpty()) { + Iterator var3 = var2.iterator(); + PotionEffect var4; + + do { + if (!var3.hasNext()) { + return false; + } + + var4 = (PotionEffect) var3.next(); + } while (!Potion.potionTypes[var4.getPotionID()].isInstant()); + + return true; + } else { + return false; + } + } + + public String getItemDisplayName(ItemStack par1ItemStack) { + if (par1ItemStack.getItemDamage() == 0) { + return StatCollector.translateToLocal("item.emptyPotion.name").trim(); + } else { + String var2 = ""; + + if (isSplash(par1ItemStack.getItemDamage())) { + var2 = StatCollector.translateToLocal("potion.prefix.grenade").trim() + " "; + } + + List var3 = Item.potion.getEffects(par1ItemStack); + String var4; + + if (var3 != null && !var3.isEmpty()) { + var4 = ((PotionEffect) var3.get(0)).getEffectName(); + var4 = var4 + ".postfix"; + return var2 + StatCollector.translateToLocal(var4).trim(); + } else { + var4 = PotionHelper.func_77905_c(par1ItemStack.getItemDamage()); + return StatCollector.translateToLocal(var4).trim() + " " + super.getItemDisplayName(par1ItemStack); + } + } + } + + /** + * allows items to add custom lines of information to the mouseover description + */ + public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { + if (par1ItemStack.getItemDamage() != 0) { + List var5 = Item.potion.getEffects(par1ItemStack); + + if (var5 != null && !var5.isEmpty()) { + Iterator var9 = var5.iterator(); + + while (var9.hasNext()) { + PotionEffect var7 = (PotionEffect) var9.next(); + String var8 = StatCollector.translateToLocal(var7.getEffectName()).trim(); + + if (var7.getAmplifier() > 0) { + var8 = var8 + " " + StatCollector.translateToLocal("potion.potency." + var7.getAmplifier()).trim(); + } + + if (var7.getDuration() > 20) { + var8 = var8 + " (" + Potion.getDurationString(var7) + ")"; + } + + if (Potion.potionTypes[var7.getPotionID()].isBadEffect()) { + par3List.add(EnumChatFormatting.RED + var8); + } else { + par3List.add(EnumChatFormatting.GRAY + var8); + } + } + } else { + String var6 = StatCollector.translateToLocal("potion.empty").trim(); + par3List.add(EnumChatFormatting.GRAY + var6); + } + } + } + + public boolean hasEffect(ItemStack par1ItemStack) { + List var2 = this.getEffects(par1ItemStack); + return var2 != null && !var2.isEmpty(); + } + + /** + * returns a list of items with the same ID, but different meta (eg: dye returns + * 16 items) + */ + public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List) { + super.getSubItems(par1, par2CreativeTabs, par3List); + int var5; + + if (field_77835_b.isEmpty()) { + for (int var4 = 0; var4 <= 15; ++var4) { + for (var5 = 0; var5 <= 1; ++var5) { + int var6; + + if (var5 == 0) { + var6 = var4 | 8192; + } else { + var6 = var4 | 16384; + } + + for (int var7 = 0; var7 <= 2; ++var7) { + int var8 = var6; + + if (var7 != 0) { + if (var7 == 1) { + var8 = var6 | 32; + } else if (var7 == 2) { + var8 = var6 | 64; + } + } + + List var9 = PotionHelper.getPotionEffects(var8, false); + + if (var9 != null && !var9.isEmpty()) { + field_77835_b.put(var9, Integer.valueOf(var8)); + } + } + } + } + } + + Iterator var10 = field_77835_b.values().iterator(); + + while (var10.hasNext()) { + var5 = ((Integer) var10.next()).intValue(); + par3List.add(new ItemStack(par1, 1, var5)); + } + } + + public void registerIcons(IconRegister par1IconRegister) { + this.field_94590_d = par1IconRegister.registerIcon("potion"); + this.field_94591_c = par1IconRegister.registerIcon("potion_splash"); + this.field_94592_ct = par1IconRegister.registerIcon("potion_contents"); + } + + public static Icon func_94589_d(String par0Str) { + return par0Str == "potion" ? Item.potion.field_94590_d : (par0Str == "potion_splash" ? Item.potion.field_94591_c : (par0Str == "potion_contents" ? Item.potion.field_94592_ct : null)); + } +} diff --git a/src/main/java/net/minecraft/src/ItemRecord.java b/src/main/java/net/minecraft/src/ItemRecord.java new file mode 100644 index 0000000..2da2b78 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemRecord.java @@ -0,0 +1,80 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ItemRecord extends Item { + /** List of all record items and their names. */ + private static final Map records = new HashMap(); + + /** The name of the record. */ + public final String recordName; + + protected ItemRecord(int par1, String par2Str) { + super(par1); + this.recordName = par2Str; + this.maxStackSize = 1; + this.setCreativeTab(CreativeTabs.tabMisc); + records.put(par2Str, this); + } + + /** + * Gets an icon index based on an item's damage value + */ + public Icon getIconFromDamage(int par1) { + return this.itemIcon; + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (par3World.getBlockId(par4, par5, par6) == Block.jukebox.blockID && par3World.getBlockMetadata(par4, par5, par6) == 0) { + if (par3World.isRemote) { + return true; + } else { + ((BlockJukeBox) Block.jukebox).insertRecord(par3World, par4, par5, par6, par1ItemStack); + par3World.playAuxSFXAtEntity((EntityPlayer) null, 1005, par4, par5, par6, this.itemID); + --par1ItemStack.stackSize; + return true; + } + } else { + return false; + } + } + + /** + * allows items to add custom lines of information to the mouseover description + */ + public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { + par3List.add(this.getRecordTitle()); + } + + /** + * Return the title for this record. + */ + public String getRecordTitle() { + return "C418 - " + this.recordName; + } + + /** + * Return an item rarity from EnumRarity + */ + public EnumRarity getRarity(ItemStack par1ItemStack) { + return EnumRarity.rare; + } + + /** + * Return the record item corresponding to the given name. + */ + public static ItemRecord getRecord(String par0Str) { + return (ItemRecord) records.get(par0Str); + } + + public void registerIcons(IconRegister par1IconRegister) { + this.itemIcon = par1IconRegister.registerIcon("record_" + this.recordName); + } +} diff --git a/src/main/java/net/minecraft/src/ItemRedstone.java b/src/main/java/net/minecraft/src/ItemRedstone.java new file mode 100644 index 0000000..6276070 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemRedstone.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +public class ItemRedstone extends Item { + public ItemRedstone(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (par3World.getBlockId(par4, par5, par6) != Block.snow.blockID) { + if (par7 == 0) { + --par5; + } + + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + + if (!par3World.isAirBlock(par4, par5, par6)) { + return false; + } + } + + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + if (Block.redstoneWire.canPlaceBlockAt(par3World, par4, par5, par6)) { + --par1ItemStack.stackSize; + par3World.setBlock(par4, par5, par6, Block.redstoneWire.blockID); + } + + return true; + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemReed.java b/src/main/java/net/minecraft/src/ItemReed.java new file mode 100644 index 0000000..ebf65b0 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemReed.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +public class ItemReed extends Item { + /** The ID of the block the reed will spawn when used from inventory bar. */ + private int spawnID; + + public ItemReed(int par1, Block par2Block) { + super(par1); + this.spawnID = par2Block.blockID; + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (var11 == Block.snow.blockID && (par3World.getBlockMetadata(par4, par5, par6) & 7) < 1) { + par7 = 1; + } else if (var11 != Block.vine.blockID && var11 != Block.tallGrass.blockID && var11 != Block.deadBush.blockID) { + if (par7 == 0) { + --par5; + } + + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + } + + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else if (par1ItemStack.stackSize == 0) { + return false; + } else { + if (par3World.canPlaceEntityOnSide(this.spawnID, par4, par5, par6, false, par7, (Entity) null, par1ItemStack)) { + Block var12 = Block.blocksList[this.spawnID]; + int var13 = var12.onBlockPlaced(par3World, par4, par5, par6, par7, par8, par9, par10, 0); + + if (par3World.setBlock(par4, par5, par6, this.spawnID, var13, 3)) { + if (par3World.getBlockId(par4, par5, par6) == this.spawnID) { + Block.blocksList[this.spawnID].onBlockPlacedBy(par3World, par4, par5, par6, par2EntityPlayer, par1ItemStack); + Block.blocksList[this.spawnID].onPostBlockPlaced(par3World, par4, par5, par6, var13); + } + + par3World.playSoundEffect((double) ((float) par4 + 0.5F), (double) ((float) par5 + 0.5F), (double) ((float) par6 + 0.5F), var12.stepSound.getPlaceSound(), (var12.stepSound.getVolume() + 1.0F) / 2.0F, + var12.stepSound.getPitch() * 0.8F); + --par1ItemStack.stackSize; + } + } + + return true; + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemRenderer.java b/src/main/java/net/minecraft/src/ItemRenderer.java new file mode 100644 index 0000000..2ee05f6 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemRenderer.java @@ -0,0 +1,638 @@ +package net.minecraft.src; + +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; + +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class ItemRenderer { + /** A reference to the Minecraft object. */ + private Minecraft mc; + private ItemStack itemToRender = null; + + /** + * How far the current item has been equipped (0 disequipped and 1 fully up) + */ + private float equippedProgress = 0.0F; + private float prevEquippedProgress = 0.0F; + + /** Instance of RenderBlocks. */ + private RenderBlocks renderBlocksInstance = new RenderBlocks(); + public final MapItemRenderer mapItemRenderer; + + /** The index of the currently held item (0-8, or -1 if not yet updated) */ + private int equippedItemSlot = -1; + + public ItemRenderer(Minecraft par1Minecraft) { + this.mc = par1Minecraft; + this.mapItemRenderer = new MapItemRenderer(par1Minecraft.fontRenderer, par1Minecraft.gameSettings, par1Minecraft.renderEngine); + } + + private static final TextureLocation terrain = new TextureLocation("/terrain.png"); + public static final TextureLocation items = new TextureLocation("/gui/items.png"); + private static final TextureLocation glint = new TextureLocation("%blur%/misc/glint.png"); + + /** + * Renders the item stack for being in an entity's hand Args: itemStack + */ + public void renderItem(EntityLiving par1EntityLiving, ItemStack par2ItemStack, int par3) { + EaglerAdapter.glPushMatrix(); + + if (par2ItemStack.getItemSpriteNumber() == 0 && Block.blocksList[par2ItemStack.itemID] != null && RenderBlocks.renderItemIn3d(Block.blocksList[par2ItemStack.itemID].getRenderType())) { + terrain.bindTexture(); + this.renderBlocksInstance.renderBlockAsItem(Block.blocksList[par2ItemStack.itemID], par2ItemStack.getItemDamage(), 1.0F); + } else { + Icon var4 = par1EntityLiving.getItemIcon(par2ItemStack, par3); + + if (var4 == null) { + EaglerAdapter.glPopMatrix(); + return; + } + + if (par2ItemStack.getItemSpriteNumber() == 0) { + terrain.bindTexture(); + } else { + items.bindTexture(); + } + + Tessellator var5 = Tessellator.instance; + float var6 = var4.getMinU(); + float var7 = var4.getMaxU(); + float var8 = var4.getMinV(); + float var9 = var4.getMaxV(); + float var10 = 0.0F; + float var11 = 0.3F; + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + EaglerAdapter.glTranslatef(-var10, -var11, 0.0F); + float var12 = 1.5F; + EaglerAdapter.glScalef(var12, var12, var12); + EaglerAdapter.glRotatef(50.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(335.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glTranslatef(-0.9375F, -0.0625F, 0.0F); + renderItemIn2D(var5, var7, var8, var6, var9, var4.getSheetWidth(), var4.getSheetHeight(), 0.0625F); + + if (par2ItemStack != null && par2ItemStack.hasEffect() && par3 == 0) { + EaglerAdapter.glDepthFunc(EaglerAdapter.GL_EQUAL); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + glint.bindTexture(); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_COLOR, EaglerAdapter.GL_ONE); + float var13 = 0.76F; + EaglerAdapter.glColor4f(0.5F * var13, 0.25F * var13, 0.8F * var13, 1.0F); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_TEXTURE); + EaglerAdapter.glPushMatrix(); + float var14 = 0.125F; + EaglerAdapter.glScalef(var14, var14, var14); + float var15 = (float) (Minecraft.getSystemTime() % 3000L) / 3000.0F * 8.0F; + EaglerAdapter.glTranslatef(var15, 0.0F, 0.0F); + EaglerAdapter.glRotatef(-50.0F, 0.0F, 0.0F, 1.0F); + renderItemIn2D(var5, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glScalef(var14, var14, var14); + var15 = (float) (Minecraft.getSystemTime() % 4873L) / 4873.0F * 8.0F; + EaglerAdapter.glTranslatef(-var15, 0.0F, 0.0F); + EaglerAdapter.glRotatef(10.0F, 0.0F, 0.0F, 1.0F); + renderItemIn2D(var5, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glDepthFunc(EaglerAdapter.GL_LEQUAL); + } + + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + } + + EaglerAdapter.glPopMatrix(); + } + + /** + * Renders an item held in hand as a 2D texture with thickness + */ + public static void renderItemIn2D(Tessellator par0Tessellator, float par1, float par2, float par3, float par4, int par5, int par6, float par7) { + par0Tessellator.startDrawingQuads(); + par0Tessellator.setNormal(0.0F, 0.0F, 1.0F); + par0Tessellator.addVertexWithUV(0.0D, 0.0D, 0.0D, (double) par1, (double) par4); + par0Tessellator.addVertexWithUV(1.0D, 0.0D, 0.0D, (double) par3, (double) par4); + par0Tessellator.addVertexWithUV(1.0D, 1.0D, 0.0D, (double) par3, (double) par2); + par0Tessellator.addVertexWithUV(0.0D, 1.0D, 0.0D, (double) par1, (double) par2); + par0Tessellator.draw(); + par0Tessellator.startDrawingQuads(); + par0Tessellator.setNormal(0.0F, 0.0F, -1.0F); + par0Tessellator.addVertexWithUV(0.0D, 1.0D, (double) (0.0F - par7), (double) par1, (double) par2); + par0Tessellator.addVertexWithUV(1.0D, 1.0D, (double) (0.0F - par7), (double) par3, (double) par2); + par0Tessellator.addVertexWithUV(1.0D, 0.0D, (double) (0.0F - par7), (double) par3, (double) par4); + par0Tessellator.addVertexWithUV(0.0D, 0.0D, (double) (0.0F - par7), (double) par1, (double) par4); + par0Tessellator.draw(); + float var8 = (float) par5 * (par1 - par3); + float var9 = (float) par6 * (par4 - par2); + par0Tessellator.startDrawingQuads(); + par0Tessellator.setNormal(-1.0F, 0.0F, 0.0F); + int var10; + float var11; + float var12; + + for (var10 = 0; (float) var10 < var8; ++var10) { + var11 = (float) var10 / var8; + var12 = par1 + (par3 - par1) * var11 - 0.5F / (float) par5; + par0Tessellator.addVertexWithUV((double) var11, 0.0D, (double) (0.0F - par7), (double) var12, (double) par4); + par0Tessellator.addVertexWithUV((double) var11, 0.0D, 0.0D, (double) var12, (double) par4); + par0Tessellator.addVertexWithUV((double) var11, 1.0D, 0.0D, (double) var12, (double) par2); + par0Tessellator.addVertexWithUV((double) var11, 1.0D, (double) (0.0F - par7), (double) var12, (double) par2); + } + + par0Tessellator.draw(); + par0Tessellator.startDrawingQuads(); + par0Tessellator.setNormal(1.0F, 0.0F, 0.0F); + float var13; + + for (var10 = 0; (float) var10 < var8; ++var10) { + var11 = (float) var10 / var8; + var12 = par1 + (par3 - par1) * var11 - 0.5F / (float) par5; + var13 = var11 + 1.0F / var8; + par0Tessellator.addVertexWithUV((double) var13, 1.0D, (double) (0.0F - par7), (double) var12, (double) par2); + par0Tessellator.addVertexWithUV((double) var13, 1.0D, 0.0D, (double) var12, (double) par2); + par0Tessellator.addVertexWithUV((double) var13, 0.0D, 0.0D, (double) var12, (double) par4); + par0Tessellator.addVertexWithUV((double) var13, 0.0D, (double) (0.0F - par7), (double) var12, (double) par4); + } + + par0Tessellator.draw(); + par0Tessellator.startDrawingQuads(); + par0Tessellator.setNormal(0.0F, 1.0F, 0.0F); + + for (var10 = 0; (float) var10 < var9; ++var10) { + var11 = (float) var10 / var9; + var12 = par4 + (par2 - par4) * var11 - 0.5F / (float) par6; + var13 = var11 + 1.0F / var9; + par0Tessellator.addVertexWithUV(0.0D, (double) var13, 0.0D, (double) par1, (double) var12); + par0Tessellator.addVertexWithUV(1.0D, (double) var13, 0.0D, (double) par3, (double) var12); + par0Tessellator.addVertexWithUV(1.0D, (double) var13, (double) (0.0F - par7), (double) par3, (double) var12); + par0Tessellator.addVertexWithUV(0.0D, (double) var13, (double) (0.0F - par7), (double) par1, (double) var12); + } + + par0Tessellator.draw(); + par0Tessellator.startDrawingQuads(); + par0Tessellator.setNormal(0.0F, -1.0F, 0.0F); + + for (var10 = 0; (float) var10 < var9; ++var10) { + var11 = (float) var10 / var9; + var12 = par4 + (par2 - par4) * var11 - 0.5F / (float) par6; + par0Tessellator.addVertexWithUV(1.0D, (double) var11, 0.0D, (double) par3, (double) var12); + par0Tessellator.addVertexWithUV(0.0D, (double) var11, 0.0D, (double) par1, (double) var12); + par0Tessellator.addVertexWithUV(0.0D, (double) var11, (double) (0.0F - par7), (double) par1, (double) var12); + par0Tessellator.addVertexWithUV(1.0D, (double) var11, (double) (0.0F - par7), (double) par3, (double) var12); + } + + par0Tessellator.draw(); + } + + private static final TextureLocation mapbg = new TextureLocation("/misc/mapbg.png"); + + /** + * Renders the active item in the player's hand when in first person mode. Args: + * partialTickTime + */ + public void renderItemInFirstPerson(float par1) { + float var2 = this.prevEquippedProgress + (this.equippedProgress - this.prevEquippedProgress) * par1; + EntityClientPlayerMP var3 = this.mc.thePlayer; + float var4 = var3.prevRotationPitch + (var3.rotationPitch - var3.prevRotationPitch) * par1; + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glRotatef(var4, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(var3.prevRotationYaw + (var3.rotationYaw - var3.prevRotationYaw) * par1, 0.0F, 1.0F, 0.0F); + RenderHelper.enableStandardItemLighting(); + EaglerAdapter.glPopMatrix(); + float var6; + float var7; + + if (var3 instanceof EntityPlayerSP) { + EntityPlayerSP var5 = (EntityPlayerSP) var3; + var6 = var5.prevRenderArmPitch + (var5.renderArmPitch - var5.prevRenderArmPitch) * par1; + var7 = var5.prevRenderArmYaw + (var5.renderArmYaw - var5.prevRenderArmYaw) * par1; + EaglerAdapter.glRotatef((var3.rotationPitch - var6) * 0.1F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef((var3.rotationYaw - var7) * 0.1F, 0.0F, 1.0F, 0.0F); + } + + ItemStack var17 = this.itemToRender; + var6 = this.mc.theWorld.getLightBrightness(MathHelper.floor_double(var3.posX), MathHelper.floor_double(var3.posY), MathHelper.floor_double(var3.posZ)); + var6 = 1.0F; + int var18 = this.mc.theWorld.getLightBrightnessForSkyBlocks(MathHelper.floor_double(var3.posX), MathHelper.floor_double(var3.posY), MathHelper.floor_double(var3.posZ), 0); + int var8 = var18 % 65536; + int var9 = var18 / 65536; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) var8 / 1.0F, (float) var9 / 1.0F); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + float var10; + float var19; + float var21; + + if (var17 != null) { + var18 = Item.itemsList[var17.itemID].getColorFromItemStack(var17, 0); + var19 = (float) (var18 >> 16 & 255) / 255.0F; + var21 = (float) (var18 >> 8 & 255) / 255.0F; + var10 = (float) (var18 & 255) / 255.0F; + EaglerAdapter.glColor4f(var6 * var19, var6 * var21, var6 * var10, 1.0F); + } else { + EaglerAdapter.glColor4f(var6, var6, var6, 1.0F); + } + + float var11; + float var12; + float var13; + Render var24 = RenderManager.instance.getEntityRenderObject(this.mc.thePlayer); + RenderPlayer var26 = (RenderPlayer) var24; + + if (var17 != null && var17.itemID == Item.map.itemID) { + EaglerAdapter.glPushMatrix(); + var7 = 0.8F; + var19 = var3.getSwingProgress(par1); + var21 = MathHelper.sin(var19 * (float) Math.PI); + var10 = MathHelper.sin(MathHelper.sqrt_float(var19) * (float) Math.PI); + EaglerAdapter.glTranslatef(-var10 * 0.4F, MathHelper.sin(MathHelper.sqrt_float(var19) * (float) Math.PI * 2.0F) * 0.2F, -var21 * 0.2F); + var19 = 1.0F - var4 / 45.0F + 0.1F; + + if (var19 < 0.0F) { + var19 = 0.0F; + } + + if (var19 > 1.0F) { + var19 = 1.0F; + } + + var19 = -MathHelper.cos(var19 * (float) Math.PI) * 0.5F + 0.5F; + EaglerAdapter.glTranslatef(0.0F, 0.0F * var7 - (1.0F - var2) * 1.2F - var19 * 0.5F + 0.04F, -0.9F * var7); + EaglerAdapter.glRotatef(90.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(var19 * -85.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + + var26.bindTexture(var3); + + for (var9 = 0; var9 < 2; ++var9) { + int var22 = var9 * 2 - 1; + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(0.0F, -0.6F, 1.1F * (float) var22); + EaglerAdapter.glRotatef((float) (-45 * var22), 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(-90.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glRotatef(59.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glRotatef((float) (-65 * var22), 0.0F, 1.0F, 0.0F); + var13 = 1.0F; + EaglerAdapter.glScalef(var13, var13, var13); + var26.renderFirstPersonArm(this.mc.thePlayer); + EaglerAdapter.glPopMatrix(); + } + + var21 = var3.getSwingProgress(par1); + var10 = MathHelper.sin(var21 * var21 * (float) Math.PI); + var11 = MathHelper.sin(MathHelper.sqrt_float(var21) * (float) Math.PI); + EaglerAdapter.glRotatef(-var10 * 20.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(-var11 * 20.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glRotatef(-var11 * 80.0F, 1.0F, 0.0F, 0.0F); + var12 = 0.38F; + EaglerAdapter.glScalef(var12, var12, var12); + EaglerAdapter.glRotatef(90.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(180.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glTranslatef(-1.0F, -1.0F, 0.0F); + var13 = 0.015625F; + EaglerAdapter.glScalef(var13, var13, var13); + mapbg.bindTexture(); + Tessellator var27 = Tessellator.instance; + EaglerAdapter.glNormal3f(0.0F, 0.0F, -1.0F); + var27.startDrawingQuads(); + byte var28 = 7; + var27.addVertexWithUV((double) (0 - var28), (double) (128 + var28), 0.0D, 0.0D, 1.0D); + var27.addVertexWithUV((double) (128 + var28), (double) (128 + var28), 0.0D, 1.0D, 1.0D); + var27.addVertexWithUV((double) (128 + var28), (double) (0 - var28), 0.0D, 1.0D, 0.0D); + var27.addVertexWithUV((double) (0 - var28), (double) (0 - var28), 0.0D, 0.0D, 0.0D); + var27.draw(); + MapData var16 = Item.map.getMapData(var17, this.mc.theWorld); + + if (var16 != null) { + this.mapItemRenderer.renderMap(this.mc.thePlayer, this.mc.renderEngine, var16); + } + + EaglerAdapter.glPopMatrix(); + } else if (var17 != null) { + EaglerAdapter.glPushMatrix(); + var7 = 0.8F; + + if (var3.getItemInUseCount() > 0) { + EnumAction var20 = var17.getItemUseAction(); + + if (var20 == EnumAction.eat || var20 == EnumAction.drink) { + var21 = (float) var3.getItemInUseCount() - par1 + 1.0F; + var10 = 1.0F - var21 / (float) var17.getMaxItemUseDuration(); + var11 = 1.0F - var10; + var11 = var11 * var11 * var11; + var11 = var11 * var11 * var11; + var11 = var11 * var11 * var11; + var12 = 1.0F - var11; + EaglerAdapter.glTranslatef(0.0F, MathHelper.abs(MathHelper.cos(var21 / 4.0F * (float) Math.PI) * 0.1F) * (float) ((double) var10 > 0.2D ? 1 : 0), 0.0F); + EaglerAdapter.glTranslatef(var12 * 0.6F, -var12 * 0.5F, 0.0F); + EaglerAdapter.glRotatef(var12 * 90.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(var12 * 10.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(var12 * 30.0F, 0.0F, 0.0F, 1.0F); + } + } else { + var19 = var3.getSwingProgress(par1); + var21 = MathHelper.sin(var19 * (float) Math.PI); + var10 = MathHelper.sin(MathHelper.sqrt_float(var19) * (float) Math.PI); + EaglerAdapter.glTranslatef(-var10 * 0.4F, MathHelper.sin(MathHelper.sqrt_float(var19) * (float) Math.PI * 2.0F) * 0.2F, -var21 * 0.2F); + } + + EaglerAdapter.glTranslatef(0.7F * var7, -0.65F * var7 - (1.0F - var2) * 0.6F, -0.9F * var7); + EaglerAdapter.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + var19 = var3.getSwingProgress(par1); + var21 = MathHelper.sin(var19 * var19 * (float) Math.PI); + var10 = MathHelper.sin(MathHelper.sqrt_float(var19) * (float) Math.PI); + EaglerAdapter.glRotatef(-var21 * 20.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(-var10 * 20.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glRotatef(-var10 * 80.0F, 1.0F, 0.0F, 0.0F); + var11 = 0.4F; + EaglerAdapter.glScalef(var11, var11, var11); + float var14; + float var15; + + if (var3.getItemInUseCount() > 0) { + EnumAction var23 = var17.getItemUseAction(); + + if (var23 == EnumAction.block) { + EaglerAdapter.glTranslatef(-0.5F, 0.2F, 0.0F); + EaglerAdapter.glRotatef(30.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(-80.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(60.0F, 0.0F, 1.0F, 0.0F); + } else if (var23 == EnumAction.bow) { + EaglerAdapter.glRotatef(-18.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glRotatef(-12.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(-8.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glTranslatef(-0.9F, 0.2F, 0.0F); + var13 = (float) var17.getMaxItemUseDuration() - ((float) var3.getItemInUseCount() - par1 + 1.0F); + var14 = var13 / 20.0F; + var14 = (var14 * var14 + var14 * 2.0F) / 3.0F; + + if (var14 > 1.0F) { + var14 = 1.0F; + } + + if (var14 > 0.1F) { + EaglerAdapter.glTranslatef(0.0F, MathHelper.sin((var13 - 0.1F) * 1.3F) * 0.01F * (var14 - 0.1F), 0.0F); + } + + EaglerAdapter.glTranslatef(0.0F, 0.0F, var14 * 0.1F); + EaglerAdapter.glRotatef(-335.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glRotatef(-50.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glTranslatef(0.0F, 0.5F, 0.0F); + var15 = 1.0F + var14 * 0.2F; + EaglerAdapter.glScalef(1.0F, 1.0F, var15); + EaglerAdapter.glTranslatef(0.0F, -0.5F, 0.0F); + EaglerAdapter.glRotatef(50.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(335.0F, 0.0F, 0.0F, 1.0F); + } + } + + if (var17.getItem().shouldRotateAroundWhenRendering()) { + EaglerAdapter.glRotatef(180.0F, 0.0F, 1.0F, 0.0F); + } + + if (var17.getItem().requiresMultipleRenderPasses()) { + this.renderItem(var3, var17, 0); + int var25 = Item.itemsList[var17.itemID].getColorFromItemStack(var17, 1); + var13 = (float) (var25 >> 16 & 255) / 255.0F; + var14 = (float) (var25 >> 8 & 255) / 255.0F; + var15 = (float) (var25 & 255) / 255.0F; + EaglerAdapter.glColor4f(var6 * var13, var6 * var14, var6 * var15, 1.0F); + this.renderItem(var3, var17, 1); + } else { + this.renderItem(var3, var17, 0); + } + + EaglerAdapter.glPopMatrix(); + } else if (!var3.isInvisible()) { + EaglerAdapter.glPushMatrix(); + var7 = 0.8F; + var19 = var3.getSwingProgress(par1); + var21 = MathHelper.sin(var19 * (float) Math.PI); + var10 = MathHelper.sin(MathHelper.sqrt_float(var19) * (float) Math.PI); + EaglerAdapter.glTranslatef(-var10 * 0.3F, MathHelper.sin(MathHelper.sqrt_float(var19) * (float) Math.PI * 2.0F) * 0.4F, -var21 * 0.4F); + EaglerAdapter.glTranslatef(0.8F * var7, -0.75F * var7 - (1.0F - var2) * 0.6F, -0.9F * var7); + EaglerAdapter.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + var19 = var3.getSwingProgress(par1); + var21 = MathHelper.sin(var19 * var19 * (float) Math.PI); + var10 = MathHelper.sin(MathHelper.sqrt_float(var19) * (float) Math.PI); + EaglerAdapter.glRotatef(var10 * 70.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(-var21 * 20.0F, 0.0F, 0.0F, 1.0F); + var26.bindTexture(var3); + EaglerAdapter.glTranslatef(-1.0F, 3.6F, 3.5F); + EaglerAdapter.glRotatef(120.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glRotatef(200.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(-135.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glScalef(1.0F, 1.0F, 1.0F); + EaglerAdapter.glTranslatef(5.6F, 0.0F, 0.0F); + var24 = RenderManager.instance.getEntityRenderObject(this.mc.thePlayer); + var26 = (RenderPlayer) var24; + var13 = 1.0F; + EaglerAdapter.glScalef(var13, var13, var13); + var26.renderFirstPersonArm(this.mc.thePlayer); + EaglerAdapter.glPopMatrix(); + } + + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + RenderHelper.disableStandardItemLighting(); + } + + private static final TextureLocation water = new TextureLocation("/misc/water.png"); + + /** + * Renders all the overlays that are in first person mode. Args: partialTickTime + */ + public void renderOverlays(float par1) { + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + + if (this.mc.thePlayer.isBurning()) { + terrain.bindTexture(); + this.renderFireInFirstPerson(par1); + } + + if (this.mc.thePlayer.isEntityInsideOpaqueBlock()) { + int var2 = MathHelper.floor_double(this.mc.thePlayer.posX); + int var3 = MathHelper.floor_double(this.mc.thePlayer.posY); + int var4 = MathHelper.floor_double(this.mc.thePlayer.posZ); + terrain.bindTexture(); + int var5 = this.mc.theWorld.getBlockId(var2, var3, var4); + + if (this.mc.theWorld.isBlockNormalCube(var2, var3, var4)) { + this.renderInsideOfBlock(par1, Block.blocksList[var5].getBlockTextureFromSide(2)); + } else { + for (int var6 = 0; var6 < 8; ++var6) { + float var7 = ((float) ((var6 >> 0) % 2) - 0.5F) * this.mc.thePlayer.width * 0.9F; + float var8 = ((float) ((var6 >> 1) % 2) - 0.5F) * this.mc.thePlayer.height * 0.2F; + float var9 = ((float) ((var6 >> 2) % 2) - 0.5F) * this.mc.thePlayer.width * 0.9F; + int var10 = MathHelper.floor_float((float) var2 + var7); + int var11 = MathHelper.floor_float((float) var3 + var8); + int var12 = MathHelper.floor_float((float) var4 + var9); + + if (this.mc.theWorld.isBlockNormalCube(var10, var11, var12)) { + var5 = this.mc.theWorld.getBlockId(var10, var11, var12); + } + } + } + + if (Block.blocksList[var5] != null) { + this.renderInsideOfBlock(par1, Block.blocksList[var5].getBlockTextureFromSide(2)); + } + } + + if (this.mc.thePlayer.isInsideOfMaterial(Material.water)) { + water.bindTexture(); + this.renderWarpedTextureOverlay(par1); + } + + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + } + + /** + * Renders the texture of the block the player is inside as an overlay. Args: + * partialTickTime, blockTextureIndex + */ + private void renderInsideOfBlock(float par1, Icon par2Icon) { + Tessellator var3 = Tessellator.instance; + float var4 = 0.1F; + EaglerAdapter.glColor4f(var4, var4, var4, 0.5F); + EaglerAdapter.glPushMatrix(); + float var5 = -1.0F; + float var6 = 1.0F; + float var7 = -1.0F; + float var8 = 1.0F; + float var9 = -0.5F; + float var10 = par2Icon.getMinU(); + float var11 = par2Icon.getMaxU(); + float var12 = par2Icon.getMinV(); + float var13 = par2Icon.getMaxV(); + var3.startDrawingQuads(); + var3.addVertexWithUV((double) var5, (double) var7, (double) var9, (double) var11, (double) var13); + var3.addVertexWithUV((double) var6, (double) var7, (double) var9, (double) var10, (double) var13); + var3.addVertexWithUV((double) var6, (double) var8, (double) var9, (double) var10, (double) var12); + var3.addVertexWithUV((double) var5, (double) var8, (double) var9, (double) var11, (double) var12); + var3.draw(); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Renders a texture that warps around based on the direction the player is + * looking. Texture needs to be bound before being called. Used for the water + * overlay. Args: parialTickTime + */ + private void renderWarpedTextureOverlay(float par1) { + Tessellator var2 = Tessellator.instance; + float var3 = this.mc.thePlayer.getBrightness(par1); + EaglerAdapter.glColor4f(var3, var3, var3, 0.5F); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glPushMatrix(); + float var4 = 4.0F; + float var5 = -1.0F; + float var6 = 1.0F; + float var7 = -1.0F; + float var8 = 1.0F; + float var9 = -0.5F; + float var10 = -this.mc.thePlayer.rotationYaw / 64.0F; + float var11 = this.mc.thePlayer.rotationPitch / 64.0F; + var2.startDrawingQuads(); + var2.addVertexWithUV((double) var5, (double) var7, (double) var9, (double) (var4 + var10), (double) (var4 + var11)); + var2.addVertexWithUV((double) var6, (double) var7, (double) var9, (double) (0.0F + var10), (double) (var4 + var11)); + var2.addVertexWithUV((double) var6, (double) var8, (double) var9, (double) (0.0F + var10), (double) (0.0F + var11)); + var2.addVertexWithUV((double) var5, (double) var8, (double) var9, (double) (var4 + var10), (double) (0.0F + var11)); + var2.draw(); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + } + + /** + * Renders the fire on the screen for first person mode. Arg: partialTickTime + */ + private void renderFireInFirstPerson(float par1) { + Tessellator var2 = Tessellator.instance; + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 0.9F); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + float var3 = 1.0F; + + for (int var4 = 0; var4 < 2; ++var4) { + EaglerAdapter.glPushMatrix(); + Icon var5 = Block.fire.func_94438_c(1); + float var6 = var5.getMinU(); + float var7 = var5.getMaxU(); + float var8 = var5.getMinV(); + float var9 = var5.getMaxV(); + float var10 = (0.0F - var3) / 2.0F; + float var11 = var10 + var3; + float var12 = 0.0F - var3 / 2.0F; + float var13 = var12 + var3; + float var14 = -0.5F; + EaglerAdapter.glTranslatef((float) (-(var4 * 2 - 1)) * 0.24F, -0.3F, 0.0F); + EaglerAdapter.glRotatef((float) (var4 * 2 - 1) * 10.0F, 0.0F, 1.0F, 0.0F); + var2.startDrawingQuads(); + var2.addVertexWithUV((double) var10, (double) var12, (double) var14, (double) var7, (double) var9); + var2.addVertexWithUV((double) var11, (double) var12, (double) var14, (double) var6, (double) var9); + var2.addVertexWithUV((double) var11, (double) var13, (double) var14, (double) var6, (double) var8); + var2.addVertexWithUV((double) var10, (double) var13, (double) var14, (double) var7, (double) var8); + var2.draw(); + EaglerAdapter.glPopMatrix(); + } + + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + } + + public void updateEquippedItem() { + this.prevEquippedProgress = this.equippedProgress; + EntityClientPlayerMP var1 = this.mc.thePlayer; + ItemStack var2 = var1.inventory.getCurrentItem(); + boolean var3 = this.equippedItemSlot == var1.inventory.currentItem && var2 == this.itemToRender; + + if (this.itemToRender == null && var2 == null) { + var3 = true; + } + + if (var2 != null && this.itemToRender != null && var2 != this.itemToRender && var2.itemID == this.itemToRender.itemID && var2.getItemDamage() == this.itemToRender.getItemDamage()) { + this.itemToRender = var2; + var3 = true; + } + + float var4 = 0.4F; + float var5 = var3 ? 1.0F : 0.0F; + float var6 = var5 - this.equippedProgress; + + if (var6 < -var4) { + var6 = -var4; + } + + if (var6 > var4) { + var6 = var4; + } + + this.equippedProgress += var6; + + if (this.equippedProgress < 0.1F) { + this.itemToRender = var2; + this.equippedItemSlot = var1.inventory.currentItem; + } + } + + /** + * Resets equippedProgress + */ + public void resetEquippedProgress() { + this.equippedProgress = 0.0F; + } + + /** + * Resets equippedProgress + */ + public void resetEquippedProgress2() { + this.equippedProgress = 0.0F; + } +} diff --git a/src/main/java/net/minecraft/src/ItemSaddle.java b/src/main/java/net/minecraft/src/ItemSaddle.java new file mode 100644 index 0000000..5766db6 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSaddle.java @@ -0,0 +1,36 @@ +package net.minecraft.src; + +public class ItemSaddle extends Item { + public ItemSaddle(int par1) { + super(par1); + this.maxStackSize = 1; + this.setCreativeTab(CreativeTabs.tabTransport); + } + + /** + * Called when a player right clicks an entity with an item. + */ + public boolean itemInteractionForEntity(ItemStack par1ItemStack, EntityLiving par2EntityLiving) { + if (par2EntityLiving instanceof EntityPig) { + EntityPig var3 = (EntityPig) par2EntityLiving; + + if (!var3.getSaddled() && !var3.isChild()) { + var3.setSaddled(true); + --par1ItemStack.stackSize; + } + + return true; + } else { + return false; + } + } + + /** + * Current implementations of this method in child classes do not use the entry + * argument beside ev. They just raise the damage on the stack. + */ + public boolean hitEntity(ItemStack par1ItemStack, EntityLiving par2EntityLiving, EntityLiving par3EntityLiving) { + this.itemInteractionForEntity(par1ItemStack, par2EntityLiving); + return true; + } +} diff --git a/src/main/java/net/minecraft/src/ItemSeedFood.java b/src/main/java/net/minecraft/src/ItemSeedFood.java new file mode 100644 index 0000000..8efaedb --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSeedFood.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + +public class ItemSeedFood extends ItemFood { + /** Block ID of the crop this seed food should place. */ + private int cropId; + + /** Block ID of the soil this seed food should be planted on. */ + private int soilId; + + public ItemSeedFood(int par1, int par2, float par3, int par4, int par5) { + super(par1, par2, par3, false); + this.cropId = par4; + this.soilId = par5; + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (par7 != 1) { + return false; + } else if (par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack) && par2EntityPlayer.canPlayerEdit(par4, par5 + 1, par6, par7, par1ItemStack)) { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (var11 == this.soilId && par3World.isAirBlock(par4, par5 + 1, par6)) { + par3World.setBlock(par4, par5 + 1, par6, this.cropId); + --par1ItemStack.stackSize; + return true; + } else { + return false; + } + } else { + return false; + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemSeeds.java b/src/main/java/net/minecraft/src/ItemSeeds.java new file mode 100644 index 0000000..484d37a --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSeeds.java @@ -0,0 +1,41 @@ +package net.minecraft.src; + +public class ItemSeeds extends Item { + /** + * The type of block this seed turns into (wheat or pumpkin stems for instance) + */ + private int blockType; + + /** BlockID of the block the seeds can be planted on. */ + private int soilBlockID; + + public ItemSeeds(int par1, int par2, int par3) { + super(par1); + this.blockType = par2; + this.soilBlockID = par3; + this.setCreativeTab(CreativeTabs.tabMaterials); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (par7 != 1) { + return false; + } else if (par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack) && par2EntityPlayer.canPlayerEdit(par4, par5 + 1, par6, par7, par1ItemStack)) { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (var11 == this.soilBlockID && par3World.isAirBlock(par4, par5 + 1, par6)) { + par3World.setBlock(par4, par5 + 1, par6, this.blockType); + --par1ItemStack.stackSize; + return true; + } else { + return false; + } + } else { + return false; + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemShears.java b/src/main/java/net/minecraft/src/ItemShears.java new file mode 100644 index 0000000..1fe1123 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemShears.java @@ -0,0 +1,34 @@ +package net.minecraft.src; + +public class ItemShears extends Item { + public ItemShears(int par1) { + super(par1); + this.setMaxStackSize(1); + this.setMaxDamage(238); + this.setCreativeTab(CreativeTabs.tabTools); + } + + public boolean onBlockDestroyed(ItemStack par1ItemStack, World par2World, int par3, int par4, int par5, int par6, EntityLiving par7EntityLiving) { + if (par3 != Block.leaves.blockID && par3 != Block.web.blockID && par3 != Block.tallGrass.blockID && par3 != Block.vine.blockID && par3 != Block.tripWire.blockID) { + return super.onBlockDestroyed(par1ItemStack, par2World, par3, par4, par5, par6, par7EntityLiving); + } else { + par1ItemStack.damageItem(1, par7EntityLiving); + return true; + } + } + + /** + * Returns if the item (tool) can harvest results from the block type. + */ + public boolean canHarvestBlock(Block par1Block) { + return par1Block.blockID == Block.web.blockID || par1Block.blockID == Block.redstoneWire.blockID || par1Block.blockID == Block.tripWire.blockID; + } + + /** + * Returns the strength of the stack against a given block. 1.0F base, + * (Quality+1)*2 if correct blocktype, 1.5F if sword + */ + public float getStrVsBlock(ItemStack par1ItemStack, Block par2Block) { + return par2Block.blockID != Block.web.blockID && par2Block.blockID != Block.leaves.blockID ? (par2Block.blockID == Block.cloth.blockID ? 5.0F : super.getStrVsBlock(par1ItemStack, par2Block)) : 15.0F; + } +} diff --git a/src/main/java/net/minecraft/src/ItemSign.java b/src/main/java/net/minecraft/src/ItemSign.java new file mode 100644 index 0000000..cbcfb44 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSign.java @@ -0,0 +1,64 @@ +package net.minecraft.src; + +public class ItemSign extends Item { + public ItemSign(int par1) { + super(par1); + this.maxStackSize = 16; + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (par7 == 0) { + return false; + } else if (!par3World.getBlockMaterial(par4, par5, par6).isSolid()) { + return false; + } else { + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else if (!Block.signPost.canPlaceBlockAt(par3World, par4, par5, par6)) { + return false; + } else { + if (par7 == 1) { + int var11 = MathHelper.floor_double((double) ((par2EntityPlayer.rotationYaw + 180.0F) * 16.0F / 360.0F) + 0.5D) & 15; + par3World.setBlock(par4, par5, par6, Block.signPost.blockID, var11, 2); + } else { + par3World.setBlock(par4, par5, par6, Block.signWall.blockID, par7, 2); + } + + --par1ItemStack.stackSize; + TileEntitySign var12 = (TileEntitySign) par3World.getBlockTileEntity(par4, par5, par6); + + if (var12 != null) { + par2EntityPlayer.displayGUIEditSign(var12); + } + + return true; + } + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemSimpleFoiled.java b/src/main/java/net/minecraft/src/ItemSimpleFoiled.java new file mode 100644 index 0000000..f0fbabe --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSimpleFoiled.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +public class ItemSimpleFoiled extends Item { + public ItemSimpleFoiled(int par1) { + super(par1); + } + + public boolean hasEffect(ItemStack par1ItemStack) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/ItemSkull.java b/src/main/java/net/minecraft/src/ItemSkull.java new file mode 100644 index 0000000..77d018b --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSkull.java @@ -0,0 +1,135 @@ +package net.minecraft.src; + +import java.util.List; + +public class ItemSkull extends Item { + private static final String[] skullTypes = new String[] { "skeleton", "wither", "zombie", "char", "creeper" }; + public static final String[] field_94587_a = new String[] { "skull_skeleton", "skull_wither", "skull_zombie", "skull_char", "skull_creeper" }; + private Icon[] field_94586_c; + + public ItemSkull(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabDecorations); + this.setMaxDamage(0); + this.setHasSubtypes(true); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (par7 == 0) { + return false; + } else if (!par3World.getBlockMaterial(par4, par5, par6).isSolid()) { + return false; + } else { + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else if (!Block.skull.canPlaceBlockAt(par3World, par4, par5, par6)) { + return false; + } else { + par3World.setBlock(par4, par5, par6, Block.skull.blockID, par7, 2); + int var11 = 0; + + if (par7 == 1) { + var11 = MathHelper.floor_double((double) (par2EntityPlayer.rotationYaw * 16.0F / 360.0F) + 0.5D) & 15; + } + + TileEntity var12 = par3World.getBlockTileEntity(par4, par5, par6); + + if (var12 != null && var12 instanceof TileEntitySkull) { + String var13 = ""; + + if (par1ItemStack.hasTagCompound() && par1ItemStack.getTagCompound().hasKey("SkullOwner")) { + var13 = par1ItemStack.getTagCompound().getString("SkullOwner"); + } + + ((TileEntitySkull) var12).setSkullType(par1ItemStack.getItemDamage(), var13); + ((TileEntitySkull) var12).setSkullRotation(var11); + ((BlockSkull) Block.skull).makeWither(par3World, par4, par5, par6, (TileEntitySkull) var12); + } + + --par1ItemStack.stackSize; + return true; + } + } + } + + /** + * returns a list of items with the same ID, but different meta (eg: dye returns + * 16 items) + */ + public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List) { + for (int var4 = 0; var4 < skullTypes.length; ++var4) { + par3List.add(new ItemStack(par1, 1, var4)); + } + } + + /** + * Gets an icon index based on an item's damage value + */ + public Icon getIconFromDamage(int par1) { + if (par1 < 0 || par1 >= skullTypes.length) { + par1 = 0; + } + + return this.field_94586_c[par1]; + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1; + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + int var2 = par1ItemStack.getItemDamage(); + + if (var2 < 0 || var2 >= skullTypes.length) { + var2 = 0; + } + + return super.getUnlocalizedName() + "." + skullTypes[var2]; + } + + public String getItemDisplayName(ItemStack par1ItemStack) { + return par1ItemStack.getItemDamage() == 3 && par1ItemStack.hasTagCompound() && par1ItemStack.getTagCompound().hasKey("SkullOwner") + ? StatCollector.translateToLocalFormatted("item.skull.player.name", new Object[] { par1ItemStack.getTagCompound().getString("SkullOwner") }) + : super.getItemDisplayName(par1ItemStack); + } + + public void registerIcons(IconRegister par1IconRegister) { + this.field_94586_c = new Icon[field_94587_a.length]; + + for (int var2 = 0; var2 < field_94587_a.length; ++var2) { + this.field_94586_c[var2] = par1IconRegister.registerIcon(field_94587_a[var2]); + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemSlab.java b/src/main/java/net/minecraft/src/ItemSlab.java new file mode 100644 index 0000000..f537ddd --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSlab.java @@ -0,0 +1,164 @@ +package net.minecraft.src; + +public class ItemSlab extends ItemBlock { + private final boolean isFullBlock; + + /** Instance of BlockHalfSlab. */ + private final BlockHalfSlab theHalfSlab; + + /** The double-slab block corresponding to this item. */ + private final BlockHalfSlab doubleSlab; + + public ItemSlab(int par1, BlockHalfSlab par2BlockHalfSlab, BlockHalfSlab par3BlockHalfSlab, boolean par4) { + super(par1); + this.theHalfSlab = par2BlockHalfSlab; + this.doubleSlab = par3BlockHalfSlab; + this.isFullBlock = par4; + this.setMaxDamage(0); + this.setHasSubtypes(true); + } + + /** + * Gets an icon index based on an item's damage value + */ + public Icon getIconFromDamage(int par1) { + return Block.blocksList[this.itemID].getIcon(2, par1); + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1; + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + return this.theHalfSlab.getFullSlabName(par1ItemStack.getItemDamage()); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (this.isFullBlock) { + return super.onItemUse(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7, par8, par9, par10); + } else if (par1ItemStack.stackSize == 0) { + return false; + } else if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + int var11 = par3World.getBlockId(par4, par5, par6); + int var12 = par3World.getBlockMetadata(par4, par5, par6); + int var13 = var12 & 7; + boolean var14 = (var12 & 8) != 0; + + if ((par7 == 1 && !var14 || par7 == 0 && var14) && var11 == this.theHalfSlab.blockID && var13 == par1ItemStack.getItemDamage()) { + if (par3World.checkNoEntityCollision(this.doubleSlab.getCollisionBoundingBoxFromPool(par3World, par4, par5, par6)) && par3World.setBlock(par4, par5, par6, this.doubleSlab.blockID, var13, 3)) { + par3World.playSoundEffect((double) ((float) par4 + 0.5F), (double) ((float) par5 + 0.5F), (double) ((float) par6 + 0.5F), this.doubleSlab.stepSound.getPlaceSound(), (this.doubleSlab.stepSound.getVolume() + 1.0F) / 2.0F, + this.doubleSlab.stepSound.getPitch() * 0.8F); + --par1ItemStack.stackSize; + } + + return true; + } else { + return this.func_77888_a(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7) ? true : super.onItemUse(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7, par8, par9, par10); + } + } + } + + /** + * Returns true if the given ItemBlock can be placed on the given side of the + * given block position. + */ + public boolean canPlaceItemBlockOnSide(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer, ItemStack par7ItemStack) { + int var8 = par2; + int var9 = par3; + int var10 = par4; + int var11 = par1World.getBlockId(par2, par3, par4); + int var12 = par1World.getBlockMetadata(par2, par3, par4); + int var13 = var12 & 7; + boolean var14 = (var12 & 8) != 0; + + if ((par5 == 1 && !var14 || par5 == 0 && var14) && var11 == this.theHalfSlab.blockID && var13 == par7ItemStack.getItemDamage()) { + return true; + } else { + if (par5 == 0) { + --par3; + } + + if (par5 == 1) { + ++par3; + } + + if (par5 == 2) { + --par4; + } + + if (par5 == 3) { + ++par4; + } + + if (par5 == 4) { + --par2; + } + + if (par5 == 5) { + ++par2; + } + + var11 = par1World.getBlockId(par2, par3, par4); + var12 = par1World.getBlockMetadata(par2, par3, par4); + var13 = var12 & 7; + var14 = (var12 & 8) != 0; + return var11 == this.theHalfSlab.blockID && var13 == par7ItemStack.getItemDamage() ? true : super.canPlaceItemBlockOnSide(par1World, var8, var9, var10, par5, par6EntityPlayer, par7ItemStack); + } + } + + private boolean func_77888_a(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7) { + if (par7 == 0) { + --par5; + } + + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + + int var8 = par3World.getBlockId(par4, par5, par6); + int var9 = par3World.getBlockMetadata(par4, par5, par6); + int var10 = var9 & 7; + + if (var8 == this.theHalfSlab.blockID && var10 == par1ItemStack.getItemDamage()) { + if (par3World.checkNoEntityCollision(this.doubleSlab.getCollisionBoundingBoxFromPool(par3World, par4, par5, par6)) && par3World.setBlock(par4, par5, par6, this.doubleSlab.blockID, var10, 3)) { + par3World.playSoundEffect((double) ((float) par4 + 0.5F), (double) ((float) par5 + 0.5F), (double) ((float) par6 + 0.5F), this.doubleSlab.stepSound.getPlaceSound(), (this.doubleSlab.stepSound.getVolume() + 1.0F) / 2.0F, + this.doubleSlab.stepSound.getPitch() * 0.8F); + --par1ItemStack.stackSize; + } + + return true; + } else { + return false; + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemSnow.java b/src/main/java/net/minecraft/src/ItemSnow.java new file mode 100644 index 0000000..d390ede --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSnow.java @@ -0,0 +1,37 @@ +package net.minecraft.src; + +public class ItemSnow extends ItemBlockWithMetadata { + public ItemSnow(int par1, Block par2Block) { + super(par1, par2Block); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (par1ItemStack.stackSize == 0) { + return false; + } else if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (var11 == Block.snow.blockID) { + Block var12 = Block.blocksList[this.getBlockID()]; + int var13 = par3World.getBlockMetadata(par4, par5, par6); + int var14 = var13 & 7; + + if (var14 <= 6 && par3World.checkNoEntityCollision(var12.getCollisionBoundingBoxFromPool(par3World, par4, par5, par6)) && par3World.setBlockMetadataWithNotify(par4, par5, par6, var14 + 1 | var13 & -8, 2)) { + par3World.playSoundEffect((double) ((float) par4 + 0.5F), (double) ((float) par5 + 0.5F), (double) ((float) par6 + 0.5F), var12.stepSound.getPlaceSound(), (var12.stepSound.getVolume() + 1.0F) / 2.0F, + var12.stepSound.getPitch() * 0.8F); + --par1ItemStack.stackSize; + return true; + } + } + + return super.onItemUse(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7, par8, par9, par10); + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemSnowball.java b/src/main/java/net/minecraft/src/ItemSnowball.java new file mode 100644 index 0000000..1a9d868 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSnowball.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class ItemSnowball extends Item { + public ItemSnowball(int par1) { + super(par1); + this.maxStackSize = 16; + this.setCreativeTab(CreativeTabs.tabMisc); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(new EntitySnowball(par2World, par3EntityPlayer)); + } + + return par1ItemStack; + } +} diff --git a/src/main/java/net/minecraft/src/ItemSoup.java b/src/main/java/net/minecraft/src/ItemSoup.java new file mode 100644 index 0000000..72efac6 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSoup.java @@ -0,0 +1,13 @@ +package net.minecraft.src; + +public class ItemSoup extends ItemFood { + public ItemSoup(int par1, int par2) { + super(par1, par2, false); + this.setMaxStackSize(1); + } + + public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + super.onEaten(par1ItemStack, par2World, par3EntityPlayer); + return new ItemStack(Item.bowlEmpty); + } +} diff --git a/src/main/java/net/minecraft/src/ItemSpade.java b/src/main/java/net/minecraft/src/ItemSpade.java new file mode 100644 index 0000000..2fdb44b --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSpade.java @@ -0,0 +1,17 @@ +package net.minecraft.src; + +public class ItemSpade extends ItemTool { + /** an array of the blocks this spade is effective against */ + private static Block[] blocksEffectiveAgainst = new Block[] { Block.grass, Block.dirt, Block.sand, Block.gravel, Block.snow, Block.blockSnow, Block.blockClay, Block.tilledField, Block.slowSand, Block.mycelium }; + + public ItemSpade(int par1, EnumToolMaterial par2EnumToolMaterial) { + super(par1, 1, par2EnumToolMaterial, blocksEffectiveAgainst); + } + + /** + * Returns if the item (tool) can harvest results from the block type. + */ + public boolean canHarvestBlock(Block par1Block) { + return par1Block == Block.snow ? true : par1Block == Block.blockSnow; + } +} diff --git a/src/main/java/net/minecraft/src/ItemStack.java b/src/main/java/net/minecraft/src/ItemStack.java new file mode 100644 index 0000000..76e2427 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemStack.java @@ -0,0 +1,643 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public final class ItemStack { + /** Size of the stack. */ + public int stackSize; + + /** + * Number of animation frames to go when receiving an item (by walking into it, + * for example). + */ + public int animationsToGo; + + /** ID of the item. */ + public int itemID; + + /** + * A NBTTagMap containing data about an ItemStack. Can only be used for non + * stackable items + */ + public NBTTagCompound stackTagCompound; + + /** Damage dealt to the item or number of use. Raise when using items. */ + private int itemDamage; + + /** Item frame this stack is on, or null if not on an item frame. */ + private EntityItemFrame itemFrame; + + public ItemStack(Block par1Block) { + this(par1Block, 1); + } + + public ItemStack(Block par1Block, int par2) { + this(par1Block.blockID, par2, 0); + } + + public ItemStack(Block par1Block, int par2, int par3) { + this(par1Block.blockID, par2, par3); + } + + public ItemStack(Item par1Item) { + this(par1Item.itemID, 1, 0); + } + + public ItemStack(Item par1Item, int par2) { + this(par1Item.itemID, par2, 0); + } + + public ItemStack(Item par1Item, int par2, int par3) { + this(par1Item.itemID, par2, par3); + } + + public ItemStack(int par1, int par2, int par3) { + this.stackSize = 0; + this.itemFrame = null; + this.itemID = par1; + this.stackSize = par2; + this.itemDamage = par3; + + if (this.itemDamage < 0) { + this.itemDamage = 0; + } + } + + public static ItemStack loadItemStackFromNBT(NBTTagCompound par0NBTTagCompound) { + ItemStack var1 = new ItemStack(); + var1.readFromNBT(par0NBTTagCompound); + return var1.getItem() != null ? var1 : null; + } + + private ItemStack() { + this.stackSize = 0; + this.itemFrame = null; + } + + /** + * Remove the argument from the stack size. Return a new stack object with + * argument size. + */ + public ItemStack splitStack(int par1) { + ItemStack var2 = new ItemStack(this.itemID, par1, this.itemDamage); + + if (this.stackTagCompound != null) { + var2.stackTagCompound = (NBTTagCompound) this.stackTagCompound.copy(); + } + + this.stackSize -= par1; + return var2; + } + + /** + * Returns the object corresponding to the stack. + */ + public Item getItem() { + return Item.itemsList[this.itemID]; + } + + /** + * Returns the icon index of the current stack. + */ + public Icon getIconIndex() { + return this.getItem().getIconIndex(this); + } + + public int getItemSpriteNumber() { + return this.getItem().getSpriteNumber(); + } + + public boolean tryPlaceItemIntoWorld(EntityPlayer par1EntityPlayer, World par2World, int par3, int par4, int par5, int par6, float par7, float par8, float par9) { + boolean var10 = this.getItem().onItemUse(this, par1EntityPlayer, par2World, par3, par4, par5, par6, par7, par8, par9); + + return var10; + } + + /** + * Returns the strength of the stack against a given block. + */ + public float getStrVsBlock(Block par1Block) { + return this.getItem().getStrVsBlock(this, par1Block); + } + + /** + * Called whenever this item stack is equipped and right clicked. Returns the + * new item stack to put in the position where this item is. Args: world, player + */ + public ItemStack useItemRightClick(World par1World, EntityPlayer par2EntityPlayer) { + return this.getItem().onItemRightClick(this, par1World, par2EntityPlayer); + } + + public ItemStack onFoodEaten(World par1World, EntityPlayer par2EntityPlayer) { + return this.getItem().onEaten(this, par1World, par2EntityPlayer); + } + + /** + * Write the stack fields to a NBT object. Return the new NBT object. + */ + public NBTTagCompound writeToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setShort("id", (short) this.itemID); + par1NBTTagCompound.setByte("Count", (byte) this.stackSize); + par1NBTTagCompound.setShort("Damage", (short) this.itemDamage); + + if (this.stackTagCompound != null) { + par1NBTTagCompound.setTag("tag", this.stackTagCompound); + } + + return par1NBTTagCompound; + } + + /** + * Read the stack fields from a NBT object. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + this.itemID = par1NBTTagCompound.getShort("id"); + this.stackSize = par1NBTTagCompound.getByte("Count"); + this.itemDamage = par1NBTTagCompound.getShort("Damage"); + + if (this.itemDamage < 0) { + this.itemDamage = 0; + } + + if (par1NBTTagCompound.hasKey("tag")) { + this.stackTagCompound = par1NBTTagCompound.getCompoundTag("tag"); + } + } + + /** + * Returns maximum size of the stack. + */ + public int getMaxStackSize() { + return this.getItem().getItemStackLimit(); + } + + /** + * Returns true if the ItemStack can hold 2 or more units of the item. + */ + public boolean isStackable() { + return this.getMaxStackSize() > 1 && (!this.isItemStackDamageable() || !this.isItemDamaged()); + } + + /** + * true if this itemStack is damageable + */ + public boolean isItemStackDamageable() { + return Item.itemsList[this.itemID].getMaxDamage() > 0; + } + + public boolean getHasSubtypes() { + return Item.itemsList[this.itemID].getHasSubtypes(); + } + + /** + * returns true when a damageable item is damaged + */ + public boolean isItemDamaged() { + return this.isItemStackDamageable() && this.itemDamage > 0; + } + + /** + * gets the damage of an itemstack, for displaying purposes + */ + public int getItemDamageForDisplay() { + return this.itemDamage; + } + + /** + * gets the damage of an itemstack + */ + public int getItemDamage() { + return this.itemDamage; + } + + /** + * Sets the item damage of the ItemStack. + */ + public void setItemDamage(int par1) { + this.itemDamage = par1; + + if (this.itemDamage < 0) { + this.itemDamage = 0; + } + } + + /** + * Returns the max damage an item in the stack can take. + */ + public int getMaxDamage() { + return Item.itemsList[this.itemID].getMaxDamage(); + } + + /** + * Attempts to damage the ItemStack with par1 amount of damage, If the ItemStack + * has the Unbreaking enchantment there is a chance for each point of damage to + * be negated. Returns true if it takes more damage than getMaxDamage(). Returns + * false otherwise or if the ItemStack can't be damaged or if all points of + * damage are negated. + */ + public boolean attemptDamageItem(int par1, Random par2Random) { + if (!this.isItemStackDamageable()) { + return false; + } else { + if (par1 > 0) { + int var3 = EnchantmentHelper.getEnchantmentLevel(Enchantment.unbreaking.effectId, this); + int var4 = 0; + + for (int var5 = 0; var3 > 0 && var5 < par1; ++var5) { + if (EnchantmentDurability.negateDamage(this, var3, par2Random)) { + ++var4; + } + } + + par1 -= var4; + + if (par1 <= 0) { + return false; + } + } + + this.itemDamage += par1; + return this.itemDamage > this.getMaxDamage(); + } + } + + /** + * Damages the item in the ItemStack + */ + public void damageItem(int par1, EntityLiving par2EntityLiving) { + if (!(par2EntityLiving instanceof EntityPlayer) || !((EntityPlayer) par2EntityLiving).capabilities.isCreativeMode) { + if (this.isItemStackDamageable()) { + if (this.attemptDamageItem(par1, par2EntityLiving.getRNG())) { + par2EntityLiving.renderBrokenItemStack(this); + + --this.stackSize; + + if (this.stackSize < 0) { + this.stackSize = 0; + } + + this.itemDamage = 0; + } + } + } + } + + /** + * Calls the corresponding fct in di + */ + public void hitEntity(EntityLiving par1EntityLiving, EntityPlayer par2EntityPlayer) { + boolean var3 = Item.itemsList[this.itemID].hitEntity(this, par1EntityLiving, par2EntityPlayer); + } + + public void onBlockDestroyed(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer) { + boolean var7 = Item.itemsList[this.itemID].onBlockDestroyed(this, par1World, par2, par3, par4, par5, par6EntityPlayer); + } + + /** + * Returns the damage against a given entity. + */ + public int getDamageVsEntity(Entity par1Entity) { + return Item.itemsList[this.itemID].getDamageVsEntity(par1Entity); + } + + /** + * Checks if the itemStack object can harvest a specified block + */ + public boolean canHarvestBlock(Block par1Block) { + return Item.itemsList[this.itemID].canHarvestBlock(par1Block); + } + + public boolean interactWith(EntityLiving par1EntityLiving) { + return Item.itemsList[this.itemID].itemInteractionForEntity(this, par1EntityLiving); + } + + /** + * Returns a new stack with the same properties. + */ + public ItemStack copy() { + ItemStack var1 = new ItemStack(this.itemID, this.stackSize, this.itemDamage); + + if (this.stackTagCompound != null) { + var1.stackTagCompound = (NBTTagCompound) this.stackTagCompound.copy(); + } + + return var1; + } + + public static boolean areItemStackTagsEqual(ItemStack par0ItemStack, ItemStack par1ItemStack) { + return par0ItemStack == null && par1ItemStack == null ? true + : (par0ItemStack != null && par1ItemStack != null + ? (par0ItemStack.stackTagCompound == null && par1ItemStack.stackTagCompound != null ? false : par0ItemStack.stackTagCompound == null || par0ItemStack.stackTagCompound.equals(par1ItemStack.stackTagCompound)) + : false); + } + + /** + * compares ItemStack argument1 with ItemStack argument2; returns true if both + * ItemStacks are equal + */ + public static boolean areItemStacksEqual(ItemStack par0ItemStack, ItemStack par1ItemStack) { + return par0ItemStack == null && par1ItemStack == null ? true : (par0ItemStack != null && par1ItemStack != null ? par0ItemStack.isItemStackEqual(par1ItemStack) : false); + } + + /** + * compares ItemStack argument to the instance ItemStack; returns true if both + * ItemStacks are equal + */ + private boolean isItemStackEqual(ItemStack par1ItemStack) { + return this.stackSize != par1ItemStack.stackSize ? false + : (this.itemID != par1ItemStack.itemID ? false + : (this.itemDamage != par1ItemStack.itemDamage ? false + : (this.stackTagCompound == null && par1ItemStack.stackTagCompound != null ? false : this.stackTagCompound == null || this.stackTagCompound.equals(par1ItemStack.stackTagCompound)))); + } + + /** + * compares ItemStack argument to the instance ItemStack; returns true if the + * Items contained in both ItemStacks are equal + */ + public boolean isItemEqual(ItemStack par1ItemStack) { + return this.itemID == par1ItemStack.itemID && this.itemDamage == par1ItemStack.itemDamage; + } + + public String getItemName() { + return Item.itemsList[this.itemID].getUnlocalizedName(this); + } + + /** + * Creates a copy of a ItemStack, a null parameters will return a null. + */ + public static ItemStack copyItemStack(ItemStack par0ItemStack) { + return par0ItemStack == null ? null : par0ItemStack.copy(); + } + + public String toString() { + return this.stackSize + "x" + Item.itemsList[this.itemID].getUnlocalizedName() + "@" + this.itemDamage; + } + + /** + * Called each tick as long the ItemStack in on player inventory. Used to + * progress the pickup animation and update maps. + */ + public void updateAnimation(World par1World, Entity par2Entity, int par3, boolean par4) { + if (this.animationsToGo > 0) { + --this.animationsToGo; + } + + Item.itemsList[this.itemID].onUpdate(this, par1World, par2Entity, par3, par4); + } + + public void onCrafting(World par1World, EntityPlayer par2EntityPlayer, int par3) { + Item.itemsList[this.itemID].onCreated(this, par1World, par2EntityPlayer); + } + + public int getMaxItemUseDuration() { + return this.getItem().getMaxItemUseDuration(this); + } + + public EnumAction getItemUseAction() { + return this.getItem().getItemUseAction(this); + } + + /** + * Called when the player releases the use item button. Args: world, + * entityplayer, itemInUseCount + */ + public void onPlayerStoppedUsing(World par1World, EntityPlayer par2EntityPlayer, int par3) { + this.getItem().onPlayerStoppedUsing(this, par1World, par2EntityPlayer, par3); + } + + /** + * Returns true if the ItemStack has an NBTTagCompound. Currently used to store + * enchantments. + */ + public boolean hasTagCompound() { + return this.stackTagCompound != null; + } + + /** + * Returns the NBTTagCompound of the ItemStack. + */ + public NBTTagCompound getTagCompound() { + return this.stackTagCompound; + } + + public NBTTagList getEnchantmentTagList() { + return this.stackTagCompound == null ? null : (NBTTagList) this.stackTagCompound.getTag("ench"); + } + + /** + * Assigns a NBTTagCompound to the ItemStack, minecraft validates that only + * non-stackable items can have it. + */ + public void setTagCompound(NBTTagCompound par1NBTTagCompound) { + this.stackTagCompound = par1NBTTagCompound; + } + + /** + * returns the display name of the itemstack + */ + public String getDisplayName() { + String var1 = this.getItem().getItemDisplayName(this); + + if (this.stackTagCompound != null && this.stackTagCompound.hasKey("display")) { + NBTTagCompound var2 = this.stackTagCompound.getCompoundTag("display"); + + if (var2.hasKey("Name")) { + var1 = var2.getString("Name"); + } + } + + return var1; + } + + /** + * Sets the item's name (used by anvil to rename the items). + */ + public void setItemName(String par1Str) { + if (this.stackTagCompound == null) { + this.stackTagCompound = new NBTTagCompound("tag"); + } + + if (!this.stackTagCompound.hasKey("display")) { + this.stackTagCompound.setCompoundTag("display", new NBTTagCompound()); + } + + this.stackTagCompound.getCompoundTag("display").setString("Name", par1Str); + } + + /** + * Returns true if the itemstack has a display name + */ + public boolean hasDisplayName() { + return this.stackTagCompound == null ? false : (!this.stackTagCompound.hasKey("display") ? false : this.stackTagCompound.getCompoundTag("display").hasKey("Name")); + } + + /** + * Return a list of strings containing information about the item + */ + public List getTooltip(EntityPlayer par1EntityPlayer, boolean par2) { + ArrayList var3 = new ArrayList(); + Item var4 = Item.itemsList[this.itemID]; + String var5 = this.getDisplayName(); + + if (this.hasDisplayName()) { + var5 = EnumChatFormatting.ITALIC + var5 + EnumChatFormatting.RESET; + } + + if (par2) { + String var6 = ""; + + if (var5.length() > 0) { + var5 = var5 + " ("; + var6 = ")"; + } + + if (this.getHasSubtypes()) { + var5 = var5 + String.format("#%04d/%d%s", new Object[] { Integer.valueOf(this.itemID), Integer.valueOf(this.itemDamage), var6 }); + } else { + var5 = var5 + String.format("#%04d%s", new Object[] { Integer.valueOf(this.itemID), var6 }); + } + } else if (!this.hasDisplayName() && this.itemID == Item.map.itemID) { + var5 = var5 + " #" + this.itemDamage; + } + + var3.add(var5); + var4.addInformation(this, par1EntityPlayer, var3, par2); + + if (this.hasTagCompound()) { + NBTTagList var10 = this.getEnchantmentTagList(); + + if (var10 != null) { + for (int var7 = 0; var7 < var10.tagCount(); ++var7) { + short var8 = ((NBTTagCompound) var10.tagAt(var7)).getShort("id"); + short var9 = ((NBTTagCompound) var10.tagAt(var7)).getShort("lvl"); + + if (Enchantment.enchantmentsList[var8] != null) { + var3.add(Enchantment.enchantmentsList[var8].getTranslatedName(var9)); + } + } + } + + if (this.stackTagCompound.hasKey("display")) { + NBTTagCompound var11 = this.stackTagCompound.getCompoundTag("display"); + + if (var11.hasKey("color")) { + if (par2) { + var3.add("Color: #" + Integer.toHexString(var11.getInteger("color")).toUpperCase()); + } else { + var3.add(EnumChatFormatting.ITALIC + StatCollector.translateToLocal("item.dyed")); + } + } + + if (var11.hasKey("Lore")) { + NBTTagList var12 = var11.getTagList("Lore"); + + if (var12.tagCount() > 0) { + for (int var13 = 0; var13 < var12.tagCount(); ++var13) { + var3.add(EnumChatFormatting.DARK_PURPLE + "" + EnumChatFormatting.ITALIC + ((NBTTagString) var12.tagAt(var13)).data); + } + } + } + } + } + + if (par2 && this.isItemDamaged()) { + var3.add("Durability: " + (this.getMaxDamage() - this.getItemDamageForDisplay()) + " / " + this.getMaxDamage()); + } + + return var3; + } + + public boolean hasEffect() { + return this.getItem().hasEffect(this); + } + + public EnumRarity getRarity() { + return this.getItem().getRarity(this); + } + + /** + * True if it is a tool and has no enchantments to begin with + */ + public boolean isItemEnchantable() { + return !this.getItem().isItemTool(this) ? false : !this.isItemEnchanted(); + } + + /** + * Adds an enchantment with a desired level on the ItemStack. + */ + public void addEnchantment(Enchantment par1Enchantment, int par2) { + if (this.stackTagCompound == null) { + this.setTagCompound(new NBTTagCompound()); + } + + if (!this.stackTagCompound.hasKey("ench")) { + this.stackTagCompound.setTag("ench", new NBTTagList("ench")); + } + + NBTTagList var3 = (NBTTagList) this.stackTagCompound.getTag("ench"); + NBTTagCompound var4 = new NBTTagCompound(); + var4.setShort("id", (short) par1Enchantment.effectId); + var4.setShort("lvl", (short) ((byte) par2)); + var3.appendTag(var4); + } + + /** + * True if the item has enchantment data + */ + public boolean isItemEnchanted() { + return this.stackTagCompound != null && this.stackTagCompound.hasKey("ench"); + } + + public void setTagInfo(String par1Str, NBTBase par2NBTBase) { + if (this.stackTagCompound == null) { + this.setTagCompound(new NBTTagCompound()); + } + + this.stackTagCompound.setTag(par1Str, par2NBTBase); + } + + public boolean func_82835_x() { + return this.getItem().func_82788_x(); + } + + /** + * Return whether this stack is on an item frame. + */ + public boolean isOnItemFrame() { + return this.itemFrame != null; + } + + /** + * Set the item frame this stack is on. + */ + public void setItemFrame(EntityItemFrame par1EntityItemFrame) { + this.itemFrame = par1EntityItemFrame; + } + + /** + * Return the item frame this stack is on. Returns null if not on an item frame. + */ + public EntityItemFrame getItemFrame() { + return this.itemFrame; + } + + /** + * Get this stack's repair cost, or 0 if no repair cost is defined. + */ + public int getRepairCost() { + return this.hasTagCompound() && this.stackTagCompound.hasKey("RepairCost") ? this.stackTagCompound.getInteger("RepairCost") : 0; + } + + /** + * Set this stack's repair cost. + */ + public void setRepairCost(int par1) { + if (!this.hasTagCompound()) { + this.stackTagCompound = new NBTTagCompound("tag"); + } + + this.stackTagCompound.setInteger("RepairCost", par1); + } +} diff --git a/src/main/java/net/minecraft/src/ItemSword.java b/src/main/java/net/minecraft/src/ItemSword.java new file mode 100644 index 0000000..40f98b1 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSword.java @@ -0,0 +1,116 @@ +package net.minecraft.src; + +public class ItemSword extends Item { + private int weaponDamage; + private final EnumToolMaterial toolMaterial; + + public ItemSword(int par1, EnumToolMaterial par2EnumToolMaterial) { + super(par1); + this.toolMaterial = par2EnumToolMaterial; + this.maxStackSize = 1; + this.setMaxDamage(par2EnumToolMaterial.getMaxUses()); + this.setCreativeTab(CreativeTabs.tabCombat); + this.weaponDamage = 4 + par2EnumToolMaterial.getDamageVsEntity(); + } + + public int func_82803_g() { + return this.toolMaterial.getDamageVsEntity(); + } + + /** + * Returns the strength of the stack against a given block. 1.0F base, + * (Quality+1)*2 if correct blocktype, 1.5F if sword + */ + public float getStrVsBlock(ItemStack par1ItemStack, Block par2Block) { + if (par2Block.blockID == Block.web.blockID) { + return 15.0F; + } else { + Material var3 = par2Block.blockMaterial; + return var3 != Material.plants && var3 != Material.vine && var3 != Material.coral && var3 != Material.leaves && var3 != Material.pumpkin ? 1.0F : 1.5F; + } + } + + /** + * Current implementations of this method in child classes do not use the entry + * argument beside ev. They just raise the damage on the stack. + */ + public boolean hitEntity(ItemStack par1ItemStack, EntityLiving par2EntityLiving, EntityLiving par3EntityLiving) { + par1ItemStack.damageItem(1, par3EntityLiving); + return true; + } + + public boolean onBlockDestroyed(ItemStack par1ItemStack, World par2World, int par3, int par4, int par5, int par6, EntityLiving par7EntityLiving) { + if ((double) Block.blocksList[par3].getBlockHardness(par2World, par4, par5, par6) != 0.0D) { + par1ItemStack.damageItem(2, par7EntityLiving); + } + + return true; + } + + /** + * Returns the damage against a given entity. + */ + public int getDamageVsEntity(Entity par1Entity) { + return this.weaponDamage; + } + + /** + * Returns True is the item is renderer in full 3D when hold. + */ + public boolean isFull3D() { + return true; + } + + /** + * returns the action that specifies what animation to play when the items is + * being used + */ + public EnumAction getItemUseAction(ItemStack par1ItemStack) { + return EnumAction.block; + } + + /** + * How long it takes to use or consume an item + */ + public int getMaxItemUseDuration(ItemStack par1ItemStack) { + return 72000; + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + par3EntityPlayer.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); + return par1ItemStack; + } + + /** + * Returns if the item (tool) can harvest results from the block type. + */ + public boolean canHarvestBlock(Block par1Block) { + return par1Block.blockID == Block.web.blockID; + } + + /** + * Return the enchantability factor of the item, most of the time is based on + * material. + */ + public int getItemEnchantability() { + return this.toolMaterial.getEnchantability(); + } + + /** + * Return the name for this tool's material. + */ + public String getToolMaterialName() { + return this.toolMaterial.toString(); + } + + /** + * Return whether this item is repairable in an anvil. + */ + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) { + return this.toolMaterial.getToolCraftingMaterial() == par2ItemStack.itemID ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); + } +} diff --git a/src/main/java/net/minecraft/src/ItemTool.java b/src/main/java/net/minecraft/src/ItemTool.java new file mode 100644 index 0000000..a9561b9 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemTool.java @@ -0,0 +1,91 @@ +package net.minecraft.src; + +public class ItemTool extends Item { + /** Array of blocks the tool has extra effect against. */ + private Block[] blocksEffectiveAgainst; + protected float efficiencyOnProperMaterial = 4.0F; + + /** Damage versus entities. */ + private int damageVsEntity; + + /** The material this tool is made from. */ + protected EnumToolMaterial toolMaterial; + + protected ItemTool(int par1, int par2, EnumToolMaterial par3EnumToolMaterial, Block[] par4ArrayOfBlock) { + super(par1); + this.toolMaterial = par3EnumToolMaterial; + this.blocksEffectiveAgainst = par4ArrayOfBlock; + this.maxStackSize = 1; + this.setMaxDamage(par3EnumToolMaterial.getMaxUses()); + this.efficiencyOnProperMaterial = par3EnumToolMaterial.getEfficiencyOnProperMaterial(); + this.damageVsEntity = par2 + par3EnumToolMaterial.getDamageVsEntity(); + this.setCreativeTab(CreativeTabs.tabTools); + } + + /** + * Returns the strength of the stack against a given block. 1.0F base, + * (Quality+1)*2 if correct blocktype, 1.5F if sword + */ + public float getStrVsBlock(ItemStack par1ItemStack, Block par2Block) { + for (int var3 = 0; var3 < this.blocksEffectiveAgainst.length; ++var3) { + if (this.blocksEffectiveAgainst[var3] == par2Block) { + return this.efficiencyOnProperMaterial; + } + } + + return 1.0F; + } + + /** + * Current implementations of this method in child classes do not use the entry + * argument beside ev. They just raise the damage on the stack. + */ + public boolean hitEntity(ItemStack par1ItemStack, EntityLiving par2EntityLiving, EntityLiving par3EntityLiving) { + par1ItemStack.damageItem(2, par3EntityLiving); + return true; + } + + public boolean onBlockDestroyed(ItemStack par1ItemStack, World par2World, int par3, int par4, int par5, int par6, EntityLiving par7EntityLiving) { + if ((double) Block.blocksList[par3].getBlockHardness(par2World, par4, par5, par6) != 0.0D) { + par1ItemStack.damageItem(1, par7EntityLiving); + } + + return true; + } + + /** + * Returns the damage against a given entity. + */ + public int getDamageVsEntity(Entity par1Entity) { + return this.damageVsEntity; + } + + /** + * Returns True is the item is renderer in full 3D when hold. + */ + public boolean isFull3D() { + return true; + } + + /** + * Return the enchantability factor of the item, most of the time is based on + * material. + */ + public int getItemEnchantability() { + return this.toolMaterial.getEnchantability(); + } + + /** + * Return the name for this tool's material. + */ + public String getToolMaterialName() { + return this.toolMaterial.toString(); + } + + /** + * Return whether this item is repairable in an anvil. + */ + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) { + return this.toolMaterial.getToolCraftingMaterial() == par2ItemStack.itemID ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); + } +} diff --git a/src/main/java/net/minecraft/src/ItemWritableBook.java b/src/main/java/net/minecraft/src/ItemWritableBook.java new file mode 100644 index 0000000..cc9a002 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemWritableBook.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + +public class ItemWritableBook extends Item { + public ItemWritableBook(int par1) { + super(par1); + this.setMaxStackSize(1); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + par3EntityPlayer.displayGUIBook(par1ItemStack); + return par1ItemStack; + } + + /** + * If this function returns true (or the item is damageable), the ItemStack's + * NBT tag will be sent to the client. + */ + public boolean getShareTag() { + return true; + } + + public static boolean validBookTagPages(NBTTagCompound par0NBTTagCompound) { + if (par0NBTTagCompound == null) { + return false; + } else if (!par0NBTTagCompound.hasKey("pages")) { + return false; + } else { + NBTTagList var1 = (NBTTagList) par0NBTTagCompound.getTag("pages"); + + for (int var2 = 0; var2 < var1.tagCount(); ++var2) { + NBTTagString var3 = (NBTTagString) var1.tagAt(var2); + + if (var3.data == null) { + return false; + } + + if (var3.data.length() > 256) { + return false; + } + } + + return true; + } + } +} diff --git a/src/main/java/net/minecraft/src/KeyBinding.java b/src/main/java/net/minecraft/src/KeyBinding.java new file mode 100644 index 0000000..6342d08 --- /dev/null +++ b/src/main/java/net/minecraft/src/KeyBinding.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class KeyBinding { + public static List keybindArray = new ArrayList(); + public static IntHashMap hash = new IntHashMap(); + public String keyDescription; + public int keyCode; + + /** because _303 wanted me to call it that(Caironater) */ + public boolean pressed; + public int pressTime = 0; + + public static void onTick(int par0) { + KeyBinding var1 = (KeyBinding) hash.lookup(par0); + + if (var1 != null) { + ++var1.pressTime; + } + } + + public static void setKeyBindState(int par0, boolean par1) { + KeyBinding var2 = (KeyBinding) hash.lookup(par0); + + if (var2 != null) { + var2.pressed = par1; + } + } + + public static void unPressAllKeys() { + Iterator var0 = keybindArray.iterator(); + + while (var0.hasNext()) { + KeyBinding var1 = (KeyBinding) var0.next(); + var1.unpressKey(); + } + } + + public static void resetKeyBindingArrayAndHash() { + hash.clearMap(); + Iterator var0 = keybindArray.iterator(); + + while (var0.hasNext()) { + KeyBinding var1 = (KeyBinding) var0.next(); + hash.addKey(var1.keyCode, var1); + } + } + + public KeyBinding(String par1Str, int par2) { + this.keyDescription = par1Str; + this.keyCode = par2; + keybindArray.add(this); + hash.addKey(par2, this); + } + + public boolean isPressed() { + if (this.pressTime == 0) { + return false; + } else { + --this.pressTime; + return true; + } + } + + private void unpressKey() { + this.pressTime = 0; + this.pressed = false; + } +} diff --git a/src/main/java/net/minecraft/src/LoadingScreenRenderer.java b/src/main/java/net/minecraft/src/LoadingScreenRenderer.java new file mode 100644 index 0000000..b34c659 --- /dev/null +++ b/src/main/java/net/minecraft/src/LoadingScreenRenderer.java @@ -0,0 +1,151 @@ +package net.minecraft.src; + +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class LoadingScreenRenderer implements IProgressUpdate { + private String field_73727_a = ""; + + /** A reference to the Minecraft object. */ + private Minecraft mc; + + /** + * The text currently displayed (i.e. the argument to the last call to printText + * or func_73722_d) + */ + private String currentlyDisplayedText = ""; + private long field_73723_d = Minecraft.getSystemTime(); + private boolean field_73724_e = false; + + public LoadingScreenRenderer(Minecraft par1Minecraft) { + this.mc = par1Minecraft; + } + + /** + * this string, followed by "working..." and then the "% complete" are the 3 + * lines shown. This resets progress to 0, and the WorkingString to + * "working...". + */ + public void resetProgressAndMessage(String par1Str) { + this.field_73724_e = false; + this.func_73722_d(par1Str); + } + + /** + * "Saving level", or the loading,or downloading equivelent + */ + public void displayProgressMessage(String par1Str) { + this.field_73724_e = true; + this.func_73722_d(par1Str); + } + + public void func_73722_d(String par1Str) { + this.currentlyDisplayedText = par1Str; + + if (!this.mc.running) { + if (!this.field_73724_e) { + throw new MinecraftError(); + } + } else { + ScaledResolution var2 = new ScaledResolution(this.mc.gameSettings, this.mc.displayWidth, this.mc.displayHeight); + EaglerAdapter.glClear(EaglerAdapter.GL_DEPTH_BUFFER_BIT); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glOrtho(0.0F, var2.getScaledWidth(), var2.getScaledHeight(), 0.0F, 100.0F, 300.0F); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glTranslatef(0.0F, 0.0F, -200.0F); + } + } + + /** + * This is called with "Working..." by resetProgressAndMessage + */ + public void resetProgresAndWorkingMessage(String par1Str) { + if (!this.mc.running) { + if (!this.field_73724_e) { + throw new MinecraftError(); + } + } else { + this.field_73723_d = 0L; + this.field_73727_a = par1Str; + this.setLoadingProgress(-1); + this.field_73723_d = 0L; + } + } + + private static final TextureLocation background = new TextureLocation("/gui/background.png"); + + /** + * Updates the progress bar on the loading screen to the specified amount. Args: + * loadProgress + */ + public void setLoadingProgress(int par1) { + if (!this.mc.running) { + if (!this.field_73724_e) { + throw new MinecraftError(); + } + } else { + long var2 = Minecraft.getSystemTime(); + + if (var2 - this.field_73723_d >= 100L) { + this.field_73723_d = var2; + ScaledResolution var4 = new ScaledResolution(this.mc.gameSettings, this.mc.displayWidth, this.mc.displayHeight); + int var5 = var4.getScaledWidth(); + int var6 = var4.getScaledHeight(); + EaglerAdapter.glClear(EaglerAdapter.GL_DEPTH_BUFFER_BIT); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_PROJECTION); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glOrtho(0.0F, var4.getScaledWidth(), var4.getScaledHeight(), 0.0F, 100.0F, 300.0F); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glTranslatef(0.0F, 0.0F, -200.0F); + EaglerAdapter.glClear(EaglerAdapter.GL_COLOR_BUFFER_BIT | EaglerAdapter.GL_DEPTH_BUFFER_BIT); + Tessellator var7 = Tessellator.instance; + background.bindTexture(); + float var8 = 32.0F; + var7.startDrawingQuads(); + var7.setColorOpaque_I(4210752); + var7.addVertexWithUV(0.0D, (double) var6, 0.0D, 0.0D, (double) ((float) var6 / var8)); + var7.addVertexWithUV((double) var5, (double) var6, 0.0D, (double) ((float) var5 / var8), (double) ((float) var6 / var8)); + var7.addVertexWithUV((double) var5, 0.0D, 0.0D, (double) ((float) var5 / var8), 0.0D); + var7.addVertexWithUV(0.0D, 0.0D, 0.0D, 0.0D, 0.0D); + var7.draw(); + + if (par1 >= 0) { + byte var9 = 100; + byte var10 = 2; + int var11 = var5 / 2 - var9 / 2; + int var12 = var6 / 2 + 16; + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + var7.startDrawingQuads(); + var7.setColorOpaque_I(8421504); + var7.addVertex((double) var11, (double) var12, 0.0D); + var7.addVertex((double) var11, (double) (var12 + var10), 0.0D); + var7.addVertex((double) (var11 + var9), (double) (var12 + var10), 0.0D); + var7.addVertex((double) (var11 + var9), (double) var12, 0.0D); + var7.setColorOpaque_I(8454016); + var7.addVertex((double) var11, (double) var12, 0.0D); + var7.addVertex((double) var11, (double) (var12 + var10), 0.0D); + var7.addVertex((double) (var11 + par1), (double) (var12 + var10), 0.0D); + var7.addVertex((double) (var11 + par1), (double) var12, 0.0D); + var7.draw(); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + } + + this.mc.fontRenderer.drawStringWithShadow(this.currentlyDisplayedText, (var5 - this.mc.fontRenderer.getStringWidth(this.currentlyDisplayedText)) / 2, var6 / 2 - 4 - 16, 16777215); + this.mc.fontRenderer.drawStringWithShadow(this.field_73727_a, (var5 - this.mc.fontRenderer.getStringWidth(this.field_73727_a)) / 2, var6 / 2 - 4 + 8, 16777215); + EaglerAdapter.updateDisplay(); + } + } + } + + /** + * called when there is no more progress to be had, both on completion and + * failure + */ + public void onNoMoreProgress() { + } +} diff --git a/src/main/java/net/minecraft/src/LogAgentINNER1.java b/src/main/java/net/minecraft/src/LogAgentINNER1.java new file mode 100644 index 0000000..13b8899 --- /dev/null +++ b/src/main/java/net/minecraft/src/LogAgentINNER1.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +class LogAgentINNER1 { +} diff --git a/src/main/java/net/minecraft/src/LongHashMap.java b/src/main/java/net/minecraft/src/LongHashMap.java new file mode 100644 index 0000000..04dd4d8 --- /dev/null +++ b/src/main/java/net/minecraft/src/LongHashMap.java @@ -0,0 +1,199 @@ +package net.minecraft.src; + +public class LongHashMap { + /** the array of all elements in the hash */ + private transient LongHashMapEntry[] hashArray = new LongHashMapEntry[16]; + + /** the number of elements in the hash array */ + private transient int numHashElements; + + /** + * the maximum amount of elements in the hash (probably 3/4 the size due to meh + * hashing function) + */ + private int capacity = 12; + + /** + * percent of the hasharray that can be used without hash colliding probably + */ + private final float percentUseable = 0.75F; + + /** count of times elements have been added/removed */ + private transient volatile int modCount; + + /** + * returns the hashed key given the original key + */ + private static int getHashedKey(long par0) { + return hash((int) (par0 ^ par0 >>> 32)); + } + + /** + * the hash function + */ + private static int hash(int par0) { + par0 ^= par0 >>> 20 ^ par0 >>> 12; + return par0 ^ par0 >>> 7 ^ par0 >>> 4; + } + + /** + * gets the index in the hash given the array length and the hashed key + */ + private static int getHashIndex(int par0, int par1) { + return par0 & par1 - 1; + } + + public int getNumHashElements() { + return this.numHashElements; + } + + /** + * get the value from the map given the key + */ + public Object getValueByKey(long par1) { + int var3 = getHashedKey(par1); + + for (LongHashMapEntry var4 = this.hashArray[getHashIndex(var3, this.hashArray.length)]; var4 != null; var4 = var4.nextEntry) { + if (var4.key == par1) { + return var4.value; + } + } + + return null; + } + + public boolean containsItem(long par1) { + return this.getEntry(par1) != null; + } + + final LongHashMapEntry getEntry(long par1) { + int var3 = getHashedKey(par1); + + for (LongHashMapEntry var4 = this.hashArray[getHashIndex(var3, this.hashArray.length)]; var4 != null; var4 = var4.nextEntry) { + if (var4.key == par1) { + return var4; + } + } + + return null; + } + + /** + * Add a key-value pair. + */ + public void add(long par1, Object par3Obj) { + int var4 = getHashedKey(par1); + int var5 = getHashIndex(var4, this.hashArray.length); + + for (LongHashMapEntry var6 = this.hashArray[var5]; var6 != null; var6 = var6.nextEntry) { + if (var6.key == par1) { + var6.value = par3Obj; + return; + } + } + + ++this.modCount; + this.createKey(var4, par1, par3Obj, var5); + } + + /** + * resizes the table + */ + private void resizeTable(int par1) { + LongHashMapEntry[] var2 = this.hashArray; + int var3 = var2.length; + + if (var3 == 1073741824) { + this.capacity = Integer.MAX_VALUE; + } else { + LongHashMapEntry[] var4 = new LongHashMapEntry[par1]; + this.copyHashTableTo(var4); + this.hashArray = var4; + this.capacity = (int) ((float) par1 * this.percentUseable); + } + } + + /** + * copies the hash table to the specified array + */ + private void copyHashTableTo(LongHashMapEntry[] par1ArrayOfLongHashMapEntry) { + LongHashMapEntry[] var2 = this.hashArray; + int var3 = par1ArrayOfLongHashMapEntry.length; + + for (int var4 = 0; var4 < var2.length; ++var4) { + LongHashMapEntry var5 = var2[var4]; + + if (var5 != null) { + var2[var4] = null; + LongHashMapEntry var6; + + do { + var6 = var5.nextEntry; + int var7 = getHashIndex(var5.hash, var3); + var5.nextEntry = par1ArrayOfLongHashMapEntry[var7]; + par1ArrayOfLongHashMapEntry[var7] = var5; + var5 = var6; + } while (var6 != null); + } + } + } + + /** + * calls the removeKey method and returns removed object + */ + public Object remove(long par1) { + LongHashMapEntry var3 = this.removeKey(par1); + return var3 == null ? null : var3.value; + } + + /** + * removes the key from the hash linked list + */ + final LongHashMapEntry removeKey(long par1) { + int var3 = getHashedKey(par1); + int var4 = getHashIndex(var3, this.hashArray.length); + LongHashMapEntry var5 = this.hashArray[var4]; + LongHashMapEntry var6; + LongHashMapEntry var7; + + for (var6 = var5; var6 != null; var6 = var7) { + var7 = var6.nextEntry; + + if (var6.key == par1) { + ++this.modCount; + --this.numHashElements; + + if (var5 == var6) { + this.hashArray[var4] = var7; + } else { + var5.nextEntry = var7; + } + + return var6; + } + + var5 = var6; + } + + return var6; + } + + /** + * creates the key in the hash table + */ + private void createKey(int par1, long par2, Object par4Obj, int par5) { + LongHashMapEntry var6 = this.hashArray[par5]; + this.hashArray[par5] = new LongHashMapEntry(par1, par2, par4Obj, var6); + + if (this.numHashElements++ >= this.capacity) { + this.resizeTable(2 * this.hashArray.length); + } + } + + /** + * public method to get the hashed key(hashCode) + */ + static int getHashCode(long par0) { + return getHashedKey(par0); + } +} diff --git a/src/main/java/net/minecraft/src/LongHashMapEntry.java b/src/main/java/net/minecraft/src/LongHashMapEntry.java new file mode 100644 index 0000000..07794c9 --- /dev/null +++ b/src/main/java/net/minecraft/src/LongHashMapEntry.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +class LongHashMapEntry { + /** + * the key as a long (for playerInstances it is the x in the most significant 32 + * bits and then y) + */ + final long key; + + /** the value held by the hash at the specified key */ + Object value; + + /** the next hashentry in the table */ + LongHashMapEntry nextEntry; + final int hash; + + LongHashMapEntry(int par1, long par2, Object par4Obj, LongHashMapEntry par5LongHashMapEntry) { + this.value = par4Obj; + this.nextEntry = par5LongHashMapEntry; + this.key = par2; + this.hash = par1; + } + + public final long getKey() { + return this.key; + } + + public final Object getValue() { + return this.value; + } + + public final boolean equals(Object par1Obj) { + if (!(par1Obj instanceof LongHashMapEntry)) { + return false; + } else { + LongHashMapEntry var2 = (LongHashMapEntry) par1Obj; + Long var3 = Long.valueOf(this.getKey()); + Long var4 = Long.valueOf(var2.getKey()); + + if (var3 == var4 || var3 != null && var3.equals(var4)) { + Object var5 = this.getValue(); + Object var6 = var2.getValue(); + + if (var5 == var6 || var5 != null && var5.equals(var6)) { + return true; + } + } + + return false; + } + } + + public final int hashCode() { + return LongHashMap.getHashCode(this.key); + } + + public final String toString() { + return this.getKey() + "=" + this.getValue(); + } +} diff --git a/src/main/java/net/minecraft/src/LowerStringMap.java b/src/main/java/net/minecraft/src/LowerStringMap.java new file mode 100644 index 0000000..3ae35c9 --- /dev/null +++ b/src/main/java/net/minecraft/src/LowerStringMap.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +public class LowerStringMap implements Map { + private final Map internalMap = new LinkedHashMap(); + + public int size() { + return this.internalMap.size(); + } + + public boolean isEmpty() { + return this.internalMap.isEmpty(); + } + + public boolean containsKey(Object par1Obj) { + return this.internalMap.containsKey(par1Obj.toString().toLowerCase()); + } + + public boolean containsValue(Object par1Obj) { + return this.internalMap.containsKey(par1Obj); + } + + public Object get(Object par1Obj) { + return this.internalMap.get(par1Obj.toString().toLowerCase()); + } + + /** + * a map already defines a general put + */ + public Object putLower(String par1Str, Object par2Obj) { + return this.internalMap.put(par1Str.toLowerCase(), par2Obj); + } + + public Object remove(Object par1Obj) { + return this.internalMap.remove(par1Obj.toString().toLowerCase()); + } + + public void putAll(Map par1Map) { + Iterator var2 = par1Map.entrySet().iterator(); + + while (var2.hasNext()) { + Entry var3 = (Entry) var2.next(); + this.putLower((String) var3.getKey(), var3.getValue()); + } + } + + public void clear() { + this.internalMap.clear(); + } + + public Set keySet() { + return this.internalMap.keySet(); + } + + public Collection values() { + return this.internalMap.values(); + } + + public Set entrySet() { + return this.internalMap.entrySet(); + } + + public Object put(Object par1Obj, Object par2Obj) { + return this.putLower((String) par1Obj, par2Obj); + } +} diff --git a/src/main/java/net/minecraft/src/MapColor.java b/src/main/java/net/minecraft/src/MapColor.java new file mode 100644 index 0000000..1608bcd --- /dev/null +++ b/src/main/java/net/minecraft/src/MapColor.java @@ -0,0 +1,62 @@ +package net.minecraft.src; + +public class MapColor { + /** + * Holds all the 16 colors used on maps, very similar of a pallete system. + */ + public static final MapColor[] mapColorArray = new MapColor[16]; + + /** The map color for Air blocks */ + public static final MapColor airColor = new MapColor(0, 0); + + /** this is the grass color in html format */ + public static final MapColor grassColor = new MapColor(1, 8368696); + + /** This is the color of the sand */ + public static final MapColor sandColor = new MapColor(2, 16247203); + + /** The map color for Cloth and Sponge blocks */ + public static final MapColor clothColor = new MapColor(3, 10987431); + + /** The map color for TNT blocks */ + public static final MapColor tntColor = new MapColor(4, 16711680); + + /** The map color for Ice blocks */ + public static final MapColor iceColor = new MapColor(5, 10526975); + + /** The map color for Iron blocks */ + public static final MapColor ironColor = new MapColor(6, 10987431); + + /** The map color for Leaf, Plant, Cactus, and Pumpkin blocks. */ + public static final MapColor foliageColor = new MapColor(7, 31744); + + /** The map color for Snow Cover and Snow blocks */ + public static final MapColor snowColor = new MapColor(8, 16777215); + + /** The map color for Clay blocks */ + public static final MapColor clayColor = new MapColor(9, 10791096); + + /** The map color for Dirt blocks */ + public static final MapColor dirtColor = new MapColor(10, 12020271); + + /** The map color for Stone blocks */ + public static final MapColor stoneColor = new MapColor(11, 7368816); + + /** The map color for Water blocks */ + public static final MapColor waterColor = new MapColor(12, 4210943); + + /** The map color for Wood blocks */ + public static final MapColor woodColor = new MapColor(13, 6837042); + + /** Holds the color in RGB value that will be rendered on maps. */ + public final int colorValue; + + /** Holds the index of the color used on map. */ + public final int colorIndex; + + private MapColor(int par1, int par2) { + this.colorIndex = par1; + this.colorValue = par2; + mapColorArray[par1] = this; + } +} diff --git a/src/main/java/net/minecraft/src/MapCoord.java b/src/main/java/net/minecraft/src/MapCoord.java new file mode 100644 index 0000000..7f75d8a --- /dev/null +++ b/src/main/java/net/minecraft/src/MapCoord.java @@ -0,0 +1,18 @@ +package net.minecraft.src; + +public class MapCoord { + public byte iconSize; + public byte centerX; + public byte centerZ; + public byte iconRotation; + + final MapData data; + + public MapCoord(MapData par1MapData, byte par2, byte par3, byte par4, byte par5) { + this.data = par1MapData; + this.iconSize = par2; + this.centerX = par3; + this.centerZ = par4; + this.iconRotation = par5; + } +} diff --git a/src/main/java/net/minecraft/src/MapData.java b/src/main/java/net/minecraft/src/MapData.java new file mode 100644 index 0000000..bfc4bfa --- /dev/null +++ b/src/main/java/net/minecraft/src/MapData.java @@ -0,0 +1,243 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + + + +public class MapData extends WorldSavedData { + public int xCenter; + public int zCenter; + public byte dimension; + public byte scale; + + /** colours */ + public byte[] colors = new byte[16384]; + + /** + * Holds a reference to the MapInfo of the players who own a copy of the map + */ + public List playersArrayList = new ArrayList(); + + /** + * Holds a reference to the players who own a copy of the map and a reference to + * their MapInfo + */ + private Map playersHashMap = new HashMap(); + public Map playersVisibleOnMap = new LinkedHashMap(); + + public MapData(String par1Str) { + super(par1Str); + } + + /** + * reads in data from the NBTTagCompound into this MapDataBase + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + this.dimension = par1NBTTagCompound.getByte("dimension"); + this.xCenter = par1NBTTagCompound.getInteger("xCenter"); + this.zCenter = par1NBTTagCompound.getInteger("zCenter"); + this.scale = par1NBTTagCompound.getByte("scale"); + + if (this.scale < 0) { + this.scale = 0; + } + + if (this.scale > 4) { + this.scale = 4; + } + + short var2 = par1NBTTagCompound.getShort("width"); + short var3 = par1NBTTagCompound.getShort("height"); + + if (var2 == 128 && var3 == 128) { + this.colors = par1NBTTagCompound.getByteArray("colors"); + } else { + byte[] var4 = par1NBTTagCompound.getByteArray("colors"); + this.colors = new byte[16384]; + int var5 = (128 - var2) / 2; + int var6 = (128 - var3) / 2; + + for (int var7 = 0; var7 < var3; ++var7) { + int var8 = var7 + var6; + + if (var8 >= 0 || var8 < 128) { + for (int var9 = 0; var9 < var2; ++var9) { + int var10 = var9 + var5; + + if (var10 >= 0 || var10 < 128) { + this.colors[var10 + var8 * 128] = var4[var9 + var7 * var2]; + } + } + } + } + } + } + + /** + * write data to NBTTagCompound from this MapDataBase, similar to Entities and + * TileEntities + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setByte("dimension", this.dimension); + par1NBTTagCompound.setInteger("xCenter", this.xCenter); + par1NBTTagCompound.setInteger("zCenter", this.zCenter); + par1NBTTagCompound.setByte("scale", this.scale); + par1NBTTagCompound.setShort("width", (short) 128); + par1NBTTagCompound.setShort("height", (short) 128); + par1NBTTagCompound.setByteArray("colors", this.colors); + } + + /** + * Adds the player passed to the list of visible players and checks to see which + * players are visible + */ + public void updateVisiblePlayers(EntityPlayer par1EntityPlayer, ItemStack par2ItemStack) { + if (!this.playersHashMap.containsKey(par1EntityPlayer)) { + MapInfo var3 = new MapInfo(this, par1EntityPlayer); + this.playersHashMap.put(par1EntityPlayer, var3); + this.playersArrayList.add(var3); + } + + if (!par1EntityPlayer.inventory.hasItemStack(par2ItemStack)) { + this.playersVisibleOnMap.remove(par1EntityPlayer.getCommandSenderName()); + } + + for (int var5 = 0; var5 < this.playersArrayList.size(); ++var5) { + MapInfo var4 = (MapInfo) this.playersArrayList.get(var5); + + if (!var4.entityplayerObj.isDead && (var4.entityplayerObj.inventory.hasItemStack(par2ItemStack) || par2ItemStack.isOnItemFrame())) { + if (!par2ItemStack.isOnItemFrame() && var4.entityplayerObj.dimension == this.dimension) { + this.func_82567_a(0, var4.entityplayerObj.worldObj, var4.entityplayerObj.getCommandSenderName(), var4.entityplayerObj.posX, var4.entityplayerObj.posZ, (double) var4.entityplayerObj.rotationYaw); + } + } else { + this.playersHashMap.remove(var4.entityplayerObj); + this.playersArrayList.remove(var4); + } + } + + if (par2ItemStack.isOnItemFrame()) { + this.func_82567_a(1, par1EntityPlayer.worldObj, "frame-" + par2ItemStack.getItemFrame().entityId, (double) par2ItemStack.getItemFrame().xPosition, (double) par2ItemStack.getItemFrame().zPosition, + (double) (par2ItemStack.getItemFrame().hangingDirection * 90)); + } + } + + private void func_82567_a(int par1, World par2World, String par3Str, double par4, double par6, double par8) { + int var10 = 1 << this.scale; + float var11 = (float) (par4 - (double) this.xCenter) / (float) var10; + float var12 = (float) (par6 - (double) this.zCenter) / (float) var10; + byte var13 = (byte) ((int) ((double) (var11 * 2.0F) + 0.5D)); + byte var14 = (byte) ((int) ((double) (var12 * 2.0F) + 0.5D)); + byte var16 = 63; + byte var15; + + if (var11 >= (float) (-var16) && var12 >= (float) (-var16) && var11 <= (float) var16 && var12 <= (float) var16) { + par8 += par8 < 0.0D ? -8.0D : 8.0D; + var15 = (byte) ((int) (par8 * 16.0D / 360.0D)); + + if (this.dimension < 0) { + int var17 = (int) (par2World.getWorldInfo().getWorldTime() / 10L); + var15 = (byte) (var17 * var17 * 34187121 + var17 * 121 >> 15 & 15); + } + } else { + if (Math.abs(var11) >= 320.0F || Math.abs(var12) >= 320.0F) { + this.playersVisibleOnMap.remove(par3Str); + return; + } + + par1 = 6; + var15 = 0; + + if (var11 <= (float) (-var16)) { + var13 = (byte) ((int) ((double) (var16 * 2) + 2.5D)); + } + + if (var12 <= (float) (-var16)) { + var14 = (byte) ((int) ((double) (var16 * 2) + 2.5D)); + } + + if (var11 >= (float) var16) { + var13 = (byte) (var16 * 2 + 1); + } + + if (var12 >= (float) var16) { + var14 = (byte) (var16 * 2 + 1); + } + } + + this.playersVisibleOnMap.put(par3Str, new MapCoord(this, (byte) par1, var13, var14, var15)); + } + + /** + * Get byte array of packet data to send to players on map for updating map data + */ + public byte[] getUpdatePacketData(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + MapInfo var4 = (MapInfo) this.playersHashMap.get(par3EntityPlayer); + return var4 == null ? null : var4.getPlayersOnMap(par1ItemStack); + } + + /** + * Marks a vertical range of pixels as being modified so they will be resent to + * clients. Parameters: X, lowest Y, highest Y + */ + public void setColumnDirty(int par1, int par2, int par3) { + super.markDirty(); + + for (int var4 = 0; var4 < this.playersArrayList.size(); ++var4) { + MapInfo var5 = (MapInfo) this.playersArrayList.get(var4); + + if (var5.field_76209_b[par1] < 0 || var5.field_76209_b[par1] > par2) { + var5.field_76209_b[par1] = par2; + } + + if (var5.field_76210_c[par1] < 0 || var5.field_76210_c[par1] < par3) { + var5.field_76210_c[par1] = par3; + } + } + } + + /** + * Updates the client's map with information from other players in MP + */ + public void updateMPMapData(byte[] par1ArrayOfByte) { + int var2; + + if (par1ArrayOfByte[0] == 0) { + var2 = par1ArrayOfByte[1] & 255; + int var3 = par1ArrayOfByte[2] & 255; + + for (int var4 = 0; var4 < par1ArrayOfByte.length - 3; ++var4) { + this.colors[(var4 + var3) * 128 + var2] = par1ArrayOfByte[var4 + 3]; + } + + this.markDirty(); + } else if (par1ArrayOfByte[0] == 1) { + this.playersVisibleOnMap.clear(); + + for (var2 = 0; var2 < (par1ArrayOfByte.length - 1) / 3; ++var2) { + byte var7 = (byte) (par1ArrayOfByte[var2 * 3 + 1] >> 4); + byte var8 = par1ArrayOfByte[var2 * 3 + 2]; + byte var5 = par1ArrayOfByte[var2 * 3 + 3]; + byte var6 = (byte) (par1ArrayOfByte[var2 * 3 + 1] & 15); + this.playersVisibleOnMap.put("icon-" + var2, new MapCoord(this, var7, var8, var5, var6)); + } + } else if (par1ArrayOfByte[0] == 2) { + this.scale = par1ArrayOfByte[1]; + } + } + + public MapInfo func_82568_a(EntityPlayer par1EntityPlayer) { + MapInfo var2 = (MapInfo) this.playersHashMap.get(par1EntityPlayer); + + if (var2 == null) { + var2 = new MapInfo(this, par1EntityPlayer); + this.playersHashMap.put(par1EntityPlayer, var2); + this.playersArrayList.add(var2); + } + + return var2; + } +} diff --git a/src/main/java/net/minecraft/src/MapInfo.java b/src/main/java/net/minecraft/src/MapInfo.java new file mode 100644 index 0000000..6504472 --- /dev/null +++ b/src/main/java/net/minecraft/src/MapInfo.java @@ -0,0 +1,115 @@ +package net.minecraft.src; + +import java.util.Iterator; + +public class MapInfo { + /** Reference for EntityPlayer object in MapInfo */ + public final EntityPlayer entityplayerObj; + public int[] field_76209_b; + public int[] field_76210_c; + + /** + * updated by x = mod(x*11,128) +1 x-1 is used to index field_76209_b and + * field_76210_c + */ + private int currentRandomNumber; + private int ticksUntilPlayerLocationMapUpdate; + + /** + * a cache of the result from getPlayersOnMap so that it is not resent when + * nothing changes + */ + private byte[] lastPlayerLocationOnMap; + public int field_82569_d; + private boolean field_82570_i; + + /** reference in MapInfo to MapData object */ + final MapData mapDataObj; + + public MapInfo(MapData par1MapData, EntityPlayer par2EntityPlayer) { + this.mapDataObj = par1MapData; + this.field_76209_b = new int[128]; + this.field_76210_c = new int[128]; + this.currentRandomNumber = 0; + this.ticksUntilPlayerLocationMapUpdate = 0; + this.field_82570_i = false; + this.entityplayerObj = par2EntityPlayer; + + for (int var3 = 0; var3 < this.field_76209_b.length; ++var3) { + this.field_76209_b[var3] = 0; + this.field_76210_c[var3] = 127; + } + } + + /** + * returns a 1+players*3 array, of x,y, and color . the name of this function + * may be partially wrong, as there is a second branch to the code here + */ + public byte[] getPlayersOnMap(ItemStack par1ItemStack) { + byte[] var2; + + if (!this.field_82570_i) { + var2 = new byte[] { (byte) 2, this.mapDataObj.scale }; + this.field_82570_i = true; + return var2; + } else { + int var3; + int var10; + + if (--this.ticksUntilPlayerLocationMapUpdate < 0) { + this.ticksUntilPlayerLocationMapUpdate = 4; + var2 = new byte[this.mapDataObj.playersVisibleOnMap.size() * 3 + 1]; + var2[0] = 1; + var3 = 0; + + for (Iterator var4 = this.mapDataObj.playersVisibleOnMap.values().iterator(); var4.hasNext(); ++var3) { + MapCoord var5 = (MapCoord) var4.next(); + var2[var3 * 3 + 1] = (byte) (var5.iconSize << 4 | var5.iconRotation & 15); + var2[var3 * 3 + 2] = var5.centerX; + var2[var3 * 3 + 3] = var5.centerZ; + } + + boolean var9 = !par1ItemStack.isOnItemFrame(); + + if (this.lastPlayerLocationOnMap != null && this.lastPlayerLocationOnMap.length == var2.length) { + for (var10 = 0; var10 < var2.length; ++var10) { + if (var2[var10] != this.lastPlayerLocationOnMap[var10]) { + var9 = false; + break; + } + } + } else { + var9 = false; + } + + if (!var9) { + this.lastPlayerLocationOnMap = var2; + return var2; + } + } + + for (int var8 = 0; var8 < 1; ++var8) { + var3 = this.currentRandomNumber++ * 11 % 128; + + if (this.field_76209_b[var3] >= 0) { + int var11 = this.field_76210_c[var3] - this.field_76209_b[var3] + 1; + var10 = this.field_76209_b[var3]; + byte[] var6 = new byte[var11 + 3]; + var6[0] = 0; + var6[1] = (byte) var3; + var6[2] = (byte) var10; + + for (int var7 = 0; var7 < var6.length - 3; ++var7) { + var6[var7 + 3] = this.mapDataObj.colors[(var7 + var10) * 128 + var3]; + } + + this.field_76210_c[var3] = -1; + this.field_76209_b[var3] = -1; + return var6; + } + } + + return null; + } + } +} diff --git a/src/main/java/net/minecraft/src/MapItemRenderer.java b/src/main/java/net/minecraft/src/MapItemRenderer.java new file mode 100644 index 0000000..37b228e --- /dev/null +++ b/src/main/java/net/minecraft/src/MapItemRenderer.java @@ -0,0 +1,110 @@ +package net.minecraft.src; + +import java.util.Iterator; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.EaglerImage; +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class MapItemRenderer { + private int[] intArray = new int[16384]; + private int bufferedImage; + private GameSettings gameSettings; + private FontRenderer fontRenderer; + + public MapItemRenderer(FontRenderer par1FontRenderer, GameSettings par2GameSettings, RenderEngine par3RenderEngine) { + this.gameSettings = par2GameSettings; + this.fontRenderer = par1FontRenderer; + this.bufferedImage = par3RenderEngine.allocateAndSetupTexture(new EaglerImage(128, 128, false)); + + for (int var4 = 0; var4 < 16384; ++var4) { + this.intArray[var4] = 0; + } + } + + private static final TextureLocation mapicons = new TextureLocation("/misc/mapicons.png"); + + public void renderMap(EntityPlayer par1EntityPlayer, RenderEngine par2RenderEngine, MapData par3MapData) { + for (int var4 = 0; var4 < 16384; ++var4) { + byte var5 = par3MapData.colors[var4]; + + if (var5 / 4 == 0) { + this.intArray[var4] = (var4 + var4 / 128 & 1) * 8 + 16 << 24; + } else { + int var6 = MapColor.mapColorArray[var5 / 4].colorValue; + int var7 = var5 & 3; + short var8 = 220; + + if (var7 == 2) { + var8 = 255; + } + + if (var7 == 0) { + var8 = 180; + } + + int var9 = (var6 >> 16 & 255) * var8 / 255; + int var10 = (var6 >> 8 & 255) * var8 / 255; + int var11 = (var6 & 255) * var8 / 255; + + if (this.gameSettings.anaglyph) { + int var12 = (var9 * 30 + var10 * 59 + var11 * 11) / 100; + int var13 = (var9 * 30 + var10 * 70) / 100; + int var14 = (var9 * 30 + var11 * 70) / 100; + var9 = var12; + var10 = var13; + var11 = var14; + } + + this.intArray[var4] = -16777216 | var9 << 16 | var10 << 8 | var11; + } + } + + par2RenderEngine.createTextureFromBytes(this.intArray, 128, 128, this.bufferedImage); + byte var15 = 0; + byte var16 = 0; + Tessellator var17 = Tessellator.instance; + float var18 = 0.0F; + EaglerAdapter.glBindTexture(EaglerAdapter.GL_TEXTURE_2D, this.bufferedImage); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_ONE, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + var17.startDrawingQuads(); + var17.addVertexWithUV((double) ((float) (var15 + 0) + var18), (double) ((float) (var16 + 128) - var18), -0.009999999776482582D, 0.0D, 1.0D); + var17.addVertexWithUV((double) ((float) (var15 + 128) - var18), (double) ((float) (var16 + 128) - var18), -0.009999999776482582D, 1.0D, 1.0D); + var17.addVertexWithUV((double) ((float) (var15 + 128) - var18), (double) ((float) (var16 + 0) + var18), -0.009999999776482582D, 1.0D, 0.0D); + var17.addVertexWithUV((double) ((float) (var15 + 0) + var18), (double) ((float) (var16 + 0) + var18), -0.009999999776482582D, 0.0D, 0.0D); + var17.draw(); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + par2RenderEngine.resetBoundTexture(); + mapicons.bindTexture(); + int var19 = 0; + + for (Iterator var20 = par3MapData.playersVisibleOnMap.values().iterator(); var20.hasNext(); ++var19) { + MapCoord var21 = (MapCoord) var20.next(); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef((float) var15 + (float) var21.centerX / 2.0F + 64.0F, (float) var16 + (float) var21.centerZ / 2.0F + 64.0F, -0.02F); + EaglerAdapter.glRotatef((float) (var21.iconRotation * 360) / 16.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glScalef(4.0F, 4.0F, 3.0F); + EaglerAdapter.glTranslatef(-0.125F, 0.125F, 0.0F); + float var22 = (float) (var21.iconSize % 4 + 0) / 4.0F; + float var23 = (float) (var21.iconSize / 4 + 0) / 4.0F; + float var24 = (float) (var21.iconSize % 4 + 1) / 4.0F; + float var25 = (float) (var21.iconSize / 4 + 1) / 4.0F; + var17.startDrawingQuads(); + var17.addVertexWithUV(-1.0D, 1.0D, (double) ((float) var19 * 0.001F), (double) var22, (double) var23); + var17.addVertexWithUV(1.0D, 1.0D, (double) ((float) var19 * 0.001F), (double) var24, (double) var23); + var17.addVertexWithUV(1.0D, -1.0D, (double) ((float) var19 * 0.001F), (double) var24, (double) var25); + var17.addVertexWithUV(-1.0D, -1.0D, (double) ((float) var19 * 0.001F), (double) var22, (double) var25); + var17.draw(); + EaglerAdapter.glPopMatrix(); + } + + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(0.0F, 0.0F, -0.04F); + EaglerAdapter.glScalef(1.0F, 1.0F, 1.0F); + EaglerAdapter.glPopMatrix(); + } +} diff --git a/src/main/java/net/minecraft/src/MapStorage.java b/src/main/java/net/minecraft/src/MapStorage.java new file mode 100644 index 0000000..67bd079 --- /dev/null +++ b/src/main/java/net/minecraft/src/MapStorage.java @@ -0,0 +1,101 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class MapStorage { + + /** Map of item data String id to loaded MapDataBases */ + private Map loadedDataMap = new HashMap(); + + /** List of loaded MapDataBases. */ + private List loadedDataList = new ArrayList(); + + /** + * Map of MapDataBase id String prefixes ('map' etc) to max known unique Short + * id (the 0 part etc) for that prefix + */ + private Map idCounts = new HashMap(); + + public MapStorage() { + this.loadIdCounts(); + } + + /** + * Loads an existing MapDataBase corresponding to the given String id from disk, + * instantiating the given Class, or returns null if none such file exists. + * args: Class to instantiate, String dataid + */ + public WorldSavedData loadData(Class par1Class, String par2Str) { + return (WorldSavedData) this.loadedDataMap.get(par2Str); + } + + /** + * Assigns the given String id to the given MapDataBase, removing any existing + * ones of the same id. + */ + public void setData(String par1Str, WorldSavedData par2WorldSavedData) { + if (par2WorldSavedData == null) { + throw new RuntimeException("Can\'t set null data"); + } else { + if (this.loadedDataMap.containsKey(par1Str)) { + this.loadedDataList.remove(this.loadedDataMap.remove(par1Str)); + } + + this.loadedDataMap.put(par1Str, par2WorldSavedData); + this.loadedDataList.add(par2WorldSavedData); + } + } + + /** + * Saves all dirty loaded MapDataBases to disk. + */ + public void saveAllData() { + for (int var1 = 0; var1 < this.loadedDataList.size(); ++var1) { + WorldSavedData var2 = (WorldSavedData) this.loadedDataList.get(var1); + + if (var2.isDirty()) { + this.saveData(var2); + var2.setDirty(false); + } + } + } + + /** + * Saves the given MapDataBase to disk. + */ + private void saveData(WorldSavedData par1WorldSavedData) { + + } + + /** + * Loads the idCounts Map from the 'idcounts' file. + */ + private void loadIdCounts() { + try { + this.idCounts.clear(); + } catch (Exception var9) { + var9.printStackTrace(); + } + } + + /** + * Returns an unique new data id for the given prefix and saves the idCounts map + * to the 'idcounts' file. + */ + public int getUniqueDataId(String par1Str) { + Short var2 = (Short) this.idCounts.get(par1Str); + + if (var2 == null) { + var2 = Short.valueOf((short) 0); + } else { + var2 = Short.valueOf((short) (var2.shortValue() + 1)); + } + + this.idCounts.put(par1Str, var2); + + return var2.shortValue(); + } +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/src/Material.java b/src/main/java/net/minecraft/src/Material.java new file mode 100644 index 0000000..faf19d6 --- /dev/null +++ b/src/main/java/net/minecraft/src/Material.java @@ -0,0 +1,209 @@ +package net.minecraft.src; + +public class Material { + public static final Material air = new MaterialTransparent(MapColor.airColor); + + /** The material used by BlockGrass. */ + public static final Material grass = new Material(MapColor.grassColor); + public static final Material ground = new Material(MapColor.dirtColor); + public static final Material wood = (new Material(MapColor.woodColor)).setBurning(); + public static final Material rock = (new Material(MapColor.stoneColor)).setRequiresTool(); + public static final Material iron = (new Material(MapColor.ironColor)).setRequiresTool(); + public static final Material anvil = (new Material(MapColor.ironColor)).setRequiresTool().setImmovableMobility(); + public static final Material water = (new MaterialLiquid(MapColor.waterColor)).setNoPushMobility(); + public static final Material lava = (new MaterialLiquid(MapColor.tntColor)).setNoPushMobility(); + public static final Material leaves = (new Material(MapColor.foliageColor)).setBurning().setTranslucent().setNoPushMobility(); + public static final Material plants = (new MaterialLogic(MapColor.foliageColor)).setNoPushMobility(); + public static final Material vine = (new MaterialLogic(MapColor.foliageColor)).setBurning().setNoPushMobility().setReplaceable(); + public static final Material sponge = new Material(MapColor.clothColor); + public static final Material cloth = (new Material(MapColor.clothColor)).setBurning(); + public static final Material fire = (new MaterialTransparent(MapColor.airColor)).setNoPushMobility(); + public static final Material sand = new Material(MapColor.sandColor); + public static final Material circuits = (new MaterialLogic(MapColor.airColor)).setNoPushMobility(); + public static final Material glass = (new Material(MapColor.airColor)).setTranslucent().setAlwaysHarvested(); + public static final Material redstoneLight = (new Material(MapColor.airColor)).setAlwaysHarvested(); + public static final Material tnt = (new Material(MapColor.tntColor)).setBurning().setTranslucent(); + public static final Material coral = (new Material(MapColor.foliageColor)).setNoPushMobility(); + public static final Material ice = (new Material(MapColor.iceColor)).setTranslucent().setAlwaysHarvested(); + public static final Material snow = (new MaterialLogic(MapColor.snowColor)).setReplaceable().setTranslucent().setRequiresTool().setNoPushMobility(); + + /** The material for crafted snow. */ + public static final Material craftedSnow = (new Material(MapColor.snowColor)).setRequiresTool(); + public static final Material cactus = (new Material(MapColor.foliageColor)).setTranslucent().setNoPushMobility(); + public static final Material clay = new Material(MapColor.clayColor); + + /** pumpkin */ + public static final Material pumpkin = (new Material(MapColor.foliageColor)).setNoPushMobility(); + public static final Material dragonEgg = (new Material(MapColor.foliageColor)).setNoPushMobility(); + + /** Material used for portals */ + public static final Material portal = (new MaterialPortal(MapColor.airColor)).setImmovableMobility(); + + /** Cake's material, see BlockCake */ + public static final Material cake = (new Material(MapColor.airColor)).setNoPushMobility(); + + /** Web's material. */ + public static final Material web = (new MaterialWeb(MapColor.clothColor)).setRequiresTool().setNoPushMobility(); + + /** Pistons' material. */ + public static final Material piston = (new Material(MapColor.stoneColor)).setImmovableMobility(); + + /** Bool defining if the block can burn or not. */ + private boolean canBurn; + + /** + * Determines whether blocks with this material can be "overwritten" by other + * blocks when placed - eg snow, vines and tall grass. + */ + private boolean replaceable; + + /** Indicates if the material is translucent */ + private boolean isTranslucent; + + /** The color index used to draw the blocks of this material on maps. */ + public final MapColor materialMapColor; + + /** + * Determines if the material can be harvested without a tool (or with the wrong + * tool) + */ + private boolean requiresNoTool = true; + + /** + * Mobility information flag. 0 indicates that this block is normal, 1 indicates + * that it can't push other blocks, 2 indicates that it can't be pushed. + */ + private int mobilityFlag; + private boolean field_85159_M; + + public Material(MapColor par1MapColor) { + this.materialMapColor = par1MapColor; + } + + /** + * Returns if blocks of these materials are liquids. + */ + public boolean isLiquid() { + return false; + } + + public boolean isSolid() { + return true; + } + + /** + * Will prevent grass from growing on dirt underneath and kill any grass below + * it if it returns true + */ + public boolean getCanBlockGrass() { + return true; + } + + /** + * Returns if this material is considered solid or not + */ + public boolean blocksMovement() { + return true; + } + + /** + * Marks the material as translucent + */ + private Material setTranslucent() { + this.isTranslucent = true; + return this; + } + + /** + * Makes blocks with this material require the correct tool to be harvested. + */ + protected Material setRequiresTool() { + this.requiresNoTool = false; + return this; + } + + /** + * Set the canBurn bool to True and return the current object. + */ + protected Material setBurning() { + this.canBurn = true; + return this; + } + + /** + * Returns if the block can burn or not. + */ + public boolean getCanBurn() { + return this.canBurn; + } + + /** + * Sets {@link #replaceable} to true. + */ + public Material setReplaceable() { + this.replaceable = true; + return this; + } + + /** + * Returns whether the material can be replaced by other blocks when placed - eg + * snow, vines and tall grass. + */ + public boolean isReplaceable() { + return this.replaceable; + } + + /** + * Indicate if the material is opaque + */ + public boolean isOpaque() { + return this.isTranslucent ? false : this.blocksMovement(); + } + + /** + * Returns true if the material can be harvested without a tool (or with the + * wrong tool) + */ + public boolean isToolNotRequired() { + return this.requiresNoTool; + } + + /** + * Returns the mobility information of the material, 0 = free, 1 = can't push + * but can move over, 2 = total immobility and stop pistons. + */ + public int getMaterialMobility() { + return this.mobilityFlag; + } + + /** + * This type of material can't be pushed, but pistons can move over it. + */ + protected Material setNoPushMobility() { + this.mobilityFlag = 1; + return this; + } + + /** + * This type of material can't be pushed, and pistons are blocked to move. + */ + protected Material setImmovableMobility() { + this.mobilityFlag = 2; + return this; + } + + /** + * Set as harvestable in any case. + */ + protected Material setAlwaysHarvested() { + this.field_85159_M = true; + return this; + } + + /** + * Check to see if we can harvest it in any case. + */ + public boolean isAlwaysHarvested() { + return this.field_85159_M; + } +} diff --git a/src/main/java/net/minecraft/src/MaterialLiquid.java b/src/main/java/net/minecraft/src/MaterialLiquid.java new file mode 100644 index 0000000..f710e93 --- /dev/null +++ b/src/main/java/net/minecraft/src/MaterialLiquid.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class MaterialLiquid extends Material { + public MaterialLiquid(MapColor par1MapColor) { + super(par1MapColor); + this.setReplaceable(); + this.setNoPushMobility(); + } + + /** + * Returns if blocks of these materials are liquids. + */ + public boolean isLiquid() { + return true; + } + + /** + * Returns if this material is considered solid or not + */ + public boolean blocksMovement() { + return false; + } + + public boolean isSolid() { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/MaterialLogic.java b/src/main/java/net/minecraft/src/MaterialLogic.java new file mode 100644 index 0000000..5e7208c --- /dev/null +++ b/src/main/java/net/minecraft/src/MaterialLogic.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class MaterialLogic extends Material { + public MaterialLogic(MapColor par1MapColor) { + super(par1MapColor); + this.setAlwaysHarvested(); + } + + public boolean isSolid() { + return false; + } + + /** + * Will prevent grass from growing on dirt underneath and kill any grass below + * it if it returns true + */ + public boolean getCanBlockGrass() { + return false; + } + + /** + * Returns if this material is considered solid or not + */ + public boolean blocksMovement() { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/MaterialPortal.java b/src/main/java/net/minecraft/src/MaterialPortal.java new file mode 100644 index 0000000..c22f740 --- /dev/null +++ b/src/main/java/net/minecraft/src/MaterialPortal.java @@ -0,0 +1,26 @@ +package net.minecraft.src; + +public class MaterialPortal extends Material { + public MaterialPortal(MapColor par1MapColor) { + super(par1MapColor); + } + + public boolean isSolid() { + return false; + } + + /** + * Will prevent grass from growing on dirt underneath and kill any grass below + * it if it returns true + */ + public boolean getCanBlockGrass() { + return false; + } + + /** + * Returns if this material is considered solid or not + */ + public boolean blocksMovement() { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/MaterialTransparent.java b/src/main/java/net/minecraft/src/MaterialTransparent.java new file mode 100644 index 0000000..f082ba5 --- /dev/null +++ b/src/main/java/net/minecraft/src/MaterialTransparent.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class MaterialTransparent extends Material { + public MaterialTransparent(MapColor par1MapColor) { + super(par1MapColor); + this.setReplaceable(); + } + + public boolean isSolid() { + return false; + } + + /** + * Will prevent grass from growing on dirt underneath and kill any grass below + * it if it returns true + */ + public boolean getCanBlockGrass() { + return false; + } + + /** + * Returns if this material is considered solid or not + */ + public boolean blocksMovement() { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/MaterialWeb.java b/src/main/java/net/minecraft/src/MaterialWeb.java new file mode 100644 index 0000000..648c793 --- /dev/null +++ b/src/main/java/net/minecraft/src/MaterialWeb.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +final class MaterialWeb extends Material { + MaterialWeb(MapColor par1MapColor) { + super(par1MapColor); + } + + /** + * Returns if this material is considered solid or not + */ + public boolean blocksMovement() { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/MathHelper.java b/src/main/java/net/minecraft/src/MathHelper.java new file mode 100644 index 0000000..b58f77f --- /dev/null +++ b/src/main/java/net/minecraft/src/MathHelper.java @@ -0,0 +1,261 @@ +package net.minecraft.src; + +import java.util.Random; + + + +public class MathHelper { + /** + * A table of sin values computed from 0 (inclusive) to 2*pi (exclusive), with + * steps of 2*PI / 65536. + */ + private static float[] SIN_TABLE = new float[65536]; + + /** + * sin looked up in a table + */ + public static final float sin(float par0) { + return SIN_TABLE[(int) (par0 * 10430.378F) & 65535]; + } + + /** + * cos looked up in the sin table with the appropriate offset + */ + public static final float cos(float par0) { + return SIN_TABLE[(int) (par0 * 10430.378F + 16384.0F) & 65535]; + } + + public static final float sqrt_float(float par0) { + return (float) Math.sqrt((double) par0); + } + + public static final float sqrt_double(double par0) { + return (float) Math.sqrt(par0); + } + + /** + * Returns the greatest integer less than or equal to the float argument + */ + public static int floor_float(float par0) { + int var1 = (int) par0; + return par0 < (float) var1 ? var1 - 1 : var1; + } + + /** + * returns par0 cast as an int, and no greater than Integer.MAX_VALUE-1024 + */ + public static int truncateDoubleToInt(double par0) { + return (int) (par0 + 1024.0D) - 1024; + } + + /** + * Returns the greatest integer less than or equal to the double argument + */ + public static int floor_double(double par0) { + int var2 = (int) par0; + return par0 < (double) var2 ? var2 - 1 : var2; + } + + /** + * Long version of floor_double + */ + public static long floor_double_long(double par0) { + long var2 = (long) par0; + return par0 < (double) var2 ? var2 - 1L : var2; + } + + public static float abs(float par0) { + return par0 >= 0.0F ? par0 : -par0; + } + + /** + * Returns the unsigned value of an int. + */ + public static int abs_int(int par0) { + return par0 >= 0 ? par0 : -par0; + } + + public static int ceiling_float_int(float par0) { + int var1 = (int) par0; + return par0 > (float) var1 ? var1 + 1 : var1; + } + + public static int ceiling_double_int(double par0) { + int var2 = (int) par0; + return par0 > (double) var2 ? var2 + 1 : var2; + } + + /** + * Returns the value of the first parameter, clamped to be within the lower and + * upper limits given by the second and third parameters. + */ + public static int clamp_int(int par0, int par1, int par2) { + return par0 < par1 ? par1 : (par0 > par2 ? par2 : par0); + } + + /** + * Returns the value of the first parameter, clamped to be within the lower and + * upper limits given by the second and third parameters + */ + public static float clamp_float(float par0, float par1, float par2) { + return par0 < par1 ? par1 : (par0 > par2 ? par2 : par0); + } + + /** + * Maximum of the absolute value of two numbers. + */ + public static double abs_max(double par0, double par2) { + if (par0 < 0.0D) { + par0 = -par0; + } + + if (par2 < 0.0D) { + par2 = -par2; + } + + return par0 > par2 ? par0 : par2; + } + + /** + * Buckets an integer with specifed bucket sizes. Args: i, bucketSize + */ + public static int bucketInt(int par0, int par1) { + return par0 < 0 ? -((-par0 - 1) / par1) - 1 : par0 / par1; + } + + /** + * Tests if a string is null or of length zero + */ + public static boolean stringNullOrLengthZero(String par0Str) { + return par0Str == null || par0Str.length() == 0; + } + + public static int getRandomIntegerInRange(Random par0Random, int par1, int par2) { + return par1 >= par2 ? par1 : par0Random.nextInt(par2 - par1 + 1) + par1; + } + + public static double getRandomDoubleInRange(Random par0Random, double par1, double par3) { + return par1 >= par3 ? par1 : par0Random.nextDouble() * (par3 - par1) + par1; + } + + public static double average(long[] par0ArrayOfLong) { + long var1 = 0L; + long[] var3 = par0ArrayOfLong; + int var4 = par0ArrayOfLong.length; + + for (int var5 = 0; var5 < var4; ++var5) { + long var6 = var3[var5]; + var1 += var6; + } + + return (double) var1 / (double) par0ArrayOfLong.length; + } + + /** + * the angle is reduced to an angle between -180 and +180 by mod, and a 360 + * check + */ + public static float wrapAngleTo180_float(float par0) { + par0 %= 360.0F; + + if (par0 >= 180.0F) { + par0 -= 360.0F; + } + + if (par0 < -180.0F) { + par0 += 360.0F; + } + + return par0; + } + + /** + * the angle is reduced to an angle between -180 and +180 by mod, and a 360 + * check + */ + public static double wrapAngleTo180_double(double par0) { + par0 %= 360.0D; + + if (par0 >= 180.0D) { + par0 -= 360.0D; + } + + if (par0 < -180.0D) { + par0 += 360.0D; + } + + return par0; + } + + /** + * parses the string as integer or returns the second parameter if it fails + */ + public static int parseIntWithDefault(String par0Str, int par1) { + int var2 = par1; + + try { + var2 = Integer.parseInt(par0Str); + } catch (Throwable var4) { + ; + } + + return var2; + } + + /** + * parses the string as integer or returns the second parameter if it fails. + * this value is capped to par2 + */ + public static int parseIntWithDefaultAndMax(String par0Str, int par1, int par2) { + int var3 = par1; + + try { + var3 = Integer.parseInt(par0Str); + } catch (Throwable var5) { + ; + } + + if (var3 < par2) { + var3 = par2; + } + + return var3; + } + + /** + * parses the string as double or returns the second parameter if it fails. + */ + public static double parseDoubleWithDefault(String par0Str, double par1) { + double var3 = par1; + + try { + var3 = Double.parseDouble(par0Str); + } catch (Throwable var6) { + ; + } + + return var3; + } + + public static double func_82713_a(String par0Str, double par1, double par3) { + double var5 = par1; + + try { + var5 = Double.parseDouble(par0Str); + } catch (Throwable var8) { + ; + } + + if (var5 < par3) { + var5 = par3; + } + + return var5; + } + + static { + for (int var0 = 0; var0 < 65536; ++var0) { + SIN_TABLE[var0] = (float) Math.sin((double) var0 * Math.PI * 2.0D / 65536.0D); + } + } +} diff --git a/src/main/java/net/minecraft/src/MerchantRecipe.java b/src/main/java/net/minecraft/src/MerchantRecipe.java new file mode 100644 index 0000000..30e2322 --- /dev/null +++ b/src/main/java/net/minecraft/src/MerchantRecipe.java @@ -0,0 +1,135 @@ +package net.minecraft.src; + +public class MerchantRecipe { + /** Item the Villager buys. */ + private ItemStack itemToBuy; + + /** Second Item the Villager buys. */ + private ItemStack secondItemToBuy; + + /** Item the Villager sells. */ + private ItemStack itemToSell; + + /** + * Saves how much has been tool used when put into to slot to be enchanted. + */ + private int toolUses; + + /** Maximum times this trade can be used. */ + private int maxTradeUses; + + public MerchantRecipe(NBTTagCompound par1NBTTagCompound) { + this.readFromTags(par1NBTTagCompound); + } + + public MerchantRecipe(ItemStack par1ItemStack, ItemStack par2ItemStack, ItemStack par3ItemStack) { + this.itemToBuy = par1ItemStack; + this.secondItemToBuy = par2ItemStack; + this.itemToSell = par3ItemStack; + this.maxTradeUses = 7; + } + + public MerchantRecipe(ItemStack par1ItemStack, ItemStack par2ItemStack) { + this(par1ItemStack, (ItemStack) null, par2ItemStack); + } + + public MerchantRecipe(ItemStack par1ItemStack, Item par2Item) { + this(par1ItemStack, new ItemStack(par2Item)); + } + + /** + * Gets the itemToBuy. + */ + public ItemStack getItemToBuy() { + return this.itemToBuy; + } + + /** + * Gets secondItemToBuy. + */ + public ItemStack getSecondItemToBuy() { + return this.secondItemToBuy; + } + + /** + * Gets if Villager has secondItemToBuy. + */ + public boolean hasSecondItemToBuy() { + return this.secondItemToBuy != null; + } + + /** + * Gets itemToSell. + */ + public ItemStack getItemToSell() { + return this.itemToSell; + } + + /** + * checks if both the first and second ItemToBuy IDs are the same + */ + public boolean hasSameIDsAs(MerchantRecipe par1MerchantRecipe) { + return this.itemToBuy.itemID == par1MerchantRecipe.itemToBuy.itemID && this.itemToSell.itemID == par1MerchantRecipe.itemToSell.itemID + ? this.secondItemToBuy == null && par1MerchantRecipe.secondItemToBuy == null + || this.secondItemToBuy != null && par1MerchantRecipe.secondItemToBuy != null && this.secondItemToBuy.itemID == par1MerchantRecipe.secondItemToBuy.itemID + : false; + } + + /** + * checks first and second ItemToBuy ID's and count. Calls hasSameIDs + */ + public boolean hasSameItemsAs(MerchantRecipe par1MerchantRecipe) { + return this.hasSameIDsAs(par1MerchantRecipe) && (this.itemToBuy.stackSize < par1MerchantRecipe.itemToBuy.stackSize || this.secondItemToBuy != null && this.secondItemToBuy.stackSize < par1MerchantRecipe.secondItemToBuy.stackSize); + } + + public void incrementToolUses() { + ++this.toolUses; + } + + public void func_82783_a(int par1) { + this.maxTradeUses += par1; + } + + public boolean func_82784_g() { + return this.toolUses >= this.maxTradeUses; + } + + public void func_82785_h() { + this.toolUses = this.maxTradeUses; + } + + public void readFromTags(NBTTagCompound par1NBTTagCompound) { + NBTTagCompound var2 = par1NBTTagCompound.getCompoundTag("buy"); + this.itemToBuy = ItemStack.loadItemStackFromNBT(var2); + NBTTagCompound var3 = par1NBTTagCompound.getCompoundTag("sell"); + this.itemToSell = ItemStack.loadItemStackFromNBT(var3); + + if (par1NBTTagCompound.hasKey("buyB")) { + this.secondItemToBuy = ItemStack.loadItemStackFromNBT(par1NBTTagCompound.getCompoundTag("buyB")); + } + + if (par1NBTTagCompound.hasKey("uses")) { + this.toolUses = par1NBTTagCompound.getInteger("uses"); + } + + if (par1NBTTagCompound.hasKey("maxUses")) { + this.maxTradeUses = par1NBTTagCompound.getInteger("maxUses"); + } else { + this.maxTradeUses = 7; + } + } + + public NBTTagCompound writeToTags() { + NBTTagCompound var1 = new NBTTagCompound(); + var1.setCompoundTag("buy", this.itemToBuy.writeToNBT(new NBTTagCompound("buy"))); + var1.setCompoundTag("sell", this.itemToSell.writeToNBT(new NBTTagCompound("sell"))); + + if (this.secondItemToBuy != null) { + var1.setCompoundTag("buyB", this.secondItemToBuy.writeToNBT(new NBTTagCompound("buyB"))); + } + + var1.setInteger("uses", this.toolUses); + var1.setInteger("maxUses", this.maxTradeUses); + return var1; + } +} diff --git a/src/main/java/net/minecraft/src/MerchantRecipeList.java b/src/main/java/net/minecraft/src/MerchantRecipeList.java new file mode 100644 index 0000000..af90696 --- /dev/null +++ b/src/main/java/net/minecraft/src/MerchantRecipeList.java @@ -0,0 +1,123 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; + +public class MerchantRecipeList extends ArrayList { + public MerchantRecipeList() { + } + + public MerchantRecipeList(NBTTagCompound par1NBTTagCompound) { + this.readRecipiesFromTags(par1NBTTagCompound); + } + + /** + * can par1,par2 be used to in crafting recipe par3 + */ + public MerchantRecipe canRecipeBeUsed(ItemStack par1ItemStack, ItemStack par2ItemStack, int par3) { + if (par3 > 0 && par3 < this.size()) { + MerchantRecipe var6 = (MerchantRecipe) this.get(par3); + return par1ItemStack.itemID == var6.getItemToBuy().itemID && (par2ItemStack == null && !var6.hasSecondItemToBuy() || var6.hasSecondItemToBuy() && par2ItemStack != null && var6.getSecondItemToBuy().itemID == par2ItemStack.itemID) + && par1ItemStack.stackSize >= var6.getItemToBuy().stackSize && (!var6.hasSecondItemToBuy() || par2ItemStack.stackSize >= var6.getSecondItemToBuy().stackSize) ? var6 : null; + } else { + for (int var4 = 0; var4 < this.size(); ++var4) { + MerchantRecipe var5 = (MerchantRecipe) this.get(var4); + + if (par1ItemStack.itemID == var5.getItemToBuy().itemID && par1ItemStack.stackSize >= var5.getItemToBuy().stackSize && (!var5.hasSecondItemToBuy() && par2ItemStack == null + || var5.hasSecondItemToBuy() && par2ItemStack != null && var5.getSecondItemToBuy().itemID == par2ItemStack.itemID && par2ItemStack.stackSize >= var5.getSecondItemToBuy().stackSize)) { + return var5; + } + } + + return null; + } + } + + /** + * checks if there is a recipie for the same ingredients already on the list, + * and replaces it. otherwise, adds it + */ + public void addToListWithCheck(MerchantRecipe par1MerchantRecipe) { + for (int var2 = 0; var2 < this.size(); ++var2) { + MerchantRecipe var3 = (MerchantRecipe) this.get(var2); + + if (par1MerchantRecipe.hasSameIDsAs(var3)) { + if (par1MerchantRecipe.hasSameItemsAs(var3)) { + this.set(var2, par1MerchantRecipe); + } + + return; + } + } + + this.add(par1MerchantRecipe); + } + + public void writeRecipiesToStream(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte((byte) (this.size() & 255)); + + for (int var2 = 0; var2 < this.size(); ++var2) { + MerchantRecipe var3 = (MerchantRecipe) this.get(var2); + Packet.writeItemStack(var3.getItemToBuy(), par1DataOutputStream); + Packet.writeItemStack(var3.getItemToSell(), par1DataOutputStream); + ItemStack var4 = var3.getSecondItemToBuy(); + par1DataOutputStream.writeBoolean(var4 != null); + + if (var4 != null) { + Packet.writeItemStack(var4, par1DataOutputStream); + } + + par1DataOutputStream.writeBoolean(var3.func_82784_g()); + } + } + + public static MerchantRecipeList readRecipiesFromStream(DataInputStream par0DataInputStream) throws IOException { + MerchantRecipeList var1 = new MerchantRecipeList(); + int var2 = par0DataInputStream.readByte() & 255; + + for (int var3 = 0; var3 < var2; ++var3) { + ItemStack var4 = Packet.readItemStack(par0DataInputStream); + ItemStack var5 = Packet.readItemStack(par0DataInputStream); + ItemStack var6 = null; + + if (par0DataInputStream.readBoolean()) { + var6 = Packet.readItemStack(par0DataInputStream); + } + + boolean var7 = par0DataInputStream.readBoolean(); + MerchantRecipe var8 = new MerchantRecipe(var4, var6, var5); + + if (var7) { + var8.func_82785_h(); + } + + var1.add(var8); + } + + return var1; + } + + public void readRecipiesFromTags(NBTTagCompound par1NBTTagCompound) { + NBTTagList var2 = par1NBTTagCompound.getTagList("Recipes"); + + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3); + this.add(new MerchantRecipe(var4)); + } + } + + public NBTTagCompound getRecipiesAsTags() { + NBTTagCompound var1 = new NBTTagCompound(); + NBTTagList var2 = new NBTTagList("Recipes"); + + for (int var3 = 0; var3 < this.size(); ++var3) { + MerchantRecipe var4 = (MerchantRecipe) this.get(var3); + var2.appendTag(var4.writeToTags()); + } + + var1.setTag("Recipes", var2); + return var1; + } +} diff --git a/src/main/java/net/minecraft/src/MinecraftError.java b/src/main/java/net/minecraft/src/MinecraftError.java new file mode 100644 index 0000000..d39c889 --- /dev/null +++ b/src/main/java/net/minecraft/src/MinecraftError.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +public class MinecraftError extends Error { +} diff --git a/src/main/java/net/minecraft/src/MinecraftException.java b/src/main/java/net/minecraft/src/MinecraftException.java new file mode 100644 index 0000000..186341e --- /dev/null +++ b/src/main/java/net/minecraft/src/MinecraftException.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +public class MinecraftException extends Exception { + public MinecraftException(String par1Str) { + super(par1Str); + } +} diff --git a/src/main/java/net/minecraft/src/ModelBase.java b/src/main/java/net/minecraft/src/ModelBase.java new file mode 100644 index 0000000..d7c4db0 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelBase.java @@ -0,0 +1,58 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +public abstract class ModelBase { + public float onGround; + public boolean isRiding = false; + + /** + * This is a list of all the boxes (ModelRenderer.class) in the current model. + */ + public List boxList = new ArrayList(); + public boolean isChild = true; + + /** A mapping for all texture offsets */ + private Map modelTextureMap = new HashMap(); + public int textureWidth = 64; + public int textureHeight = 32; + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + } + + /** + * Used for easily adding entity-dependent animations. The second and third + * float params here are the same second and third as in the setRotationAngles + * method. + */ + public void setLivingAnimations(EntityLiving par1EntityLiving, float par2, float par3, float par4) { + } + + public ModelRenderer getRandomModelBox(Random par1Random) { + return (ModelRenderer) this.boxList.get(par1Random.nextInt(this.boxList.size())); + } + + protected void setTextureOffset(String par1Str, int par2, int par3) { + this.modelTextureMap.put(par1Str, new TextureOffset(par2, par3)); + } + + public TextureOffset getTextureOffset(String par1Str) { + return (TextureOffset) this.modelTextureMap.get(par1Str); + } +} diff --git a/src/main/java/net/minecraft/src/ModelBat.java b/src/main/java/net/minecraft/src/ModelBat.java new file mode 100644 index 0000000..73b0f13 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelBat.java @@ -0,0 +1,102 @@ +package net.minecraft.src; + + + +public class ModelBat extends ModelBase { + private ModelRenderer batHead; + + /** The body box of the bat model. */ + private ModelRenderer batBody; + + /** The inner right wing box of the bat model. */ + private ModelRenderer batRightWing; + + /** The inner left wing box of the bat model. */ + private ModelRenderer batLeftWing; + + /** The outer right wing box of the bat model. */ + private ModelRenderer batOuterRightWing; + + /** The outer left wing box of the bat model. */ + private ModelRenderer batOuterLeftWing; + + public ModelBat() { + this.textureWidth = 64; + this.textureHeight = 64; + this.batHead = new ModelRenderer(this, 0, 0); + this.batHead.addBox(-3.0F, -3.0F, -3.0F, 6, 6, 6); + ModelRenderer var1 = new ModelRenderer(this, 24, 0); + var1.addBox(-4.0F, -6.0F, -2.0F, 3, 4, 1); + this.batHead.addChild(var1); + ModelRenderer var2 = new ModelRenderer(this, 24, 0); + var2.mirror = true; + var2.addBox(1.0F, -6.0F, -2.0F, 3, 4, 1); + this.batHead.addChild(var2); + this.batBody = new ModelRenderer(this, 0, 16); + this.batBody.addBox(-3.0F, 4.0F, -3.0F, 6, 12, 6); + this.batBody.setTextureOffset(0, 34).addBox(-5.0F, 16.0F, 0.0F, 10, 6, 1); + this.batRightWing = new ModelRenderer(this, 42, 0); + this.batRightWing.addBox(-12.0F, 1.0F, 1.5F, 10, 16, 1); + this.batOuterRightWing = new ModelRenderer(this, 24, 16); + this.batOuterRightWing.setRotationPoint(-12.0F, 1.0F, 1.5F); + this.batOuterRightWing.addBox(-8.0F, 1.0F, 0.0F, 8, 12, 1); + this.batLeftWing = new ModelRenderer(this, 42, 0); + this.batLeftWing.mirror = true; + this.batLeftWing.addBox(2.0F, 1.0F, 1.5F, 10, 16, 1); + this.batOuterLeftWing = new ModelRenderer(this, 24, 16); + this.batOuterLeftWing.mirror = true; + this.batOuterLeftWing.setRotationPoint(12.0F, 1.0F, 1.5F); + this.batOuterLeftWing.addBox(0.0F, 1.0F, 0.0F, 8, 12, 1); + this.batBody.addChild(this.batRightWing); + this.batBody.addChild(this.batLeftWing); + this.batRightWing.addChild(this.batOuterRightWing); + this.batLeftWing.addChild(this.batOuterLeftWing); + } + + /** + * not actually sure this is size, is not used as of now, but the model would be + * recreated if the value changed and it seems a good match for a bats size + */ + public int getBatSize() { + return 36; + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + EntityBat var8 = (EntityBat) par1Entity; + + if (var8.getIsBatHanging()) { + this.batHead.rotateAngleX = par6 / (180F / (float) Math.PI); + this.batHead.rotateAngleY = (float) Math.PI - par5 / (180F / (float) Math.PI); + this.batHead.rotateAngleZ = (float) Math.PI; + this.batHead.setRotationPoint(0.0F, -2.0F, 0.0F); + this.batRightWing.setRotationPoint(-3.0F, 0.0F, 3.0F); + this.batLeftWing.setRotationPoint(3.0F, 0.0F, 3.0F); + this.batBody.rotateAngleX = (float) Math.PI; + this.batRightWing.rotateAngleX = -0.15707964F; + this.batRightWing.rotateAngleY = -((float) Math.PI * 2F / 5F); + this.batOuterRightWing.rotateAngleY = -1.7278761F; + this.batLeftWing.rotateAngleX = this.batRightWing.rotateAngleX; + this.batLeftWing.rotateAngleY = -this.batRightWing.rotateAngleY; + this.batOuterLeftWing.rotateAngleY = -this.batOuterRightWing.rotateAngleY; + } else { + this.batHead.rotateAngleX = par6 / (180F / (float) Math.PI); + this.batHead.rotateAngleY = par5 / (180F / (float) Math.PI); + this.batHead.rotateAngleZ = 0.0F; + this.batHead.setRotationPoint(0.0F, 0.0F, 0.0F); + this.batRightWing.setRotationPoint(0.0F, 0.0F, 0.0F); + this.batLeftWing.setRotationPoint(0.0F, 0.0F, 0.0F); + this.batBody.rotateAngleX = ((float) Math.PI / 4F) + MathHelper.cos(par4 * 0.1F) * 0.15F; + this.batBody.rotateAngleY = 0.0F; + this.batRightWing.rotateAngleY = MathHelper.cos(par4 * 1.3F) * (float) Math.PI * 0.25F; + this.batLeftWing.rotateAngleY = -this.batRightWing.rotateAngleY; + this.batOuterRightWing.rotateAngleY = this.batRightWing.rotateAngleY * 0.5F; + this.batOuterLeftWing.rotateAngleY = -this.batRightWing.rotateAngleY * 0.5F; + } + + this.batHead.render(par7); + this.batBody.render(par7); + } +} diff --git a/src/main/java/net/minecraft/src/ModelBiped.java b/src/main/java/net/minecraft/src/ModelBiped.java new file mode 100644 index 0000000..9d2caf5 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelBiped.java @@ -0,0 +1,234 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; + + +public class ModelBiped extends ModelBase { + public ModelRenderer bipedHead; + public ModelRenderer bipedHeadwear; + public ModelRenderer bipedBody; + public ModelRenderer bipedRightArm; + public ModelRenderer bipedLeftArm; + public ModelRenderer bipedRightLeg; + public ModelRenderer bipedLeftLeg; + public ModelRenderer bipedEars; + public ModelRenderer bipedCloak; + + /** + * Records whether the model should be rendered holding an item in the left + * hand, and if that item is a block. + */ + public int heldItemLeft; + + /** + * Records whether the model should be rendered holding an item in the right + * hand, and if that item is a block. + */ + public int heldItemRight; + public boolean isSneak; + + /** Records whether the model should be rendered aiming a bow. */ + public boolean aimedBow; + + public ModelBiped() { + this(0.0F); + } + + public ModelBiped(float par1) { + this(par1, 0.0F, 64, 32); + } + + public ModelBiped(float par1, float par2, int par3, int par4) { + this.heldItemLeft = 0; + this.heldItemRight = 0; + this.isSneak = false; + this.aimedBow = false; + this.textureWidth = par3; + this.textureHeight = par4; + this.bipedCloak = new ModelRenderer(this, 0, 0); + this.bipedCloak.addBox(-5.0F, 0.0F, -1.0F, 10, 16, 1, par1); + this.bipedEars = new ModelRenderer(this, 24, 0); + this.bipedEars.addBox(-3.0F, -6.0F, -1.0F, 6, 6, 1, par1); + this.bipedHead = new ModelRenderer(this, 0, 0); + this.bipedHead.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, par1); + this.bipedHead.setRotationPoint(0.0F, 0.0F + par2, 0.0F); + this.bipedHeadwear = new ModelRenderer(this, 32, 0); + this.bipedHeadwear.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, par1 + 0.5F); + this.bipedHeadwear.setRotationPoint(0.0F, 0.0F + par2, 0.0F); + this.bipedBody = new ModelRenderer(this, 16, 16); + this.bipedBody.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, par1); + this.bipedBody.setRotationPoint(0.0F, 0.0F + par2, 0.0F); + this.bipedRightArm = new ModelRenderer(this, 40, 16); + this.bipedRightArm.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4, par1); + this.bipedRightArm.setRotationPoint(-5.0F, 2.0F + par2, 0.0F); + this.bipedLeftArm = new ModelRenderer(this, 40, 16); + this.bipedLeftArm.mirror = true; + this.bipedLeftArm.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, par1); + this.bipedLeftArm.setRotationPoint(5.0F, 2.0F + par2, 0.0F); + this.bipedRightLeg = new ModelRenderer(this, 0, 16); + this.bipedRightLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, par1); + this.bipedRightLeg.setRotationPoint(-1.9F, 12.0F + par2, 0.0F); + this.bipedLeftLeg = new ModelRenderer(this, 0, 16); + this.bipedLeftLeg.mirror = true; + this.bipedLeftLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, par1); + this.bipedLeftLeg.setRotationPoint(1.9F, 12.0F + par2, 0.0F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + + if (this.isChild) { + float var8 = 2.0F; + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glScalef(1.5F / var8, 1.5F / var8, 1.5F / var8); + EaglerAdapter.glTranslatef(0.0F, 16.0F * par7, 0.0F); + this.bipedHead.render(par7); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glScalef(1.0F / var8, 1.0F / var8, 1.0F / var8); + EaglerAdapter.glTranslatef(0.0F, 24.0F * par7, 0.0F); + this.bipedBody.render(par7); + this.bipedRightArm.render(par7); + this.bipedLeftArm.render(par7); + this.bipedRightLeg.render(par7); + this.bipedLeftLeg.render(par7); + this.bipedHeadwear.render(par7); + EaglerAdapter.glPopMatrix(); + } else { + this.bipedHead.render(par7); + this.bipedBody.render(par7); + this.bipedRightArm.render(par7); + this.bipedLeftArm.render(par7); + this.bipedRightLeg.render(par7); + this.bipedLeftLeg.render(par7); + this.bipedHeadwear.render(par7); + } + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + this.bipedHead.rotateAngleY = par4 / (180F / (float) Math.PI); + this.bipedHead.rotateAngleX = par5 / (180F / (float) Math.PI); + this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; + this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; + this.bipedRightArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float) Math.PI) * 2.0F * par2 * 0.5F; + this.bipedLeftArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 2.0F * par2 * 0.5F; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + this.bipedRightLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; + this.bipedLeftLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float) Math.PI) * 1.4F * par2; + this.bipedRightLeg.rotateAngleY = 0.0F; + this.bipedLeftLeg.rotateAngleY = 0.0F; + + if (this.isRiding) { + this.bipedRightArm.rotateAngleX += -((float) Math.PI / 5F); + this.bipedLeftArm.rotateAngleX += -((float) Math.PI / 5F); + this.bipedRightLeg.rotateAngleX = -((float) Math.PI * 2F / 5F); + this.bipedLeftLeg.rotateAngleX = -((float) Math.PI * 2F / 5F); + this.bipedRightLeg.rotateAngleY = ((float) Math.PI / 10F); + this.bipedLeftLeg.rotateAngleY = -((float) Math.PI / 10F); + } + + if (this.heldItemLeft != 0) { + this.bipedLeftArm.rotateAngleX = this.bipedLeftArm.rotateAngleX * 0.5F - ((float) Math.PI / 10F) * (float) this.heldItemLeft; + } + + if (this.heldItemRight != 0) { + this.bipedRightArm.rotateAngleX = this.bipedRightArm.rotateAngleX * 0.5F - ((float) Math.PI / 10F) * (float) this.heldItemRight; + } + + this.bipedRightArm.rotateAngleY = 0.0F; + this.bipedLeftArm.rotateAngleY = 0.0F; + float var8; + float var9; + + if (this.onGround > -9990.0F) { + var8 = this.onGround; + this.bipedBody.rotateAngleY = MathHelper.sin(MathHelper.sqrt_float(var8) * (float) Math.PI * 2.0F) * 0.2F; + this.bipedRightArm.rotationPointZ = MathHelper.sin(this.bipedBody.rotateAngleY) * 5.0F; + this.bipedRightArm.rotationPointX = -MathHelper.cos(this.bipedBody.rotateAngleY) * 5.0F; + this.bipedLeftArm.rotationPointZ = -MathHelper.sin(this.bipedBody.rotateAngleY) * 5.0F; + this.bipedLeftArm.rotationPointX = MathHelper.cos(this.bipedBody.rotateAngleY) * 5.0F; + this.bipedRightArm.rotateAngleY += this.bipedBody.rotateAngleY; + this.bipedLeftArm.rotateAngleY += this.bipedBody.rotateAngleY; + this.bipedLeftArm.rotateAngleX += this.bipedBody.rotateAngleY; + var8 = 1.0F - this.onGround; + var8 *= var8; + var8 *= var8; + var8 = 1.0F - var8; + var9 = MathHelper.sin(var8 * (float) Math.PI); + float var10 = MathHelper.sin(this.onGround * (float) Math.PI) * -(this.bipedHead.rotateAngleX - 0.7F) * 0.75F; + this.bipedRightArm.rotateAngleX = (float) ((double) this.bipedRightArm.rotateAngleX - ((double) var9 * 1.2D + (double) var10)); + this.bipedRightArm.rotateAngleY += this.bipedBody.rotateAngleY * 2.0F; + this.bipedRightArm.rotateAngleZ = MathHelper.sin(this.onGround * (float) Math.PI) * -0.4F; + } + + if (this.isSneak) { + this.bipedBody.rotateAngleX = 0.5F; + this.bipedRightArm.rotateAngleX += 0.4F; + this.bipedLeftArm.rotateAngleX += 0.4F; + this.bipedRightLeg.rotationPointZ = 4.0F; + this.bipedLeftLeg.rotationPointZ = 4.0F; + this.bipedRightLeg.rotationPointY = 9.0F; + this.bipedLeftLeg.rotationPointY = 9.0F; + this.bipedHead.rotationPointY = 1.0F; + this.bipedHeadwear.rotationPointY = 1.0F; + } else { + this.bipedBody.rotateAngleX = 0.0F; + this.bipedRightLeg.rotationPointZ = 0.1F; + this.bipedLeftLeg.rotationPointZ = 0.1F; + this.bipedRightLeg.rotationPointY = 12.0F; + this.bipedLeftLeg.rotationPointY = 12.0F; + this.bipedHead.rotationPointY = 0.0F; + this.bipedHeadwear.rotationPointY = 0.0F; + } + + this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.067F) * 0.05F; + + if (this.aimedBow) { + var8 = 0.0F; + var9 = 0.0F; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + this.bipedRightArm.rotateAngleY = -(0.1F - var8 * 0.6F) + this.bipedHead.rotateAngleY; + this.bipedLeftArm.rotateAngleY = 0.1F - var8 * 0.6F + this.bipedHead.rotateAngleY + 0.4F; + this.bipedRightArm.rotateAngleX = -((float) Math.PI / 2F) + this.bipedHead.rotateAngleX; + this.bipedLeftArm.rotateAngleX = -((float) Math.PI / 2F) + this.bipedHead.rotateAngleX; + this.bipedRightArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.bipedLeftArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.067F) * 0.05F; + } + } + + /** + * renders the ears (specifically, deadmau5's) + */ + public void renderEars(float par1) { + this.bipedEars.rotateAngleY = this.bipedHead.rotateAngleY; + this.bipedEars.rotateAngleX = this.bipedHead.rotateAngleX; + this.bipedEars.rotationPointX = 0.0F; + this.bipedEars.rotationPointY = 0.0F; + this.bipedEars.render(par1); + } + + /** + * Renders the cloak of the current biped (in most cases, it's a player) + */ + public void renderCloak(float par1) { + this.bipedCloak.render(par1); + } +} diff --git a/src/main/java/net/minecraft/src/ModelBlaze.java b/src/main/java/net/minecraft/src/ModelBlaze.java new file mode 100644 index 0000000..4235001 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelBlaze.java @@ -0,0 +1,74 @@ +package net.minecraft.src; + + + +public class ModelBlaze extends ModelBase { + /** The sticks that fly around the Blaze. */ + private ModelRenderer[] blazeSticks = new ModelRenderer[12]; + private ModelRenderer blazeHead; + + public ModelBlaze() { + for (int var1 = 0; var1 < this.blazeSticks.length; ++var1) { + this.blazeSticks[var1] = new ModelRenderer(this, 0, 16); + this.blazeSticks[var1].addBox(0.0F, 0.0F, 0.0F, 2, 8, 2); + } + + this.blazeHead = new ModelRenderer(this, 0, 0); + this.blazeHead.addBox(-4.0F, -4.0F, -4.0F, 8, 8, 8); + } + + public int func_78104_a() { + return 8; + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + this.blazeHead.render(par7); + + for (int var8 = 0; var8 < this.blazeSticks.length; ++var8) { + this.blazeSticks[var8].render(par7); + } + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + float var8 = par3 * (float) Math.PI * -0.1F; + int var9; + + for (var9 = 0; var9 < 4; ++var9) { + this.blazeSticks[var9].rotationPointY = -2.0F + MathHelper.cos(((float) (var9 * 2) + par3) * 0.25F); + this.blazeSticks[var9].rotationPointX = MathHelper.cos(var8) * 9.0F; + this.blazeSticks[var9].rotationPointZ = MathHelper.sin(var8) * 9.0F; + ++var8; + } + + var8 = ((float) Math.PI / 4F) + par3 * (float) Math.PI * 0.03F; + + for (var9 = 4; var9 < 8; ++var9) { + this.blazeSticks[var9].rotationPointY = 2.0F + MathHelper.cos(((float) (var9 * 2) + par3) * 0.25F); + this.blazeSticks[var9].rotationPointX = MathHelper.cos(var8) * 7.0F; + this.blazeSticks[var9].rotationPointZ = MathHelper.sin(var8) * 7.0F; + ++var8; + } + + var8 = 0.47123894F + par3 * (float) Math.PI * -0.05F; + + for (var9 = 8; var9 < 12; ++var9) { + this.blazeSticks[var9].rotationPointY = 11.0F + MathHelper.cos(((float) var9 * 1.5F + par3) * 0.5F); + this.blazeSticks[var9].rotationPointX = MathHelper.cos(var8) * 5.0F; + this.blazeSticks[var9].rotationPointZ = MathHelper.sin(var8) * 5.0F; + ++var8; + } + + this.blazeHead.rotateAngleY = par4 / (180F / (float) Math.PI); + this.blazeHead.rotateAngleX = par5 / (180F / (float) Math.PI); + } +} diff --git a/src/main/java/net/minecraft/src/ModelBoat.java b/src/main/java/net/minecraft/src/ModelBoat.java new file mode 100644 index 0000000..ad3ad5e --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelBoat.java @@ -0,0 +1,42 @@ +package net.minecraft.src; + + + +public class ModelBoat extends ModelBase { + public ModelRenderer[] boatSides = new ModelRenderer[5]; + + public ModelBoat() { + this.boatSides[0] = new ModelRenderer(this, 0, 8); + this.boatSides[1] = new ModelRenderer(this, 0, 0); + this.boatSides[2] = new ModelRenderer(this, 0, 0); + this.boatSides[3] = new ModelRenderer(this, 0, 0); + this.boatSides[4] = new ModelRenderer(this, 0, 0); + byte var1 = 24; + byte var2 = 6; + byte var3 = 20; + byte var4 = 4; + this.boatSides[0].addBox((float) (-var1 / 2), (float) (-var3 / 2 + 2), -3.0F, var1, var3 - 4, 4, 0.0F); + this.boatSides[0].setRotationPoint(0.0F, (float) var4, 0.0F); + this.boatSides[1].addBox((float) (-var1 / 2 + 2), (float) (-var2 - 1), -1.0F, var1 - 4, var2, 2, 0.0F); + this.boatSides[1].setRotationPoint((float) (-var1 / 2 + 1), (float) var4, 0.0F); + this.boatSides[2].addBox((float) (-var1 / 2 + 2), (float) (-var2 - 1), -1.0F, var1 - 4, var2, 2, 0.0F); + this.boatSides[2].setRotationPoint((float) (var1 / 2 - 1), (float) var4, 0.0F); + this.boatSides[3].addBox((float) (-var1 / 2 + 2), (float) (-var2 - 1), -1.0F, var1 - 4, var2, 2, 0.0F); + this.boatSides[3].setRotationPoint(0.0F, (float) var4, (float) (-var3 / 2 + 1)); + this.boatSides[4].addBox((float) (-var1 / 2 + 2), (float) (-var2 - 1), -1.0F, var1 - 4, var2, 2, 0.0F); + this.boatSides[4].setRotationPoint(0.0F, (float) var4, (float) (var3 / 2 - 1)); + this.boatSides[0].rotateAngleX = ((float) Math.PI / 2F); + this.boatSides[1].rotateAngleY = ((float) Math.PI * 3F / 2F); + this.boatSides[2].rotateAngleY = ((float) Math.PI / 2F); + this.boatSides[3].rotateAngleY = (float) Math.PI; + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + for (int var8 = 0; var8 < 5; ++var8) { + this.boatSides[var8].render(par7); + } + } +} diff --git a/src/main/java/net/minecraft/src/ModelBook.java b/src/main/java/net/minecraft/src/ModelBook.java new file mode 100644 index 0000000..d9e06c3 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelBook.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + + + +public class ModelBook extends ModelBase { + /** Right cover renderer (when facing the book) */ + public ModelRenderer coverRight = (new ModelRenderer(this)).setTextureOffset(0, 0).addBox(-6.0F, -5.0F, 0.0F, 6, 10, 0); + + /** Left cover renderer (when facing the book) */ + public ModelRenderer coverLeft = (new ModelRenderer(this)).setTextureOffset(16, 0).addBox(0.0F, -5.0F, 0.0F, 6, 10, 0); + + /** The right pages renderer (when facing the book) */ + public ModelRenderer pagesRight = (new ModelRenderer(this)).setTextureOffset(0, 10).addBox(0.0F, -4.0F, -0.99F, 5, 8, 1); + + /** The left pages renderer (when facing the book) */ + public ModelRenderer pagesLeft = (new ModelRenderer(this)).setTextureOffset(12, 10).addBox(0.0F, -4.0F, -0.01F, 5, 8, 1); + + /** Right cover renderer (when facing the book) */ + public ModelRenderer flippingPageRight = (new ModelRenderer(this)).setTextureOffset(24, 10).addBox(0.0F, -4.0F, 0.0F, 5, 8, 0); + + /** Right cover renderer (when facing the book) */ + public ModelRenderer flippingPageLeft = (new ModelRenderer(this)).setTextureOffset(24, 10).addBox(0.0F, -4.0F, 0.0F, 5, 8, 0); + + /** The renderer of spine of the book */ + public ModelRenderer bookSpine = (new ModelRenderer(this)).setTextureOffset(12, 0).addBox(-1.0F, -5.0F, 0.0F, 2, 10, 0); + + public ModelBook() { + this.coverRight.setRotationPoint(0.0F, 0.0F, -1.0F); + this.coverLeft.setRotationPoint(0.0F, 0.0F, 1.0F); + this.bookSpine.rotateAngleY = ((float) Math.PI / 2F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + this.coverRight.render(par7); + this.coverLeft.render(par7); + this.bookSpine.render(par7); + this.pagesRight.render(par7); + this.pagesLeft.render(par7); + this.flippingPageRight.render(par7); + this.flippingPageLeft.render(par7); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + float var8 = (MathHelper.sin(par1 * 0.02F) * 0.1F + 1.25F) * par4; + this.coverRight.rotateAngleY = (float) Math.PI + var8; + this.coverLeft.rotateAngleY = -var8; + this.pagesRight.rotateAngleY = var8; + this.pagesLeft.rotateAngleY = -var8; + this.flippingPageRight.rotateAngleY = var8 - var8 * 2.0F * par2; + this.flippingPageLeft.rotateAngleY = var8 - var8 * 2.0F * par3; + this.pagesRight.rotationPointX = MathHelper.sin(var8); + this.pagesLeft.rotationPointX = MathHelper.sin(var8); + this.flippingPageRight.rotationPointX = MathHelper.sin(var8); + this.flippingPageLeft.rotationPointX = MathHelper.sin(var8); + } +} diff --git a/src/main/java/net/minecraft/src/ModelBox.java b/src/main/java/net/minecraft/src/ModelBox.java new file mode 100644 index 0000000..5bc8314 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelBox.java @@ -0,0 +1,104 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class ModelBox { + /** + * The (x,y,z) vertex positions and (u,v) texture coordinates for each of the 8 + * points on a cube + */ + private PositionTextureVertex[] vertexPositions; + + /** An array of 6 TexturedQuads, one for each face of a cube */ + private TexturedQuad[] quadList; + + /** X vertex coordinate of lower box corner */ + public final float posX1; + + /** Y vertex coordinate of lower box corner */ + public final float posY1; + + /** Z vertex coordinate of lower box corner */ + public final float posZ1; + + /** X vertex coordinate of upper box corner */ + public final float posX2; + + /** Y vertex coordinate of upper box corner */ + public final float posY2; + + /** Z vertex coordinate of upper box corner */ + public final float posZ2; + public String field_78247_g; + + public ModelBox(ModelRenderer par1ModelRenderer, int par2, int par3, float par4, float par5, float par6, int par7, int par8, int par9, float par10) { + this.posX1 = par4; + this.posY1 = par5; + this.posZ1 = par6; + this.posX2 = par4 + (float) par7; + this.posY2 = par5 + (float) par8; + this.posZ2 = par6 + (float) par9; + this.vertexPositions = new PositionTextureVertex[8]; + this.quadList = new TexturedQuad[6]; + float var11 = par4 + (float) par7; + float var12 = par5 + (float) par8; + float var13 = par6 + (float) par9; + par4 -= par10; + par5 -= par10; + par6 -= par10; + var11 += par10; + var12 += par10; + var13 += par10; + + if (par1ModelRenderer.mirror) { + float var14 = var11; + var11 = par4; + par4 = var14; + } + + PositionTextureVertex var23 = new PositionTextureVertex(par4, par5, par6, 0.0F, 0.0F); + PositionTextureVertex var15 = new PositionTextureVertex(var11, par5, par6, 0.0F, 8.0F); + PositionTextureVertex var16 = new PositionTextureVertex(var11, var12, par6, 8.0F, 8.0F); + PositionTextureVertex var17 = new PositionTextureVertex(par4, var12, par6, 8.0F, 0.0F); + PositionTextureVertex var18 = new PositionTextureVertex(par4, par5, var13, 0.0F, 0.0F); + PositionTextureVertex var19 = new PositionTextureVertex(var11, par5, var13, 0.0F, 8.0F); + PositionTextureVertex var20 = new PositionTextureVertex(var11, var12, var13, 8.0F, 8.0F); + PositionTextureVertex var21 = new PositionTextureVertex(par4, var12, var13, 8.0F, 0.0F); + this.vertexPositions[0] = var23; + this.vertexPositions[1] = var15; + this.vertexPositions[2] = var16; + this.vertexPositions[3] = var17; + this.vertexPositions[4] = var18; + this.vertexPositions[5] = var19; + this.vertexPositions[6] = var20; + this.vertexPositions[7] = var21; + this.quadList[0] = new TexturedQuad(new PositionTextureVertex[] { var19, var15, var16, var20 }, par2 + par9 + par7, par3 + par9, par2 + par9 + par7 + par9, par3 + par9 + par8, par1ModelRenderer.textureWidth, + par1ModelRenderer.textureHeight); + this.quadList[1] = new TexturedQuad(new PositionTextureVertex[] { var23, var18, var21, var17 }, par2, par3 + par9, par2 + par9, par3 + par9 + par8, par1ModelRenderer.textureWidth, par1ModelRenderer.textureHeight); + this.quadList[2] = new TexturedQuad(new PositionTextureVertex[] { var19, var18, var23, var15 }, par2 + par9, par3, par2 + par9 + par7, par3 + par9, par1ModelRenderer.textureWidth, par1ModelRenderer.textureHeight); + this.quadList[3] = new TexturedQuad(new PositionTextureVertex[] { var16, var17, var21, var20 }, par2 + par9 + par7, par3 + par9, par2 + par9 + par7 + par7, par3, par1ModelRenderer.textureWidth, par1ModelRenderer.textureHeight); + this.quadList[4] = new TexturedQuad(new PositionTextureVertex[] { var15, var23, var17, var16 }, par2 + par9, par3 + par9, par2 + par9 + par7, par3 + par9 + par8, par1ModelRenderer.textureWidth, par1ModelRenderer.textureHeight); + this.quadList[5] = new TexturedQuad(new PositionTextureVertex[] { var18, var19, var20, var21 }, par2 + par9 + par7 + par9, par3 + par9, par2 + par9 + par7 + par9 + par7, par3 + par9 + par8, par1ModelRenderer.textureWidth, + par1ModelRenderer.textureHeight); + + if (par1ModelRenderer.mirror) { + for (int var22 = 0; var22 < this.quadList.length; ++var22) { + this.quadList[var22].flipFace(); + } + } + } + + /** + * Draw the six sided box defined by this ModelBox + */ + public void render(Tessellator par1Tessellator, float par2) { + for (int var3 = 0; var3 < this.quadList.length; ++var3) { + this.quadList[var3].draw(par1Tessellator, par2); + } + } + + public ModelBox func_78244_a(String par1Str) { + this.field_78247_g = par1Str; + return this; + } +} diff --git a/src/main/java/net/minecraft/src/ModelChest.java b/src/main/java/net/minecraft/src/ModelChest.java new file mode 100644 index 0000000..52aa1a1 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelChest.java @@ -0,0 +1,39 @@ +package net.minecraft.src; + +public class ModelChest extends ModelBase { + /** The chest lid in the chest's model. */ + public ModelRenderer chestLid = (new ModelRenderer(this, 0, 0)).setTextureSize(64, 64); + + /** The model of the bottom of the chest. */ + public ModelRenderer chestBelow; + + /** The chest's knob in the chest model. */ + public ModelRenderer chestKnob; + + public ModelChest() { + this.chestLid.addBox(0.0F, -5.0F, -14.0F, 14, 5, 14, 0.0F); + this.chestLid.rotationPointX = 1.0F; + this.chestLid.rotationPointY = 7.0F; + this.chestLid.rotationPointZ = 15.0F; + this.chestKnob = (new ModelRenderer(this, 0, 0)).setTextureSize(64, 64); + this.chestKnob.addBox(-1.0F, -2.0F, -15.0F, 2, 4, 1, 0.0F); + this.chestKnob.rotationPointX = 8.0F; + this.chestKnob.rotationPointY = 7.0F; + this.chestKnob.rotationPointZ = 15.0F; + this.chestBelow = (new ModelRenderer(this, 0, 19)).setTextureSize(64, 64); + this.chestBelow.addBox(0.0F, 0.0F, 0.0F, 14, 10, 14, 0.0F); + this.chestBelow.rotationPointX = 1.0F; + this.chestBelow.rotationPointY = 6.0F; + this.chestBelow.rotationPointZ = 1.0F; + } + + /** + * This method renders out all parts of the chest model. + */ + public void renderAll() { + this.chestKnob.rotateAngleX = this.chestLid.rotateAngleX; + this.chestLid.render(0.0625F); + this.chestKnob.render(0.0625F); + this.chestBelow.render(0.0625F); + } +} diff --git a/src/main/java/net/minecraft/src/ModelChicken.java b/src/main/java/net/minecraft/src/ModelChicken.java new file mode 100644 index 0000000..e6a4a6b --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelChicken.java @@ -0,0 +1,98 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; + + +public class ModelChicken extends ModelBase { + public ModelRenderer head; + public ModelRenderer body; + public ModelRenderer rightLeg; + public ModelRenderer leftLeg; + public ModelRenderer rightWing; + public ModelRenderer leftWing; + public ModelRenderer bill; + public ModelRenderer chin; + + public ModelChicken() { + byte var1 = 16; + this.head = new ModelRenderer(this, 0, 0); + this.head.addBox(-2.0F, -6.0F, -2.0F, 4, 6, 3, 0.0F); + this.head.setRotationPoint(0.0F, (float) (-1 + var1), -4.0F); + this.bill = new ModelRenderer(this, 14, 0); + this.bill.addBox(-2.0F, -4.0F, -4.0F, 4, 2, 2, 0.0F); + this.bill.setRotationPoint(0.0F, (float) (-1 + var1), -4.0F); + this.chin = new ModelRenderer(this, 14, 4); + this.chin.addBox(-1.0F, -2.0F, -3.0F, 2, 2, 2, 0.0F); + this.chin.setRotationPoint(0.0F, (float) (-1 + var1), -4.0F); + this.body = new ModelRenderer(this, 0, 9); + this.body.addBox(-3.0F, -4.0F, -3.0F, 6, 8, 6, 0.0F); + this.body.setRotationPoint(0.0F, (float) var1, 0.0F); + this.rightLeg = new ModelRenderer(this, 26, 0); + this.rightLeg.addBox(-1.0F, 0.0F, -3.0F, 3, 5, 3); + this.rightLeg.setRotationPoint(-2.0F, (float) (3 + var1), 1.0F); + this.leftLeg = new ModelRenderer(this, 26, 0); + this.leftLeg.addBox(-1.0F, 0.0F, -3.0F, 3, 5, 3); + this.leftLeg.setRotationPoint(1.0F, (float) (3 + var1), 1.0F); + this.rightWing = new ModelRenderer(this, 24, 13); + this.rightWing.addBox(0.0F, 0.0F, -3.0F, 1, 4, 6); + this.rightWing.setRotationPoint(-4.0F, (float) (-3 + var1), 0.0F); + this.leftWing = new ModelRenderer(this, 24, 13); + this.leftWing.addBox(-1.0F, 0.0F, -3.0F, 1, 4, 6); + this.leftWing.setRotationPoint(4.0F, (float) (-3 + var1), 0.0F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + + if (this.isChild) { + float var8 = 2.0F; + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(0.0F, 5.0F * par7, 2.0F * par7); + this.head.render(par7); + this.bill.render(par7); + this.chin.render(par7); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glScalef(1.0F / var8, 1.0F / var8, 1.0F / var8); + EaglerAdapter.glTranslatef(0.0F, 24.0F * par7, 0.0F); + this.body.render(par7); + this.rightLeg.render(par7); + this.leftLeg.render(par7); + this.rightWing.render(par7); + this.leftWing.render(par7); + EaglerAdapter.glPopMatrix(); + } else { + this.head.render(par7); + this.bill.render(par7); + this.chin.render(par7); + this.body.render(par7); + this.rightLeg.render(par7); + this.leftLeg.render(par7); + this.rightWing.render(par7); + this.leftWing.render(par7); + } + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + this.head.rotateAngleX = par5 / (180F / (float) Math.PI); + this.head.rotateAngleY = par4 / (180F / (float) Math.PI); + this.bill.rotateAngleX = this.head.rotateAngleX; + this.bill.rotateAngleY = this.head.rotateAngleY; + this.chin.rotateAngleX = this.head.rotateAngleX; + this.chin.rotateAngleY = this.head.rotateAngleY; + this.body.rotateAngleX = ((float) Math.PI / 2F); + this.rightLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; + this.leftLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float) Math.PI) * 1.4F * par2; + this.rightWing.rotateAngleZ = par3; + this.leftWing.rotateAngleZ = -par3; + } +} diff --git a/src/main/java/net/minecraft/src/ModelCow.java b/src/main/java/net/minecraft/src/ModelCow.java new file mode 100644 index 0000000..577a219 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelCow.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +public class ModelCow extends ModelQuadruped { + public ModelCow() { + super(12, 0.0F); + this.head = new ModelRenderer(this, 0, 0); + this.head.addBox(-4.0F, -4.0F, -6.0F, 8, 8, 6, 0.0F); + this.head.setRotationPoint(0.0F, 4.0F, -8.0F); + this.head.setTextureOffset(22, 0).addBox(-5.0F, -5.0F, -4.0F, 1, 3, 1, 0.0F); + this.head.setTextureOffset(22, 0).addBox(4.0F, -5.0F, -4.0F, 1, 3, 1, 0.0F); + this.body = new ModelRenderer(this, 18, 4); + this.body.addBox(-6.0F, -10.0F, -7.0F, 12, 18, 10, 0.0F); + this.body.setRotationPoint(0.0F, 5.0F, 2.0F); + this.body.setTextureOffset(52, 0).addBox(-2.0F, 2.0F, -8.0F, 4, 6, 1); + --this.leg1.rotationPointX; + ++this.leg2.rotationPointX; + this.leg1.rotationPointZ += 0.0F; + this.leg2.rotationPointZ += 0.0F; + --this.leg3.rotationPointX; + ++this.leg4.rotationPointX; + --this.leg3.rotationPointZ; + --this.leg4.rotationPointZ; + this.field_78151_h += 2.0F; + } +} diff --git a/src/main/java/net/minecraft/src/ModelCreeper.java b/src/main/java/net/minecraft/src/ModelCreeper.java new file mode 100644 index 0000000..cbd93d1 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelCreeper.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + + + +public class ModelCreeper extends ModelBase { + public ModelRenderer head; + public ModelRenderer field_78133_b; + public ModelRenderer body; + public ModelRenderer leg1; + public ModelRenderer leg2; + public ModelRenderer leg3; + public ModelRenderer leg4; + + public ModelCreeper() { + this(0.0F); + } + + public ModelCreeper(float par1) { + byte var2 = 4; + this.head = new ModelRenderer(this, 0, 0); + this.head.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, par1); + this.head.setRotationPoint(0.0F, (float) var2, 0.0F); + this.field_78133_b = new ModelRenderer(this, 32, 0); + this.field_78133_b.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, par1 + 0.5F); + this.field_78133_b.setRotationPoint(0.0F, (float) var2, 0.0F); + this.body = new ModelRenderer(this, 16, 16); + this.body.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, par1); + this.body.setRotationPoint(0.0F, (float) var2, 0.0F); + this.leg1 = new ModelRenderer(this, 0, 16); + this.leg1.addBox(-2.0F, 0.0F, -2.0F, 4, 6, 4, par1); + this.leg1.setRotationPoint(-2.0F, (float) (12 + var2), 4.0F); + this.leg2 = new ModelRenderer(this, 0, 16); + this.leg2.addBox(-2.0F, 0.0F, -2.0F, 4, 6, 4, par1); + this.leg2.setRotationPoint(2.0F, (float) (12 + var2), 4.0F); + this.leg3 = new ModelRenderer(this, 0, 16); + this.leg3.addBox(-2.0F, 0.0F, -2.0F, 4, 6, 4, par1); + this.leg3.setRotationPoint(-2.0F, (float) (12 + var2), -4.0F); + this.leg4 = new ModelRenderer(this, 0, 16); + this.leg4.addBox(-2.0F, 0.0F, -2.0F, 4, 6, 4, par1); + this.leg4.setRotationPoint(2.0F, (float) (12 + var2), -4.0F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + this.head.render(par7); + this.body.render(par7); + this.leg1.render(par7); + this.leg2.render(par7); + this.leg3.render(par7); + this.leg4.render(par7); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + this.head.rotateAngleY = par4 / (180F / (float) Math.PI); + this.head.rotateAngleX = par5 / (180F / (float) Math.PI); + this.leg1.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; + this.leg2.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float) Math.PI) * 1.4F * par2; + this.leg3.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float) Math.PI) * 1.4F * par2; + this.leg4.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; + } +} diff --git a/src/main/java/net/minecraft/src/ModelDragon.java b/src/main/java/net/minecraft/src/ModelDragon.java new file mode 100644 index 0000000..0dfe03d --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelDragon.java @@ -0,0 +1,252 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; + + +public class ModelDragon extends ModelBase { + /** The head Model renderer of the dragon */ + private ModelRenderer head; + + /** The neck Model renderer of the dragon */ + private ModelRenderer neck; + + /** The jaw Model renderer of the dragon */ + private ModelRenderer jaw; + + /** The body Model renderer of the dragon */ + private ModelRenderer body; + + /** The rear leg Model renderer of the dragon */ + private ModelRenderer rearLeg; + + /** The front leg Model renderer of the dragon */ + private ModelRenderer frontLeg; + + /** The rear leg tip Model renderer of the dragon */ + private ModelRenderer rearLegTip; + + /** The front leg tip Model renderer of the dragon */ + private ModelRenderer frontLegTip; + + /** The rear foot Model renderer of the dragon */ + private ModelRenderer rearFoot; + + /** The front foot Model renderer of the dragon */ + private ModelRenderer frontFoot; + + /** The wing Model renderer of the dragon */ + private ModelRenderer wing; + + /** The wing tip Model renderer of the dragon */ + private ModelRenderer wingTip; + private float partialTicks; + + public ModelDragon(float par1) { + this.textureWidth = 256; + this.textureHeight = 256; + this.setTextureOffset("body.body", 0, 0); + this.setTextureOffset("wing.skin", -56, 88); + this.setTextureOffset("wingtip.skin", -56, 144); + this.setTextureOffset("rearleg.main", 0, 0); + this.setTextureOffset("rearfoot.main", 112, 0); + this.setTextureOffset("rearlegtip.main", 196, 0); + this.setTextureOffset("head.upperhead", 112, 30); + this.setTextureOffset("wing.bone", 112, 88); + this.setTextureOffset("head.upperlip", 176, 44); + this.setTextureOffset("jaw.jaw", 176, 65); + this.setTextureOffset("frontleg.main", 112, 104); + this.setTextureOffset("wingtip.bone", 112, 136); + this.setTextureOffset("frontfoot.main", 144, 104); + this.setTextureOffset("neck.box", 192, 104); + this.setTextureOffset("frontlegtip.main", 226, 138); + this.setTextureOffset("body.scale", 220, 53); + this.setTextureOffset("head.scale", 0, 0); + this.setTextureOffset("neck.scale", 48, 0); + this.setTextureOffset("head.nostril", 112, 0); + float var2 = -16.0F; + this.head = new ModelRenderer(this, "head"); + this.head.addBox("upperlip", -6.0F, -1.0F, -8.0F + var2, 12, 5, 16); + this.head.addBox("upperhead", -8.0F, -8.0F, 6.0F + var2, 16, 16, 16); + this.head.mirror = true; + this.head.addBox("scale", -5.0F, -12.0F, 12.0F + var2, 2, 4, 6); + this.head.addBox("nostril", -5.0F, -3.0F, -6.0F + var2, 2, 2, 4); + this.head.mirror = false; + this.head.addBox("scale", 3.0F, -12.0F, 12.0F + var2, 2, 4, 6); + this.head.addBox("nostril", 3.0F, -3.0F, -6.0F + var2, 2, 2, 4); + this.jaw = new ModelRenderer(this, "jaw"); + this.jaw.setRotationPoint(0.0F, 4.0F, 8.0F + var2); + this.jaw.addBox("jaw", -6.0F, 0.0F, -16.0F, 12, 4, 16); + this.head.addChild(this.jaw); + this.neck = new ModelRenderer(this, "neck"); + this.neck.addBox("box", -5.0F, -5.0F, -5.0F, 10, 10, 10); + this.neck.addBox("scale", -1.0F, -9.0F, -3.0F, 2, 4, 6); + this.body = new ModelRenderer(this, "body"); + this.body.setRotationPoint(0.0F, 4.0F, 8.0F); + this.body.addBox("body", -12.0F, 0.0F, -16.0F, 24, 24, 64); + this.body.addBox("scale", -1.0F, -6.0F, -10.0F, 2, 6, 12); + this.body.addBox("scale", -1.0F, -6.0F, 10.0F, 2, 6, 12); + this.body.addBox("scale", -1.0F, -6.0F, 30.0F, 2, 6, 12); + this.wing = new ModelRenderer(this, "wing"); + this.wing.setRotationPoint(-12.0F, 5.0F, 2.0F); + this.wing.addBox("bone", -56.0F, -4.0F, -4.0F, 56, 8, 8); + this.wing.addBox("skin", -56.0F, 0.0F, 2.0F, 56, 0, 56); + this.wingTip = new ModelRenderer(this, "wingtip"); + this.wingTip.setRotationPoint(-56.0F, 0.0F, 0.0F); + this.wingTip.addBox("bone", -56.0F, -2.0F, -2.0F, 56, 4, 4); + this.wingTip.addBox("skin", -56.0F, 0.0F, 2.0F, 56, 0, 56); + this.wing.addChild(this.wingTip); + this.frontLeg = new ModelRenderer(this, "frontleg"); + this.frontLeg.setRotationPoint(-12.0F, 20.0F, 2.0F); + this.frontLeg.addBox("main", -4.0F, -4.0F, -4.0F, 8, 24, 8); + this.frontLegTip = new ModelRenderer(this, "frontlegtip"); + this.frontLegTip.setRotationPoint(0.0F, 20.0F, -1.0F); + this.frontLegTip.addBox("main", -3.0F, -1.0F, -3.0F, 6, 24, 6); + this.frontLeg.addChild(this.frontLegTip); + this.frontFoot = new ModelRenderer(this, "frontfoot"); + this.frontFoot.setRotationPoint(0.0F, 23.0F, 0.0F); + this.frontFoot.addBox("main", -4.0F, 0.0F, -12.0F, 8, 4, 16); + this.frontLegTip.addChild(this.frontFoot); + this.rearLeg = new ModelRenderer(this, "rearleg"); + this.rearLeg.setRotationPoint(-16.0F, 16.0F, 42.0F); + this.rearLeg.addBox("main", -8.0F, -4.0F, -8.0F, 16, 32, 16); + this.rearLegTip = new ModelRenderer(this, "rearlegtip"); + this.rearLegTip.setRotationPoint(0.0F, 32.0F, -4.0F); + this.rearLegTip.addBox("main", -6.0F, -2.0F, 0.0F, 12, 32, 12); + this.rearLeg.addChild(this.rearLegTip); + this.rearFoot = new ModelRenderer(this, "rearfoot"); + this.rearFoot.setRotationPoint(0.0F, 31.0F, 4.0F); + this.rearFoot.addBox("main", -9.0F, 0.0F, -20.0F, 18, 6, 24); + this.rearLegTip.addChild(this.rearFoot); + } + + /** + * Used for easily adding entity-dependent animations. The second and third + * float params here are the same second and third as in the setRotationAngles + * method. + */ + public void setLivingAnimations(EntityLiving par1EntityLiving, float par2, float par3, float par4) { + this.partialTicks = par4; + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + EaglerAdapter.glPushMatrix(); + EntityDragon var8 = (EntityDragon) par1Entity; + float var9 = var8.prevAnimTime + (var8.animTime - var8.prevAnimTime) * this.partialTicks; + this.jaw.rotateAngleX = (float) (Math.sin((double) (var9 * (float) Math.PI * 2.0F)) + 1.0D) * 0.2F; + float var10 = (float) (Math.sin((double) (var9 * (float) Math.PI * 2.0F - 1.0F)) + 1.0D); + var10 = (var10 * var10 * 1.0F + var10 * 2.0F) * 0.05F; + EaglerAdapter.glTranslatef(0.0F, var10 - 2.0F, -3.0F); + EaglerAdapter.glRotatef(var10 * 2.0F, 1.0F, 0.0F, 0.0F); + float var11 = -30.0F; + float var13 = 0.0F; + float var14 = 1.5F; + double[] var15 = var8.getMovementOffsets(6, this.partialTicks); + float var16 = this.updateRotations(var8.getMovementOffsets(5, this.partialTicks)[0] - var8.getMovementOffsets(10, this.partialTicks)[0]); + float var17 = this.updateRotations(var8.getMovementOffsets(5, this.partialTicks)[0] + (double) (var16 / 2.0F)); + var11 += 2.0F; + float var18 = var9 * (float) Math.PI * 2.0F; + var11 = 20.0F; + float var12 = -12.0F; + float var21; + + for (int var19 = 0; var19 < 5; ++var19) { + double[] var20 = var8.getMovementOffsets(5 - var19, this.partialTicks); + var21 = (float) Math.cos((double) ((float) var19 * 0.45F + var18)) * 0.15F; + this.neck.rotateAngleY = this.updateRotations(var20[0] - var15[0]) * (float) Math.PI / 180.0F * var14; + this.neck.rotateAngleX = var21 + (float) (var20[1] - var15[1]) * (float) Math.PI / 180.0F * var14 * 5.0F; + this.neck.rotateAngleZ = -this.updateRotations(var20[0] - (double) var17) * (float) Math.PI / 180.0F * var14; + this.neck.rotationPointY = var11; + this.neck.rotationPointZ = var12; + this.neck.rotationPointX = var13; + var11 = (float) ((double) var11 + Math.sin((double) this.neck.rotateAngleX) * 10.0D); + var12 = (float) ((double) var12 - Math.cos((double) this.neck.rotateAngleY) * Math.cos((double) this.neck.rotateAngleX) * 10.0D); + var13 = (float) ((double) var13 - Math.sin((double) this.neck.rotateAngleY) * Math.cos((double) this.neck.rotateAngleX) * 10.0D); + this.neck.render(par7); + } + + this.head.rotationPointY = var11; + this.head.rotationPointZ = var12; + this.head.rotationPointX = var13; + double[] var22 = var8.getMovementOffsets(0, this.partialTicks); + this.head.rotateAngleY = this.updateRotations(var22[0] - var15[0]) * (float) Math.PI / 180.0F * 1.0F; + this.head.rotateAngleZ = -this.updateRotations(var22[0] - (double) var17) * (float) Math.PI / 180.0F * 1.0F; + this.head.render(par7); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(-var16 * var14 * 1.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glTranslatef(0.0F, -1.0F, 0.0F); + this.body.rotateAngleZ = 0.0F; + this.body.render(par7); + + for (int var23 = 0; var23 < 2; ++var23) { + EaglerAdapter.glEnable(EaglerAdapter.GL_CULL_FACE); + var21 = var9 * (float) Math.PI * 2.0F; + this.wing.rotateAngleX = 0.125F - (float) Math.cos((double) var21) * 0.2F; + this.wing.rotateAngleY = 0.25F; + this.wing.rotateAngleZ = (float) (Math.sin((double) var21) + 0.125D) * 0.8F; + this.wingTip.rotateAngleZ = -((float) (Math.sin((double) (var21 + 2.0F)) + 0.5D)) * 0.75F; + this.rearLeg.rotateAngleX = 1.0F + var10 * 0.1F; + this.rearLegTip.rotateAngleX = 0.5F + var10 * 0.1F; + this.rearFoot.rotateAngleX = 0.75F + var10 * 0.1F; + this.frontLeg.rotateAngleX = 1.3F + var10 * 0.1F; + this.frontLegTip.rotateAngleX = -0.5F - var10 * 0.1F; + this.frontFoot.rotateAngleX = 0.75F + var10 * 0.1F; + this.wing.render(par7); + this.frontLeg.render(par7); + this.rearLeg.render(par7); + EaglerAdapter.glScalef(-1.0F, 1.0F, 1.0F); + + if (var23 == 0) { + EaglerAdapter.glCullFace(EaglerAdapter.GL_FRONT); + } + } + + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glCullFace(EaglerAdapter.GL_BACK); + EaglerAdapter.glDisable(EaglerAdapter.GL_CULL_FACE); + float var24 = -((float) Math.sin((double) (var9 * (float) Math.PI * 2.0F))) * 0.0F; + var18 = var9 * (float) Math.PI * 2.0F; + var11 = 10.0F; + var12 = 60.0F; + var13 = 0.0F; + var15 = var8.getMovementOffsets(11, this.partialTicks); + + for (int var25 = 0; var25 < 12; ++var25) { + var22 = var8.getMovementOffsets(12 + var25, this.partialTicks); + var24 = (float) ((double) var24 + Math.sin((double) ((float) var25 * 0.45F + var18)) * 0.05000000074505806D); + this.neck.rotateAngleY = (this.updateRotations(var22[0] - var15[0]) * var14 + 180.0F) * (float) Math.PI / 180.0F; + this.neck.rotateAngleX = var24 + (float) (var22[1] - var15[1]) * (float) Math.PI / 180.0F * var14 * 5.0F; + this.neck.rotateAngleZ = this.updateRotations(var22[0] - (double) var17) * (float) Math.PI / 180.0F * var14; + this.neck.rotationPointY = var11; + this.neck.rotationPointZ = var12; + this.neck.rotationPointX = var13; + var11 = (float) ((double) var11 + Math.sin((double) this.neck.rotateAngleX) * 10.0D); + var12 = (float) ((double) var12 - Math.cos((double) this.neck.rotateAngleY) * Math.cos((double) this.neck.rotateAngleX) * 10.0D); + var13 = (float) ((double) var13 - Math.sin((double) this.neck.rotateAngleY) * Math.cos((double) this.neck.rotateAngleX) * 10.0D); + this.neck.render(par7); + } + + EaglerAdapter.glPopMatrix(); + } + + /** + * Updates the rotations in the parameters for rotations greater than 180 + * degrees or less than -180 degrees. It adds or subtracts 360 degrees, so that + * the appearance is the same, although the numbers are then simplified to range + * -180 to 180 + */ + private float updateRotations(double par1) { + while (par1 >= 180.0D) { + par1 -= 360.0D; + } + + while (par1 < -180.0D) { + par1 += 360.0D; + } + + return (float) par1; + } +} diff --git a/src/main/java/net/minecraft/src/ModelEnderCrystal.java b/src/main/java/net/minecraft/src/ModelEnderCrystal.java new file mode 100644 index 0000000..25a779a --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelEnderCrystal.java @@ -0,0 +1,53 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +public class ModelEnderCrystal extends ModelBase { + /** The cube model for the Ender Crystal. */ + private ModelRenderer cube; + + /** The glass model for the Ender Crystal. */ + private ModelRenderer glass = new ModelRenderer(this, "glass"); + + /** The base model for the Ender Crystal. */ + private ModelRenderer base; + + public ModelEnderCrystal(float par1, boolean par2) { + this.glass.setTextureOffset(0, 0).addBox(-4.0F, -4.0F, -4.0F, 8, 8, 8); + this.cube = new ModelRenderer(this, "cube"); + this.cube.setTextureOffset(32, 0).addBox(-4.0F, -4.0F, -4.0F, 8, 8, 8); + + if (par2) { + this.base = new ModelRenderer(this, "base"); + this.base.setTextureOffset(0, 16).addBox(-6.0F, 0.0F, -6.0F, 12, 4, 12); + } + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glScalef(2.0F, 2.0F, 2.0F); + EaglerAdapter.glTranslatef(0.0F, -0.5F, 0.0F); + + if (this.base != null) { + this.base.render(par7); + } + + EaglerAdapter.glRotatef(par3, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glTranslatef(0.0F, 0.8F + par4, 0.0F); + EaglerAdapter.glRotatef(60.0F, 0.7071F, 0.0F, 0.7071F); + this.glass.render(par7); + float var8 = 0.875F; + EaglerAdapter.glScalef(var8, var8, var8); + EaglerAdapter.glRotatef(60.0F, 0.7071F, 0.0F, 0.7071F); + EaglerAdapter.glRotatef(par3, 0.0F, 1.0F, 0.0F); + this.glass.render(par7); + EaglerAdapter.glScalef(var8, var8, var8); + EaglerAdapter.glRotatef(60.0F, 0.7071F, 0.0F, 0.7071F); + EaglerAdapter.glRotatef(par3, 0.0F, 1.0F, 0.0F); + this.cube.render(par7); + EaglerAdapter.glPopMatrix(); + } +} diff --git a/src/main/java/net/minecraft/src/ModelEnderman.java b/src/main/java/net/minecraft/src/ModelEnderman.java new file mode 100644 index 0000000..68d99b4 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelEnderman.java @@ -0,0 +1,116 @@ +package net.minecraft.src; + +public class ModelEnderman extends ModelBiped { + /** Is the enderman carrying a block? */ + public boolean isCarrying = false; + + /** Is the enderman attacking an entity? */ + public boolean isAttacking = false; + + public ModelEnderman() { + super(0.0F, -14.0F, 64, 32); + float var1 = -14.0F; + float var2 = 0.0F; + this.bipedHeadwear = new ModelRenderer(this, 0, 16); + this.bipedHeadwear.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, var2 - 0.5F); + this.bipedHeadwear.setRotationPoint(0.0F, 0.0F + var1, 0.0F); + this.bipedBody = new ModelRenderer(this, 32, 16); + this.bipedBody.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, var2); + this.bipedBody.setRotationPoint(0.0F, 0.0F + var1, 0.0F); + this.bipedRightArm = new ModelRenderer(this, 56, 0); + this.bipedRightArm.addBox(-1.0F, -2.0F, -1.0F, 2, 30, 2, var2); + this.bipedRightArm.setRotationPoint(-3.0F, 2.0F + var1, 0.0F); + this.bipedLeftArm = new ModelRenderer(this, 56, 0); + this.bipedLeftArm.mirror = true; + this.bipedLeftArm.addBox(-1.0F, -2.0F, -1.0F, 2, 30, 2, var2); + this.bipedLeftArm.setRotationPoint(5.0F, 2.0F + var1, 0.0F); + this.bipedRightLeg = new ModelRenderer(this, 56, 0); + this.bipedRightLeg.addBox(-1.0F, 0.0F, -1.0F, 2, 30, 2, var2); + this.bipedRightLeg.setRotationPoint(-2.0F, 12.0F + var1, 0.0F); + this.bipedLeftLeg = new ModelRenderer(this, 56, 0); + this.bipedLeftLeg.mirror = true; + this.bipedLeftLeg.addBox(-1.0F, 0.0F, -1.0F, 2, 30, 2, var2); + this.bipedLeftLeg.setRotationPoint(2.0F, 12.0F + var1, 0.0F); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); + this.bipedHead.showModel = true; + float var8 = -14.0F; + this.bipedBody.rotateAngleX = 0.0F; + this.bipedBody.rotationPointY = var8; + this.bipedBody.rotationPointZ = -0.0F; + this.bipedRightLeg.rotateAngleX -= 0.0F; + this.bipedLeftLeg.rotateAngleX -= 0.0F; + this.bipedRightArm.rotateAngleX = (float) ((double) this.bipedRightArm.rotateAngleX * 0.5D); + this.bipedLeftArm.rotateAngleX = (float) ((double) this.bipedLeftArm.rotateAngleX * 0.5D); + this.bipedRightLeg.rotateAngleX = (float) ((double) this.bipedRightLeg.rotateAngleX * 0.5D); + this.bipedLeftLeg.rotateAngleX = (float) ((double) this.bipedLeftLeg.rotateAngleX * 0.5D); + float var9 = 0.4F; + + if (this.bipedRightArm.rotateAngleX > var9) { + this.bipedRightArm.rotateAngleX = var9; + } + + if (this.bipedLeftArm.rotateAngleX > var9) { + this.bipedLeftArm.rotateAngleX = var9; + } + + if (this.bipedRightArm.rotateAngleX < -var9) { + this.bipedRightArm.rotateAngleX = -var9; + } + + if (this.bipedLeftArm.rotateAngleX < -var9) { + this.bipedLeftArm.rotateAngleX = -var9; + } + + if (this.bipedRightLeg.rotateAngleX > var9) { + this.bipedRightLeg.rotateAngleX = var9; + } + + if (this.bipedLeftLeg.rotateAngleX > var9) { + this.bipedLeftLeg.rotateAngleX = var9; + } + + if (this.bipedRightLeg.rotateAngleX < -var9) { + this.bipedRightLeg.rotateAngleX = -var9; + } + + if (this.bipedLeftLeg.rotateAngleX < -var9) { + this.bipedLeftLeg.rotateAngleX = -var9; + } + + if (this.isCarrying) { + this.bipedRightArm.rotateAngleX = -0.5F; + this.bipedLeftArm.rotateAngleX = -0.5F; + this.bipedRightArm.rotateAngleZ = 0.05F; + this.bipedLeftArm.rotateAngleZ = -0.05F; + } + + this.bipedRightArm.rotationPointZ = 0.0F; + this.bipedLeftArm.rotationPointZ = 0.0F; + this.bipedRightLeg.rotationPointZ = 0.0F; + this.bipedLeftLeg.rotationPointZ = 0.0F; + this.bipedRightLeg.rotationPointY = 9.0F + var8; + this.bipedLeftLeg.rotationPointY = 9.0F + var8; + this.bipedHead.rotationPointZ = -0.0F; + this.bipedHead.rotationPointY = var8 + 1.0F; + this.bipedHeadwear.rotationPointX = this.bipedHead.rotationPointX; + this.bipedHeadwear.rotationPointY = this.bipedHead.rotationPointY; + this.bipedHeadwear.rotationPointZ = this.bipedHead.rotationPointZ; + this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; + this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; + this.bipedHeadwear.rotateAngleZ = this.bipedHead.rotateAngleZ; + + if (this.isAttacking) { + float var10 = 1.0F; + this.bipedHead.rotationPointY -= var10 * 5.0F; + } + } +} diff --git a/src/main/java/net/minecraft/src/ModelGhast.java b/src/main/java/net/minecraft/src/ModelGhast.java new file mode 100644 index 0000000..8342948 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelGhast.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +import java.util.Random; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +public class ModelGhast extends ModelBase { + ModelRenderer body; + ModelRenderer[] tentacles = new ModelRenderer[9]; + + public ModelGhast() { + byte var1 = -16; + this.body = new ModelRenderer(this, 0, 0); + this.body.addBox(-8.0F, -8.0F, -8.0F, 16, 16, 16); + this.body.rotationPointY += (float) (24 + var1); + Random var2 = new Random(1660L); + + for (int var3 = 0; var3 < this.tentacles.length; ++var3) { + this.tentacles[var3] = new ModelRenderer(this, 0, 0); + float var4 = (((float) (var3 % 3) - (float) (var3 / 3 % 2) * 0.5F + 0.25F) / 2.0F * 2.0F - 1.0F) * 5.0F; + float var5 = ((float) (var3 / 3) / 2.0F * 2.0F - 1.0F) * 5.0F; + int var6 = var2.nextInt(7) + 8; + this.tentacles[var3].addBox(-1.0F, 0.0F, -1.0F, 2, var6, 2); + this.tentacles[var3].rotationPointX = var4; + this.tentacles[var3].rotationPointZ = var5; + this.tentacles[var3].rotationPointY = (float) (31 + var1); + } + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + for (int var8 = 0; var8 < this.tentacles.length; ++var8) { + this.tentacles[var8].rotateAngleX = 0.2F * MathHelper.sin(par3 * 0.3F + (float) var8) + 0.4F; + } + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(0.0F, 0.6F, 0.0F); + this.body.render(par7); + ModelRenderer[] var8 = this.tentacles; + int var9 = var8.length; + + for (int var10 = 0; var10 < var9; ++var10) { + ModelRenderer var11 = var8[var10]; + var11.render(par7); + } + + EaglerAdapter.glPopMatrix(); + } +} diff --git a/src/main/java/net/minecraft/src/ModelIronGolem.java b/src/main/java/net/minecraft/src/ModelIronGolem.java new file mode 100644 index 0000000..339ad1f --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelIronGolem.java @@ -0,0 +1,114 @@ +package net.minecraft.src; + + + +public class ModelIronGolem extends ModelBase { + /** The head model for the iron golem. */ + public ModelRenderer ironGolemHead; + + /** The body model for the iron golem. */ + public ModelRenderer ironGolemBody; + + /** The right arm model for the iron golem. */ + public ModelRenderer ironGolemRightArm; + + /** The left arm model for the iron golem. */ + public ModelRenderer ironGolemLeftArm; + + /** The left leg model for the Iron Golem. */ + public ModelRenderer ironGolemLeftLeg; + + /** The right leg model for the Iron Golem. */ + public ModelRenderer ironGolemRightLeg; + + public ModelIronGolem() { + this(0.0F); + } + + public ModelIronGolem(float par1) { + this(par1, -7.0F); + } + + public ModelIronGolem(float par1, float par2) { + short var3 = 128; + short var4 = 128; + this.ironGolemHead = (new ModelRenderer(this)).setTextureSize(var3, var4); + this.ironGolemHead.setRotationPoint(0.0F, 0.0F + par2, -2.0F); + this.ironGolemHead.setTextureOffset(0, 0).addBox(-4.0F, -12.0F, -5.5F, 8, 10, 8, par1); + this.ironGolemHead.setTextureOffset(24, 0).addBox(-1.0F, -5.0F, -7.5F, 2, 4, 2, par1); + this.ironGolemBody = (new ModelRenderer(this)).setTextureSize(var3, var4); + this.ironGolemBody.setRotationPoint(0.0F, 0.0F + par2, 0.0F); + this.ironGolemBody.setTextureOffset(0, 40).addBox(-9.0F, -2.0F, -6.0F, 18, 12, 11, par1); + this.ironGolemBody.setTextureOffset(0, 70).addBox(-4.5F, 10.0F, -3.0F, 9, 5, 6, par1 + 0.5F); + this.ironGolemRightArm = (new ModelRenderer(this)).setTextureSize(var3, var4); + this.ironGolemRightArm.setRotationPoint(0.0F, -7.0F, 0.0F); + this.ironGolemRightArm.setTextureOffset(60, 21).addBox(-13.0F, -2.5F, -3.0F, 4, 30, 6, par1); + this.ironGolemLeftArm = (new ModelRenderer(this)).setTextureSize(var3, var4); + this.ironGolemLeftArm.setRotationPoint(0.0F, -7.0F, 0.0F); + this.ironGolemLeftArm.setTextureOffset(60, 58).addBox(9.0F, -2.5F, -3.0F, 4, 30, 6, par1); + this.ironGolemLeftLeg = (new ModelRenderer(this, 0, 22)).setTextureSize(var3, var4); + this.ironGolemLeftLeg.setRotationPoint(-4.0F, 18.0F + par2, 0.0F); + this.ironGolemLeftLeg.setTextureOffset(37, 0).addBox(-3.5F, -3.0F, -3.0F, 6, 16, 5, par1); + this.ironGolemRightLeg = (new ModelRenderer(this, 0, 22)).setTextureSize(var3, var4); + this.ironGolemRightLeg.mirror = true; + this.ironGolemRightLeg.setTextureOffset(60, 0).setRotationPoint(5.0F, 18.0F + par2, 0.0F); + this.ironGolemRightLeg.addBox(-3.5F, -3.0F, -3.0F, 6, 16, 5, par1); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + this.ironGolemHead.render(par7); + this.ironGolemBody.render(par7); + this.ironGolemLeftLeg.render(par7); + this.ironGolemRightLeg.render(par7); + this.ironGolemRightArm.render(par7); + this.ironGolemLeftArm.render(par7); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + this.ironGolemHead.rotateAngleY = par4 / (180F / (float) Math.PI); + this.ironGolemHead.rotateAngleX = par5 / (180F / (float) Math.PI); + this.ironGolemLeftLeg.rotateAngleX = -1.5F * this.func_78172_a(par1, 13.0F) * par2; + this.ironGolemRightLeg.rotateAngleX = 1.5F * this.func_78172_a(par1, 13.0F) * par2; + this.ironGolemLeftLeg.rotateAngleY = 0.0F; + this.ironGolemRightLeg.rotateAngleY = 0.0F; + } + + /** + * Used for easily adding entity-dependent animations. The second and third + * float params here are the same second and third as in the setRotationAngles + * method. + */ + public void setLivingAnimations(EntityLiving par1EntityLiving, float par2, float par3, float par4) { + EntityIronGolem var5 = (EntityIronGolem) par1EntityLiving; + int var6 = var5.getAttackTimer(); + + if (var6 > 0) { + this.ironGolemRightArm.rotateAngleX = -2.0F + 1.5F * this.func_78172_a((float) var6 - par4, 10.0F); + this.ironGolemLeftArm.rotateAngleX = -2.0F + 1.5F * this.func_78172_a((float) var6 - par4, 10.0F); + } else { + int var7 = var5.getHoldRoseTick(); + + if (var7 > 0) { + this.ironGolemRightArm.rotateAngleX = -0.8F + 0.025F * this.func_78172_a((float) var7, 70.0F); + this.ironGolemLeftArm.rotateAngleX = 0.0F; + } else { + this.ironGolemRightArm.rotateAngleX = (-0.2F + 1.5F * this.func_78172_a(par2, 13.0F)) * par3; + this.ironGolemLeftArm.rotateAngleX = (-0.2F - 1.5F * this.func_78172_a(par2, 13.0F)) * par3; + } + } + } + + private float func_78172_a(float par1, float par2) { + return (Math.abs(par1 % par2 - par2 * 0.5F) - par2 * 0.25F) / (par2 * 0.25F); + } +} diff --git a/src/main/java/net/minecraft/src/ModelLargeChest.java b/src/main/java/net/minecraft/src/ModelLargeChest.java new file mode 100644 index 0000000..ba38769 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelLargeChest.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +public class ModelLargeChest extends ModelChest { + public ModelLargeChest() { + this.chestLid = (new ModelRenderer(this, 0, 0)).setTextureSize(128, 64); + this.chestLid.addBox(0.0F, -5.0F, -14.0F, 30, 5, 14, 0.0F); + this.chestLid.rotationPointX = 1.0F; + this.chestLid.rotationPointY = 7.0F; + this.chestLid.rotationPointZ = 15.0F; + this.chestKnob = (new ModelRenderer(this, 0, 0)).setTextureSize(128, 64); + this.chestKnob.addBox(-1.0F, -2.0F, -15.0F, 2, 4, 1, 0.0F); + this.chestKnob.rotationPointX = 16.0F; + this.chestKnob.rotationPointY = 7.0F; + this.chestKnob.rotationPointZ = 15.0F; + this.chestBelow = (new ModelRenderer(this, 0, 19)).setTextureSize(128, 64); + this.chestBelow.addBox(0.0F, 0.0F, 0.0F, 30, 10, 14, 0.0F); + this.chestBelow.rotationPointX = 1.0F; + this.chestBelow.rotationPointY = 6.0F; + this.chestBelow.rotationPointZ = 1.0F; + } +} diff --git a/src/main/java/net/minecraft/src/ModelMagmaCube.java b/src/main/java/net/minecraft/src/ModelMagmaCube.java new file mode 100644 index 0000000..52c0ea9 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelMagmaCube.java @@ -0,0 +1,61 @@ +package net.minecraft.src; + +public class ModelMagmaCube extends ModelBase { + ModelRenderer[] field_78109_a = new ModelRenderer[8]; + ModelRenderer field_78108_b; + + public ModelMagmaCube() { + for (int var1 = 0; var1 < this.field_78109_a.length; ++var1) { + byte var2 = 0; + int var3 = var1; + + if (var1 == 2) { + var2 = 24; + var3 = 10; + } else if (var1 == 3) { + var2 = 24; + var3 = 19; + } + + this.field_78109_a[var1] = new ModelRenderer(this, var2, var3); + this.field_78109_a[var1].addBox(-4.0F, (float) (16 + var1), -4.0F, 8, 1, 8); + } + + this.field_78108_b = new ModelRenderer(this, 0, 16); + this.field_78108_b.addBox(-2.0F, 18.0F, -2.0F, 4, 4, 4); + } + + public int func_78107_a() { + return 5; + } + + /** + * Used for easily adding entity-dependent animations. The second and third + * float params here are the same second and third as in the setRotationAngles + * method. + */ + public void setLivingAnimations(EntityLiving par1EntityLiving, float par2, float par3, float par4) { + EntityMagmaCube var5 = (EntityMagmaCube) par1EntityLiving; + float var6 = var5.field_70812_c + (var5.field_70811_b - var5.field_70812_c) * par4; + + if (var6 < 0.0F) { + var6 = 0.0F; + } + + for (int var7 = 0; var7 < this.field_78109_a.length; ++var7) { + this.field_78109_a[var7].rotationPointY = (float) (-(4 - var7)) * var6 * 1.7F; + } + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + this.field_78108_b.render(par7); + + for (int var8 = 0; var8 < this.field_78109_a.length; ++var8) { + this.field_78109_a[var8].render(par7); + } + } +} diff --git a/src/main/java/net/minecraft/src/ModelMinecart.java b/src/main/java/net/minecraft/src/ModelMinecart.java new file mode 100644 index 0000000..c579f87 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelMinecart.java @@ -0,0 +1,48 @@ +package net.minecraft.src; + + + +public class ModelMinecart extends ModelBase { + public ModelRenderer[] sideModels = new ModelRenderer[7]; + + public ModelMinecart() { + this.sideModels[0] = new ModelRenderer(this, 0, 10); + this.sideModels[1] = new ModelRenderer(this, 0, 0); + this.sideModels[2] = new ModelRenderer(this, 0, 0); + this.sideModels[3] = new ModelRenderer(this, 0, 0); + this.sideModels[4] = new ModelRenderer(this, 0, 0); + this.sideModels[5] = new ModelRenderer(this, 44, 10); + byte var1 = 20; + byte var2 = 8; + byte var3 = 16; + byte var4 = 4; + this.sideModels[0].addBox((float) (-var1 / 2), (float) (-var3 / 2), -1.0F, var1, var3, 2, 0.0F); + this.sideModels[0].setRotationPoint(0.0F, (float) var4, 0.0F); + this.sideModels[5].addBox((float) (-var1 / 2 + 1), (float) (-var3 / 2 + 1), -1.0F, var1 - 2, var3 - 2, 1, 0.0F); + this.sideModels[5].setRotationPoint(0.0F, (float) var4, 0.0F); + this.sideModels[1].addBox((float) (-var1 / 2 + 2), (float) (-var2 - 1), -1.0F, var1 - 4, var2, 2, 0.0F); + this.sideModels[1].setRotationPoint((float) (-var1 / 2 + 1), (float) var4, 0.0F); + this.sideModels[2].addBox((float) (-var1 / 2 + 2), (float) (-var2 - 1), -1.0F, var1 - 4, var2, 2, 0.0F); + this.sideModels[2].setRotationPoint((float) (var1 / 2 - 1), (float) var4, 0.0F); + this.sideModels[3].addBox((float) (-var1 / 2 + 2), (float) (-var2 - 1), -1.0F, var1 - 4, var2, 2, 0.0F); + this.sideModels[3].setRotationPoint(0.0F, (float) var4, (float) (-var3 / 2 + 1)); + this.sideModels[4].addBox((float) (-var1 / 2 + 2), (float) (-var2 - 1), -1.0F, var1 - 4, var2, 2, 0.0F); + this.sideModels[4].setRotationPoint(0.0F, (float) var4, (float) (var3 / 2 - 1)); + this.sideModels[0].rotateAngleX = ((float) Math.PI / 2F); + this.sideModels[1].rotateAngleY = ((float) Math.PI * 3F / 2F); + this.sideModels[2].rotateAngleY = ((float) Math.PI / 2F); + this.sideModels[3].rotateAngleY = (float) Math.PI; + this.sideModels[5].rotateAngleX = -((float) Math.PI / 2F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.sideModels[5].rotationPointY = 4.0F - par4; + + for (int var8 = 0; var8 < 6; ++var8) { + this.sideModels[var8].render(par7); + } + } +} diff --git a/src/main/java/net/minecraft/src/ModelOcelot.java b/src/main/java/net/minecraft/src/ModelOcelot.java new file mode 100644 index 0000000..bd45f5a --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelOcelot.java @@ -0,0 +1,196 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; + + +public class ModelOcelot extends ModelBase { + /** The back left leg model for the Ocelot. */ + ModelRenderer ocelotBackLeftLeg; + + /** The back right leg model for the Ocelot. */ + ModelRenderer ocelotBackRightLeg; + + /** The front left leg model for the Ocelot. */ + ModelRenderer ocelotFrontLeftLeg; + + /** The front right leg model for the Ocelot. */ + ModelRenderer ocelotFrontRightLeg; + + /** The tail model for the Ocelot. */ + ModelRenderer ocelotTail; + + /** The second part of tail model for the Ocelot. */ + ModelRenderer ocelotTail2; + + /** The head model for the Ocelot. */ + ModelRenderer ocelotHead; + + /** The body model for the Ocelot. */ + ModelRenderer ocelotBody; + int field_78163_i = 1; + + public ModelOcelot() { + this.setTextureOffset("head.main", 0, 0); + this.setTextureOffset("head.nose", 0, 24); + this.setTextureOffset("head.ear1", 0, 10); + this.setTextureOffset("head.ear2", 6, 10); + this.ocelotHead = new ModelRenderer(this, "head"); + this.ocelotHead.addBox("main", -2.5F, -2.0F, -3.0F, 5, 4, 5); + this.ocelotHead.addBox("nose", -1.5F, 0.0F, -4.0F, 3, 2, 2); + this.ocelotHead.addBox("ear1", -2.0F, -3.0F, 0.0F, 1, 1, 2); + this.ocelotHead.addBox("ear2", 1.0F, -3.0F, 0.0F, 1, 1, 2); + this.ocelotHead.setRotationPoint(0.0F, 15.0F, -9.0F); + this.ocelotBody = new ModelRenderer(this, 20, 0); + this.ocelotBody.addBox(-2.0F, 3.0F, -8.0F, 4, 16, 6, 0.0F); + this.ocelotBody.setRotationPoint(0.0F, 12.0F, -10.0F); + this.ocelotTail = new ModelRenderer(this, 0, 15); + this.ocelotTail.addBox(-0.5F, 0.0F, 0.0F, 1, 8, 1); + this.ocelotTail.rotateAngleX = 0.9F; + this.ocelotTail.setRotationPoint(0.0F, 15.0F, 8.0F); + this.ocelotTail2 = new ModelRenderer(this, 4, 15); + this.ocelotTail2.addBox(-0.5F, 0.0F, 0.0F, 1, 8, 1); + this.ocelotTail2.setRotationPoint(0.0F, 20.0F, 14.0F); + this.ocelotBackLeftLeg = new ModelRenderer(this, 8, 13); + this.ocelotBackLeftLeg.addBox(-1.0F, 0.0F, 1.0F, 2, 6, 2); + this.ocelotBackLeftLeg.setRotationPoint(1.1F, 18.0F, 5.0F); + this.ocelotBackRightLeg = new ModelRenderer(this, 8, 13); + this.ocelotBackRightLeg.addBox(-1.0F, 0.0F, 1.0F, 2, 6, 2); + this.ocelotBackRightLeg.setRotationPoint(-1.1F, 18.0F, 5.0F); + this.ocelotFrontLeftLeg = new ModelRenderer(this, 40, 0); + this.ocelotFrontLeftLeg.addBox(-1.0F, 0.0F, 0.0F, 2, 10, 2); + this.ocelotFrontLeftLeg.setRotationPoint(1.2F, 13.8F, -5.0F); + this.ocelotFrontRightLeg = new ModelRenderer(this, 40, 0); + this.ocelotFrontRightLeg.addBox(-1.0F, 0.0F, 0.0F, 2, 10, 2); + this.ocelotFrontRightLeg.setRotationPoint(-1.2F, 13.8F, -5.0F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + + if (this.isChild) { + float var8 = 2.0F; + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glScalef(1.5F / var8, 1.5F / var8, 1.5F / var8); + EaglerAdapter.glTranslatef(0.0F, 10.0F * par7, 4.0F * par7); + this.ocelotHead.render(par7); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glScalef(1.0F / var8, 1.0F / var8, 1.0F / var8); + EaglerAdapter.glTranslatef(0.0F, 24.0F * par7, 0.0F); + this.ocelotBody.render(par7); + this.ocelotBackLeftLeg.render(par7); + this.ocelotBackRightLeg.render(par7); + this.ocelotFrontLeftLeg.render(par7); + this.ocelotFrontRightLeg.render(par7); + this.ocelotTail.render(par7); + this.ocelotTail2.render(par7); + EaglerAdapter.glPopMatrix(); + } else { + this.ocelotHead.render(par7); + this.ocelotBody.render(par7); + this.ocelotTail.render(par7); + this.ocelotTail2.render(par7); + this.ocelotBackLeftLeg.render(par7); + this.ocelotBackRightLeg.render(par7); + this.ocelotFrontLeftLeg.render(par7); + this.ocelotFrontRightLeg.render(par7); + } + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + this.ocelotHead.rotateAngleX = par5 / (180F / (float) Math.PI); + this.ocelotHead.rotateAngleY = par4 / (180F / (float) Math.PI); + + if (this.field_78163_i != 3) { + this.ocelotBody.rotateAngleX = ((float) Math.PI / 2F); + + if (this.field_78163_i == 2) { + this.ocelotBackLeftLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.0F * par2; + this.ocelotBackRightLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + 0.3F) * 1.0F * par2; + this.ocelotFrontLeftLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float) Math.PI + 0.3F) * 1.0F * par2; + this.ocelotFrontRightLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float) Math.PI) * 1.0F * par2; + this.ocelotTail2.rotateAngleX = 1.7278761F + ((float) Math.PI / 10F) * MathHelper.cos(par1) * par2; + } else { + this.ocelotBackLeftLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.0F * par2; + this.ocelotBackRightLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float) Math.PI) * 1.0F * par2; + this.ocelotFrontLeftLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float) Math.PI) * 1.0F * par2; + this.ocelotFrontRightLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.0F * par2; + + if (this.field_78163_i == 1) { + this.ocelotTail2.rotateAngleX = 1.7278761F + ((float) Math.PI / 4F) * MathHelper.cos(par1) * par2; + } else { + this.ocelotTail2.rotateAngleX = 1.7278761F + 0.47123894F * MathHelper.cos(par1) * par2; + } + } + } + } + + /** + * Used for easily adding entity-dependent animations. The second and third + * float params here are the same second and third as in the setRotationAngles + * method. + */ + public void setLivingAnimations(EntityLiving par1EntityLiving, float par2, float par3, float par4) { + EntityOcelot var5 = (EntityOcelot) par1EntityLiving; + this.ocelotBody.rotationPointY = 12.0F; + this.ocelotBody.rotationPointZ = -10.0F; + this.ocelotHead.rotationPointY = 15.0F; + this.ocelotHead.rotationPointZ = -9.0F; + this.ocelotTail.rotationPointY = 15.0F; + this.ocelotTail.rotationPointZ = 8.0F; + this.ocelotTail2.rotationPointY = 20.0F; + this.ocelotTail2.rotationPointZ = 14.0F; + this.ocelotFrontLeftLeg.rotationPointY = this.ocelotFrontRightLeg.rotationPointY = 13.8F; + this.ocelotFrontLeftLeg.rotationPointZ = this.ocelotFrontRightLeg.rotationPointZ = -5.0F; + this.ocelotBackLeftLeg.rotationPointY = this.ocelotBackRightLeg.rotationPointY = 18.0F; + this.ocelotBackLeftLeg.rotationPointZ = this.ocelotBackRightLeg.rotationPointZ = 5.0F; + this.ocelotTail.rotateAngleX = 0.9F; + + if (var5.isSneaking()) { + ++this.ocelotBody.rotationPointY; + this.ocelotHead.rotationPointY += 2.0F; + ++this.ocelotTail.rotationPointY; + this.ocelotTail2.rotationPointY += -4.0F; + this.ocelotTail2.rotationPointZ += 2.0F; + this.ocelotTail.rotateAngleX = ((float) Math.PI / 2F); + this.ocelotTail2.rotateAngleX = ((float) Math.PI / 2F); + this.field_78163_i = 0; + } else if (var5.isSprinting()) { + this.ocelotTail2.rotationPointY = this.ocelotTail.rotationPointY; + this.ocelotTail2.rotationPointZ += 2.0F; + this.ocelotTail.rotateAngleX = ((float) Math.PI / 2F); + this.ocelotTail2.rotateAngleX = ((float) Math.PI / 2F); + this.field_78163_i = 2; + } else if (var5.isSitting()) { + this.ocelotBody.rotateAngleX = ((float) Math.PI / 4F); + this.ocelotBody.rotationPointY += -4.0F; + this.ocelotBody.rotationPointZ += 5.0F; + this.ocelotHead.rotationPointY += -3.3F; + ++this.ocelotHead.rotationPointZ; + this.ocelotTail.rotationPointY += 8.0F; + this.ocelotTail.rotationPointZ += -2.0F; + this.ocelotTail2.rotationPointY += 2.0F; + this.ocelotTail2.rotationPointZ += -0.8F; + this.ocelotTail.rotateAngleX = 1.7278761F; + this.ocelotTail2.rotateAngleX = 2.670354F; + this.ocelotFrontLeftLeg.rotateAngleX = this.ocelotFrontRightLeg.rotateAngleX = -0.15707964F; + this.ocelotFrontLeftLeg.rotationPointY = this.ocelotFrontRightLeg.rotationPointY = 15.8F; + this.ocelotFrontLeftLeg.rotationPointZ = this.ocelotFrontRightLeg.rotationPointZ = -7.0F; + this.ocelotBackLeftLeg.rotateAngleX = this.ocelotBackRightLeg.rotateAngleX = -((float) Math.PI / 2F); + this.ocelotBackLeftLeg.rotationPointY = this.ocelotBackRightLeg.rotationPointY = 21.0F; + this.ocelotBackLeftLeg.rotationPointZ = this.ocelotBackRightLeg.rotationPointZ = 1.0F; + this.field_78163_i = 3; + } else { + this.field_78163_i = 1; + } + } +} diff --git a/src/main/java/net/minecraft/src/ModelPig.java b/src/main/java/net/minecraft/src/ModelPig.java new file mode 100644 index 0000000..b81f54c --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelPig.java @@ -0,0 +1,13 @@ +package net.minecraft.src; + +public class ModelPig extends ModelQuadruped { + public ModelPig() { + this(0.0F); + } + + public ModelPig(float par1) { + super(6, par1); + this.head.setTextureOffset(16, 16).addBox(-2.0F, 0.0F, -9.0F, 4, 3, 1, par1); + this.field_78145_g = 4.0F; + } +} diff --git a/src/main/java/net/minecraft/src/ModelQuadruped.java b/src/main/java/net/minecraft/src/ModelQuadruped.java new file mode 100644 index 0000000..c9d6e53 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelQuadruped.java @@ -0,0 +1,82 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; + + +public class ModelQuadruped extends ModelBase { + public ModelRenderer head = new ModelRenderer(this, 0, 0); + public ModelRenderer body; + public ModelRenderer leg1; + public ModelRenderer leg2; + public ModelRenderer leg3; + public ModelRenderer leg4; + protected float field_78145_g = 8.0F; + protected float field_78151_h = 4.0F; + + public ModelQuadruped(int par1, float par2) { + this.head.addBox(-4.0F, -4.0F, -8.0F, 8, 8, 8, par2); + this.head.setRotationPoint(0.0F, (float) (18 - par1), -6.0F); + this.body = new ModelRenderer(this, 28, 8); + this.body.addBox(-5.0F, -10.0F, -7.0F, 10, 16, 8, par2); + this.body.setRotationPoint(0.0F, (float) (17 - par1), 2.0F); + this.leg1 = new ModelRenderer(this, 0, 16); + this.leg1.addBox(-2.0F, 0.0F, -2.0F, 4, par1, 4, par2); + this.leg1.setRotationPoint(-3.0F, (float) (24 - par1), 7.0F); + this.leg2 = new ModelRenderer(this, 0, 16); + this.leg2.addBox(-2.0F, 0.0F, -2.0F, 4, par1, 4, par2); + this.leg2.setRotationPoint(3.0F, (float) (24 - par1), 7.0F); + this.leg3 = new ModelRenderer(this, 0, 16); + this.leg3.addBox(-2.0F, 0.0F, -2.0F, 4, par1, 4, par2); + this.leg3.setRotationPoint(-3.0F, (float) (24 - par1), -5.0F); + this.leg4 = new ModelRenderer(this, 0, 16); + this.leg4.addBox(-2.0F, 0.0F, -2.0F, 4, par1, 4, par2); + this.leg4.setRotationPoint(3.0F, (float) (24 - par1), -5.0F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + + if (this.isChild) { + float var8 = 2.0F; + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(0.0F, this.field_78145_g * par7, this.field_78151_h * par7); + this.head.render(par7); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glScalef(1.0F / var8, 1.0F / var8, 1.0F / var8); + EaglerAdapter.glTranslatef(0.0F, 24.0F * par7, 0.0F); + this.body.render(par7); + this.leg1.render(par7); + this.leg2.render(par7); + this.leg3.render(par7); + this.leg4.render(par7); + EaglerAdapter.glPopMatrix(); + } else { + this.head.render(par7); + this.body.render(par7); + this.leg1.render(par7); + this.leg2.render(par7); + this.leg3.render(par7); + this.leg4.render(par7); + } + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + this.head.rotateAngleX = par5 / (180F / (float) Math.PI); + this.head.rotateAngleY = par4 / (180F / (float) Math.PI); + this.body.rotateAngleX = ((float) Math.PI / 2F); + this.leg1.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; + this.leg2.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float) Math.PI) * 1.4F * par2; + this.leg3.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float) Math.PI) * 1.4F * par2; + this.leg4.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; + } +} diff --git a/src/main/java/net/minecraft/src/ModelRenderer.java b/src/main/java/net/minecraft/src/ModelRenderer.java new file mode 100644 index 0000000..f8d9614 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelRenderer.java @@ -0,0 +1,261 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class ModelRenderer { + /** The size of the texture file's width in pixels. */ + public float textureWidth; + + /** The size of the texture file's height in pixels. */ + public float textureHeight; + + /** The X offset into the texture used for displaying this model */ + private int textureOffsetX; + + /** The Y offset into the texture used for displaying this model */ + private int textureOffsetY; + public float rotationPointX; + public float rotationPointY; + public float rotationPointZ; + public float rotateAngleX; + public float rotateAngleY; + public float rotateAngleZ; + private boolean compiled; + + /** The GL display list rendered by the Tessellator for this model */ + private int displayList; + public boolean mirror; + public boolean showModel; + + /** Hides the model. */ + public boolean isHidden; + public List cubeList; + public List childModels; + public final String boxName; + private ModelBase baseModel; + public float field_82906_o; + public float field_82908_p; + public float field_82907_q; + + public ModelRenderer(ModelBase par1ModelBase, String par2Str) { + this.textureWidth = 64.0F; + this.textureHeight = 32.0F; + this.compiled = false; + this.displayList = 0; + this.mirror = false; + this.showModel = true; + this.isHidden = false; + this.cubeList = new ArrayList(); + this.baseModel = par1ModelBase; + par1ModelBase.boxList.add(this); + this.boxName = par2Str; + this.setTextureSize(par1ModelBase.textureWidth, par1ModelBase.textureHeight); + } + + public ModelRenderer(ModelBase par1ModelBase) { + this(par1ModelBase, (String) null); + } + + public ModelRenderer(ModelBase par1ModelBase, int par2, int par3) { + this(par1ModelBase); + this.setTextureOffset(par2, par3); + } + + /** + * Sets the current box's rotation points and rotation angles to another box. + */ + public void addChild(ModelRenderer par1ModelRenderer) { + if (this.childModels == null) { + this.childModels = new ArrayList(); + } + + this.childModels.add(par1ModelRenderer); + } + + public ModelRenderer setTextureOffset(int par1, int par2) { + this.textureOffsetX = par1; + this.textureOffsetY = par2; + return this; + } + + public ModelRenderer addBox(String par1Str, float par2, float par3, float par4, int par5, int par6, int par7) { + par1Str = this.boxName + "." + par1Str; + TextureOffset var8 = this.baseModel.getTextureOffset(par1Str); + this.setTextureOffset(var8.textureOffsetX, var8.textureOffsetY); + this.cubeList.add((new ModelBox(this, this.textureOffsetX, this.textureOffsetY, par2, par3, par4, par5, par6, par7, 0.0F)).func_78244_a(par1Str)); + return this; + } + + public ModelRenderer addBox(float par1, float par2, float par3, int par4, int par5, int par6) { + this.cubeList.add(new ModelBox(this, this.textureOffsetX, this.textureOffsetY, par1, par2, par3, par4, par5, par6, 0.0F)); + return this; + } + + /** + * Creates a textured box. Args: originX, originY, originZ, width, height, + * depth, scaleFactor. + */ + public void addBox(float par1, float par2, float par3, int par4, int par5, int par6, float par7) { + this.cubeList.add(new ModelBox(this, this.textureOffsetX, this.textureOffsetY, par1, par2, par3, par4, par5, par6, par7)); + } + + public void setRotationPoint(float par1, float par2, float par3) { + this.rotationPointX = par1; + this.rotationPointY = par2; + this.rotationPointZ = par3; + } + + public void render(float par1) { + if (!this.isHidden) { + if (this.showModel) { + if (!this.compiled) { + this.compileDisplayList(par1); + } + + EaglerAdapter.glTranslatef(this.field_82906_o, this.field_82908_p, this.field_82907_q); + int var2; + + if (this.rotateAngleX == 0.0F && this.rotateAngleY == 0.0F && this.rotateAngleZ == 0.0F) { + if (this.rotationPointX == 0.0F && this.rotationPointY == 0.0F && this.rotationPointZ == 0.0F) { + EaglerAdapter.glCallList(this.displayList); + + if (this.childModels != null) { + for (var2 = 0; var2 < this.childModels.size(); ++var2) { + ((ModelRenderer) this.childModels.get(var2)).render(par1); + } + } + } else { + EaglerAdapter.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1); + EaglerAdapter.glCallList(this.displayList); + + if (this.childModels != null) { + for (var2 = 0; var2 < this.childModels.size(); ++var2) { + ((ModelRenderer) this.childModels.get(var2)).render(par1); + } + } + + EaglerAdapter.glTranslatef(-this.rotationPointX * par1, -this.rotationPointY * par1, -this.rotationPointZ * par1); + } + } else { + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1); + + if (this.rotateAngleZ != 0.0F) { + EaglerAdapter.glRotatef(this.rotateAngleZ * (180F / (float) Math.PI), 0.0F, 0.0F, 1.0F); + } + + if (this.rotateAngleY != 0.0F) { + EaglerAdapter.glRotatef(this.rotateAngleY * (180F / (float) Math.PI), 0.0F, 1.0F, 0.0F); + } + + if (this.rotateAngleX != 0.0F) { + EaglerAdapter.glRotatef(this.rotateAngleX * (180F / (float) Math.PI), 1.0F, 0.0F, 0.0F); + } + + EaglerAdapter.glCallList(this.displayList); + + if (this.childModels != null) { + for (var2 = 0; var2 < this.childModels.size(); ++var2) { + ((ModelRenderer) this.childModels.get(var2)).render(par1); + } + } + + EaglerAdapter.glPopMatrix(); + } + + EaglerAdapter.glTranslatef(-this.field_82906_o, -this.field_82908_p, -this.field_82907_q); + } + } + } + + public void renderWithRotation(float par1) { + if (!this.isHidden) { + if (this.showModel) { + if (!this.compiled) { + this.compileDisplayList(par1); + } + + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1); + + if (this.rotateAngleY != 0.0F) { + EaglerAdapter.glRotatef(this.rotateAngleY * (180F / (float) Math.PI), 0.0F, 1.0F, 0.0F); + } + + if (this.rotateAngleX != 0.0F) { + EaglerAdapter.glRotatef(this.rotateAngleX * (180F / (float) Math.PI), 1.0F, 0.0F, 0.0F); + } + + if (this.rotateAngleZ != 0.0F) { + EaglerAdapter.glRotatef(this.rotateAngleZ * (180F / (float) Math.PI), 0.0F, 0.0F, 1.0F); + } + + EaglerAdapter.glCallList(this.displayList); + EaglerAdapter.glPopMatrix(); + } + } + } + + /** + * Allows the changing of Angles after a box has been rendered + */ + public void postRender(float par1) { + if (!this.isHidden) { + if (this.showModel) { + if (!this.compiled) { + this.compileDisplayList(par1); + } + + if (this.rotateAngleX == 0.0F && this.rotateAngleY == 0.0F && this.rotateAngleZ == 0.0F) { + if (this.rotationPointX != 0.0F || this.rotationPointY != 0.0F || this.rotationPointZ != 0.0F) { + EaglerAdapter.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1); + } + } else { + EaglerAdapter.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1); + + if (this.rotateAngleZ != 0.0F) { + EaglerAdapter.glRotatef(this.rotateAngleZ * (180F / (float) Math.PI), 0.0F, 0.0F, 1.0F); + } + + if (this.rotateAngleY != 0.0F) { + EaglerAdapter.glRotatef(this.rotateAngleY * (180F / (float) Math.PI), 0.0F, 1.0F, 0.0F); + } + + if (this.rotateAngleX != 0.0F) { + EaglerAdapter.glRotatef(this.rotateAngleX * (180F / (float) Math.PI), 1.0F, 0.0F, 0.0F); + } + } + } + } + } + + /** + * Compiles a GL display list for this model + */ + private void compileDisplayList(float par1) { + this.displayList = GLAllocation.generateDisplayLists(1); + EaglerAdapter.glNewList(this.displayList, EaglerAdapter.GL_COMPILE); + Tessellator var2 = Tessellator.instance; + + for (int var3 = 0; var3 < this.cubeList.size(); ++var3) { + ((ModelBox) this.cubeList.get(var3)).render(var2, par1); + } + + EaglerAdapter.glEndList(); + this.compiled = true; + } + + /** + * Returns the model renderer with the new texture parameters. + */ + public ModelRenderer setTextureSize(int par1, int par2) { + this.textureWidth = (float) par1; + this.textureHeight = (float) par2; + return this; + } +} diff --git a/src/main/java/net/minecraft/src/ModelSheep1.java b/src/main/java/net/minecraft/src/ModelSheep1.java new file mode 100644 index 0000000..cb70fb2 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSheep1.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + +public class ModelSheep1 extends ModelQuadruped { + private float field_78152_i; + + public ModelSheep1() { + super(12, 0.0F); + this.head = new ModelRenderer(this, 0, 0); + this.head.addBox(-3.0F, -4.0F, -4.0F, 6, 6, 6, 0.6F); + this.head.setRotationPoint(0.0F, 6.0F, -8.0F); + this.body = new ModelRenderer(this, 28, 8); + this.body.addBox(-4.0F, -10.0F, -7.0F, 8, 16, 6, 1.75F); + this.body.setRotationPoint(0.0F, 5.0F, 2.0F); + float var1 = 0.5F; + this.leg1 = new ModelRenderer(this, 0, 16); + this.leg1.addBox(-2.0F, 0.0F, -2.0F, 4, 6, 4, var1); + this.leg1.setRotationPoint(-3.0F, 12.0F, 7.0F); + this.leg2 = new ModelRenderer(this, 0, 16); + this.leg2.addBox(-2.0F, 0.0F, -2.0F, 4, 6, 4, var1); + this.leg2.setRotationPoint(3.0F, 12.0F, 7.0F); + this.leg3 = new ModelRenderer(this, 0, 16); + this.leg3.addBox(-2.0F, 0.0F, -2.0F, 4, 6, 4, var1); + this.leg3.setRotationPoint(-3.0F, 12.0F, -5.0F); + this.leg4 = new ModelRenderer(this, 0, 16); + this.leg4.addBox(-2.0F, 0.0F, -2.0F, 4, 6, 4, var1); + this.leg4.setRotationPoint(3.0F, 12.0F, -5.0F); + } + + /** + * Used for easily adding entity-dependent animations. The second and third + * float params here are the same second and third as in the setRotationAngles + * method. + */ + public void setLivingAnimations(EntityLiving par1EntityLiving, float par2, float par3, float par4) { + super.setLivingAnimations(par1EntityLiving, par2, par3, par4); + this.head.rotationPointY = 6.0F + ((EntitySheep) par1EntityLiving).func_70894_j(par4) * 9.0F; + this.field_78152_i = ((EntitySheep) par1EntityLiving).func_70890_k(par4); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); + this.head.rotateAngleX = this.field_78152_i; + } +} diff --git a/src/main/java/net/minecraft/src/ModelSheep2.java b/src/main/java/net/minecraft/src/ModelSheep2.java new file mode 100644 index 0000000..b8e7b09 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSheep2.java @@ -0,0 +1,37 @@ +package net.minecraft.src; + +public class ModelSheep2 extends ModelQuadruped { + private float field_78153_i; + + public ModelSheep2() { + super(12, 0.0F); + this.head = new ModelRenderer(this, 0, 0); + this.head.addBox(-3.0F, -4.0F, -6.0F, 6, 6, 8, 0.0F); + this.head.setRotationPoint(0.0F, 6.0F, -8.0F); + this.body = new ModelRenderer(this, 28, 8); + this.body.addBox(-4.0F, -10.0F, -7.0F, 8, 16, 6, 0.0F); + this.body.setRotationPoint(0.0F, 5.0F, 2.0F); + } + + /** + * Used for easily adding entity-dependent animations. The second and third + * float params here are the same second and third as in the setRotationAngles + * method. + */ + public void setLivingAnimations(EntityLiving par1EntityLiving, float par2, float par3, float par4) { + super.setLivingAnimations(par1EntityLiving, par2, par3, par4); + this.head.rotationPointY = 6.0F + ((EntitySheep) par1EntityLiving).func_70894_j(par4) * 9.0F; + this.field_78153_i = ((EntitySheep) par1EntityLiving).func_70890_k(par4); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); + this.head.rotateAngleX = this.field_78153_i; + } +} diff --git a/src/main/java/net/minecraft/src/ModelSign.java b/src/main/java/net/minecraft/src/ModelSign.java new file mode 100644 index 0000000..46e2a38 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSign.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +public class ModelSign extends ModelBase { + /** The board on a sign that has the writing on it. */ + public ModelRenderer signBoard = new ModelRenderer(this, 0, 0); + + /** The stick a sign stands on. */ + public ModelRenderer signStick; + + public ModelSign() { + this.signBoard.addBox(-12.0F, -14.0F, -1.0F, 24, 12, 2, 0.0F); + this.signStick = new ModelRenderer(this, 0, 14); + this.signStick.addBox(-1.0F, -2.0F, -1.0F, 2, 14, 2, 0.0F); + } + + /** + * Renders the sign model through TileEntitySignRenderer + */ + public void renderSign() { + this.signBoard.render(0.0625F); + this.signStick.render(0.0625F); + } +} diff --git a/src/main/java/net/minecraft/src/ModelSilverfish.java b/src/main/java/net/minecraft/src/ModelSilverfish.java new file mode 100644 index 0000000..b1384db --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSilverfish.java @@ -0,0 +1,79 @@ +package net.minecraft.src; + + + +public class ModelSilverfish extends ModelBase { + /** The body parts of the silverfish's model. */ + private ModelRenderer[] silverfishBodyParts = new ModelRenderer[7]; + + /** The wings (dust-looking sprites) on the silverfish's model. */ + private ModelRenderer[] silverfishWings; + private float[] field_78170_c = new float[7]; + + /** The widths, heights, and lengths for the silverfish model boxes. */ + private static final int[][] silverfishBoxLength = new int[][] { { 3, 2, 2 }, { 4, 3, 2 }, { 6, 4, 3 }, { 3, 3, 3 }, { 2, 2, 3 }, { 2, 1, 2 }, { 1, 1, 2 } }; + + /** The texture positions for the silverfish's model's boxes. */ + private static final int[][] silverfishTexturePositions = new int[][] { { 0, 0 }, { 0, 4 }, { 0, 9 }, { 0, 16 }, { 0, 22 }, { 11, 0 }, { 13, 4 } }; + + public ModelSilverfish() { + float var1 = -3.5F; + + for (int var2 = 0; var2 < this.silverfishBodyParts.length; ++var2) { + this.silverfishBodyParts[var2] = new ModelRenderer(this, silverfishTexturePositions[var2][0], silverfishTexturePositions[var2][1]); + this.silverfishBodyParts[var2].addBox((float) silverfishBoxLength[var2][0] * -0.5F, 0.0F, (float) silverfishBoxLength[var2][2] * -0.5F, silverfishBoxLength[var2][0], silverfishBoxLength[var2][1], silverfishBoxLength[var2][2]); + this.silverfishBodyParts[var2].setRotationPoint(0.0F, (float) (24 - silverfishBoxLength[var2][1]), var1); + this.field_78170_c[var2] = var1; + + if (var2 < this.silverfishBodyParts.length - 1) { + var1 += (float) (silverfishBoxLength[var2][2] + silverfishBoxLength[var2 + 1][2]) * 0.5F; + } + } + + this.silverfishWings = new ModelRenderer[3]; + this.silverfishWings[0] = new ModelRenderer(this, 20, 0); + this.silverfishWings[0].addBox(-5.0F, 0.0F, (float) silverfishBoxLength[2][2] * -0.5F, 10, 8, silverfishBoxLength[2][2]); + this.silverfishWings[0].setRotationPoint(0.0F, 16.0F, this.field_78170_c[2]); + this.silverfishWings[1] = new ModelRenderer(this, 20, 11); + this.silverfishWings[1].addBox(-3.0F, 0.0F, (float) silverfishBoxLength[4][2] * -0.5F, 6, 4, silverfishBoxLength[4][2]); + this.silverfishWings[1].setRotationPoint(0.0F, 20.0F, this.field_78170_c[4]); + this.silverfishWings[2] = new ModelRenderer(this, 20, 18); + this.silverfishWings[2].addBox(-3.0F, 0.0F, (float) silverfishBoxLength[4][2] * -0.5F, 6, 5, silverfishBoxLength[1][2]); + this.silverfishWings[2].setRotationPoint(0.0F, 19.0F, this.field_78170_c[1]); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + int var8; + + for (var8 = 0; var8 < this.silverfishBodyParts.length; ++var8) { + this.silverfishBodyParts[var8].render(par7); + } + + for (var8 = 0; var8 < this.silverfishWings.length; ++var8) { + this.silverfishWings[var8].render(par7); + } + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + for (int var8 = 0; var8 < this.silverfishBodyParts.length; ++var8) { + this.silverfishBodyParts[var8].rotateAngleY = MathHelper.cos(par3 * 0.9F + (float) var8 * 0.15F * (float) Math.PI) * (float) Math.PI * 0.05F * (float) (1 + Math.abs(var8 - 2)); + this.silverfishBodyParts[var8].rotationPointX = MathHelper.sin(par3 * 0.9F + (float) var8 * 0.15F * (float) Math.PI) * (float) Math.PI * 0.2F * (float) Math.abs(var8 - 2); + } + + this.silverfishWings[0].rotateAngleY = this.silverfishBodyParts[2].rotateAngleY; + this.silverfishWings[1].rotateAngleY = this.silverfishBodyParts[4].rotateAngleY; + this.silverfishWings[1].rotationPointX = this.silverfishBodyParts[4].rotationPointX; + this.silverfishWings[2].rotateAngleY = this.silverfishBodyParts[1].rotateAngleY; + this.silverfishWings[2].rotationPointX = this.silverfishBodyParts[1].rotationPointX; + } +} diff --git a/src/main/java/net/minecraft/src/ModelSkeleton.java b/src/main/java/net/minecraft/src/ModelSkeleton.java new file mode 100644 index 0000000..aa3d90b --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSkeleton.java @@ -0,0 +1,45 @@ +package net.minecraft.src; + +public class ModelSkeleton extends ModelZombie { + public ModelSkeleton() { + this(0.0F); + } + + public ModelSkeleton(float par1) { + super(par1, 0.0F, 64, 32); + this.bipedRightArm = new ModelRenderer(this, 40, 16); + this.bipedRightArm.addBox(-1.0F, -2.0F, -1.0F, 2, 12, 2, par1); + this.bipedRightArm.setRotationPoint(-5.0F, 2.0F, 0.0F); + this.bipedLeftArm = new ModelRenderer(this, 40, 16); + this.bipedLeftArm.mirror = true; + this.bipedLeftArm.addBox(-1.0F, -2.0F, -1.0F, 2, 12, 2, par1); + this.bipedLeftArm.setRotationPoint(5.0F, 2.0F, 0.0F); + this.bipedRightLeg = new ModelRenderer(this, 0, 16); + this.bipedRightLeg.addBox(-1.0F, 0.0F, -1.0F, 2, 12, 2, par1); + this.bipedRightLeg.setRotationPoint(-2.0F, 12.0F, 0.0F); + this.bipedLeftLeg = new ModelRenderer(this, 0, 16); + this.bipedLeftLeg.mirror = true; + this.bipedLeftLeg.addBox(-1.0F, 0.0F, -1.0F, 2, 12, 2, par1); + this.bipedLeftLeg.setRotationPoint(2.0F, 12.0F, 0.0F); + } + + /** + * Used for easily adding entity-dependent animations. The second and third + * float params here are the same second and third as in the setRotationAngles + * method. + */ + public void setLivingAnimations(EntityLiving par1EntityLiving, float par2, float par3, float par4) { + this.aimedBow = par1EntityLiving == null || !(par1EntityLiving instanceof EntitySkeleton) || ((EntitySkeleton) par1EntityLiving).getSkeletonType() == 1; + super.setLivingAnimations(par1EntityLiving, par2, par3, par4); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); + } +} diff --git a/src/main/java/net/minecraft/src/ModelSkeletonHead.java b/src/main/java/net/minecraft/src/ModelSkeletonHead.java new file mode 100644 index 0000000..afaa81f --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSkeletonHead.java @@ -0,0 +1,39 @@ +package net.minecraft.src; + + + +public class ModelSkeletonHead extends ModelBase { + public ModelRenderer skeletonHead; + + public ModelSkeletonHead() { + this(0, 35, 64, 64); + } + + public ModelSkeletonHead(int par1, int par2, int par3, int par4) { + this.textureWidth = par3; + this.textureHeight = par4; + this.skeletonHead = new ModelRenderer(this, par1, par2); + this.skeletonHead.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.0F); + this.skeletonHead.setRotationPoint(0.0F, 0.0F, 0.0F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + this.skeletonHead.render(par7); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); + this.skeletonHead.rotateAngleY = par4 / (180F / (float) Math.PI); + this.skeletonHead.rotateAngleX = par5 / (180F / (float) Math.PI); + } +} diff --git a/src/main/java/net/minecraft/src/ModelSlime.java b/src/main/java/net/minecraft/src/ModelSlime.java new file mode 100644 index 0000000..15d5f63 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSlime.java @@ -0,0 +1,45 @@ +package net.minecraft.src; + +public class ModelSlime extends ModelBase { + /** The slime's bodies, both the inside box and the outside box */ + ModelRenderer slimeBodies; + + /** The slime's right eye */ + ModelRenderer slimeRightEye; + + /** The slime's left eye */ + ModelRenderer slimeLeftEye; + + /** The slime's mouth */ + ModelRenderer slimeMouth; + + public ModelSlime(int par1) { + this.slimeBodies = new ModelRenderer(this, 0, par1); + this.slimeBodies.addBox(-4.0F, 16.0F, -4.0F, 8, 8, 8); + + if (par1 > 0) { + this.slimeBodies = new ModelRenderer(this, 0, par1); + this.slimeBodies.addBox(-3.0F, 17.0F, -3.0F, 6, 6, 6); + this.slimeRightEye = new ModelRenderer(this, 32, 0); + this.slimeRightEye.addBox(-3.25F, 18.0F, -3.5F, 2, 2, 2); + this.slimeLeftEye = new ModelRenderer(this, 32, 4); + this.slimeLeftEye.addBox(1.25F, 18.0F, -3.5F, 2, 2, 2); + this.slimeMouth = new ModelRenderer(this, 32, 8); + this.slimeMouth.addBox(0.0F, 21.0F, -3.5F, 1, 1, 1); + } + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + this.slimeBodies.render(par7); + + if (this.slimeRightEye != null) { + this.slimeRightEye.render(par7); + this.slimeLeftEye.render(par7); + this.slimeMouth.render(par7); + } + } +} diff --git a/src/main/java/net/minecraft/src/ModelSnowMan.java b/src/main/java/net/minecraft/src/ModelSnowMan.java new file mode 100644 index 0000000..7d4dba5 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSnowMan.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + + + +public class ModelSnowMan extends ModelBase { + public ModelRenderer body; + public ModelRenderer bottomBody; + public ModelRenderer head; + public ModelRenderer rightHand; + public ModelRenderer leftHand; + + public ModelSnowMan() { + float var1 = 4.0F; + float var2 = 0.0F; + this.head = (new ModelRenderer(this, 0, 0)).setTextureSize(64, 64); + this.head.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, var2 - 0.5F); + this.head.setRotationPoint(0.0F, 0.0F + var1, 0.0F); + this.rightHand = (new ModelRenderer(this, 32, 0)).setTextureSize(64, 64); + this.rightHand.addBox(-1.0F, 0.0F, -1.0F, 12, 2, 2, var2 - 0.5F); + this.rightHand.setRotationPoint(0.0F, 0.0F + var1 + 9.0F - 7.0F, 0.0F); + this.leftHand = (new ModelRenderer(this, 32, 0)).setTextureSize(64, 64); + this.leftHand.addBox(-1.0F, 0.0F, -1.0F, 12, 2, 2, var2 - 0.5F); + this.leftHand.setRotationPoint(0.0F, 0.0F + var1 + 9.0F - 7.0F, 0.0F); + this.body = (new ModelRenderer(this, 0, 16)).setTextureSize(64, 64); + this.body.addBox(-5.0F, -10.0F, -5.0F, 10, 10, 10, var2 - 0.5F); + this.body.setRotationPoint(0.0F, 0.0F + var1 + 9.0F, 0.0F); + this.bottomBody = (new ModelRenderer(this, 0, 36)).setTextureSize(64, 64); + this.bottomBody.addBox(-6.0F, -12.0F, -6.0F, 12, 12, 12, var2 - 0.5F); + this.bottomBody.setRotationPoint(0.0F, 0.0F + var1 + 20.0F, 0.0F); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); + this.head.rotateAngleY = par4 / (180F / (float) Math.PI); + this.head.rotateAngleX = par5 / (180F / (float) Math.PI); + this.body.rotateAngleY = par4 / (180F / (float) Math.PI) * 0.25F; + float var8 = MathHelper.sin(this.body.rotateAngleY); + float var9 = MathHelper.cos(this.body.rotateAngleY); + this.rightHand.rotateAngleZ = 1.0F; + this.leftHand.rotateAngleZ = -1.0F; + this.rightHand.rotateAngleY = 0.0F + this.body.rotateAngleY; + this.leftHand.rotateAngleY = (float) Math.PI + this.body.rotateAngleY; + this.rightHand.rotationPointX = var9 * 5.0F; + this.rightHand.rotationPointZ = -var8 * 5.0F; + this.leftHand.rotationPointX = -var9 * 5.0F; + this.leftHand.rotationPointZ = var8 * 5.0F; + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + this.body.render(par7); + this.bottomBody.render(par7); + this.head.render(par7); + this.rightHand.render(par7); + this.leftHand.render(par7); + } +} diff --git a/src/main/java/net/minecraft/src/ModelSpider.java b/src/main/java/net/minecraft/src/ModelSpider.java new file mode 100644 index 0000000..4b2ac52 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSpider.java @@ -0,0 +1,148 @@ +package net.minecraft.src; + + + +public class ModelSpider extends ModelBase { + /** The spider's head box */ + public ModelRenderer spiderHead; + + /** The spider's neck box */ + public ModelRenderer spiderNeck; + + /** The spider's body box */ + public ModelRenderer spiderBody; + + /** Spider's first leg */ + public ModelRenderer spiderLeg1; + + /** Spider's second leg */ + public ModelRenderer spiderLeg2; + + /** Spider's third leg */ + public ModelRenderer spiderLeg3; + + /** Spider's fourth leg */ + public ModelRenderer spiderLeg4; + + /** Spider's fifth leg */ + public ModelRenderer spiderLeg5; + + /** Spider's sixth leg */ + public ModelRenderer spiderLeg6; + + /** Spider's seventh leg */ + public ModelRenderer spiderLeg7; + + /** Spider's eight leg */ + public ModelRenderer spiderLeg8; + + public ModelSpider() { + float var1 = 0.0F; + byte var2 = 15; + this.spiderHead = new ModelRenderer(this, 32, 4); + this.spiderHead.addBox(-4.0F, -4.0F, -8.0F, 8, 8, 8, var1); + this.spiderHead.setRotationPoint(0.0F, (float) var2, -3.0F); + this.spiderNeck = new ModelRenderer(this, 0, 0); + this.spiderNeck.addBox(-3.0F, -3.0F, -3.0F, 6, 6, 6, var1); + this.spiderNeck.setRotationPoint(0.0F, (float) var2, 0.0F); + this.spiderBody = new ModelRenderer(this, 0, 12); + this.spiderBody.addBox(-5.0F, -4.0F, -6.0F, 10, 8, 12, var1); + this.spiderBody.setRotationPoint(0.0F, (float) var2, 9.0F); + this.spiderLeg1 = new ModelRenderer(this, 18, 0); + this.spiderLeg1.addBox(-15.0F, -1.0F, -1.0F, 16, 2, 2, var1); + this.spiderLeg1.setRotationPoint(-4.0F, (float) var2, 2.0F); + this.spiderLeg2 = new ModelRenderer(this, 18, 0); + this.spiderLeg2.addBox(-1.0F, -1.0F, -1.0F, 16, 2, 2, var1); + this.spiderLeg2.setRotationPoint(4.0F, (float) var2, 2.0F); + this.spiderLeg3 = new ModelRenderer(this, 18, 0); + this.spiderLeg3.addBox(-15.0F, -1.0F, -1.0F, 16, 2, 2, var1); + this.spiderLeg3.setRotationPoint(-4.0F, (float) var2, 1.0F); + this.spiderLeg4 = new ModelRenderer(this, 18, 0); + this.spiderLeg4.addBox(-1.0F, -1.0F, -1.0F, 16, 2, 2, var1); + this.spiderLeg4.setRotationPoint(4.0F, (float) var2, 1.0F); + this.spiderLeg5 = new ModelRenderer(this, 18, 0); + this.spiderLeg5.addBox(-15.0F, -1.0F, -1.0F, 16, 2, 2, var1); + this.spiderLeg5.setRotationPoint(-4.0F, (float) var2, 0.0F); + this.spiderLeg6 = new ModelRenderer(this, 18, 0); + this.spiderLeg6.addBox(-1.0F, -1.0F, -1.0F, 16, 2, 2, var1); + this.spiderLeg6.setRotationPoint(4.0F, (float) var2, 0.0F); + this.spiderLeg7 = new ModelRenderer(this, 18, 0); + this.spiderLeg7.addBox(-15.0F, -1.0F, -1.0F, 16, 2, 2, var1); + this.spiderLeg7.setRotationPoint(-4.0F, (float) var2, -1.0F); + this.spiderLeg8 = new ModelRenderer(this, 18, 0); + this.spiderLeg8.addBox(-1.0F, -1.0F, -1.0F, 16, 2, 2, var1); + this.spiderLeg8.setRotationPoint(4.0F, (float) var2, -1.0F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + this.spiderHead.render(par7); + this.spiderNeck.render(par7); + this.spiderBody.render(par7); + this.spiderLeg1.render(par7); + this.spiderLeg2.render(par7); + this.spiderLeg3.render(par7); + this.spiderLeg4.render(par7); + this.spiderLeg5.render(par7); + this.spiderLeg6.render(par7); + this.spiderLeg7.render(par7); + this.spiderLeg8.render(par7); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + this.spiderHead.rotateAngleY = par4 / (180F / (float) Math.PI); + this.spiderHead.rotateAngleX = par5 / (180F / (float) Math.PI); + float var8 = ((float) Math.PI / 4F); + this.spiderLeg1.rotateAngleZ = -var8; + this.spiderLeg2.rotateAngleZ = var8; + this.spiderLeg3.rotateAngleZ = -var8 * 0.74F; + this.spiderLeg4.rotateAngleZ = var8 * 0.74F; + this.spiderLeg5.rotateAngleZ = -var8 * 0.74F; + this.spiderLeg6.rotateAngleZ = var8 * 0.74F; + this.spiderLeg7.rotateAngleZ = -var8; + this.spiderLeg8.rotateAngleZ = var8; + float var9 = 0.0F; + float var10 = 0.3926991F; + this.spiderLeg1.rotateAngleY = var10 * 2.0F + var9; + this.spiderLeg2.rotateAngleY = -var10 * 2.0F - var9; + this.spiderLeg3.rotateAngleY = var10 * 1.0F + var9; + this.spiderLeg4.rotateAngleY = -var10 * 1.0F - var9; + this.spiderLeg5.rotateAngleY = -var10 * 1.0F + var9; + this.spiderLeg6.rotateAngleY = var10 * 1.0F - var9; + this.spiderLeg7.rotateAngleY = -var10 * 2.0F + var9; + this.spiderLeg8.rotateAngleY = var10 * 2.0F - var9; + float var11 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + 0.0F) * 0.4F) * par2; + float var12 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + (float) Math.PI) * 0.4F) * par2; + float var13 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + ((float) Math.PI / 2F)) * 0.4F) * par2; + float var14 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + ((float) Math.PI * 3F / 2F)) * 0.4F) * par2; + float var15 = Math.abs(MathHelper.sin(par1 * 0.6662F + 0.0F) * 0.4F) * par2; + float var16 = Math.abs(MathHelper.sin(par1 * 0.6662F + (float) Math.PI) * 0.4F) * par2; + float var17 = Math.abs(MathHelper.sin(par1 * 0.6662F + ((float) Math.PI / 2F)) * 0.4F) * par2; + float var18 = Math.abs(MathHelper.sin(par1 * 0.6662F + ((float) Math.PI * 3F / 2F)) * 0.4F) * par2; + this.spiderLeg1.rotateAngleY += var11; + this.spiderLeg2.rotateAngleY += -var11; + this.spiderLeg3.rotateAngleY += var12; + this.spiderLeg4.rotateAngleY += -var12; + this.spiderLeg5.rotateAngleY += var13; + this.spiderLeg6.rotateAngleY += -var13; + this.spiderLeg7.rotateAngleY += var14; + this.spiderLeg8.rotateAngleY += -var14; + this.spiderLeg1.rotateAngleZ += var15; + this.spiderLeg2.rotateAngleZ += -var15; + this.spiderLeg3.rotateAngleZ += var16; + this.spiderLeg4.rotateAngleZ += -var16; + this.spiderLeg5.rotateAngleZ += var17; + this.spiderLeg6.rotateAngleZ += -var17; + this.spiderLeg7.rotateAngleZ += var18; + this.spiderLeg8.rotateAngleZ += -var18; + } +} diff --git a/src/main/java/net/minecraft/src/ModelSquid.java b/src/main/java/net/minecraft/src/ModelSquid.java new file mode 100644 index 0000000..1f266db --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSquid.java @@ -0,0 +1,59 @@ +package net.minecraft.src; + + + +public class ModelSquid extends ModelBase { + /** The squid's body */ + ModelRenderer squidBody; + + /** The squid's tentacles */ + ModelRenderer[] squidTentacles = new ModelRenderer[8]; + + public ModelSquid() { + byte var1 = -16; + this.squidBody = new ModelRenderer(this, 0, 0); + this.squidBody.addBox(-6.0F, -8.0F, -6.0F, 12, 16, 12); + this.squidBody.rotationPointY += (float) (24 + var1); + + for (int var2 = 0; var2 < this.squidTentacles.length; ++var2) { + this.squidTentacles[var2] = new ModelRenderer(this, 48, 0); + double var3 = (double) var2 * Math.PI * 2.0D / (double) this.squidTentacles.length; + float var5 = (float) Math.cos(var3) * 5.0F; + float var6 = (float) Math.sin(var3) * 5.0F; + this.squidTentacles[var2].addBox(-1.0F, 0.0F, -1.0F, 2, 18, 2); + this.squidTentacles[var2].rotationPointX = var5; + this.squidTentacles[var2].rotationPointZ = var6; + this.squidTentacles[var2].rotationPointY = (float) (31 + var1); + var3 = (double) var2 * Math.PI * -2.0D / (double) this.squidTentacles.length + (Math.PI / 2D); + this.squidTentacles[var2].rotateAngleY = (float) var3; + } + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + ModelRenderer[] var8 = this.squidTentacles; + int var9 = var8.length; + + for (int var10 = 0; var10 < var9; ++var10) { + ModelRenderer var11 = var8[var10]; + var11.rotateAngleX = par3; + } + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + this.squidBody.render(par7); + + for (int var8 = 0; var8 < this.squidTentacles.length; ++var8) { + this.squidTentacles[var8].render(par7); + } + } +} diff --git a/src/main/java/net/minecraft/src/ModelVillager.java b/src/main/java/net/minecraft/src/ModelVillager.java new file mode 100644 index 0000000..c0f6a16 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelVillager.java @@ -0,0 +1,81 @@ +package net.minecraft.src; + + + +public class ModelVillager extends ModelBase { + /** The head box of the VillagerModel */ + public ModelRenderer villagerHead; + + /** The body of the VillagerModel */ + public ModelRenderer villagerBody; + + /** The arms of the VillagerModel */ + public ModelRenderer villagerArms; + + /** The right leg of the VillagerModel */ + public ModelRenderer rightVillagerLeg; + + /** The left leg of the VillagerModel */ + public ModelRenderer leftVillagerLeg; + public ModelRenderer field_82898_f; + + public ModelVillager(float par1) { + this(par1, 0.0F, 64, 64); + } + + public ModelVillager(float par1, float par2, int par3, int par4) { + this.villagerHead = (new ModelRenderer(this)).setTextureSize(par3, par4); + this.villagerHead.setRotationPoint(0.0F, 0.0F + par2, 0.0F); + this.villagerHead.setTextureOffset(0, 0).addBox(-4.0F, -10.0F, -4.0F, 8, 10, 8, par1); + this.field_82898_f = (new ModelRenderer(this)).setTextureSize(par3, par4); + this.field_82898_f.setRotationPoint(0.0F, par2 - 2.0F, 0.0F); + this.field_82898_f.setTextureOffset(24, 0).addBox(-1.0F, -1.0F, -6.0F, 2, 4, 2, par1); + this.villagerHead.addChild(this.field_82898_f); + this.villagerBody = (new ModelRenderer(this)).setTextureSize(par3, par4); + this.villagerBody.setRotationPoint(0.0F, 0.0F + par2, 0.0F); + this.villagerBody.setTextureOffset(16, 20).addBox(-4.0F, 0.0F, -3.0F, 8, 12, 6, par1); + this.villagerBody.setTextureOffset(0, 38).addBox(-4.0F, 0.0F, -3.0F, 8, 18, 6, par1 + 0.5F); + this.villagerArms = (new ModelRenderer(this)).setTextureSize(par3, par4); + this.villagerArms.setRotationPoint(0.0F, 0.0F + par2 + 2.0F, 0.0F); + this.villagerArms.setTextureOffset(44, 22).addBox(-8.0F, -2.0F, -2.0F, 4, 8, 4, par1); + this.villagerArms.setTextureOffset(44, 22).addBox(4.0F, -2.0F, -2.0F, 4, 8, 4, par1); + this.villagerArms.setTextureOffset(40, 38).addBox(-4.0F, 2.0F, -2.0F, 8, 4, 4, par1); + this.rightVillagerLeg = (new ModelRenderer(this, 0, 22)).setTextureSize(par3, par4); + this.rightVillagerLeg.setRotationPoint(-2.0F, 12.0F + par2, 0.0F); + this.rightVillagerLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, par1); + this.leftVillagerLeg = (new ModelRenderer(this, 0, 22)).setTextureSize(par3, par4); + this.leftVillagerLeg.mirror = true; + this.leftVillagerLeg.setRotationPoint(2.0F, 12.0F + par2, 0.0F); + this.leftVillagerLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, par1); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + this.villagerHead.render(par7); + this.villagerBody.render(par7); + this.rightVillagerLeg.render(par7); + this.leftVillagerLeg.render(par7); + this.villagerArms.render(par7); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + this.villagerHead.rotateAngleY = par4 / (180F / (float) Math.PI); + this.villagerHead.rotateAngleX = par5 / (180F / (float) Math.PI); + this.villagerArms.rotationPointY = 3.0F; + this.villagerArms.rotationPointZ = -1.0F; + this.villagerArms.rotateAngleX = -0.75F; + this.rightVillagerLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2 * 0.5F; + this.leftVillagerLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float) Math.PI) * 1.4F * par2 * 0.5F; + this.rightVillagerLeg.rotateAngleY = 0.0F; + this.leftVillagerLeg.rotateAngleY = 0.0F; + } +} diff --git a/src/main/java/net/minecraft/src/ModelWitch.java b/src/main/java/net/minecraft/src/ModelWitch.java new file mode 100644 index 0000000..d07e000 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelWitch.java @@ -0,0 +1,63 @@ +package net.minecraft.src; + + + +public class ModelWitch extends ModelVillager { + public boolean field_82900_g = false; + private ModelRenderer field_82901_h = (new ModelRenderer(this)).setTextureSize(64, 128); + private ModelRenderer witchHat; + + public ModelWitch(float par1) { + super(par1, 0.0F, 64, 128); + this.field_82901_h.setRotationPoint(0.0F, -2.0F, 0.0F); + this.field_82901_h.setTextureOffset(0, 0).addBox(0.0F, 3.0F, -6.75F, 1, 1, 1, -0.25F); + this.field_82898_f.addChild(this.field_82901_h); + this.witchHat = (new ModelRenderer(this)).setTextureSize(64, 128); + this.witchHat.setRotationPoint(-5.0F, -10.03125F, -5.0F); + this.witchHat.setTextureOffset(0, 64).addBox(0.0F, 0.0F, 0.0F, 10, 2, 10); + this.villagerHead.addChild(this.witchHat); + ModelRenderer var2 = (new ModelRenderer(this)).setTextureSize(64, 128); + var2.setRotationPoint(1.75F, -4.0F, 2.0F); + var2.setTextureOffset(0, 76).addBox(0.0F, 0.0F, 0.0F, 7, 4, 7); + var2.rotateAngleX = -0.05235988F; + var2.rotateAngleZ = 0.02617994F; + this.witchHat.addChild(var2); + ModelRenderer var3 = (new ModelRenderer(this)).setTextureSize(64, 128); + var3.setRotationPoint(1.75F, -4.0F, 2.0F); + var3.setTextureOffset(0, 87).addBox(0.0F, 0.0F, 0.0F, 4, 4, 4); + var3.rotateAngleX = -0.10471976F; + var3.rotateAngleZ = 0.05235988F; + var2.addChild(var3); + ModelRenderer var4 = (new ModelRenderer(this)).setTextureSize(64, 128); + var4.setRotationPoint(1.75F, -2.0F, 2.0F); + var4.setTextureOffset(0, 95).addBox(0.0F, 0.0F, 0.0F, 1, 2, 1, 0.25F); + var4.rotateAngleX = -0.20943952F; + var4.rotateAngleZ = 0.10471976F; + var3.addChild(var4); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); + this.field_82898_f.field_82906_o = this.field_82898_f.field_82908_p = this.field_82898_f.field_82907_q = 0.0F; + float var8 = 0.01F * (float) (par7Entity.entityId % 10); + this.field_82898_f.rotateAngleX = MathHelper.sin((float) par7Entity.ticksExisted * var8) * 4.5F * (float) Math.PI / 180.0F; + this.field_82898_f.rotateAngleY = 0.0F; + this.field_82898_f.rotateAngleZ = MathHelper.cos((float) par7Entity.ticksExisted * var8) * 2.5F * (float) Math.PI / 180.0F; + + if (this.field_82900_g) { + this.field_82898_f.rotateAngleX = -0.9F; + this.field_82898_f.field_82907_q = -0.09375F; + this.field_82898_f.field_82908_p = 0.1875F; + } + } + + public int func_82899_a() { + return 0; + } +} diff --git a/src/main/java/net/minecraft/src/ModelWither.java b/src/main/java/net/minecraft/src/ModelWither.java new file mode 100644 index 0000000..e6c278a --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelWither.java @@ -0,0 +1,92 @@ +package net.minecraft.src; + + + +public class ModelWither extends ModelBase { + private ModelRenderer[] field_82905_a; + private ModelRenderer[] field_82904_b; + + public ModelWither() { + this.textureWidth = 64; + this.textureHeight = 64; + this.field_82905_a = new ModelRenderer[3]; + this.field_82905_a[0] = new ModelRenderer(this, 0, 16); + this.field_82905_a[0].addBox(-10.0F, 3.9F, -0.5F, 20, 3, 3); + this.field_82905_a[1] = (new ModelRenderer(this)).setTextureSize(this.textureWidth, this.textureHeight); + this.field_82905_a[1].setRotationPoint(-2.0F, 6.9F, -0.5F); + this.field_82905_a[1].setTextureOffset(0, 22).addBox(0.0F, 0.0F, 0.0F, 3, 10, 3); + this.field_82905_a[1].setTextureOffset(24, 22).addBox(-4.0F, 1.5F, 0.5F, 11, 2, 2); + this.field_82905_a[1].setTextureOffset(24, 22).addBox(-4.0F, 4.0F, 0.5F, 11, 2, 2); + this.field_82905_a[1].setTextureOffset(24, 22).addBox(-4.0F, 6.5F, 0.5F, 11, 2, 2); + this.field_82905_a[2] = new ModelRenderer(this, 12, 22); + this.field_82905_a[2].addBox(0.0F, 0.0F, 0.0F, 3, 6, 3); + this.field_82904_b = new ModelRenderer[3]; + this.field_82904_b[0] = new ModelRenderer(this, 0, 0); + this.field_82904_b[0].addBox(-4.0F, -4.0F, -4.0F, 8, 8, 8); + this.field_82904_b[1] = new ModelRenderer(this, 32, 0); + this.field_82904_b[1].addBox(-4.0F, -4.0F, -4.0F, 6, 6, 6); + this.field_82904_b[1].rotationPointX = -8.0F; + this.field_82904_b[1].rotationPointY = 4.0F; + this.field_82904_b[2] = new ModelRenderer(this, 32, 0); + this.field_82904_b[2].addBox(-4.0F, -4.0F, -4.0F, 6, 6, 6); + this.field_82904_b[2].rotationPointX = 10.0F; + this.field_82904_b[2].rotationPointY = 4.0F; + } + + public int func_82903_a() { + return 32; + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + ModelRenderer[] var8 = this.field_82904_b; + int var9 = var8.length; + int var10; + ModelRenderer var11; + + for (var10 = 0; var10 < var9; ++var10) { + var11 = var8[var10]; + var11.render(par7); + } + + var8 = this.field_82905_a; + var9 = var8.length; + + for (var10 = 0; var10 < var9; ++var10) { + var11 = var8[var10]; + var11.render(par7); + } + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + float var8 = MathHelper.cos(par3 * 0.1F); + this.field_82905_a[1].rotateAngleX = (0.065F + 0.05F * var8) * (float) Math.PI; + this.field_82905_a[2].setRotationPoint(-2.0F, 6.9F + MathHelper.cos(this.field_82905_a[1].rotateAngleX) * 10.0F, -0.5F + MathHelper.sin(this.field_82905_a[1].rotateAngleX) * 10.0F); + this.field_82905_a[2].rotateAngleX = (0.265F + 0.1F * var8) * (float) Math.PI; + this.field_82904_b[0].rotateAngleY = par4 / (180F / (float) Math.PI); + this.field_82904_b[0].rotateAngleX = par5 / (180F / (float) Math.PI); + } + + /** + * Used for easily adding entity-dependent animations. The second and third + * float params here are the same second and third as in the setRotationAngles + * method. + */ + public void setLivingAnimations(EntityLiving par1EntityLiving, float par2, float par3, float par4) { + EntityWither var5 = (EntityWither) par1EntityLiving; + + for (int var6 = 1; var6 < 3; ++var6) { + this.field_82904_b[var6].rotateAngleY = (var5.func_82207_a(var6 - 1) - par1EntityLiving.renderYawOffset) / (180F / (float) Math.PI); + this.field_82904_b[var6].rotateAngleX = var5.func_82210_r(var6 - 1) / (180F / (float) Math.PI); + } + } +} diff --git a/src/main/java/net/minecraft/src/ModelWolf.java b/src/main/java/net/minecraft/src/ModelWolf.java new file mode 100644 index 0000000..89cf401 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelWolf.java @@ -0,0 +1,162 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; + + +public class ModelWolf extends ModelBase { + /** main box for the wolf head */ + public ModelRenderer wolfHeadMain; + + /** The wolf's body */ + public ModelRenderer wolfBody; + + /** Wolf'se first leg */ + public ModelRenderer wolfLeg1; + + /** Wolf's second leg */ + public ModelRenderer wolfLeg2; + + /** Wolf's third leg */ + public ModelRenderer wolfLeg3; + + /** Wolf's fourth leg */ + public ModelRenderer wolfLeg4; + + /** The wolf's tail */ + ModelRenderer wolfTail; + + /** The wolf's mane */ + ModelRenderer wolfMane; + + public ModelWolf() { + float var1 = 0.0F; + float var2 = 13.5F; + this.wolfHeadMain = new ModelRenderer(this, 0, 0); + this.wolfHeadMain.addBox(-3.0F, -3.0F, -2.0F, 6, 6, 4, var1); + this.wolfHeadMain.setRotationPoint(-1.0F, var2, -7.0F); + this.wolfBody = new ModelRenderer(this, 18, 14); + this.wolfBody.addBox(-4.0F, -2.0F, -3.0F, 6, 9, 6, var1); + this.wolfBody.setRotationPoint(0.0F, 14.0F, 2.0F); + this.wolfMane = new ModelRenderer(this, 21, 0); + this.wolfMane.addBox(-4.0F, -3.0F, -3.0F, 8, 6, 7, var1); + this.wolfMane.setRotationPoint(-1.0F, 14.0F, 2.0F); + this.wolfLeg1 = new ModelRenderer(this, 0, 18); + this.wolfLeg1.addBox(-1.0F, 0.0F, -1.0F, 2, 8, 2, var1); + this.wolfLeg1.setRotationPoint(-2.5F, 16.0F, 7.0F); + this.wolfLeg2 = new ModelRenderer(this, 0, 18); + this.wolfLeg2.addBox(-1.0F, 0.0F, -1.0F, 2, 8, 2, var1); + this.wolfLeg2.setRotationPoint(0.5F, 16.0F, 7.0F); + this.wolfLeg3 = new ModelRenderer(this, 0, 18); + this.wolfLeg3.addBox(-1.0F, 0.0F, -1.0F, 2, 8, 2, var1); + this.wolfLeg3.setRotationPoint(-2.5F, 16.0F, -4.0F); + this.wolfLeg4 = new ModelRenderer(this, 0, 18); + this.wolfLeg4.addBox(-1.0F, 0.0F, -1.0F, 2, 8, 2, var1); + this.wolfLeg4.setRotationPoint(0.5F, 16.0F, -4.0F); + this.wolfTail = new ModelRenderer(this, 9, 18); + this.wolfTail.addBox(-1.0F, 0.0F, -1.0F, 2, 8, 2, var1); + this.wolfTail.setRotationPoint(-1.0F, 12.0F, 8.0F); + this.wolfHeadMain.setTextureOffset(16, 14).addBox(-3.0F, -5.0F, 0.0F, 2, 2, 1, var1); + this.wolfHeadMain.setTextureOffset(16, 14).addBox(1.0F, -5.0F, 0.0F, 2, 2, 1, var1); + this.wolfHeadMain.setTextureOffset(0, 10).addBox(-1.5F, 0.0F, -5.0F, 3, 3, 4, var1); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { + super.render(par1Entity, par2, par3, par4, par5, par6, par7); + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + + if (this.isChild) { + float var8 = 2.0F; + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(0.0F, 5.0F * par7, 2.0F * par7); + this.wolfHeadMain.renderWithRotation(par7); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glScalef(1.0F / var8, 1.0F / var8, 1.0F / var8); + EaglerAdapter.glTranslatef(0.0F, 24.0F * par7, 0.0F); + this.wolfBody.render(par7); + this.wolfLeg1.render(par7); + this.wolfLeg2.render(par7); + this.wolfLeg3.render(par7); + this.wolfLeg4.render(par7); + this.wolfTail.renderWithRotation(par7); + this.wolfMane.render(par7); + EaglerAdapter.glPopMatrix(); + } else { + this.wolfHeadMain.renderWithRotation(par7); + this.wolfBody.render(par7); + this.wolfLeg1.render(par7); + this.wolfLeg2.render(par7); + this.wolfLeg3.render(par7); + this.wolfLeg4.render(par7); + this.wolfTail.renderWithRotation(par7); + this.wolfMane.render(par7); + } + } + + /** + * Used for easily adding entity-dependent animations. The second and third + * float params here are the same second and third as in the setRotationAngles + * method. + */ + public void setLivingAnimations(EntityLiving par1EntityLiving, float par2, float par3, float par4) { + EntityWolf var5 = (EntityWolf) par1EntityLiving; + + if (var5.isAngry()) { + this.wolfTail.rotateAngleY = 0.0F; + } else { + this.wolfTail.rotateAngleY = MathHelper.cos(par2 * 0.6662F) * 1.4F * par3; + } + + if (var5.isSitting()) { + this.wolfMane.setRotationPoint(-1.0F, 16.0F, -3.0F); + this.wolfMane.rotateAngleX = ((float) Math.PI * 2F / 5F); + this.wolfMane.rotateAngleY = 0.0F; + this.wolfBody.setRotationPoint(0.0F, 18.0F, 0.0F); + this.wolfBody.rotateAngleX = ((float) Math.PI / 4F); + this.wolfTail.setRotationPoint(-1.0F, 21.0F, 6.0F); + this.wolfLeg1.setRotationPoint(-2.5F, 22.0F, 2.0F); + this.wolfLeg1.rotateAngleX = ((float) Math.PI * 3F / 2F); + this.wolfLeg2.setRotationPoint(0.5F, 22.0F, 2.0F); + this.wolfLeg2.rotateAngleX = ((float) Math.PI * 3F / 2F); + this.wolfLeg3.rotateAngleX = 5.811947F; + this.wolfLeg3.setRotationPoint(-2.49F, 17.0F, -4.0F); + this.wolfLeg4.rotateAngleX = 5.811947F; + this.wolfLeg4.setRotationPoint(0.51F, 17.0F, -4.0F); + } else { + this.wolfBody.setRotationPoint(0.0F, 14.0F, 2.0F); + this.wolfBody.rotateAngleX = ((float) Math.PI / 2F); + this.wolfMane.setRotationPoint(-1.0F, 14.0F, -3.0F); + this.wolfMane.rotateAngleX = this.wolfBody.rotateAngleX; + this.wolfTail.setRotationPoint(-1.0F, 12.0F, 8.0F); + this.wolfLeg1.setRotationPoint(-2.5F, 16.0F, 7.0F); + this.wolfLeg2.setRotationPoint(0.5F, 16.0F, 7.0F); + this.wolfLeg3.setRotationPoint(-2.5F, 16.0F, -4.0F); + this.wolfLeg4.setRotationPoint(0.5F, 16.0F, -4.0F); + this.wolfLeg1.rotateAngleX = MathHelper.cos(par2 * 0.6662F) * 1.4F * par3; + this.wolfLeg2.rotateAngleX = MathHelper.cos(par2 * 0.6662F + (float) Math.PI) * 1.4F * par3; + this.wolfLeg3.rotateAngleX = MathHelper.cos(par2 * 0.6662F + (float) Math.PI) * 1.4F * par3; + this.wolfLeg4.rotateAngleX = MathHelper.cos(par2 * 0.6662F) * 1.4F * par3; + } + + this.wolfHeadMain.rotateAngleZ = var5.getInterestedAngle(par4) + var5.getShakeAngle(par4, 0.0F); + this.wolfMane.rotateAngleZ = var5.getShakeAngle(par4, -0.08F); + this.wolfBody.rotateAngleZ = var5.getShakeAngle(par4, -0.16F); + this.wolfTail.rotateAngleZ = var5.getShakeAngle(par4, -0.2F); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); + this.wolfHeadMain.rotateAngleX = par5 / (180F / (float) Math.PI); + this.wolfHeadMain.rotateAngleY = par4 / (180F / (float) Math.PI); + this.wolfTail.rotateAngleX = par3; + } +} diff --git a/src/main/java/net/minecraft/src/ModelZombie.java b/src/main/java/net/minecraft/src/ModelZombie.java new file mode 100644 index 0000000..060ff94 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelZombie.java @@ -0,0 +1,41 @@ +package net.minecraft.src; + + + +public class ModelZombie extends ModelBiped { + public ModelZombie() { + this(0.0F, false); + } + + protected ModelZombie(float par1, float par2, int par3, int par4) { + super(par1, par2, par3, par4); + } + + public ModelZombie(float par1, boolean par2) { + super(par1, 0.0F, 64, par2 ? 32 : 64); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); + float var8 = MathHelper.sin(this.onGround * (float) Math.PI); + float var9 = MathHelper.sin((1.0F - (1.0F - this.onGround) * (1.0F - this.onGround)) * (float) Math.PI); + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + this.bipedRightArm.rotateAngleY = -(0.1F - var8 * 0.6F); + this.bipedLeftArm.rotateAngleY = 0.1F - var8 * 0.6F; + this.bipedRightArm.rotateAngleX = -((float) Math.PI / 2F); + this.bipedLeftArm.rotateAngleX = -((float) Math.PI / 2F); + this.bipedRightArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.bipedLeftArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.067F) * 0.05F; + } +} diff --git a/src/main/java/net/minecraft/src/ModelZombieVillager.java b/src/main/java/net/minecraft/src/ModelZombieVillager.java new file mode 100644 index 0000000..8faa3e6 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelZombieVillager.java @@ -0,0 +1,52 @@ +package net.minecraft.src; + + + +public class ModelZombieVillager extends ModelBiped { + public ModelZombieVillager() { + this(0.0F, 0.0F, false); + } + + public ModelZombieVillager(float par1, float par2, boolean par3) { + super(par1, 0.0F, 64, par3 ? 32 : 64); + + if (par3) { + this.bipedHead = new ModelRenderer(this, 0, 0); + this.bipedHead.addBox(-4.0F, -10.0F, -4.0F, 8, 6, 8, par1); + this.bipedHead.setRotationPoint(0.0F, 0.0F + par2, 0.0F); + } else { + this.bipedHead = new ModelRenderer(this); + this.bipedHead.setRotationPoint(0.0F, 0.0F + par2, 0.0F); + this.bipedHead.setTextureOffset(0, 32).addBox(-4.0F, -10.0F, -4.0F, 8, 10, 8, par1); + this.bipedHead.setTextureOffset(24, 32).addBox(-1.0F, -3.0F, -6.0F, 2, 4, 2, par1); + } + } + + public int func_82897_a() { + return 10; + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) { + super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); + float var8 = MathHelper.sin(this.onGround * (float) Math.PI); + float var9 = MathHelper.sin((1.0F - (1.0F - this.onGround) * (1.0F - this.onGround)) * (float) Math.PI); + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + this.bipedRightArm.rotateAngleY = -(0.1F - var8 * 0.6F); + this.bipedLeftArm.rotateAngleY = 0.1F - var8 * 0.6F; + this.bipedRightArm.rotateAngleX = -((float) Math.PI / 2F); + this.bipedLeftArm.rotateAngleX = -((float) Math.PI / 2F); + this.bipedRightArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.bipedLeftArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.067F) * 0.05F; + } +} diff --git a/src/main/java/net/minecraft/src/MouseFilter.java b/src/main/java/net/minecraft/src/MouseFilter.java new file mode 100644 index 0000000..c14a3e9 --- /dev/null +++ b/src/main/java/net/minecraft/src/MouseFilter.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +public class MouseFilter { + private float field_76336_a; + private float field_76334_b; + private float field_76335_c; + + /** + * Smooths mouse input + */ + public float smooth(float par1, float par2) { + this.field_76336_a += par1; + par1 = (this.field_76336_a - this.field_76334_b) * par2; + this.field_76335_c += (par1 - this.field_76335_c) * 0.5F; + + if (par1 > 0.0F && par1 > this.field_76335_c || par1 < 0.0F && par1 < this.field_76335_c) { + par1 = this.field_76335_c; + } + + this.field_76334_b += par1; + return par1; + } +} diff --git a/src/main/java/net/minecraft/src/MouseHelper.java b/src/main/java/net/minecraft/src/MouseHelper.java new file mode 100644 index 0000000..9f6bd03 --- /dev/null +++ b/src/main/java/net/minecraft/src/MouseHelper.java @@ -0,0 +1,44 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.minecraft.client.Minecraft; + +public class MouseHelper { + private final GameSettings field_85184_d; + + /** Mouse delta X this frame */ + public int deltaX; + + /** Mouse delta Y this frame */ + public int deltaY; + + public MouseHelper(GameSettings par2GameSettings) { + this.field_85184_d = par2GameSettings; + } + + /** + * Grabs the mouse cursor it doesn't move and isn't seen. + */ + public void grabMouseCursor() { + EaglerAdapter.mouseSetGrabbed(true); + this.deltaX = 0; + this.deltaY = 0; + } + + /** + * Ungrabs the mouse cursor so it can be moved and set it to the center of the + * screen + */ + public void ungrabMouseCursor() { + int var1 = Minecraft.getMinecraft().displayWidth; + int var2 = Minecraft.getMinecraft().displayHeight; + + EaglerAdapter.mouseSetCursorPosition(var1 / 2, var2 / 2); + EaglerAdapter.mouseSetGrabbed(false); + } + + public void mouseXYChange() { + this.deltaX = EaglerAdapter.mouseGetDX(); + this.deltaY = EaglerAdapter.mouseGetDY(); + } +} diff --git a/src/main/java/net/minecraft/src/MovementInput.java b/src/main/java/net/minecraft/src/MovementInput.java new file mode 100644 index 0000000..bdbfc4a --- /dev/null +++ b/src/main/java/net/minecraft/src/MovementInput.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +public class MovementInput { + /** + * The speed at which the player is strafing. Postive numbers to the left and + * negative to the right. + */ + public float moveStrafe = 0.0F; + + /** + * The speed at which the player is moving forward. Negative numbers will move + * backwards. + */ + public float moveForward = 0.0F; + public boolean jump = false; + public boolean sneak = false; + + public void updatePlayerMoveState() { + } +} diff --git a/src/main/java/net/minecraft/src/MovementInputFromOptions.java b/src/main/java/net/minecraft/src/MovementInputFromOptions.java new file mode 100644 index 0000000..0ad6f74 --- /dev/null +++ b/src/main/java/net/minecraft/src/MovementInputFromOptions.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + +public class MovementInputFromOptions extends MovementInput { + private GameSettings gameSettings; + + public MovementInputFromOptions(GameSettings par1GameSettings) { + this.gameSettings = par1GameSettings; + } + + public void updatePlayerMoveState() { + this.moveStrafe = 0.0F; + this.moveForward = 0.0F; + + if (this.gameSettings.keyBindForward.pressed) { + ++this.moveForward; + } + + if (this.gameSettings.keyBindBack.pressed) { + --this.moveForward; + } + + if (this.gameSettings.keyBindLeft.pressed) { + ++this.moveStrafe; + } + + if (this.gameSettings.keyBindRight.pressed) { + --this.moveStrafe; + } + + this.jump = this.gameSettings.keyBindJump.pressed; + this.sneak = this.gameSettings.keyBindSneak.pressed; + + if (this.sneak) { + this.moveStrafe = (float) ((double) this.moveStrafe * 0.3D); + this.moveForward = (float) ((double) this.moveForward * 0.3D); + } + } +} diff --git a/src/main/java/net/minecraft/src/MovingObjectPosition.java b/src/main/java/net/minecraft/src/MovingObjectPosition.java new file mode 100644 index 0000000..c380841 --- /dev/null +++ b/src/main/java/net/minecraft/src/MovingObjectPosition.java @@ -0,0 +1,42 @@ +package net.minecraft.src; + +public class MovingObjectPosition { + /** What type of ray trace hit was this? 0 = block, 1 = entity */ + public EnumMovingObjectType typeOfHit; + + /** x coordinate of the block ray traced against */ + public int blockX; + + /** y coordinate of the block ray traced against */ + public int blockY; + + /** z coordinate of the block ray traced against */ + public int blockZ; + + /** + * Which side was hit. If its -1 then it went the full length of the ray trace. + * Bottom = 0, Top = 1, East = 2, West = 3, North = 4, South = 5. + */ + public int sideHit; + + /** The vector position of the hit */ + public Vec3 hitVec; + + /** The hit entity */ + public Entity entityHit; + + public MovingObjectPosition(int par1, int par2, int par3, int par4, Vec3 par5Vec3) { + this.typeOfHit = EnumMovingObjectType.TILE; + this.blockX = par1; + this.blockY = par2; + this.blockZ = par3; + this.sideHit = par4; + this.hitVec = par5Vec3.myVec3LocalPool.getVecFromPool(par5Vec3.xCoord, par5Vec3.yCoord, par5Vec3.zCoord); + } + + public MovingObjectPosition(Entity par1Entity) { + this.typeOfHit = EnumMovingObjectType.ENTITY; + this.entityHit = par1Entity; + this.hitVec = par1Entity.worldObj.getWorldVec3Pool().getVecFromPool(par1Entity.posX, par1Entity.posY, par1Entity.posZ); + } +} diff --git a/src/main/java/net/minecraft/src/NBTBase.java b/src/main/java/net/minecraft/src/NBTBase.java new file mode 100644 index 0000000..288d741 --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTBase.java @@ -0,0 +1,198 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public abstract class NBTBase { + public static final String[] NBTTypes = new String[] { "END", "BYTE", "SHORT", "INT", "LONG", "FLOAT", "DOUBLE", "BYTE[]", "STRING", "LIST", "COMPOUND", "INT[]" }; + + /** The UTF string key used to lookup values. */ + private String name; + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + abstract void write(DataOutput var1) throws IOException; + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + abstract void load(DataInput var1) throws IOException; + + /** + * Gets the type byte for the tag. + */ + public abstract byte getId(); + + protected NBTBase(String par1Str) { + if (par1Str == null) { + this.name = ""; + } else { + this.name = par1Str; + } + } + + /** + * Sets the name for this tag and returns this for convenience. + */ + public NBTBase setName(String par1Str) { + if (par1Str == null) { + this.name = ""; + } else { + this.name = par1Str; + } + + return this; + } + + /** + * Gets the name corresponding to the tag, or an empty string if none set. + */ + public String getName() { + return this.name == null ? "" : this.name; + } + + /** + * Reads and returns a tag from the given DataInput, or the End tag if no tag + * could be read. + */ + public static NBTBase readNamedTag(DataInput par0DataInput) throws IOException { + byte var1 = par0DataInput.readByte(); + + if (var1 == 0) { + return new NBTTagEnd(); + } else { + String var2 = par0DataInput.readUTF(); + NBTBase var3 = newTag(var1, var2); + var3.load(par0DataInput); + return var3; + } + } + + /** + * Writes the specified tag to the given DataOutput, writing the type byte, the + * UTF string key and then calling the tag to write its data. + */ + public static void writeNamedTag(NBTBase par0NBTBase, DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeByte(par0NBTBase.getId()); + + if (par0NBTBase.getId() != 0) { + par1DataOutput.writeUTF(par0NBTBase.getName()); + par0NBTBase.write(par1DataOutput); + } + } + + /** + * Creates and returns a new tag of the specified type, or null if invalid. + */ + public static NBTBase newTag(byte par0, String par1Str) { + switch (par0) { + case 0: + return new NBTTagEnd(); + + case 1: + return new NBTTagByte(par1Str); + + case 2: + return new NBTTagShort(par1Str); + + case 3: + return new NBTTagInt(par1Str); + + case 4: + return new NBTTagLong(par1Str); + + case 5: + return new NBTTagFloat(par1Str); + + case 6: + return new NBTTagDouble(par1Str); + + case 7: + return new NBTTagByteArray(par1Str); + + case 8: + return new NBTTagString(par1Str); + + case 9: + return new NBTTagList(par1Str); + + case 10: + return new NBTTagCompound(par1Str); + + case 11: + return new NBTTagIntArray(par1Str); + + default: + return null; + } + } + + /** + * Returns the string name of a tag with the specified type, or 'UNKNOWN' if + * invalid. + */ + public static String getTagName(byte par0) { + switch (par0) { + 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"; + + default: + return "UNKNOWN"; + } + } + + /** + * Creates a clone of the tag. + */ + public abstract NBTBase copy(); + + public boolean equals(Object par1Obj) { + if (!(par1Obj instanceof NBTBase)) { + return false; + } else { + NBTBase var2 = (NBTBase) par1Obj; + return this.getId() != var2.getId() ? false : ((this.name != null || var2.name == null) && (this.name == null || var2.name != null) ? this.name == null || this.name.equals(var2.name) : false); + } + } + + public int hashCode() { + return this.name.hashCode() ^ this.getId(); + } +} diff --git a/src/main/java/net/minecraft/src/NBTTagByte.java b/src/main/java/net/minecraft/src/NBTTagByte.java new file mode 100644 index 0000000..b0f43ee --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagByte.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagByte extends NBTBase { + /** The byte value for the tag. */ + public byte data; + + public NBTTagByte(String par1Str) { + super(par1Str); + } + + public NBTTagByte(String par1Str, byte par2) { + super(par1Str); + this.data = par2; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeByte(this.data); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.data = par1DataInput.readByte(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 1; + } + + public String toString() { + return "" + this.data; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagByte(this.getName(), this.data); + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagByte var2 = (NBTTagByte) par1Obj; + return this.data == var2.data; + } else { + return false; + } + } + + public int hashCode() { + return super.hashCode() ^ this.data; + } +} diff --git a/src/main/java/net/minecraft/src/NBTTagByteArray.java b/src/main/java/net/minecraft/src/NBTTagByteArray.java new file mode 100644 index 0000000..9e6ffad --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagByteArray.java @@ -0,0 +1,67 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Arrays; + +public class NBTTagByteArray extends NBTBase { + /** The byte array stored in the tag. */ + public byte[] byteArray; + + public NBTTagByteArray(String par1Str) { + super(par1Str); + } + + public NBTTagByteArray(String par1Str, byte[] par2ArrayOfByte) { + super(par1Str); + this.byteArray = par2ArrayOfByte; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeInt(this.byteArray.length); + par1DataOutput.write(this.byteArray); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + int var2 = par1DataInput.readInt(); + this.byteArray = new byte[var2]; + par1DataInput.readFully(this.byteArray); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 7; + } + + public String toString() { + return "[" + this.byteArray.length + " bytes]"; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + byte[] var1 = new byte[this.byteArray.length]; + System.arraycopy(this.byteArray, 0, var1, 0, this.byteArray.length); + return new NBTTagByteArray(this.getName(), var1); + } + + public boolean equals(Object par1Obj) { + return super.equals(par1Obj) ? Arrays.equals(this.byteArray, ((NBTTagByteArray) par1Obj).byteArray) : false; + } + + public int hashCode() { + return super.hashCode() ^ Arrays.hashCode(this.byteArray); + } +} diff --git a/src/main/java/net/minecraft/src/NBTTagCompound.java b/src/main/java/net/minecraft/src/NBTTagCompound.java new file mode 100644 index 0000000..ca30019 --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagCompound.java @@ -0,0 +1,333 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class NBTTagCompound extends NBTBase { + /** + * The key-value pairs for the tag. Each key is a UTF string, each value is a + * tag. + */ + private Map tagMap = new HashMap(); + + public NBTTagCompound() { + super(""); + } + + public NBTTagCompound(String par1Str) { + super(par1Str); + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + Iterator var2 = this.tagMap.values().iterator(); + + while (var2.hasNext()) { + NBTBase var3 = (NBTBase) var2.next(); + NBTBase.writeNamedTag(var3, par1DataOutput); + } + + par1DataOutput.writeByte(0); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.tagMap.clear(); + NBTBase var2; + + while ((var2 = NBTBase.readNamedTag(par1DataInput)).getId() != 0) { + this.tagMap.put(var2.getName(), var2); + } + } + + /** + * Returns all the values in the tagMap HashMap. + */ + public Collection getTags() { + return this.tagMap.values(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 10; + } + + /** + * Stores the given tag into the map with the given string key. This is mostly + * used to store tag lists. + */ + public void setTag(String par1Str, NBTBase par2NBTBase) { + this.tagMap.put(par1Str, par2NBTBase.setName(par1Str)); + } + + /** + * Stores a new NBTTagByte with the given byte value into the map with the given + * string key. + */ + public void setByte(String par1Str, byte par2) { + this.tagMap.put(par1Str, new NBTTagByte(par1Str, par2)); + } + + /** + * Stores a new NBTTagShort with the given short value into the map with the + * given string key. + */ + public void setShort(String par1Str, short par2) { + this.tagMap.put(par1Str, new NBTTagShort(par1Str, par2)); + } + + /** + * Stores a new NBTTagInt with the given integer value into the map with the + * given string key. + */ + public void setInteger(String par1Str, int par2) { + this.tagMap.put(par1Str, new NBTTagInt(par1Str, par2)); + } + + /** + * Stores a new NBTTagLong with the given long value into the map with the given + * string key. + */ + public void setLong(String par1Str, long par2) { + this.tagMap.put(par1Str, new NBTTagLong(par1Str, par2)); + } + + /** + * Stores a new NBTTagFloat with the given float value into the map with the + * given string key. + */ + public void setFloat(String par1Str, float par2) { + this.tagMap.put(par1Str, new NBTTagFloat(par1Str, par2)); + } + + /** + * Stores a new NBTTagDouble with the given double value into the map with the + * given string key. + */ + public void setDouble(String par1Str, double par2) { + this.tagMap.put(par1Str, new NBTTagDouble(par1Str, par2)); + } + + /** + * Stores a new NBTTagString with the given string value into the map with the + * given string key. + */ + public void setString(String par1Str, String par2Str) { + this.tagMap.put(par1Str, new NBTTagString(par1Str, par2Str)); + } + + /** + * Stores a new NBTTagByteArray with the given array as data into the map with + * the given string key. + */ + public void setByteArray(String par1Str, byte[] par2ArrayOfByte) { + this.tagMap.put(par1Str, new NBTTagByteArray(par1Str, par2ArrayOfByte)); + } + + /** + * Stores a new NBTTagIntArray with the given array as data into the map with + * the given string key. + */ + public void setIntArray(String par1Str, int[] par2ArrayOfInteger) { + this.tagMap.put(par1Str, new NBTTagIntArray(par1Str, par2ArrayOfInteger)); + } + + /** + * Stores the given NBTTagCompound into the map with the given string key. + */ + public void setCompoundTag(String par1Str, NBTTagCompound par2NBTTagCompound) { + this.tagMap.put(par1Str, par2NBTTagCompound.setName(par1Str)); + } + + /** + * Stores the given boolean value as a NBTTagByte, storing 1 for true and 0 for + * false, using the given string key. + */ + public void setBoolean(String par1Str, boolean par2) { + this.setByte(par1Str, (byte) (par2 ? 1 : 0)); + } + + /** + * gets a generic tag with the specified name + */ + public NBTBase getTag(String par1Str) { + return (NBTBase) this.tagMap.get(par1Str); + } + + /** + * Returns whether the given string has been previously stored as a key in the + * map. + */ + public boolean hasKey(String par1Str) { + return this.tagMap.containsKey(par1Str); + } + + /** + * Retrieves a byte value using the specified key, or 0 if no such key was + * stored. + */ + public byte getByte(String par1Str) { + return !this.tagMap.containsKey(par1Str) ? 0 : ((NBTTagByte) this.tagMap.get(par1Str)).data; + } + + /** + * Retrieves a short value using the specified key, or 0 if no such key was + * stored. + */ + public short getShort(String par1Str) { + return !this.tagMap.containsKey(par1Str) ? 0 : ((NBTTagShort) this.tagMap.get(par1Str)).data; + } + + /** + * Retrieves an integer value using the specified key, or 0 if no such key was + * stored. + */ + public int getInteger(String par1Str) { + return !this.tagMap.containsKey(par1Str) ? 0 : ((NBTTagInt) this.tagMap.get(par1Str)).data; + } + + /** + * Retrieves a long value using the specified key, or 0 if no such key was + * stored. + */ + public long getLong(String par1Str) { + return !this.tagMap.containsKey(par1Str) ? 0L : ((NBTTagLong) this.tagMap.get(par1Str)).data; + } + + /** + * Retrieves a float value using the specified key, or 0 if no such key was + * stored. + */ + public float getFloat(String par1Str) { + return !this.tagMap.containsKey(par1Str) ? 0.0F : ((NBTTagFloat) this.tagMap.get(par1Str)).data; + } + + /** + * Retrieves a double value using the specified key, or 0 if no such key was + * stored. + */ + public double getDouble(String par1Str) { + return !this.tagMap.containsKey(par1Str) ? 0.0D : ((NBTTagDouble) this.tagMap.get(par1Str)).data; + } + + /** + * Retrieves a string value using the specified key, or an empty string if no + * such key was stored. + */ + public String getString(String par1Str) { + return !this.tagMap.containsKey(par1Str) ? "" : ((NBTTagString) this.tagMap.get(par1Str)).data; + } + + /** + * Retrieves a byte array using the specified key, or a zero-length array if no + * such key was stored. + */ + public byte[] getByteArray(String par1Str) { + return !this.tagMap.containsKey(par1Str) ? new byte[0] : ((NBTTagByteArray) this.tagMap.get(par1Str)).byteArray; + } + + /** + * Retrieves an int array using the specified key, or a zero-length array if no + * such key was stored. + */ + public int[] getIntArray(String par1Str) { + return !this.tagMap.containsKey(par1Str) ? new int[0] : ((NBTTagIntArray) this.tagMap.get(par1Str)).intArray; + } + + /** + * Retrieves a NBTTagCompound subtag matching the specified key, or a new empty + * NBTTagCompound if no such key was stored. + */ + public NBTTagCompound getCompoundTag(String par1Str) { + return !this.tagMap.containsKey(par1Str) ? new NBTTagCompound(par1Str) : (NBTTagCompound) this.tagMap.get(par1Str); + } + + /** + * Retrieves a NBTTagList subtag matching the specified key, or a new empty + * NBTTagList if no such key was stored. + */ + public NBTTagList getTagList(String par1Str) { + return !this.tagMap.containsKey(par1Str) ? new NBTTagList(par1Str) : (NBTTagList) this.tagMap.get(par1Str); + } + + /** + * Retrieves a boolean value using the specified key, or false if no such key + * was stored. This uses the getByte method. + */ + public boolean getBoolean(String par1Str) { + return this.getByte(par1Str) != 0; + } + + /** + * Remove the specified tag. + */ + public void removeTag(String par1Str) { + this.tagMap.remove(par1Str); + } + + public String toString() { + String var1 = this.getName() + ":["; + String var3; + + for (Iterator var2 = this.tagMap.keySet().iterator(); var2.hasNext(); var1 = var1 + var3 + ":" + this.tagMap.get(var3) + ",") { + var3 = (String) var2.next(); + } + + return var1 + "]"; + } + + /** + * Return whether this compound has no tags. + */ + public boolean hasNoTags() { + return this.tagMap.isEmpty(); + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + NBTTagCompound var1 = new NBTTagCompound(this.getName()); + Iterator var2 = this.tagMap.keySet().iterator(); + + while (var2.hasNext()) { + String var3 = (String) var2.next(); + var1.setTag(var3, ((NBTBase) this.tagMap.get(var3)).copy()); + } + + return var1; + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagCompound var2 = (NBTTagCompound) par1Obj; + return this.tagMap.entrySet().equals(var2.tagMap.entrySet()); + } else { + return false; + } + } + + public int hashCode() { + return super.hashCode() ^ this.tagMap.hashCode(); + } + + /** + * Return the tag map for this compound. + */ + public static Map getTagMap(NBTTagCompound par0NBTTagCompound) { + return par0NBTTagCompound.tagMap; + } +} diff --git a/src/main/java/net/minecraft/src/NBTTagDouble.java b/src/main/java/net/minecraft/src/NBTTagDouble.java new file mode 100644 index 0000000..4164c6b --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagDouble.java @@ -0,0 +1,67 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagDouble extends NBTBase { + /** The double value for the tag. */ + public double data; + + public NBTTagDouble(String par1Str) { + super(par1Str); + } + + public NBTTagDouble(String par1Str, double par2) { + super(par1Str); + this.data = par2; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeDouble(this.data); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.data = par1DataInput.readDouble(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 6; + } + + public String toString() { + return "" + this.data; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagDouble(this.getName(), this.data); + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagDouble var2 = (NBTTagDouble) par1Obj; + return this.data == var2.data; + } else { + return false; + } + } + + public int hashCode() { + long var1 = Double.doubleToLongBits(this.data); + return super.hashCode() ^ (int) (var1 ^ var1 >>> 32); + } +} diff --git a/src/main/java/net/minecraft/src/NBTTagEnd.java b/src/main/java/net/minecraft/src/NBTTagEnd.java new file mode 100644 index 0000000..871292c --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagEnd.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagEnd extends NBTBase { + public NBTTagEnd() { + super((String) null); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 0; + } + + public String toString() { + return "END"; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagEnd(); + } +} diff --git a/src/main/java/net/minecraft/src/NBTTagFloat.java b/src/main/java/net/minecraft/src/NBTTagFloat.java new file mode 100644 index 0000000..8b50568 --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagFloat.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagFloat extends NBTBase { + /** The float value for the tag. */ + public float data; + + public NBTTagFloat(String par1Str) { + super(par1Str); + } + + public NBTTagFloat(String par1Str, float par2) { + super(par1Str); + this.data = par2; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeFloat(this.data); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.data = par1DataInput.readFloat(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 5; + } + + public String toString() { + return "" + this.data; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagFloat(this.getName(), this.data); + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagFloat var2 = (NBTTagFloat) par1Obj; + return this.data == var2.data; + } else { + return false; + } + } + + public int hashCode() { + return super.hashCode() ^ Float.floatToIntBits(this.data); + } +} diff --git a/src/main/java/net/minecraft/src/NBTTagInt.java b/src/main/java/net/minecraft/src/NBTTagInt.java new file mode 100644 index 0000000..ddbd2bf --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagInt.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagInt extends NBTBase { + /** The integer value for the tag. */ + public int data; + + public NBTTagInt(String par1Str) { + super(par1Str); + } + + public NBTTagInt(String par1Str, int par2) { + super(par1Str); + this.data = par2; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeInt(this.data); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.data = par1DataInput.readInt(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 3; + } + + public String toString() { + return "" + this.data; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagInt(this.getName(), this.data); + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagInt var2 = (NBTTagInt) par1Obj; + return this.data == var2.data; + } else { + return false; + } + } + + public int hashCode() { + return super.hashCode() ^ this.data; + } +} diff --git a/src/main/java/net/minecraft/src/NBTTagIntArray.java b/src/main/java/net/minecraft/src/NBTTagIntArray.java new file mode 100644 index 0000000..965ab78 --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagIntArray.java @@ -0,0 +1,78 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Arrays; + +public class NBTTagIntArray extends NBTBase { + /** The array of saved integers */ + public int[] intArray; + + public NBTTagIntArray(String par1Str) { + super(par1Str); + } + + public NBTTagIntArray(String par1Str, int[] par2ArrayOfInteger) { + super(par1Str); + this.intArray = par2ArrayOfInteger; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeInt(this.intArray.length); + + for (int var2 = 0; var2 < this.intArray.length; ++var2) { + par1DataOutput.writeInt(this.intArray[var2]); + } + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + int var2 = par1DataInput.readInt(); + this.intArray = new int[var2]; + + for (int var3 = 0; var3 < var2; ++var3) { + this.intArray[var3] = par1DataInput.readInt(); + } + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 11; + } + + public String toString() { + return "[" + this.intArray.length + " bytes]"; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + int[] var1 = new int[this.intArray.length]; + System.arraycopy(this.intArray, 0, var1, 0, this.intArray.length); + return new NBTTagIntArray(this.getName(), var1); + } + + public boolean equals(Object par1Obj) { + if (!super.equals(par1Obj)) { + return false; + } else { + NBTTagIntArray var2 = (NBTTagIntArray) par1Obj; + return this.intArray == null && var2.intArray == null || this.intArray != null && Arrays.equals(this.intArray, var2.intArray); + } + } + + public int hashCode() { + return super.hashCode() ^ Arrays.hashCode(this.intArray); + } +} diff --git a/src/main/java/net/minecraft/src/NBTTagList.java b/src/main/java/net/minecraft/src/NBTTagList.java new file mode 100644 index 0000000..a526f74 --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagList.java @@ -0,0 +1,135 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class NBTTagList extends NBTBase { + /** The array list containing the tags encapsulated in this list. */ + private List tagList = new ArrayList(); + + /** + * The type byte for the tags in the list - they must all be of the same type. + */ + private byte tagType; + + public NBTTagList() { + super(""); + } + + public NBTTagList(String par1Str) { + super(par1Str); + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + if (!this.tagList.isEmpty()) { + this.tagType = ((NBTBase) this.tagList.get(0)).getId(); + } else { + this.tagType = 1; + } + + par1DataOutput.writeByte(this.tagType); + par1DataOutput.writeInt(this.tagList.size()); + + for (int var2 = 0; var2 < this.tagList.size(); ++var2) { + ((NBTBase) this.tagList.get(var2)).write(par1DataOutput); + } + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.tagType = par1DataInput.readByte(); + int var2 = par1DataInput.readInt(); + this.tagList = new ArrayList(); + + for (int var3 = 0; var3 < var2; ++var3) { + NBTBase var4 = NBTBase.newTag(this.tagType, (String) null); + var4.load(par1DataInput); + this.tagList.add(var4); + } + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 9; + } + + public String toString() { + return "" + this.tagList.size() + " entries of type " + NBTBase.getTagName(this.tagType); + } + + /** + * Adds the provided tag to the end of the list. There is no check to verify + * this tag is of the same type as any previous tag. + */ + public void appendTag(NBTBase par1NBTBase) { + this.tagType = par1NBTBase.getId(); + this.tagList.add(par1NBTBase); + } + + /** + * Removes a tag at the given index. + */ + public NBTBase removeTag(int par1) { + return (NBTBase) this.tagList.remove(par1); + } + + /** + * Retrieves the tag at the specified index from the list. + */ + public NBTBase tagAt(int par1) { + return (NBTBase) this.tagList.get(par1); + } + + /** + * Returns the number of tags in the list. + */ + public int tagCount() { + return this.tagList.size(); + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + NBTTagList var1 = new NBTTagList(this.getName()); + var1.tagType = this.tagType; + Iterator var2 = this.tagList.iterator(); + + while (var2.hasNext()) { + NBTBase var3 = (NBTBase) var2.next(); + NBTBase var4 = var3.copy(); + var1.tagList.add(var4); + } + + return var1; + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagList var2 = (NBTTagList) par1Obj; + + if (this.tagType == var2.tagType) { + return this.tagList.equals(var2.tagList); + } + } + + return false; + } + + public int hashCode() { + return super.hashCode() ^ this.tagList.hashCode(); + } +} diff --git a/src/main/java/net/minecraft/src/NBTTagLong.java b/src/main/java/net/minecraft/src/NBTTagLong.java new file mode 100644 index 0000000..280633d --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagLong.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagLong extends NBTBase { + /** The long value for the tag. */ + public long data; + + public NBTTagLong(String par1Str) { + super(par1Str); + } + + public NBTTagLong(String par1Str, long par2) { + super(par1Str); + this.data = par2; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeLong(this.data); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.data = par1DataInput.readLong(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 4; + } + + public String toString() { + return "" + this.data; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagLong(this.getName(), this.data); + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagLong var2 = (NBTTagLong) par1Obj; + return this.data == var2.data; + } else { + return false; + } + } + + public int hashCode() { + return super.hashCode() ^ (int) (this.data ^ this.data >>> 32); + } +} diff --git a/src/main/java/net/minecraft/src/NBTTagShort.java b/src/main/java/net/minecraft/src/NBTTagShort.java new file mode 100644 index 0000000..57b2231 --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagShort.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagShort extends NBTBase { + /** The short value for the tag. */ + public short data; + + public NBTTagShort(String par1Str) { + super(par1Str); + } + + public NBTTagShort(String par1Str, short par2) { + super(par1Str); + this.data = par2; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeShort(this.data); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.data = par1DataInput.readShort(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 2; + } + + public String toString() { + return "" + this.data; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagShort(this.getName(), this.data); + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagShort var2 = (NBTTagShort) par1Obj; + return this.data == var2.data; + } else { + return false; + } + } + + public int hashCode() { + return super.hashCode() ^ this.data; + } +} diff --git a/src/main/java/net/minecraft/src/NBTTagString.java b/src/main/java/net/minecraft/src/NBTTagString.java new file mode 100644 index 0000000..36c5334 --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagString.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagString extends NBTBase { + /** The string value for the tag (cannot be empty). */ + public String data; + + public NBTTagString(String par1Str) { + super(par1Str); + } + + public NBTTagString(String par1Str, String par2Str) { + super(par1Str); + this.data = par2Str; + + if (par2Str == null) { + throw new IllegalArgumentException("Empty string not allowed"); + } + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeUTF(this.data); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.data = par1DataInput.readUTF(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 8; + } + + public String toString() { + return "" + this.data; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagString(this.getName(), this.data); + } + + public boolean equals(Object par1Obj) { + if (!super.equals(par1Obj)) { + return false; + } else { + NBTTagString var2 = (NBTTagString) par1Obj; + return this.data == null && var2.data == null || this.data != null && this.data.equals(var2.data); + } + } + + public int hashCode() { + return super.hashCode() ^ this.data.hashCode(); + } +} diff --git a/src/main/java/net/minecraft/src/NetClientHandler.java b/src/main/java/net/minecraft/src/NetClientHandler.java new file mode 100644 index 0000000..b952a67 --- /dev/null +++ b/src/main/java/net/minecraft/src/NetClientHandler.java @@ -0,0 +1,1239 @@ +package net.minecraft.src; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import net.lax1dude.eaglercraft.DefaultSkinRenderer; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.WebsocketNetworkManager; +import net.minecraft.client.Minecraft; + +public class NetClientHandler extends NetHandler { + /** True if kicked or disconnected from the server. */ + private boolean disconnected = false; + + /** Reference to the NetworkManager object. */ + private INetworkManager netManager; + public String field_72560_a; + + /** Reference to the Minecraft object. */ + private Minecraft mc; + private WorldClient worldClient; + + /** + * True if the client has finished downloading terrain and may spawn. Set upon + * receipt of a player position packet, reset upon respawning. + */ + private boolean doneLoadingTerrain = false; + public MapStorage mapStorage = new MapStorage(); + + /** A HashMap of all player names and their player information objects */ + private Map playerInfoMap = new HashMap(); + + /** + * An ArrayList of GuiPlayerInfo (includes all the players' GuiPlayerInfo on the + * current server) + */ + public List playerInfoList = new ArrayList(); + public int currentServerMaxPlayers = 20; + private GuiScreen field_98183_l = null; + + /** RNG. */ + Random rand = new Random(); + + public NetClientHandler(Minecraft par1Minecraft, String par2Str, int par3) throws IOException { + this.mc = par1Minecraft; + this.netManager = new WebsocketNetworkManager(par2Str, null, this); + } + + //public NetClientHandler(Minecraft par1Minecraft, String par2Str, int par3, GuiScreen par4GuiScreen) throws IOException { + // this.mc = par1Minecraft; + // this.field_98183_l = par4GuiScreen; + // Socket var5 = new Socket(InetAddress.getByName(par2Str), par3); + // this.netManager = new TcpConnection(var5, "Client", this); + //} + + /** + * sets netManager and worldClient to null + */ + public void cleanup() { + if (this.netManager != null) { + this.netManager.wakeThreads(); + } + + this.netManager = null; + this.worldClient = null; + } + + /** + * Processes the packets that have been read since the last call to this + * function. + */ + public void processReadPackets() { + if (!this.disconnected && this.netManager != null) { + this.netManager.processReadPackets(); + } + + if (this.netManager != null) { + this.netManager.wakeThreads(); + } + } + + public void handleServerAuthData(Packet253ServerAuthData par1Packet253ServerAuthData) { + + this.addToSendQueue(new Packet252SharedKey()); + } + + public void handleSharedKey(Packet252SharedKey par1Packet252SharedKey) { + this.addToSendQueue(new Packet205ClientCommand(0)); + } + + public void handleLogin(Packet1Login par1Packet1Login) { + this.mc.playerController = new PlayerControllerMP(this.mc, this); + this.worldClient = new WorldClient(this, new WorldSettings(0L, par1Packet1Login.gameType, false, par1Packet1Login.hardcoreMode, par1Packet1Login.terrainType), par1Packet1Login.dimension, par1Packet1Login.difficultySetting, + this.mc.mcProfiler); + this.worldClient.isRemote = true; + this.mc.loadWorld(this.worldClient); + this.mc.thePlayer.dimension = par1Packet1Login.dimension; + this.mc.displayGuiScreen(new GuiDownloadTerrain(this)); + this.mc.thePlayer.entityId = par1Packet1Login.clientEntityId; + this.currentServerMaxPlayers = par1Packet1Login.maxPlayers; + this.mc.playerController.setGameType(par1Packet1Login.gameType); + this.mc.gameSettings.sendSettingsToServer(); + } + + public void handleVehicleSpawn(Packet23VehicleSpawn par1Packet23VehicleSpawn) { + double var2 = (double) par1Packet23VehicleSpawn.xPosition / 32.0D; + double var4 = (double) par1Packet23VehicleSpawn.yPosition / 32.0D; + double var6 = (double) par1Packet23VehicleSpawn.zPosition / 32.0D; + Object var8 = null; + + if (par1Packet23VehicleSpawn.type == 10) { + var8 = EntityMinecart.createMinecart(this.worldClient, var2, var4, var6, par1Packet23VehicleSpawn.throwerEntityId); + } else if (par1Packet23VehicleSpawn.type == 90) { + Entity var9 = this.getEntityByID(par1Packet23VehicleSpawn.throwerEntityId); + + if (var9 instanceof EntityPlayer) { + var8 = new EntityFishHook(this.worldClient, var2, var4, var6, (EntityPlayer) var9); + } + + par1Packet23VehicleSpawn.throwerEntityId = 0; + } else if (par1Packet23VehicleSpawn.type == 60) { + var8 = new EntityArrow(this.worldClient, var2, var4, var6); + } else if (par1Packet23VehicleSpawn.type == 61) { + var8 = new EntitySnowball(this.worldClient, var2, var4, var6); + } else if (par1Packet23VehicleSpawn.type == 71) { + var8 = new EntityItemFrame(this.worldClient, (int) var2, (int) var4, (int) var6, par1Packet23VehicleSpawn.throwerEntityId); + par1Packet23VehicleSpawn.throwerEntityId = 0; + } else if (par1Packet23VehicleSpawn.type == 65) { + var8 = new EntityEnderPearl(this.worldClient, var2, var4, var6); + } else if (par1Packet23VehicleSpawn.type == 72) { + var8 = new EntityEnderEye(this.worldClient, var2, var4, var6); + } else if (par1Packet23VehicleSpawn.type == 76) { + var8 = new EntityFireworkRocket(this.worldClient, var2, var4, var6, (ItemStack) null); + } else if (par1Packet23VehicleSpawn.type == 63) { + var8 = new EntityLargeFireball(this.worldClient, var2, var4, var6, (double) par1Packet23VehicleSpawn.speedX / 8000.0D, (double) par1Packet23VehicleSpawn.speedY / 8000.0D, (double) par1Packet23VehicleSpawn.speedZ / 8000.0D); + par1Packet23VehicleSpawn.throwerEntityId = 0; + } else if (par1Packet23VehicleSpawn.type == 64) { + var8 = new EntitySmallFireball(this.worldClient, var2, var4, var6, (double) par1Packet23VehicleSpawn.speedX / 8000.0D, (double) par1Packet23VehicleSpawn.speedY / 8000.0D, (double) par1Packet23VehicleSpawn.speedZ / 8000.0D); + par1Packet23VehicleSpawn.throwerEntityId = 0; + } else if (par1Packet23VehicleSpawn.type == 66) { + var8 = new EntityWitherSkull(this.worldClient, var2, var4, var6, (double) par1Packet23VehicleSpawn.speedX / 8000.0D, (double) par1Packet23VehicleSpawn.speedY / 8000.0D, (double) par1Packet23VehicleSpawn.speedZ / 8000.0D); + par1Packet23VehicleSpawn.throwerEntityId = 0; + } else if (par1Packet23VehicleSpawn.type == 62) { + var8 = new EntityEgg(this.worldClient, var2, var4, var6); + } else if (par1Packet23VehicleSpawn.type == 73) { + var8 = new EntityPotion(this.worldClient, var2, var4, var6, par1Packet23VehicleSpawn.throwerEntityId); + par1Packet23VehicleSpawn.throwerEntityId = 0; + } else if (par1Packet23VehicleSpawn.type == 75) { + var8 = new EntityExpBottle(this.worldClient, var2, var4, var6); + par1Packet23VehicleSpawn.throwerEntityId = 0; + } else if (par1Packet23VehicleSpawn.type == 1) { + var8 = new EntityBoat(this.worldClient, var2, var4, var6); + } else if (par1Packet23VehicleSpawn.type == 50) { + var8 = new EntityTNTPrimed(this.worldClient, var2, var4, var6, (EntityLiving) null); + } else if (par1Packet23VehicleSpawn.type == 51) { + var8 = new EntityEnderCrystal(this.worldClient, var2, var4, var6); + } else if (par1Packet23VehicleSpawn.type == 2) { + var8 = new EntityItem(this.worldClient, var2, var4, var6); + } else if (par1Packet23VehicleSpawn.type == 70) { + var8 = new EntityFallingSand(this.worldClient, var2, var4, var6, par1Packet23VehicleSpawn.throwerEntityId & 65535, par1Packet23VehicleSpawn.throwerEntityId >> 16); + par1Packet23VehicleSpawn.throwerEntityId = 0; + } + + if (var8 != null) { + if(((Entity) var8).worldObj == null) ((Entity) var8).setWorld(worldClient); + ((Entity) var8).serverPosX = par1Packet23VehicleSpawn.xPosition; + ((Entity) var8).serverPosY = par1Packet23VehicleSpawn.yPosition; + ((Entity) var8).serverPosZ = par1Packet23VehicleSpawn.zPosition; + ((Entity) var8).rotationPitch = (float) (par1Packet23VehicleSpawn.pitch * 360) / 256.0F; + ((Entity) var8).rotationYaw = (float) (par1Packet23VehicleSpawn.yaw * 360) / 256.0F; + Entity[] var12 = ((Entity) var8).getParts(); + + if (var12 != null) { + int var10 = par1Packet23VehicleSpawn.entityId - ((Entity) var8).entityId; + + for (int var11 = 0; var11 < var12.length; ++var11) { + var12[var11].entityId += var10; + } + } + + ((Entity) var8).entityId = par1Packet23VehicleSpawn.entityId; + this.worldClient.addEntityToWorld(par1Packet23VehicleSpawn.entityId, (Entity) var8); + + if (par1Packet23VehicleSpawn.throwerEntityId > 0) { + if (par1Packet23VehicleSpawn.type == 60) { + Entity var13 = this.getEntityByID(par1Packet23VehicleSpawn.throwerEntityId); + + if (var13 instanceof EntityLiving) { + EntityArrow var14 = (EntityArrow) var8; + var14.shootingEntity = var13; + } + } + + ((Entity) var8).setVelocity((double) par1Packet23VehicleSpawn.speedX / 8000.0D, (double) par1Packet23VehicleSpawn.speedY / 8000.0D, (double) par1Packet23VehicleSpawn.speedZ / 8000.0D); + } + } + } + + /** + * Handle a entity experience orb packet. + */ + public void handleEntityExpOrb(Packet26EntityExpOrb par1Packet26EntityExpOrb) { + EntityXPOrb var2 = new EntityXPOrb(this.worldClient, (double) par1Packet26EntityExpOrb.posX, (double) par1Packet26EntityExpOrb.posY, (double) par1Packet26EntityExpOrb.posZ, par1Packet26EntityExpOrb.xpValue); + var2.serverPosX = par1Packet26EntityExpOrb.posX; + var2.serverPosY = par1Packet26EntityExpOrb.posY; + var2.serverPosZ = par1Packet26EntityExpOrb.posZ; + var2.rotationYaw = 0.0F; + var2.rotationPitch = 0.0F; + var2.entityId = par1Packet26EntityExpOrb.entityId; + this.worldClient.addEntityToWorld(par1Packet26EntityExpOrb.entityId, var2); + } + + /** + * Handles weather packet + */ + public void handleWeather(Packet71Weather par1Packet71Weather) { + double var2 = (double) par1Packet71Weather.posX / 32.0D; + double var4 = (double) par1Packet71Weather.posY / 32.0D; + double var6 = (double) par1Packet71Weather.posZ / 32.0D; + EntityLightningBolt var8 = null; + + if (par1Packet71Weather.isLightningBolt == 1) { + var8 = new EntityLightningBolt(this.worldClient, var2, var4, var6); + } + + if (var8 != null) { + var8.serverPosX = par1Packet71Weather.posX; + var8.serverPosY = par1Packet71Weather.posY; + var8.serverPosZ = par1Packet71Weather.posZ; + var8.rotationYaw = 0.0F; + var8.rotationPitch = 0.0F; + var8.entityId = par1Packet71Weather.entityID; + this.worldClient.addWeatherEffect(var8); + } + } + + /** + * Packet handler + */ + public void handleEntityPainting(Packet25EntityPainting par1Packet25EntityPainting) { + EntityPainting var2 = new EntityPainting(this.worldClient, par1Packet25EntityPainting.xPosition, par1Packet25EntityPainting.yPosition, par1Packet25EntityPainting.zPosition, par1Packet25EntityPainting.direction, + par1Packet25EntityPainting.title); + this.worldClient.addEntityToWorld(par1Packet25EntityPainting.entityId, var2); + } + + /** + * Packet handler + */ + public void handleEntityVelocity(Packet28EntityVelocity par1Packet28EntityVelocity) { + Entity var2 = this.getEntityByID(par1Packet28EntityVelocity.entityId); + + if (var2 != null) { + var2.setVelocity((double) par1Packet28EntityVelocity.motionX / 8000.0D, (double) par1Packet28EntityVelocity.motionY / 8000.0D, (double) par1Packet28EntityVelocity.motionZ / 8000.0D); + } + } + + /** + * Packet handler + */ + public void handleEntityMetadata(Packet40EntityMetadata par1Packet40EntityMetadata) { + Entity var2 = this.getEntityByID(par1Packet40EntityMetadata.entityId); + + if (var2 != null && par1Packet40EntityMetadata.getMetadata() != null) { + var2.getDataWatcher().updateWatchedObjectsFromList(par1Packet40EntityMetadata.getMetadata()); + } + } + + public void handleNamedEntitySpawn(Packet20NamedEntitySpawn par1Packet20NamedEntitySpawn) { + double var2 = (double) par1Packet20NamedEntitySpawn.xPosition / 32.0D; + double var4 = (double) par1Packet20NamedEntitySpawn.yPosition / 32.0D; + double var6 = (double) par1Packet20NamedEntitySpawn.zPosition / 32.0D; + float var8 = (float) (par1Packet20NamedEntitySpawn.rotation * 360) / 256.0F; + float var9 = (float) (par1Packet20NamedEntitySpawn.pitch * 360) / 256.0F; + EntityOtherPlayerMP var10 = new EntityOtherPlayerMP(this.mc.theWorld, par1Packet20NamedEntitySpawn.name); + var10.prevPosX = var10.lastTickPosX = (double) (var10.serverPosX = par1Packet20NamedEntitySpawn.xPosition); + var10.prevPosY = var10.lastTickPosY = (double) (var10.serverPosY = par1Packet20NamedEntitySpawn.yPosition); + var10.prevPosZ = var10.lastTickPosZ = (double) (var10.serverPosZ = par1Packet20NamedEntitySpawn.zPosition); + int var11 = par1Packet20NamedEntitySpawn.currentItem; + + if (var11 == 0) { + var10.inventory.mainInventory[var10.inventory.currentItem] = null; + } else { + var10.inventory.mainInventory[var10.inventory.currentItem] = new ItemStack(var11, 1, 0); + } + + var10.setPositionAndRotation(var2, var4, var6, var8, var9); + this.worldClient.addEntityToWorld(par1Packet20NamedEntitySpawn.entityId, var10); + List var12 = par1Packet20NamedEntitySpawn.getWatchedMetadata(); + + if (var12 != null) { + var10.getDataWatcher().updateWatchedObjectsFromList(var12); + } + } + + public void handleEntityTeleport(Packet34EntityTeleport par1Packet34EntityTeleport) { + Entity var2 = this.getEntityByID(par1Packet34EntityTeleport.entityId); + + if (var2 != null) { + var2.serverPosX = par1Packet34EntityTeleport.xPosition; + var2.serverPosY = par1Packet34EntityTeleport.yPosition; + var2.serverPosZ = par1Packet34EntityTeleport.zPosition; + double var3 = (double) var2.serverPosX / 32.0D; + double var5 = (double) var2.serverPosY / 32.0D + 0.015625D; + double var7 = (double) var2.serverPosZ / 32.0D; + float var9 = (float) (par1Packet34EntityTeleport.yaw * 360) / 256.0F; + float var10 = (float) (par1Packet34EntityTeleport.pitch * 360) / 256.0F; + var2.setPositionAndRotation2(var3, var5, var7, var9, var10, 3); + } + } + + public void handleBlockItemSwitch(Packet16BlockItemSwitch par1Packet16BlockItemSwitch) { + if (par1Packet16BlockItemSwitch.id >= 0 && par1Packet16BlockItemSwitch.id < InventoryPlayer.getHotbarSize()) { + this.mc.thePlayer.inventory.currentItem = par1Packet16BlockItemSwitch.id; + } + } + + public void handleEntity(Packet30Entity par1Packet30Entity) { + Entity var2 = this.getEntityByID(par1Packet30Entity.entityId); + + if (var2 != null) { + var2.serverPosX += par1Packet30Entity.xPosition; + var2.serverPosY += par1Packet30Entity.yPosition; + var2.serverPosZ += par1Packet30Entity.zPosition; + double var3 = (double) var2.serverPosX / 32.0D; + double var5 = (double) var2.serverPosY / 32.0D; + double var7 = (double) var2.serverPosZ / 32.0D; + float var9 = par1Packet30Entity.rotating ? (float) (par1Packet30Entity.yaw * 360) / 256.0F : var2.rotationYaw; + float var10 = par1Packet30Entity.rotating ? (float) (par1Packet30Entity.pitch * 360) / 256.0F : var2.rotationPitch; + var2.setPositionAndRotation2(var3, var5, var7, var9, var10, 3); + } + } + + public void handleEntityHeadRotation(Packet35EntityHeadRotation par1Packet35EntityHeadRotation) { + Entity var2 = this.getEntityByID(par1Packet35EntityHeadRotation.entityId); + + if (var2 != null) { + float var3 = (float) (par1Packet35EntityHeadRotation.headRotationYaw * 360) / 256.0F; + var2.setRotationYawHead(var3); + } + } + + public void handleDestroyEntity(Packet29DestroyEntity par1Packet29DestroyEntity) { + for (int var2 = 0; var2 < par1Packet29DestroyEntity.entityId.length; ++var2) { + this.worldClient.removeEntityFromWorld(par1Packet29DestroyEntity.entityId[var2]); + } + } + + public void handleFlying(Packet10Flying par1Packet10Flying) { + EntityClientPlayerMP var2 = this.mc.thePlayer; + double var3 = var2.posX; + double var5 = var2.posY; + double var7 = var2.posZ; + float var9 = var2.rotationYaw; + float var10 = var2.rotationPitch; + + if (par1Packet10Flying.moving) { + var3 = par1Packet10Flying.xPosition; + var5 = par1Packet10Flying.yPosition; + var7 = par1Packet10Flying.zPosition; + } + + if (par1Packet10Flying.rotating) { + var9 = par1Packet10Flying.yaw; + var10 = par1Packet10Flying.pitch; + } + + var2.ySize = 0.0F; + var2.motionX = var2.motionY = var2.motionZ = 0.0D; + var2.setPositionAndRotation(var3, var5, var7, var9, var10); + par1Packet10Flying.xPosition = var2.posX; + par1Packet10Flying.yPosition = var2.boundingBox.minY; + par1Packet10Flying.zPosition = var2.posZ; + par1Packet10Flying.stance = var2.posY; + this.netManager.addToSendQueue(par1Packet10Flying); + + if (!this.doneLoadingTerrain) { + this.mc.thePlayer.prevPosX = this.mc.thePlayer.posX; + this.mc.thePlayer.prevPosY = this.mc.thePlayer.posY; + this.mc.thePlayer.prevPosZ = this.mc.thePlayer.posZ; + this.doneLoadingTerrain = true; + this.mc.displayGuiScreen((GuiScreen) null); + } + } + + public void handleMultiBlockChange(Packet52MultiBlockChange par1Packet52MultiBlockChange) { + int var2 = par1Packet52MultiBlockChange.xPosition * 16; + int var3 = par1Packet52MultiBlockChange.zPosition * 16; + + if (par1Packet52MultiBlockChange.metadataArray != null) { + DataInputStream var4 = new DataInputStream(new ByteArrayInputStream(par1Packet52MultiBlockChange.metadataArray)); + + try { + for (int var5 = 0; var5 < par1Packet52MultiBlockChange.size; ++var5) { + short var6 = var4.readShort(); + short var7 = var4.readShort(); + int var8 = var7 >> 4 & 4095; + int var9 = var7 & 15; + int var10 = var6 >> 12 & 15; + int var11 = var6 >> 8 & 15; + int var12 = var6 & 255; + this.worldClient.setBlockAndMetadataAndInvalidate(var10 + var2, var12, var11 + var3, var8, var9); + } + } catch (IOException var13) { + ; + } + } + } + + /** + * Handle Packet51MapChunk (full chunk update of blocks, metadata, light levels, + * and optionally biome data) + */ + public void handleMapChunk(Packet51MapChunk par1Packet51MapChunk) { + if (par1Packet51MapChunk.includeInitialize) { + if (par1Packet51MapChunk.yChMin == 0) { + this.worldClient.doPreChunk(par1Packet51MapChunk.xCh, par1Packet51MapChunk.zCh, false); + return; + } + + this.worldClient.doPreChunk(par1Packet51MapChunk.xCh, par1Packet51MapChunk.zCh, true); + } + + this.worldClient.invalidateBlockReceiveRegion(par1Packet51MapChunk.xCh << 4, 0, par1Packet51MapChunk.zCh << 4, (par1Packet51MapChunk.xCh << 4) + 15, 256, (par1Packet51MapChunk.zCh << 4) + 15); + Chunk var2 = this.worldClient.getChunkFromChunkCoords(par1Packet51MapChunk.xCh, par1Packet51MapChunk.zCh); + + if (par1Packet51MapChunk.includeInitialize && var2 == null) { + this.worldClient.doPreChunk(par1Packet51MapChunk.xCh, par1Packet51MapChunk.zCh, true); + var2 = this.worldClient.getChunkFromChunkCoords(par1Packet51MapChunk.xCh, par1Packet51MapChunk.zCh); + } + + if (var2 != null) { + var2.fillChunk(par1Packet51MapChunk.getCompressedChunkData(), par1Packet51MapChunk.yChMin, par1Packet51MapChunk.yChMax, par1Packet51MapChunk.includeInitialize); + this.worldClient.markBlockRangeForRenderUpdate(par1Packet51MapChunk.xCh << 4, 0, par1Packet51MapChunk.zCh << 4, (par1Packet51MapChunk.xCh << 4) + 15, 256, (par1Packet51MapChunk.zCh << 4) + 15); + + if (!par1Packet51MapChunk.includeInitialize || !(this.worldClient.provider instanceof WorldProviderSurface)) { + var2.resetRelightChecks(); + } + } + } + + public void handleBlockChange(Packet53BlockChange par1Packet53BlockChange) { + this.worldClient.setBlockAndMetadataAndInvalidate(par1Packet53BlockChange.xPosition, par1Packet53BlockChange.yPosition, par1Packet53BlockChange.zPosition, par1Packet53BlockChange.type, par1Packet53BlockChange.metadata); + } + + public void handleKickDisconnect(Packet255KickDisconnect par1Packet255KickDisconnect) { + this.netManager.networkShutdown("disconnect.kicked", new Object[0]); + this.disconnected = true; + this.mc.loadWorld((WorldClient) null); + + this.mc.displayGuiScreen(new GuiDisconnected(new GuiMultiplayer(new GuiMainMenu()), "disconnect.disconnected", "disconnect.genericReason", new Object[] { par1Packet255KickDisconnect.reason })); + + } + + public void handleErrorMessage(String par1Str, Object[] par2ArrayOfObj) { + if (!this.disconnected) { + this.disconnected = true; + this.mc.loadWorld((WorldClient) null); + + this.mc.displayGuiScreen(new GuiDisconnected(new GuiMultiplayer(new GuiMainMenu()), "disconnect.lost", par1Str, par2ArrayOfObj)); + } + } + + public void quitWithPacket(Packet par1Packet) { + if (!this.disconnected) { + this.netManager.addToSendQueue(par1Packet); + this.netManager.serverShutdown(); + } + } + + /** + * Adds the packet to the send queue + */ + public void addToSendQueue(Packet par1Packet) { + if (!this.disconnected) { + this.netManager.addToSendQueue(par1Packet); + } + } + + public void handleCollect(Packet22Collect par1Packet22Collect) { + Entity var2 = this.getEntityByID(par1Packet22Collect.collectedEntityId); + Object var3 = (EntityLiving) this.getEntityByID(par1Packet22Collect.collectorEntityId); + + if (var3 == null) { + var3 = this.mc.thePlayer; + } + + if (var2 != null) { + if (var2 instanceof EntityXPOrb) { + this.worldClient.playSoundAtEntity(var2, "random.orb", 0.2F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + } else { + this.worldClient.playSoundAtEntity(var2, "random.pop", 0.2F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + } + + this.mc.effectRenderer.addEffect(new EntityPickupFX(this.mc.theWorld, var2, (Entity) var3, -0.5F)); + this.worldClient.removeEntityFromWorld(par1Packet22Collect.collectedEntityId); + } + } + + public void handleChat(Packet3Chat par1Packet3Chat) { + this.mc.ingameGUI.getChatGUI().printChatMessage(par1Packet3Chat.message); + } + + public void handleAnimation(Packet18Animation par1Packet18Animation) { + Entity var2 = this.getEntityByID(par1Packet18Animation.entityId); + + if (var2 != null) { + if (par1Packet18Animation.animate == 1) { + EntityLiving var3 = (EntityLiving) var2; + var3.swingItem(); + } else if (par1Packet18Animation.animate == 2) { + var2.performHurtAnimation(); + } else if (par1Packet18Animation.animate == 3) { + EntityPlayer var4 = (EntityPlayer) var2; + var4.wakeUpPlayer(false, false, false); + } else if (par1Packet18Animation.animate != 4) { + if (par1Packet18Animation.animate == 6) { + this.mc.effectRenderer.addEffect(new EntityCrit2FX(this.mc.theWorld, var2)); + } else if (par1Packet18Animation.animate == 7) { + EntityCrit2FX var5 = new EntityCrit2FX(this.mc.theWorld, var2, "magicCrit"); + this.mc.effectRenderer.addEffect(var5); + } else if (par1Packet18Animation.animate == 5 && var2 instanceof EntityOtherPlayerMP) { + ; + } + } + } + } + + public void handleSleep(Packet17Sleep par1Packet17Sleep) { + Entity var2 = this.getEntityByID(par1Packet17Sleep.entityID); + + if (var2 != null) { + if (par1Packet17Sleep.field_73622_e == 0) { + EntityPlayer var3 = (EntityPlayer) var2; + var3.sleepInBedAt(par1Packet17Sleep.bedX, par1Packet17Sleep.bedY, par1Packet17Sleep.bedZ); + } + } + } + + /** + * Disconnects the network connection. + */ + public void disconnect() { + this.disconnected = true; + this.netManager.wakeThreads(); + this.netManager.networkShutdown("disconnect.closed", new Object[0]); + } + + public void handleMobSpawn(Packet24MobSpawn par1Packet24MobSpawn) { + double var2 = (double) par1Packet24MobSpawn.xPosition / 32.0D; + double var4 = (double) par1Packet24MobSpawn.yPosition / 32.0D; + double var6 = (double) par1Packet24MobSpawn.zPosition / 32.0D; + float var8 = (float) (par1Packet24MobSpawn.yaw * 360) / 256.0F; + float var9 = (float) (par1Packet24MobSpawn.pitch * 360) / 256.0F; + EntityLiving var10 = (EntityLiving) EntityList.createEntityByID(par1Packet24MobSpawn.type, this.mc.theWorld); + var10.serverPosX = par1Packet24MobSpawn.xPosition; + var10.serverPosY = par1Packet24MobSpawn.yPosition; + var10.serverPosZ = par1Packet24MobSpawn.zPosition; + var10.rotationYawHead = (float) (par1Packet24MobSpawn.headYaw * 360) / 256.0F; + Entity[] var11 = var10.getParts(); + + if (var11 != null) { + int var12 = par1Packet24MobSpawn.entityId - var10.entityId; + + for (int var13 = 0; var13 < var11.length; ++var13) { + var11[var13].entityId += var12; + } + } + + var10.entityId = par1Packet24MobSpawn.entityId; + var10.setPositionAndRotation(var2, var4, var6, var8, var9); + var10.motionX = (double) ((float) par1Packet24MobSpawn.velocityX / 8000.0F); + var10.motionY = (double) ((float) par1Packet24MobSpawn.velocityY / 8000.0F); + var10.motionZ = (double) ((float) par1Packet24MobSpawn.velocityZ / 8000.0F); + this.worldClient.addEntityToWorld(par1Packet24MobSpawn.entityId, var10); + List var14 = par1Packet24MobSpawn.getMetadata(); + + if (var14 != null) { + var10.getDataWatcher().updateWatchedObjectsFromList(var14); + } + } + + public void handleUpdateTime(Packet4UpdateTime par1Packet4UpdateTime) { + this.mc.theWorld.func_82738_a(par1Packet4UpdateTime.worldAge); + this.mc.theWorld.setWorldTime(par1Packet4UpdateTime.time); + } + + public void handleSpawnPosition(Packet6SpawnPosition par1Packet6SpawnPosition) { + this.mc.thePlayer.setSpawnChunk(new ChunkCoordinates(par1Packet6SpawnPosition.xPosition, par1Packet6SpawnPosition.yPosition, par1Packet6SpawnPosition.zPosition), true); + this.mc.theWorld.getWorldInfo().setSpawnPosition(par1Packet6SpawnPosition.xPosition, par1Packet6SpawnPosition.yPosition, par1Packet6SpawnPosition.zPosition); + } + + /** + * Packet handler + */ + public void handleAttachEntity(Packet39AttachEntity par1Packet39AttachEntity) { + Object var2 = this.getEntityByID(par1Packet39AttachEntity.entityId); + Entity var3 = this.getEntityByID(par1Packet39AttachEntity.vehicleEntityId); + + if (par1Packet39AttachEntity.entityId == this.mc.thePlayer.entityId) { + var2 = this.mc.thePlayer; + + if (var3 instanceof EntityBoat) { + ((EntityBoat) var3).func_70270_d(false); + } + } else if (var3 instanceof EntityBoat) { + ((EntityBoat) var3).func_70270_d(true); + } + + if (var2 != null) { + ((Entity) var2).mountEntity(var3); + } + } + + /** + * Packet handler + */ + public void handleEntityStatus(Packet38EntityStatus par1Packet38EntityStatus) { + Entity var2 = this.getEntityByID(par1Packet38EntityStatus.entityId); + + if (var2 != null) { + var2.handleHealthUpdate(par1Packet38EntityStatus.entityStatus); + } + } + + private Entity getEntityByID(int par1) { + return (Entity) (par1 == this.mc.thePlayer.entityId ? this.mc.thePlayer : this.worldClient.getEntityByID(par1)); + } + + /** + * Recieves player health from the server and then proceeds to set it locally on + * the client. + */ + public void handleUpdateHealth(Packet8UpdateHealth par1Packet8UpdateHealth) { + this.mc.thePlayer.setHealth(par1Packet8UpdateHealth.healthMP); + this.mc.thePlayer.getFoodStats().setFoodLevel(par1Packet8UpdateHealth.food); + this.mc.thePlayer.getFoodStats().setFoodSaturationLevel(par1Packet8UpdateHealth.foodSaturation); + } + + /** + * Handle an experience packet. + */ + public void handleExperience(Packet43Experience par1Packet43Experience) { + this.mc.thePlayer.setXPStats(par1Packet43Experience.experience, par1Packet43Experience.experienceTotal, par1Packet43Experience.experienceLevel); + } + + /** + * respawns the player + */ + public void handleRespawn(Packet9Respawn par1Packet9Respawn) { + if (par1Packet9Respawn.respawnDimension != this.mc.thePlayer.dimension) { + this.doneLoadingTerrain = false; + Scoreboard var2 = this.worldClient.getScoreboard(); + this.worldClient = new WorldClient(this, new WorldSettings(0L, par1Packet9Respawn.gameType, false, this.mc.theWorld.getWorldInfo().isHardcoreModeEnabled(), par1Packet9Respawn.terrainType), par1Packet9Respawn.respawnDimension, + par1Packet9Respawn.difficulty, this.mc.mcProfiler); + this.worldClient.func_96443_a(var2); + this.worldClient.isRemote = true; + this.mc.loadWorld(this.worldClient); + this.mc.thePlayer.dimension = par1Packet9Respawn.respawnDimension; + this.mc.displayGuiScreen(new GuiDownloadTerrain(this)); + } + + this.mc.setDimensionAndSpawnPlayer(par1Packet9Respawn.respawnDimension); + this.mc.playerController.setGameType(par1Packet9Respawn.gameType); + } + + public void handleExplosion(Packet60Explosion par1Packet60Explosion) { + Explosion var2 = new Explosion(this.mc.theWorld, (Entity) null, par1Packet60Explosion.explosionX, par1Packet60Explosion.explosionY, par1Packet60Explosion.explosionZ, par1Packet60Explosion.explosionSize); + var2.affectedBlockPositions = par1Packet60Explosion.chunkPositionRecords; + var2.doExplosionB(true); + this.mc.thePlayer.motionX += (double) par1Packet60Explosion.getPlayerVelocityX(); + this.mc.thePlayer.motionY += (double) par1Packet60Explosion.getPlayerVelocityY(); + this.mc.thePlayer.motionZ += (double) par1Packet60Explosion.getPlayerVelocityZ(); + } + + public void handleOpenWindow(Packet100OpenWindow par1Packet100OpenWindow) { + EntityClientPlayerMP var2 = this.mc.thePlayer; + + switch (par1Packet100OpenWindow.inventoryType) { + case 0: + var2.displayGUIChest(new InventoryBasic(par1Packet100OpenWindow.windowTitle, par1Packet100OpenWindow.useProvidedWindowTitle, par1Packet100OpenWindow.slotsCount)); + var2.openContainer.windowId = par1Packet100OpenWindow.windowId; + break; + + case 1: + var2.displayGUIWorkbench(MathHelper.floor_double(var2.posX), MathHelper.floor_double(var2.posY), MathHelper.floor_double(var2.posZ)); + var2.openContainer.windowId = par1Packet100OpenWindow.windowId; + break; + + case 2: + TileEntityFurnace var4 = new TileEntityFurnace(); + + if (par1Packet100OpenWindow.useProvidedWindowTitle) { + var4.func_94129_a(par1Packet100OpenWindow.windowTitle); + } + + var2.displayGUIFurnace(var4); + var2.openContainer.windowId = par1Packet100OpenWindow.windowId; + break; + + case 3: + TileEntityDispenser var7 = new TileEntityDispenser(); + + if (par1Packet100OpenWindow.useProvidedWindowTitle) { + var7.setCustomName(par1Packet100OpenWindow.windowTitle); + } + + var2.displayGUIDispenser(var7); + var2.openContainer.windowId = par1Packet100OpenWindow.windowId; + break; + + case 4: + var2.displayGUIEnchantment(MathHelper.floor_double(var2.posX), MathHelper.floor_double(var2.posY), MathHelper.floor_double(var2.posZ), par1Packet100OpenWindow.useProvidedWindowTitle ? par1Packet100OpenWindow.windowTitle : null); + var2.openContainer.windowId = par1Packet100OpenWindow.windowId; + break; + + case 5: + TileEntityBrewingStand var5 = new TileEntityBrewingStand(); + + if (par1Packet100OpenWindow.useProvidedWindowTitle) { + var5.func_94131_a(par1Packet100OpenWindow.windowTitle); + } + + var2.displayGUIBrewingStand(var5); + var2.openContainer.windowId = par1Packet100OpenWindow.windowId; + break; + + case 6: + var2.displayGUIMerchant(new NpcMerchant(var2), par1Packet100OpenWindow.useProvidedWindowTitle ? par1Packet100OpenWindow.windowTitle : null); + var2.openContainer.windowId = par1Packet100OpenWindow.windowId; + break; + + case 7: + TileEntityBeacon var8 = new TileEntityBeacon(); + var2.displayGUIBeacon(var8); + + if (par1Packet100OpenWindow.useProvidedWindowTitle) { + var8.func_94047_a(par1Packet100OpenWindow.windowTitle); + } + + var2.openContainer.windowId = par1Packet100OpenWindow.windowId; + break; + + case 8: + var2.displayGUIAnvil(MathHelper.floor_double(var2.posX), MathHelper.floor_double(var2.posY), MathHelper.floor_double(var2.posZ)); + var2.openContainer.windowId = par1Packet100OpenWindow.windowId; + break; + + case 9: + TileEntityHopper var3 = new TileEntityHopper(); + + if (par1Packet100OpenWindow.useProvidedWindowTitle) { + var3.setInventoryName(par1Packet100OpenWindow.windowTitle); + } + + var2.displayGUIHopper(var3); + var2.openContainer.windowId = par1Packet100OpenWindow.windowId; + break; + + case 10: + TileEntityDropper var6 = new TileEntityDropper(); + + if (par1Packet100OpenWindow.useProvidedWindowTitle) { + var6.setCustomName(par1Packet100OpenWindow.windowTitle); + } + + var2.displayGUIDispenser(var6); + var2.openContainer.windowId = par1Packet100OpenWindow.windowId; + } + } + + public void handleSetSlot(Packet103SetSlot par1Packet103SetSlot) { + EntityClientPlayerMP var2 = this.mc.thePlayer; + + if (par1Packet103SetSlot.windowId == -1) { + var2.inventory.setItemStack(par1Packet103SetSlot.myItemStack); + } else { + boolean var3 = false; + + if (this.mc.currentScreen instanceof GuiContainerCreative) { + GuiContainerCreative var4 = (GuiContainerCreative) this.mc.currentScreen; + var3 = var4.func_74230_h() != CreativeTabs.tabInventory.getTabIndex(); + } + + if (par1Packet103SetSlot.windowId == 0 && par1Packet103SetSlot.itemSlot >= 36 && par1Packet103SetSlot.itemSlot < 45) { + ItemStack var5 = var2.inventoryContainer.getSlot(par1Packet103SetSlot.itemSlot).getStack(); + + if (par1Packet103SetSlot.myItemStack != null && (var5 == null || var5.stackSize < par1Packet103SetSlot.myItemStack.stackSize)) { + par1Packet103SetSlot.myItemStack.animationsToGo = 5; + } + + var2.inventoryContainer.putStackInSlot(par1Packet103SetSlot.itemSlot, par1Packet103SetSlot.myItemStack); + } else if (par1Packet103SetSlot.windowId == var2.openContainer.windowId && (par1Packet103SetSlot.windowId != 0 || !var3)) { + var2.openContainer.putStackInSlot(par1Packet103SetSlot.itemSlot, par1Packet103SetSlot.myItemStack); + } + } + } + + public void handleTransaction(Packet106Transaction par1Packet106Transaction) { + Container var2 = null; + EntityClientPlayerMP var3 = this.mc.thePlayer; + + if (par1Packet106Transaction.windowId == 0) { + var2 = var3.inventoryContainer; + } else if (par1Packet106Transaction.windowId == var3.openContainer.windowId) { + var2 = var3.openContainer; + } + + if (var2 != null && !par1Packet106Transaction.accepted) { + this.addToSendQueue(new Packet106Transaction(par1Packet106Transaction.windowId, par1Packet106Transaction.shortWindowId, true)); + } + } + + public void handleWindowItems(Packet104WindowItems par1Packet104WindowItems) { + EntityClientPlayerMP var2 = this.mc.thePlayer; + + if (par1Packet104WindowItems.windowId == 0) { + var2.inventoryContainer.putStacksInSlots(par1Packet104WindowItems.itemStack); + } else if (par1Packet104WindowItems.windowId == var2.openContainer.windowId) { + var2.openContainer.putStacksInSlots(par1Packet104WindowItems.itemStack); + } + } + + /** + * Updates Client side signs + */ + public void handleUpdateSign(Packet130UpdateSign par1Packet130UpdateSign) { + boolean var2 = false; + + if (this.mc.theWorld.blockExists(par1Packet130UpdateSign.xPosition, par1Packet130UpdateSign.yPosition, par1Packet130UpdateSign.zPosition)) { + TileEntity var3 = this.mc.theWorld.getBlockTileEntity(par1Packet130UpdateSign.xPosition, par1Packet130UpdateSign.yPosition, par1Packet130UpdateSign.zPosition); + + if (var3 instanceof TileEntitySign) { + TileEntitySign var4 = (TileEntitySign) var3; + + if (var4.isEditable()) { + for (int var5 = 0; var5 < 4; ++var5) { + var4.signText[var5] = par1Packet130UpdateSign.signLines[var5]; + } + + var4.onInventoryChanged(); + } + + var2 = true; + } + } + + if (!var2 && this.mc.thePlayer != null) { + this.mc.thePlayer.sendChatToPlayer("Unable to locate sign at " + par1Packet130UpdateSign.xPosition + ", " + par1Packet130UpdateSign.yPosition + ", " + par1Packet130UpdateSign.zPosition); + } + } + + public void handleTileEntityData(Packet132TileEntityData par1Packet132TileEntityData) { + if (this.mc.theWorld.blockExists(par1Packet132TileEntityData.xPosition, par1Packet132TileEntityData.yPosition, par1Packet132TileEntityData.zPosition)) { + TileEntity var2 = this.mc.theWorld.getBlockTileEntity(par1Packet132TileEntityData.xPosition, par1Packet132TileEntityData.yPosition, par1Packet132TileEntityData.zPosition); + + if (var2 != null) { + if (par1Packet132TileEntityData.actionType == 1 && var2 instanceof TileEntityMobSpawner) { + var2.readFromNBT(par1Packet132TileEntityData.customParam1); + } else if (par1Packet132TileEntityData.actionType == 2 && var2 instanceof TileEntityCommandBlock) { + var2.readFromNBT(par1Packet132TileEntityData.customParam1); + } else if (par1Packet132TileEntityData.actionType == 3 && var2 instanceof TileEntityBeacon) { + var2.readFromNBT(par1Packet132TileEntityData.customParam1); + } else if (par1Packet132TileEntityData.actionType == 4 && var2 instanceof TileEntitySkull) { + var2.readFromNBT(par1Packet132TileEntityData.customParam1); + } + } + } + } + + public void handleUpdateProgressbar(Packet105UpdateProgressbar par1Packet105UpdateProgressbar) { + EntityClientPlayerMP var2 = this.mc.thePlayer; + this.unexpectedPacket(par1Packet105UpdateProgressbar); + + if (var2.openContainer != null && var2.openContainer.windowId == par1Packet105UpdateProgressbar.windowId) { + var2.openContainer.updateProgressBar(par1Packet105UpdateProgressbar.progressBar, par1Packet105UpdateProgressbar.progressBarValue); + } + } + + public void handlePlayerInventory(Packet5PlayerInventory par1Packet5PlayerInventory) { + Entity var2 = this.getEntityByID(par1Packet5PlayerInventory.entityID); + + if (var2 != null) { + var2.setCurrentItemOrArmor(par1Packet5PlayerInventory.slot, par1Packet5PlayerInventory.getItemSlot()); + } + } + + public void handleCloseWindow(Packet101CloseWindow par1Packet101CloseWindow) { + this.mc.thePlayer.func_92015_f(); + } + + public void handleBlockEvent(Packet54PlayNoteBlock par1Packet54PlayNoteBlock) { + this.mc.theWorld.addBlockEvent(par1Packet54PlayNoteBlock.xLocation, par1Packet54PlayNoteBlock.yLocation, par1Packet54PlayNoteBlock.zLocation, par1Packet54PlayNoteBlock.blockId, par1Packet54PlayNoteBlock.instrumentType, + par1Packet54PlayNoteBlock.pitch); + } + + public void handleBlockDestroy(Packet55BlockDestroy par1Packet55BlockDestroy) { + this.mc.theWorld.destroyBlockInWorldPartially(par1Packet55BlockDestroy.getEntityId(), par1Packet55BlockDestroy.getPosX(), par1Packet55BlockDestroy.getPosY(), par1Packet55BlockDestroy.getPosZ(), + par1Packet55BlockDestroy.getDestroyedStage()); + } + + public void handleMapChunks(Packet56MapChunks par1Packet56MapChunks) { + for (int var2 = 0; var2 < par1Packet56MapChunks.getNumberOfChunkInPacket(); ++var2) { + int var3 = par1Packet56MapChunks.getChunkPosX(var2); + int var4 = par1Packet56MapChunks.getChunkPosZ(var2); + this.worldClient.doPreChunk(var3, var4, true); + this.worldClient.invalidateBlockReceiveRegion(var3 << 4, 0, var4 << 4, (var3 << 4) + 15, 256, (var4 << 4) + 15); + Chunk var5 = this.worldClient.getChunkFromChunkCoords(var3, var4); + + if (var5 == null) { + this.worldClient.doPreChunk(var3, var4, true); + var5 = this.worldClient.getChunkFromChunkCoords(var3, var4); + } + + if (var5 != null) { + var5.fillChunk(par1Packet56MapChunks.getChunkCompressedData(var2), par1Packet56MapChunks.field_73590_a[var2], par1Packet56MapChunks.field_73588_b[var2], true); + this.worldClient.markBlockRangeForRenderUpdate(var3 << 4, 0, var4 << 4, (var3 << 4) + 15, 256, (var4 << 4) + 15); + + if (!(this.worldClient.provider instanceof WorldProviderSurface)) { + var5.resetRelightChecks(); + } + } + } + } + + /** + * If this returns false, all packets will be queued for the main thread to + * handle, even if they would otherwise be processed asynchronously. Used to + * avoid processing packets on the client before the world has been downloaded + * (which happens on the main thread) + */ + public boolean canProcessPacketsAsync() { + return this.mc != null && this.mc.theWorld != null && this.mc.thePlayer != null && this.worldClient != null; + } + + public void handleGameEvent(Packet70GameEvent par1Packet70GameEvent) { + EntityClientPlayerMP var2 = this.mc.thePlayer; + int var3 = par1Packet70GameEvent.eventType; + int var4 = par1Packet70GameEvent.gameMode; + + if (var3 >= 0 && var3 < Packet70GameEvent.clientMessage.length && Packet70GameEvent.clientMessage[var3] != null) { + var2.addChatMessage(Packet70GameEvent.clientMessage[var3]); + } + + if (var3 == 1) { + this.worldClient.getWorldInfo().setRaining(true); + this.worldClient.setRainStrength(0.0F); + } else if (var3 == 2) { + this.worldClient.getWorldInfo().setRaining(false); + this.worldClient.setRainStrength(1.0F); + } else if (var3 == 3) { + this.mc.playerController.setGameType(EnumGameType.getByID(var4)); + } else if (var3 == 4) { + this.mc.displayGuiScreen(new GuiWinGame()); + } else if (var3 == 5) { + GameSettings var5 = this.mc.gameSettings; + + if (var4 == 0) { + return; + } else if (var4 == 101) { + this.mc.ingameGUI.getChatGUI().addTranslatedMessage("demo.help.movement", + new Object[] { EaglerAdapter.getKeyName(var5.keyBindForward.keyCode), EaglerAdapter.getKeyName(var5.keyBindLeft.keyCode), EaglerAdapter.getKeyName(var5.keyBindBack.keyCode), EaglerAdapter.getKeyName(var5.keyBindRight.keyCode) }); + } else if (var4 == 102) { + this.mc.ingameGUI.getChatGUI().addTranslatedMessage("demo.help.jump", new Object[] { EaglerAdapter.getKeyName(var5.keyBindJump.keyCode) }); + } else if (var4 == 103) { + this.mc.ingameGUI.getChatGUI().addTranslatedMessage("demo.help.inventory", new Object[] { EaglerAdapter.getKeyName(var5.keyBindInventory.keyCode) }); + } + } else if (var3 == 6) { + this.worldClient.playSound(var2.posX, var2.posY + (double) var2.getEyeHeight(), var2.posZ, "random.successful_hit", 0.18F, 0.45F, false); + } + } + + /** + * Contains logic for handling packets containing arbitrary unique item data. + * Currently this is only for maps. + */ + public void handleMapData(Packet131MapData par1Packet131MapData) { + if (par1Packet131MapData.itemID == Item.map.itemID) { + ItemMap.getMPMapData(par1Packet131MapData.uniqueID, this.mc.theWorld).updateMPMapData(par1Packet131MapData.itemData); + } else { + System.err.println("Unknown itemid: " + par1Packet131MapData.uniqueID); + } + } + + public void handleDoorChange(Packet61DoorChange par1Packet61DoorChange) { + if (par1Packet61DoorChange.getRelativeVolumeDisabled()) { + this.mc.theWorld.func_82739_e(par1Packet61DoorChange.sfxID, par1Packet61DoorChange.posX, par1Packet61DoorChange.posY, par1Packet61DoorChange.posZ, par1Packet61DoorChange.auxData); + } else { + this.mc.theWorld.playAuxSFX(par1Packet61DoorChange.sfxID, par1Packet61DoorChange.posX, par1Packet61DoorChange.posY, par1Packet61DoorChange.posZ, par1Packet61DoorChange.auxData); + } + } + + /** + * Increment player statistics + */ + public void handleStatistic(Packet200Statistic par1Packet200Statistic) { + if(par1Packet200Statistic.statisticId >= 5242880) { + for(Achievement m : AchievementList.achievementList) { + if(m.statId == par1Packet200Statistic.statisticId) { + this.mc.thePlayer.incrementStat(m, 1); + break; + } + } + } + } + + /** + * Handle an entity effect packet. + */ + public void handleEntityEffect(Packet41EntityEffect par1Packet41EntityEffect) { + Entity var2 = this.getEntityByID(par1Packet41EntityEffect.entityId); + + if (var2 instanceof EntityLiving) { + PotionEffect var3 = new PotionEffect(par1Packet41EntityEffect.effectId, par1Packet41EntityEffect.duration, par1Packet41EntityEffect.effectAmplifier); + var3.setPotionDurationMax(par1Packet41EntityEffect.isDurationMax()); + ((EntityLiving) var2).addPotionEffect(var3); + } + } + + /** + * Handle a remove entity effect packet. + */ + public void handleRemoveEntityEffect(Packet42RemoveEntityEffect par1Packet42RemoveEntityEffect) { + Entity var2 = this.getEntityByID(par1Packet42RemoveEntityEffect.entityId); + + if (var2 instanceof EntityLiving) { + ((EntityLiving) var2).removePotionEffectClient(par1Packet42RemoveEntityEffect.effectId); + } + } + + /** + * determine if it is a server handler + */ + public boolean isServerHandler() { + return false; + } + + /** + * Handle a player information packet. + */ + public void handlePlayerInfo(Packet201PlayerInfo par1Packet201PlayerInfo) { + GuiPlayerInfo var2 = (GuiPlayerInfo) this.playerInfoMap.get(par1Packet201PlayerInfo.playerName); + + if (var2 == null && par1Packet201PlayerInfo.isConnected) { + var2 = new GuiPlayerInfo(par1Packet201PlayerInfo.playerName); + this.playerInfoMap.put(par1Packet201PlayerInfo.playerName, var2); + this.playerInfoList.add(var2); + } + + if (var2 != null && !par1Packet201PlayerInfo.isConnected) { + this.playerInfoMap.remove(par1Packet201PlayerInfo.playerName); + this.playerInfoList.remove(var2); + } + + if (par1Packet201PlayerInfo.isConnected && var2 != null) { + var2.responseTime = par1Packet201PlayerInfo.ping; + } + } + + /** + * Handle a keep alive packet. + */ + public void handleKeepAlive(Packet0KeepAlive par1Packet0KeepAlive) { + this.addToSendQueue(new Packet0KeepAlive(par1Packet0KeepAlive.randomId)); + } + + /** + * Handle a player abilities packet. + */ + public void handlePlayerAbilities(Packet202PlayerAbilities par1Packet202PlayerAbilities) { + EntityClientPlayerMP var2 = this.mc.thePlayer; + var2.capabilities.isFlying = par1Packet202PlayerAbilities.getFlying(); + var2.capabilities.isCreativeMode = par1Packet202PlayerAbilities.isCreativeMode(); + var2.capabilities.disableDamage = par1Packet202PlayerAbilities.getDisableDamage(); + var2.capabilities.allowFlying = par1Packet202PlayerAbilities.getAllowFlying(); + var2.capabilities.setFlySpeed(par1Packet202PlayerAbilities.getFlySpeed()); + var2.capabilities.setPlayerWalkSpeed(par1Packet202PlayerAbilities.getWalkSpeed()); + } + + public void handleAutoComplete(Packet203AutoComplete par1Packet203AutoComplete) { + String[] var2 = par1Packet203AutoComplete.getText().split("\u0000"); + + if (this.mc.currentScreen instanceof GuiChat) { + GuiChat var3 = (GuiChat) this.mc.currentScreen; + var3.func_73894_a(var2); + } + } + + public void handleLevelSound(Packet62LevelSound par1Packet62LevelSound) { + this.mc.theWorld.playSound(par1Packet62LevelSound.getEffectX(), par1Packet62LevelSound.getEffectY(), par1Packet62LevelSound.getEffectZ(), par1Packet62LevelSound.getSoundName(), par1Packet62LevelSound.getVolume(), + par1Packet62LevelSound.getPitch(), false); + } + + public void handleCustomPayload(Packet250CustomPayload par1Packet250CustomPayload) { + if ("MC|TrList".equals(par1Packet250CustomPayload.channel)) { + DataInputStream var8 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data)); + + try { + int var9 = var8.readInt(); + GuiScreen var4 = this.mc.currentScreen; + + if (var4 != null && var4 instanceof GuiMerchant && var9 == this.mc.thePlayer.openContainer.windowId) { + IMerchant var5 = ((GuiMerchant) var4).getIMerchant(); + MerchantRecipeList var6 = MerchantRecipeList.readRecipiesFromStream(var8); + var5.setRecipes(var6); + } + } catch (IOException var7) { + var7.printStackTrace(); + } + }else if("EAG|UserSkin".equals(par1Packet250CustomPayload.channel)) { + DefaultSkinRenderer.skinResponse(par1Packet250CustomPayload.data); + } + } + + /** + * Handle a set objective packet. + */ + public void handleSetObjective(Packet206SetObjective par1Packet206SetObjective) { + Scoreboard var2 = this.worldClient.getScoreboard(); + ScoreObjective var3; + + if (par1Packet206SetObjective.change == 0) { + var3 = var2.func_96535_a(par1Packet206SetObjective.objectiveName, ScoreObjectiveCriteria.field_96641_b); + var3.setDisplayName(par1Packet206SetObjective.objectiveDisplayName); + } else { + var3 = var2.getObjective(par1Packet206SetObjective.objectiveName); + + if (par1Packet206SetObjective.change == 1) { + var2.func_96519_k(var3); + } else if (par1Packet206SetObjective.change == 2) { + var3.setDisplayName(par1Packet206SetObjective.objectiveDisplayName); + } + } + } + + /** + * Handle a set score packet. + */ + public void handleSetScore(Packet207SetScore par1Packet207SetScore) { + Scoreboard var2 = this.worldClient.getScoreboard(); + ScoreObjective var3 = var2.getObjective(par1Packet207SetScore.scoreName); + + if (par1Packet207SetScore.updateOrRemove == 0) { + Score var4 = var2.func_96529_a(par1Packet207SetScore.itemName, var3); + var4.func_96647_c(par1Packet207SetScore.value); + } else if (par1Packet207SetScore.updateOrRemove == 1) { + var2.func_96515_c(par1Packet207SetScore.itemName); + } + } + + /** + * Handle a set display objective packet. + */ + public void handleSetDisplayObjective(Packet208SetDisplayObjective par1Packet208SetDisplayObjective) { + Scoreboard var2 = this.worldClient.getScoreboard(); + + if (par1Packet208SetDisplayObjective.scoreName.length() == 0) { + var2.func_96530_a(par1Packet208SetDisplayObjective.scoreboardPosition, (ScoreObjective) null); + } else { + ScoreObjective var3 = var2.getObjective(par1Packet208SetDisplayObjective.scoreName); + var2.func_96530_a(par1Packet208SetDisplayObjective.scoreboardPosition, var3); + } + } + + /** + * Handle a set player team packet. + */ + public void handleSetPlayerTeam(Packet209SetPlayerTeam par1Packet209SetPlayerTeam) { + Scoreboard var2 = this.worldClient.getScoreboard(); + ScorePlayerTeam var3; + + if (par1Packet209SetPlayerTeam.mode == 0) { + var3 = var2.func_96527_f(par1Packet209SetPlayerTeam.teamName); + } else { + var3 = var2.func_96508_e(par1Packet209SetPlayerTeam.teamName); + } + + if (par1Packet209SetPlayerTeam.mode == 0 || par1Packet209SetPlayerTeam.mode == 2) { + var3.func_96664_a(par1Packet209SetPlayerTeam.teamDisplayName); + var3.func_96666_b(par1Packet209SetPlayerTeam.teamPrefix); + var3.func_96662_c(par1Packet209SetPlayerTeam.teamSuffix); + var3.func_98298_a(par1Packet209SetPlayerTeam.friendlyFire); + } + + Iterator var4; + String var5; + + if (par1Packet209SetPlayerTeam.mode == 0 || par1Packet209SetPlayerTeam.mode == 3) { + var4 = par1Packet209SetPlayerTeam.playerNames.iterator(); + + while (var4.hasNext()) { + var5 = (String) var4.next(); + var2.func_96521_a(var5, var3); + } + } + + if (par1Packet209SetPlayerTeam.mode == 4) { + var4 = par1Packet209SetPlayerTeam.playerNames.iterator(); + + while (var4.hasNext()) { + var5 = (String) var4.next(); + var2.removePlayerFromTeam(var5, var3); + } + } + + if (par1Packet209SetPlayerTeam.mode == 1) { + var2.func_96511_d(var3); + } + } + + /** + * Handle a world particles packet. + */ + public void handleWorldParticles(Packet63WorldParticles par1Packet63WorldParticles) { + for (int var2 = 0; var2 < par1Packet63WorldParticles.getQuantity(); ++var2) { + double var3 = this.rand.nextGaussian() * (double) par1Packet63WorldParticles.getOffsetX(); + double var5 = this.rand.nextGaussian() * (double) par1Packet63WorldParticles.getOffsetY(); + double var7 = this.rand.nextGaussian() * (double) par1Packet63WorldParticles.getOffsetZ(); + double var9 = this.rand.nextGaussian() * (double) par1Packet63WorldParticles.getSpeed(); + double var11 = this.rand.nextGaussian() * (double) par1Packet63WorldParticles.getSpeed(); + double var13 = this.rand.nextGaussian() * (double) par1Packet63WorldParticles.getSpeed(); + this.worldClient.spawnParticle(par1Packet63WorldParticles.getParticleName(), par1Packet63WorldParticles.getPositionX() + var3, par1Packet63WorldParticles.getPositionY() + var5, par1Packet63WorldParticles.getPositionZ() + var7, + var9, var11, var13); + } + } + + /** + * Return the NetworkManager instance used by this NetClientHandler + */ + public INetworkManager getNetManager() { + return this.netManager; + } +} diff --git a/src/main/java/net/minecraft/src/NetHandler.java b/src/main/java/net/minecraft/src/NetHandler.java new file mode 100644 index 0000000..64671e0 --- /dev/null +++ b/src/main/java/net/minecraft/src/NetHandler.java @@ -0,0 +1,400 @@ +package net.minecraft.src; + +public abstract class NetHandler { + /** + * determine if it is a server handler + */ + public abstract boolean isServerHandler(); + + /** + * Handle Packet51MapChunk (full chunk update of blocks, metadata, light levels, + * and optionally biome data) + */ + public void handleMapChunk(Packet51MapChunk par1Packet51MapChunk) { + } + + /** + * Default handler called for packets that don't have their own handlers in + * NetClientHandler; currentlly does nothing. + */ + public void unexpectedPacket(Packet par1Packet) { + } + + public void handleErrorMessage(String par1Str, Object[] par2ArrayOfObj) { + } + + public void handleKickDisconnect(Packet255KickDisconnect par1Packet255KickDisconnect) { + this.unexpectedPacket(par1Packet255KickDisconnect); + } + + public void handleLogin(Packet1Login par1Packet1Login) { + this.unexpectedPacket(par1Packet1Login); + } + + public void handleFlying(Packet10Flying par1Packet10Flying) { + this.unexpectedPacket(par1Packet10Flying); + } + + public void handleMultiBlockChange(Packet52MultiBlockChange par1Packet52MultiBlockChange) { + this.unexpectedPacket(par1Packet52MultiBlockChange); + } + + public void handleBlockDig(Packet14BlockDig par1Packet14BlockDig) { + this.unexpectedPacket(par1Packet14BlockDig); + } + + public void handleBlockChange(Packet53BlockChange par1Packet53BlockChange) { + this.unexpectedPacket(par1Packet53BlockChange); + } + + public void handleNamedEntitySpawn(Packet20NamedEntitySpawn par1Packet20NamedEntitySpawn) { + this.unexpectedPacket(par1Packet20NamedEntitySpawn); + } + + public void handleEntity(Packet30Entity par1Packet30Entity) { + this.unexpectedPacket(par1Packet30Entity); + } + + public void handleEntityTeleport(Packet34EntityTeleport par1Packet34EntityTeleport) { + this.unexpectedPacket(par1Packet34EntityTeleport); + } + + public void handlePlace(Packet15Place par1Packet15Place) { + this.unexpectedPacket(par1Packet15Place); + } + + public void handleBlockItemSwitch(Packet16BlockItemSwitch par1Packet16BlockItemSwitch) { + this.unexpectedPacket(par1Packet16BlockItemSwitch); + } + + public void handleDestroyEntity(Packet29DestroyEntity par1Packet29DestroyEntity) { + this.unexpectedPacket(par1Packet29DestroyEntity); + } + + public void handleCollect(Packet22Collect par1Packet22Collect) { + this.unexpectedPacket(par1Packet22Collect); + } + + public void handleChat(Packet3Chat par1Packet3Chat) { + this.unexpectedPacket(par1Packet3Chat); + } + + public void handleVehicleSpawn(Packet23VehicleSpawn par1Packet23VehicleSpawn) { + this.unexpectedPacket(par1Packet23VehicleSpawn); + } + + public void handleAnimation(Packet18Animation par1Packet18Animation) { + this.unexpectedPacket(par1Packet18Animation); + } + + /** + * runs registerPacket on the given Packet19EntityAction + */ + public void handleEntityAction(Packet19EntityAction par1Packet19EntityAction) { + this.unexpectedPacket(par1Packet19EntityAction); + } + + public void handleClientProtocol(Packet2ClientProtocol par1Packet2ClientProtocol) { + this.unexpectedPacket(par1Packet2ClientProtocol); + } + + public void handleServerAuthData(Packet253ServerAuthData par1Packet253ServerAuthData) { + this.unexpectedPacket(par1Packet253ServerAuthData); + } + + public void handleSharedKey(Packet252SharedKey par1Packet252SharedKey) { + this.unexpectedPacket(par1Packet252SharedKey); + } + + public void handleMobSpawn(Packet24MobSpawn par1Packet24MobSpawn) { + this.unexpectedPacket(par1Packet24MobSpawn); + } + + public void handleUpdateTime(Packet4UpdateTime par1Packet4UpdateTime) { + this.unexpectedPacket(par1Packet4UpdateTime); + } + + public void handleSpawnPosition(Packet6SpawnPosition par1Packet6SpawnPosition) { + this.unexpectedPacket(par1Packet6SpawnPosition); + } + + /** + * Packet handler + */ + public void handleEntityVelocity(Packet28EntityVelocity par1Packet28EntityVelocity) { + this.unexpectedPacket(par1Packet28EntityVelocity); + } + + /** + * Packet handler + */ + public void handleEntityMetadata(Packet40EntityMetadata par1Packet40EntityMetadata) { + this.unexpectedPacket(par1Packet40EntityMetadata); + } + + /** + * Packet handler + */ + public void handleAttachEntity(Packet39AttachEntity par1Packet39AttachEntity) { + this.unexpectedPacket(par1Packet39AttachEntity); + } + + public void handleUseEntity(Packet7UseEntity par1Packet7UseEntity) { + this.unexpectedPacket(par1Packet7UseEntity); + } + + /** + * Packet handler + */ + public void handleEntityStatus(Packet38EntityStatus par1Packet38EntityStatus) { + this.unexpectedPacket(par1Packet38EntityStatus); + } + + /** + * Recieves player health from the server and then proceeds to set it locally on + * the client. + */ + public void handleUpdateHealth(Packet8UpdateHealth par1Packet8UpdateHealth) { + this.unexpectedPacket(par1Packet8UpdateHealth); + } + + /** + * respawns the player + */ + public void handleRespawn(Packet9Respawn par1Packet9Respawn) { + this.unexpectedPacket(par1Packet9Respawn); + } + + public void handleExplosion(Packet60Explosion par1Packet60Explosion) { + this.unexpectedPacket(par1Packet60Explosion); + } + + public void handleOpenWindow(Packet100OpenWindow par1Packet100OpenWindow) { + this.unexpectedPacket(par1Packet100OpenWindow); + } + + public void handleCloseWindow(Packet101CloseWindow par1Packet101CloseWindow) { + this.unexpectedPacket(par1Packet101CloseWindow); + } + + public void handleWindowClick(Packet102WindowClick par1Packet102WindowClick) { + this.unexpectedPacket(par1Packet102WindowClick); + } + + public void handleSetSlot(Packet103SetSlot par1Packet103SetSlot) { + this.unexpectedPacket(par1Packet103SetSlot); + } + + public void handleWindowItems(Packet104WindowItems par1Packet104WindowItems) { + this.unexpectedPacket(par1Packet104WindowItems); + } + + /** + * Updates Client side signs + */ + public void handleUpdateSign(Packet130UpdateSign par1Packet130UpdateSign) { + this.unexpectedPacket(par1Packet130UpdateSign); + } + + public void handleUpdateProgressbar(Packet105UpdateProgressbar par1Packet105UpdateProgressbar) { + this.unexpectedPacket(par1Packet105UpdateProgressbar); + } + + public void handlePlayerInventory(Packet5PlayerInventory par1Packet5PlayerInventory) { + this.unexpectedPacket(par1Packet5PlayerInventory); + } + + public void handleTransaction(Packet106Transaction par1Packet106Transaction) { + this.unexpectedPacket(par1Packet106Transaction); + } + + /** + * Packet handler + */ + public void handleEntityPainting(Packet25EntityPainting par1Packet25EntityPainting) { + this.unexpectedPacket(par1Packet25EntityPainting); + } + + public void handleBlockEvent(Packet54PlayNoteBlock par1Packet54PlayNoteBlock) { + this.unexpectedPacket(par1Packet54PlayNoteBlock); + } + + /** + * Increment player statistics + */ + public void handleStatistic(Packet200Statistic par1Packet200Statistic) { + this.unexpectedPacket(par1Packet200Statistic); + } + + public void handleSleep(Packet17Sleep par1Packet17Sleep) { + this.unexpectedPacket(par1Packet17Sleep); + } + + public void handleGameEvent(Packet70GameEvent par1Packet70GameEvent) { + this.unexpectedPacket(par1Packet70GameEvent); + } + + /** + * Handles weather packet + */ + public void handleWeather(Packet71Weather par1Packet71Weather) { + this.unexpectedPacket(par1Packet71Weather); + } + + /** + * Contains logic for handling packets containing arbitrary unique item data. + * Currently this is only for maps. + */ + public void handleMapData(Packet131MapData par1Packet131MapData) { + this.unexpectedPacket(par1Packet131MapData); + } + + public void handleDoorChange(Packet61DoorChange par1Packet61DoorChange) { + this.unexpectedPacket(par1Packet61DoorChange); + } + + /** + * Handle a server ping packet. + */ + public void handleServerPing(Packet254ServerPing par1Packet254ServerPing) { + this.unexpectedPacket(par1Packet254ServerPing); + } + + /** + * Handle an entity effect packet. + */ + public void handleEntityEffect(Packet41EntityEffect par1Packet41EntityEffect) { + this.unexpectedPacket(par1Packet41EntityEffect); + } + + /** + * Handle a remove entity effect packet. + */ + public void handleRemoveEntityEffect(Packet42RemoveEntityEffect par1Packet42RemoveEntityEffect) { + this.unexpectedPacket(par1Packet42RemoveEntityEffect); + } + + /** + * Handle a player information packet. + */ + public void handlePlayerInfo(Packet201PlayerInfo par1Packet201PlayerInfo) { + this.unexpectedPacket(par1Packet201PlayerInfo); + } + + /** + * Handle a keep alive packet. + */ + public void handleKeepAlive(Packet0KeepAlive par1Packet0KeepAlive) { + this.unexpectedPacket(par1Packet0KeepAlive); + } + + /** + * Handle an experience packet. + */ + public void handleExperience(Packet43Experience par1Packet43Experience) { + this.unexpectedPacket(par1Packet43Experience); + } + + /** + * Handle a creative slot packet. + */ + public void handleCreativeSetSlot(Packet107CreativeSetSlot par1Packet107CreativeSetSlot) { + this.unexpectedPacket(par1Packet107CreativeSetSlot); + } + + /** + * Handle a entity experience orb packet. + */ + public void handleEntityExpOrb(Packet26EntityExpOrb par1Packet26EntityExpOrb) { + this.unexpectedPacket(par1Packet26EntityExpOrb); + } + + public void handleEnchantItem(Packet108EnchantItem par1Packet108EnchantItem) { + } + + public void handleCustomPayload(Packet250CustomPayload par1Packet250CustomPayload) { + } + + public void handleEntityHeadRotation(Packet35EntityHeadRotation par1Packet35EntityHeadRotation) { + this.unexpectedPacket(par1Packet35EntityHeadRotation); + } + + public void handleTileEntityData(Packet132TileEntityData par1Packet132TileEntityData) { + this.unexpectedPacket(par1Packet132TileEntityData); + } + + /** + * Handle a player abilities packet. + */ + public void handlePlayerAbilities(Packet202PlayerAbilities par1Packet202PlayerAbilities) { + this.unexpectedPacket(par1Packet202PlayerAbilities); + } + + public void handleAutoComplete(Packet203AutoComplete par1Packet203AutoComplete) { + this.unexpectedPacket(par1Packet203AutoComplete); + } + + public void handleClientInfo(Packet204ClientInfo par1Packet204ClientInfo) { + this.unexpectedPacket(par1Packet204ClientInfo); + } + + public void handleLevelSound(Packet62LevelSound par1Packet62LevelSound) { + this.unexpectedPacket(par1Packet62LevelSound); + } + + public void handleBlockDestroy(Packet55BlockDestroy par1Packet55BlockDestroy) { + this.unexpectedPacket(par1Packet55BlockDestroy); + } + + public void handleClientCommand(Packet205ClientCommand par1Packet205ClientCommand) { + } + + public void handleMapChunks(Packet56MapChunks par1Packet56MapChunks) { + this.unexpectedPacket(par1Packet56MapChunks); + } + + /** + * If this returns false, all packets will be queued for the main thread to + * handle, even if they would otherwise be processed asynchronously. Used to + * avoid processing packets on the client before the world has been downloaded + * (which happens on the main thread) + */ + public boolean canProcessPacketsAsync() { + return false; + } + + /** + * Handle a set objective packet. + */ + public void handleSetObjective(Packet206SetObjective par1Packet206SetObjective) { + this.unexpectedPacket(par1Packet206SetObjective); + } + + /** + * Handle a set score packet. + */ + public void handleSetScore(Packet207SetScore par1Packet207SetScore) { + this.unexpectedPacket(par1Packet207SetScore); + } + + /** + * Handle a set display objective packet. + */ + public void handleSetDisplayObjective(Packet208SetDisplayObjective par1Packet208SetDisplayObjective) { + this.unexpectedPacket(par1Packet208SetDisplayObjective); + } + + /** + * Handle a set player team packet. + */ + public void handleSetPlayerTeam(Packet209SetPlayerTeam par1Packet209SetPlayerTeam) { + this.unexpectedPacket(par1Packet209SetPlayerTeam); + } + + /** + * Handle a world particles packet. + */ + public void handleWorldParticles(Packet63WorldParticles par1Packet63WorldParticles) { + this.unexpectedPacket(par1Packet63WorldParticles); + } +} diff --git a/src/main/java/net/minecraft/src/NextTickListEntry.java b/src/main/java/net/minecraft/src/NextTickListEntry.java new file mode 100644 index 0000000..0fb9a4b --- /dev/null +++ b/src/main/java/net/minecraft/src/NextTickListEntry.java @@ -0,0 +1,80 @@ +package net.minecraft.src; + +public class NextTickListEntry implements Comparable { + /** The id number for the next tick entry */ + private static long nextTickEntryID = 0L; + + /** X position this tick is occuring at */ + public int xCoord; + + /** Y position this tick is occuring at */ + public int yCoord; + + /** Z position this tick is occuring at */ + public int zCoord; + + /** + * blockID of the scheduled tick (ensures when the tick occurs its still for + * this block) + */ + public int blockID; + + /** Time this tick is scheduled to occur at */ + public long scheduledTime; + public int field_82754_f; + + /** The id of the tick entry */ + private long tickEntryID; + + public NextTickListEntry(int par1, int par2, int par3, int par4) { + this.tickEntryID = (long) (nextTickEntryID++); + this.xCoord = par1; + this.yCoord = par2; + this.zCoord = par3; + this.blockID = par4; + } + + public boolean equals(Object par1Obj) { + if (!(par1Obj instanceof NextTickListEntry)) { + return false; + } else { + NextTickListEntry var2 = (NextTickListEntry) par1Obj; + return this.xCoord == var2.xCoord && this.yCoord == var2.yCoord && this.zCoord == var2.zCoord && Block.isAssociatedBlockID(this.blockID, var2.blockID); + } + } + + public int hashCode() { + return (this.xCoord * 1024 * 1024 + this.zCoord * 1024 + this.yCoord) * 256; + } + + /** + * Sets the scheduled time for this tick entry + */ + public NextTickListEntry setScheduledTime(long par1) { + this.scheduledTime = par1; + return this; + } + + public void func_82753_a(int par1) { + this.field_82754_f = par1; + } + + /** + * Compares this tick entry to another tick entry for sorting purposes. Compared + * first based on the scheduled time and second based on tickEntryID. + */ + public int comparer(NextTickListEntry par1NextTickListEntry) { + return this.scheduledTime < par1NextTickListEntry.scheduledTime ? -1 + : (this.scheduledTime > par1NextTickListEntry.scheduledTime ? 1 + : (this.field_82754_f != par1NextTickListEntry.field_82754_f ? this.field_82754_f - par1NextTickListEntry.field_82754_f + : (this.tickEntryID < par1NextTickListEntry.tickEntryID ? -1 : (this.tickEntryID > par1NextTickListEntry.tickEntryID ? 1 : 0)))); + } + + public String toString() { + return this.blockID + ": (" + this.xCoord + ", " + this.yCoord + ", " + this.zCoord + "), " + this.scheduledTime + ", " + this.field_82754_f + ", " + this.tickEntryID; + } + + public int compareTo(Object par1Obj) { + return this.comparer((NextTickListEntry) par1Obj); + } +} diff --git a/src/main/java/net/minecraft/src/NibbleArray.java b/src/main/java/net/minecraft/src/NibbleArray.java new file mode 100644 index 0000000..608d328 --- /dev/null +++ b/src/main/java/net/minecraft/src/NibbleArray.java @@ -0,0 +1,59 @@ +package net.minecraft.src; + +public class NibbleArray { + /** + * Byte array of data stored in this holder. Possibly a light map or some chunk + * data. Data is accessed in 4-bit pieces. + */ + public final byte[] data; + + /** + * Log base 2 of the chunk height (128); applied as a shift on Z coordinate + */ + private final int depthBits; + + /** + * Log base 2 of the chunk height (128) * width (16); applied as a shift on X + * coordinate + */ + private final int depthBitsPlusFour; + + public NibbleArray(int par1, int par2) { + this.data = new byte[par1 >> 1]; + this.depthBits = par2; + this.depthBitsPlusFour = par2 + 4; + } + + public NibbleArray(byte[] par1ArrayOfByte, int par2) { + this.data = par1ArrayOfByte; + this.depthBits = par2; + this.depthBitsPlusFour = par2 + 4; + } + + /** + * Returns the nibble of data corresponding to the passed in x, y, z. y is at + * most 6 bits, z is at most 4. + */ + public int get(int par1, int par2, int par3) { + int var4 = par2 << this.depthBitsPlusFour | par3 << this.depthBits | par1; + int var5 = var4 >> 1; + int var6 = var4 & 1; + return var6 == 0 ? this.data[var5] & 15 : this.data[var5] >> 4 & 15; + } + + /** + * Arguments are x, y, z, val. Sets the nibble of data at x << 11 | z << 7 | y + * to val. + */ + public void set(int par1, int par2, int par3, int par4) { + int var5 = par2 << this.depthBitsPlusFour | par3 << this.depthBits | par1; + int var6 = var5 >> 1; + int var7 = var5 & 1; + + if (var7 == 0) { + this.data[var6] = (byte) (this.data[var6] & 240 | par4 & 15); + } else { + this.data[var6] = (byte) (this.data[var6] & 15 | (par4 & 15) << 4); + } + } +} diff --git a/src/main/java/net/minecraft/src/NibbleArrayReader.java b/src/main/java/net/minecraft/src/NibbleArrayReader.java new file mode 100644 index 0000000..3299cb7 --- /dev/null +++ b/src/main/java/net/minecraft/src/NibbleArrayReader.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +public class NibbleArrayReader { + public final byte[] data; + private final int depthBits; + private final int depthBitsPlusFour; + + public NibbleArrayReader(byte[] par1ArrayOfByte, int par2) { + this.data = par1ArrayOfByte; + this.depthBits = par2; + this.depthBitsPlusFour = par2 + 4; + } + + public int get(int par1, int par2, int par3) { + int var4 = par1 << this.depthBitsPlusFour | par3 << this.depthBits | par2; + int var5 = var4 >> 1; + int var6 = var4 & 1; + return var6 == 0 ? this.data[var5] & 15 : this.data[var5] >> 4 & 15; + } +} diff --git a/src/main/java/net/minecraft/src/NoiseGenerator.java b/src/main/java/net/minecraft/src/NoiseGenerator.java new file mode 100644 index 0000000..bb08431 --- /dev/null +++ b/src/main/java/net/minecraft/src/NoiseGenerator.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +public abstract class NoiseGenerator { +} diff --git a/src/main/java/net/minecraft/src/NoiseGeneratorOctaves.java b/src/main/java/net/minecraft/src/NoiseGeneratorOctaves.java new file mode 100644 index 0000000..3828722 --- /dev/null +++ b/src/main/java/net/minecraft/src/NoiseGeneratorOctaves.java @@ -0,0 +1,62 @@ +package net.minecraft.src; + +import java.util.Random; + +public class NoiseGeneratorOctaves extends NoiseGenerator { + /** + * Collection of noise generation functions. Output is combined to produce + * different octaves of noise. + */ + private NoiseGeneratorPerlin[] generatorCollection; + private int octaves; + + public NoiseGeneratorOctaves(Random par1Random, int par2) { + this.octaves = par2; + this.generatorCollection = new NoiseGeneratorPerlin[par2]; + + for (int var3 = 0; var3 < par2; ++var3) { + this.generatorCollection[var3] = new NoiseGeneratorPerlin(par1Random); + } + } + + /** + * pars:(par2,3,4=noiseOffset ; so that adjacent noise segments connect) + * (pars5,6,7=x,y,zArraySize),(pars8,10,12 = x,y,z noiseScale) + */ + public double[] generateNoiseOctaves(double[] par1ArrayOfDouble, int par2, int par3, int par4, int par5, int par6, int par7, double par8, double par10, double par12) { + if (par1ArrayOfDouble == null) { + par1ArrayOfDouble = new double[par5 * par6 * par7]; + } else { + for (int var14 = 0; var14 < par1ArrayOfDouble.length; ++var14) { + par1ArrayOfDouble[var14] = 0.0D; + } + } + + double var27 = 1.0D; + + for (int var16 = 0; var16 < this.octaves; ++var16) { + double var17 = (double) par2 * var27 * par8; + double var19 = (double) par3 * var27 * par10; + double var21 = (double) par4 * var27 * par12; + long var23 = MathHelper.floor_double_long(var17); + long var25 = MathHelper.floor_double_long(var21); + var17 -= (double) var23; + var21 -= (double) var25; + var23 %= 16777216L; + var25 %= 16777216L; + var17 += (double) var23; + var21 += (double) var25; + this.generatorCollection[var16].populateNoiseArray(par1ArrayOfDouble, var17, var19, var21, par5, par6, par7, par8 * var27, par10 * var27, par12 * var27, var27); + var27 /= 2.0D; + } + + return par1ArrayOfDouble; + } + + /** + * Bouncer function to the main one with some default arguments. + */ + public double[] generateNoiseOctaves(double[] par1ArrayOfDouble, int par2, int par3, int par4, int par5, double par6, double par8, double par10) { + return this.generateNoiseOctaves(par1ArrayOfDouble, par2, 10, par3, par4, 1, par5, par6, 1.0D, par8); + } +} diff --git a/src/main/java/net/minecraft/src/NoiseGeneratorPerlin.java b/src/main/java/net/minecraft/src/NoiseGeneratorPerlin.java new file mode 100644 index 0000000..3fe459c --- /dev/null +++ b/src/main/java/net/minecraft/src/NoiseGeneratorPerlin.java @@ -0,0 +1,190 @@ +package net.minecraft.src; + +import java.util.Random; + +public class NoiseGeneratorPerlin extends NoiseGenerator { + private int[] permutations; + public double xCoord; + public double yCoord; + public double zCoord; + + public NoiseGeneratorPerlin() { + this(new Random()); + } + + public NoiseGeneratorPerlin(Random par1Random) { + this.permutations = new int[512]; + this.xCoord = par1Random.nextDouble() * 256.0D; + this.yCoord = par1Random.nextDouble() * 256.0D; + this.zCoord = par1Random.nextDouble() * 256.0D; + int var2; + + for (var2 = 0; var2 < 256; this.permutations[var2] = var2++) { + ; + } + + for (var2 = 0; var2 < 256; ++var2) { + int var3 = par1Random.nextInt(256 - var2) + var2; + int var4 = this.permutations[var2]; + this.permutations[var2] = this.permutations[var3]; + this.permutations[var3] = var4; + this.permutations[var2 + 256] = this.permutations[var2]; + } + } + + public final double lerp(double par1, double par3, double par5) { + return par3 + par1 * (par5 - par3); + } + + public final double func_76309_a(int par1, double par2, double par4) { + int var6 = par1 & 15; + double var7 = (double) (1 - ((var6 & 8) >> 3)) * par2; + double var9 = var6 < 4 ? 0.0D : (var6 != 12 && var6 != 14 ? par4 : par2); + return ((var6 & 1) == 0 ? var7 : -var7) + ((var6 & 2) == 0 ? var9 : -var9); + } + + public final double grad(int par1, double par2, double par4, double par6) { + int var8 = par1 & 15; + double var9 = var8 < 8 ? par2 : par4; + double var11 = var8 < 4 ? par4 : (var8 != 12 && var8 != 14 ? par6 : par2); + return ((var8 & 1) == 0 ? var9 : -var9) + ((var8 & 2) == 0 ? var11 : -var11); + } + + /** + * pars: noiseArray , xOffset , yOffset , zOffset , xSize , ySize , zSize , + * xScale, yScale , zScale , noiseScale. noiseArray should be xSize*ySize*zSize + * in size + */ + public void populateNoiseArray(double[] par1ArrayOfDouble, double par2, double par4, double par6, int par8, int par9, int par10, double par11, double par13, double par15, double par17) { + int var10001; + int var19; + int var22; + double var31; + double var35; + int var37; + double var38; + int var40; + int var41; + double var42; + int var75; + + if (par9 == 1) { + boolean var64 = false; + boolean var65 = false; + boolean var21 = false; + boolean var68 = false; + double var70 = 0.0D; + double var73 = 0.0D; + var75 = 0; + double var77 = 1.0D / par17; + + for (int var30 = 0; var30 < par8; ++var30) { + var31 = par2 + (double) var30 * par11 + this.xCoord; + int var78 = (int) var31; + + if (var31 < (double) var78) { + --var78; + } + + int var34 = var78 & 255; + var31 -= (double) var78; + var35 = var31 * var31 * var31 * (var31 * (var31 * 6.0D - 15.0D) + 10.0D); + + for (var37 = 0; var37 < par10; ++var37) { + var38 = par6 + (double) var37 * par15 + this.zCoord; + var40 = (int) var38; + + if (var38 < (double) var40) { + --var40; + } + + var41 = var40 & 255; + var38 -= (double) var40; + var42 = var38 * var38 * var38 * (var38 * (var38 * 6.0D - 15.0D) + 10.0D); + var19 = this.permutations[var34] + 0; + int var66 = this.permutations[var19] + var41; + int var67 = this.permutations[var34 + 1] + 0; + var22 = this.permutations[var67] + var41; + var70 = this.lerp(var35, this.func_76309_a(this.permutations[var66], var31, var38), this.grad(this.permutations[var22], var31 - 1.0D, 0.0D, var38)); + var73 = this.lerp(var35, this.grad(this.permutations[var66 + 1], var31, 0.0D, var38 - 1.0D), this.grad(this.permutations[var22 + 1], var31 - 1.0D, 0.0D, var38 - 1.0D)); + double var79 = this.lerp(var42, var70, var73); + var10001 = var75++; + par1ArrayOfDouble[var10001] += var79 * var77; + } + } + } else { + var19 = 0; + double var20 = 1.0D / par17; + var22 = -1; + boolean var23 = false; + boolean var24 = false; + boolean var25 = false; + boolean var26 = false; + boolean var27 = false; + boolean var28 = false; + double var29 = 0.0D; + var31 = 0.0D; + double var33 = 0.0D; + var35 = 0.0D; + + for (var37 = 0; var37 < par8; ++var37) { + var38 = par2 + (double) var37 * par11 + this.xCoord; + var40 = (int) var38; + + if (var38 < (double) var40) { + --var40; + } + + var41 = var40 & 255; + var38 -= (double) var40; + var42 = var38 * var38 * var38 * (var38 * (var38 * 6.0D - 15.0D) + 10.0D); + + for (int var44 = 0; var44 < par10; ++var44) { + double var45 = par6 + (double) var44 * par15 + this.zCoord; + int var47 = (int) var45; + + if (var45 < (double) var47) { + --var47; + } + + int var48 = var47 & 255; + var45 -= (double) var47; + double var49 = var45 * var45 * var45 * (var45 * (var45 * 6.0D - 15.0D) + 10.0D); + + for (int var51 = 0; var51 < par9; ++var51) { + double var52 = par4 + (double) var51 * par13 + this.yCoord; + int var54 = (int) var52; + + if (var52 < (double) var54) { + --var54; + } + + int var55 = var54 & 255; + var52 -= (double) var54; + double var56 = var52 * var52 * var52 * (var52 * (var52 * 6.0D - 15.0D) + 10.0D); + + if (var51 == 0 || var55 != var22) { + var22 = var55; + int var69 = this.permutations[var41] + var55; + int var71 = this.permutations[var69] + var48; + int var72 = this.permutations[var69 + 1] + var48; + int var74 = this.permutations[var41 + 1] + var55; + var75 = this.permutations[var74] + var48; + int var76 = this.permutations[var74 + 1] + var48; + var29 = this.lerp(var42, this.grad(this.permutations[var71], var38, var52, var45), this.grad(this.permutations[var75], var38 - 1.0D, var52, var45)); + var31 = this.lerp(var42, this.grad(this.permutations[var72], var38, var52 - 1.0D, var45), this.grad(this.permutations[var76], var38 - 1.0D, var52 - 1.0D, var45)); + var33 = this.lerp(var42, this.grad(this.permutations[var71 + 1], var38, var52, var45 - 1.0D), this.grad(this.permutations[var75 + 1], var38 - 1.0D, var52, var45 - 1.0D)); + var35 = this.lerp(var42, this.grad(this.permutations[var72 + 1], var38, var52 - 1.0D, var45 - 1.0D), this.grad(this.permutations[var76 + 1], var38 - 1.0D, var52 - 1.0D, var45 - 1.0D)); + } + + double var58 = this.lerp(var56, var29, var31); + double var60 = this.lerp(var56, var33, var35); + double var62 = this.lerp(var49, var58, var60); + var10001 = var19++; + par1ArrayOfDouble[var10001] += var62 * var20; + } + } + } + } + } +} diff --git a/src/main/java/net/minecraft/src/NpcMerchant.java b/src/main/java/net/minecraft/src/NpcMerchant.java new file mode 100644 index 0000000..f8c2dc4 --- /dev/null +++ b/src/main/java/net/minecraft/src/NpcMerchant.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +public class NpcMerchant implements IMerchant { + /** Instance of Merchants Inventory. */ + private InventoryMerchant theMerchantInventory; + + /** This merchant's current player customer. */ + private EntityPlayer customer; + + /** The MerchantRecipeList instance. */ + private MerchantRecipeList recipeList; + + public NpcMerchant(EntityPlayer par1EntityPlayer) { + this.customer = par1EntityPlayer; + this.theMerchantInventory = new InventoryMerchant(par1EntityPlayer, this); + } + + public EntityPlayer getCustomer() { + return this.customer; + } + + public void setCustomer(EntityPlayer par1EntityPlayer) { + } + + public MerchantRecipeList getRecipes(EntityPlayer par1EntityPlayer) { + return this.recipeList; + } + + public void setRecipes(MerchantRecipeList par1MerchantRecipeList) { + this.recipeList = par1MerchantRecipeList; + } + + public void useRecipe(MerchantRecipe par1MerchantRecipe) { + } +} diff --git a/src/main/java/net/minecraft/src/OpenGlHelper.java b/src/main/java/net/minecraft/src/OpenGlHelper.java new file mode 100644 index 0000000..cf6d2da --- /dev/null +++ b/src/main/java/net/minecraft/src/OpenGlHelper.java @@ -0,0 +1,46 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +public class OpenGlHelper { + /** + * An OpenGL constant corresponding to GL_TEXTURE0, used when setting data + * pertaining to auxiliary OpenGL texture units. + */ + public static int defaultTexUnit; + + /** + * An OpenGL constant corresponding to GL_TEXTURE1, used when setting data + * pertaining to auxiliary OpenGL texture units. + */ + public static int lightmapTexUnit; + + /** + * Initializes the texture constants to be used when rendering lightmap values + */ + public static void initializeTextures() { + defaultTexUnit = EaglerAdapter.GL_TEXTURE0; + lightmapTexUnit = EaglerAdapter.GL_TEXTURE1; + } + + /** + * Sets the current lightmap texture to the specified OpenGL constant + */ + public static void setActiveTexture(int par0) { + EaglerAdapter.glActiveTexture(par0); + } + + /** + * Sets the current lightmap texture to the specified OpenGL constant + */ + public static void setClientActiveTexture(int par0) { + EaglerAdapter.glClientActiveTexture(par0); + } + + /** + * Sets the current coordinates of the given lightmap texture + */ + public static void setLightmapTextureCoords(int par0, float par1, float par2) { + EaglerAdapter.glMultiTexCoord2f(par0, par1, par2); + } +} diff --git a/src/main/java/net/minecraft/src/Packet.java b/src/main/java/net/minecraft/src/Packet.java new file mode 100644 index 0000000..d6ceb7b --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet.java @@ -0,0 +1,376 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.EOFException; +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public abstract class Packet { + /** Maps packet id to packet class */ + public static IntHashMap packetIdToClassMap = new IntHashMap(); + + /** Maps packet class to packet id */ + private static Map packetClassToIdMap = new HashMap(); + + /** List of the client's packet IDs. */ + private static Set clientPacketIdList = new HashSet(); + + /** List of the server's packet IDs. */ + private static Set serverPacketIdList = new HashSet(); + protected ILogAgent field_98193_m; + + /** the system time in milliseconds when this packet was created. */ + public final long creationTimeMillis = System.currentTimeMillis(); + public static long receivedID; + public static long receivedSize; + + /** Assumed to be sequential by the profiler. */ + public static long sentID; + public static long sentSize; + + /** + * Only true for Packet51MapChunk, Packet52MultiBlockChange, Packet53BlockChange + * and Packet59ComplexEntity. Used to separate them into a different send queue. + */ + public boolean isChunkDataPacket = false; + + /** + * Adds a two way mapping between the packet ID and packet class. + */ + static void addIdClassMapping(int par0, boolean par1, boolean par2, Class par3Class) { + if (packetIdToClassMap.containsItem(par0)) { + throw new IllegalArgumentException("Duplicate packet id:" + par0); + } else if (packetClassToIdMap.containsKey(par3Class)) { + throw new IllegalArgumentException("Duplicate packet class:" + par3Class); + } else { + packetIdToClassMap.addKey(par0, par3Class); + packetClassToIdMap.put(par3Class, Integer.valueOf(par0)); + + if (par1) { + clientPacketIdList.add(Integer.valueOf(par0)); + } + + if (par2) { + serverPacketIdList.add(Integer.valueOf(par0)); + } + } + } + + /** + * Returns a new instance of the specified Packet class. + */ + public static Packet getNewPacket(int par1) { + try { + Class var2 = (Class) packetIdToClassMap.lookup(par1); + return var2 == null ? null : (Packet) var2.newInstance(); + } catch (Exception var3) { + var3.printStackTrace(); + System.err.println("Skipping packet with id " + par1); + return null; + } + } + + /** + * Writes a byte array to the DataOutputStream + */ + public static void writeByteArray(DataOutputStream par0DataOutputStream, byte[] par1ArrayOfByte) throws IOException { + par0DataOutputStream.writeShort(par1ArrayOfByte.length); + par0DataOutputStream.write(par1ArrayOfByte); + } + + /** + * the first short in the stream indicates the number of bytes to read + */ + public static byte[] readBytesFromStream(DataInputStream par0DataInputStream) throws IOException { + short var1 = par0DataInputStream.readShort(); + + if (var1 < 0) { + throw new IOException("Key was smaller than nothing! Weird key!"); + } else { + byte[] var2 = new byte[var1]; + par0DataInputStream.readFully(var2); + return var2; + } + } + + /** + * Returns the ID of this packet. + */ + public final int getPacketId() { + return ((Integer) packetClassToIdMap.get(this.getClass())).intValue(); + } + + /** + * Read a packet, prefixed by its ID, from the data stream. + */ + public static Packet readPacket(DataInputStream par1DataInputStream, boolean par2) throws IOException { + boolean var4 = false; + Packet var5 = null; + int var9 = par1DataInputStream.read(); + + if (var9 == -1) { + return null; + } + + if (par2 && !serverPacketIdList.contains(Integer.valueOf(var9)) || !par2 && !clientPacketIdList.contains(Integer.valueOf(var9))) { + throw new IOException("Bad packet id " + var9); + } + + var5 = getNewPacket(var9); + + if (var5 == null) { + throw new IOException("Bad packet id " + var9); + } + + var5.readPacketData(par1DataInputStream); + ++receivedID; + receivedSize += (long) var5.getPacketSize(); + + PacketCount.countPacket(var9, (long) var5.getPacketSize()); + ++receivedID; + receivedSize += (long) var5.getPacketSize(); + return var5; + } + + /** + * Writes a packet, prefixed by its ID, to the data stream. + */ + public static void writePacket(Packet par0Packet, DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.write(par0Packet.getPacketId()); + par0Packet.writePacketData(par1DataOutputStream); + ++sentID; + sentSize += (long) par0Packet.getPacketSize(); + } + + /** + * Writes a String to the DataOutputStream + */ + public static void writeString(String par0Str, DataOutputStream par1DataOutputStream) throws IOException { + if (par0Str.length() > 32767) { + throw new IOException("String too big"); + } else { + par1DataOutputStream.writeShort(par0Str.length()); + par1DataOutputStream.writeChars(par0Str); + } + } + + /** + * Reads a string from a packet + */ + public static String readString(DataInputStream par0DataInputStream, int par1) throws IOException { + short var2 = par0DataInputStream.readShort(); + + if (var2 > par1) { + throw new IOException("Received string length longer than maximum allowed (" + var2 + " > " + par1 + ")"); + } else if (var2 < 0) { + throw new IOException("Received string length is less than zero! Weird string!"); + } else { + StringBuilder var3 = new StringBuilder(); + + for (int var4 = 0; var4 < var2; ++var4) { + var3.append(par0DataInputStream.readChar()); + } + + return var3.toString(); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public abstract void readPacketData(DataInputStream var1) throws IOException; + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public abstract void writePacketData(DataOutputStream var1) throws IOException; + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public abstract void processPacket(NetHandler var1); + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public abstract int getPacketSize(); + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return false; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return false; + } + + /** + * If this returns true, the packet may be processed on any thread; otherwise it + * is queued for the main thread to handle. + */ + public boolean canProcessAsync() { + return false; + } + + public String toString() { + String var1 = this.getClass().getSimpleName(); + return var1; + } + + /** + * Reads a ItemStack from the InputStream + */ + public static ItemStack readItemStack(DataInputStream par0DataInputStream) throws IOException { + ItemStack var1 = null; + short var2 = par0DataInputStream.readShort(); + + if (var2 >= 0) { + byte var3 = par0DataInputStream.readByte(); + short var4 = par0DataInputStream.readShort(); + var1 = new ItemStack(var2, var3, var4); + var1.stackTagCompound = readNBTTagCompound(par0DataInputStream); + } + + return var1; + } + + /** + * Writes the ItemStack's ID (short), then size (byte), then damage. (short) + */ + public static void writeItemStack(ItemStack par0ItemStack, DataOutputStream par1DataOutputStream) throws IOException { + if (par0ItemStack == null) { + par1DataOutputStream.writeShort(-1); + } else { + par1DataOutputStream.writeShort(par0ItemStack.itemID); + par1DataOutputStream.writeByte(par0ItemStack.stackSize); + par1DataOutputStream.writeShort(par0ItemStack.getItemDamage()); + NBTTagCompound var2 = null; + + if (par0ItemStack.getItem().isDamageable() || par0ItemStack.getItem().getShareTag()) { + var2 = par0ItemStack.stackTagCompound; + } + + writeNBTTagCompound(var2, par1DataOutputStream); + } + } + + /** + * Reads a compressed NBTTagCompound from the InputStream + */ + public static NBTTagCompound readNBTTagCompound(DataInputStream par0DataInputStream) throws IOException { + short var1 = par0DataInputStream.readShort(); + + if (var1 < 0) { + return null; + } else { + byte[] var2 = new byte[var1]; + par0DataInputStream.readFully(var2); + return CompressedStreamTools.decompress(var2); + } + } + + /** + * Writes a compressed NBTTagCompound to the OutputStream + */ + protected static void writeNBTTagCompound(NBTTagCompound par0NBTTagCompound, DataOutputStream par1DataOutputStream) throws IOException { + if (par0NBTTagCompound == null) { + par1DataOutputStream.writeShort(-1); + } else { + byte[] var2 = CompressedStreamTools.compress(par0NBTTagCompound); + par1DataOutputStream.writeShort((short) var2.length); + par1DataOutputStream.write(var2); + } + } + + static { + addIdClassMapping(0, true, true, Packet0KeepAlive.class); + addIdClassMapping(1, true, true, Packet1Login.class); + addIdClassMapping(2, false, true, Packet2ClientProtocol.class); + addIdClassMapping(3, true, true, Packet3Chat.class); + addIdClassMapping(4, true, false, Packet4UpdateTime.class); + addIdClassMapping(5, true, false, Packet5PlayerInventory.class); + addIdClassMapping(6, true, false, Packet6SpawnPosition.class); + addIdClassMapping(7, false, true, Packet7UseEntity.class); + addIdClassMapping(8, true, false, Packet8UpdateHealth.class); + addIdClassMapping(9, true, true, Packet9Respawn.class); + addIdClassMapping(10, true, true, Packet10Flying.class); + addIdClassMapping(11, true, true, Packet11PlayerPosition.class); + addIdClassMapping(12, true, true, Packet12PlayerLook.class); + addIdClassMapping(13, true, true, Packet13PlayerLookMove.class); + addIdClassMapping(14, false, true, Packet14BlockDig.class); + addIdClassMapping(15, false, true, Packet15Place.class); + addIdClassMapping(16, true, true, Packet16BlockItemSwitch.class); + addIdClassMapping(17, true, false, Packet17Sleep.class); + addIdClassMapping(18, true, true, Packet18Animation.class); + addIdClassMapping(19, false, true, Packet19EntityAction.class); + addIdClassMapping(20, true, false, Packet20NamedEntitySpawn.class); + addIdClassMapping(22, true, false, Packet22Collect.class); + addIdClassMapping(23, true, false, Packet23VehicleSpawn.class); + addIdClassMapping(24, true, false, Packet24MobSpawn.class); + addIdClassMapping(25, true, false, Packet25EntityPainting.class); + addIdClassMapping(26, true, false, Packet26EntityExpOrb.class); + addIdClassMapping(28, true, false, Packet28EntityVelocity.class); + addIdClassMapping(29, true, false, Packet29DestroyEntity.class); + addIdClassMapping(30, true, false, Packet30Entity.class); + addIdClassMapping(31, true, false, Packet31RelEntityMove.class); + addIdClassMapping(32, true, false, Packet32EntityLook.class); + addIdClassMapping(33, true, false, Packet33RelEntityMoveLook.class); + addIdClassMapping(34, true, false, Packet34EntityTeleport.class); + addIdClassMapping(35, true, false, Packet35EntityHeadRotation.class); + addIdClassMapping(38, true, false, Packet38EntityStatus.class); + addIdClassMapping(39, true, false, Packet39AttachEntity.class); + addIdClassMapping(40, true, false, Packet40EntityMetadata.class); + addIdClassMapping(41, true, false, Packet41EntityEffect.class); + addIdClassMapping(42, true, false, Packet42RemoveEntityEffect.class); + addIdClassMapping(43, true, false, Packet43Experience.class); + addIdClassMapping(51, true, false, Packet51MapChunk.class); + addIdClassMapping(52, true, false, Packet52MultiBlockChange.class); + addIdClassMapping(53, true, false, Packet53BlockChange.class); + addIdClassMapping(54, true, false, Packet54PlayNoteBlock.class); + addIdClassMapping(55, true, false, Packet55BlockDestroy.class); + addIdClassMapping(56, true, false, Packet56MapChunks.class); + addIdClassMapping(60, true, false, Packet60Explosion.class); + addIdClassMapping(61, true, false, Packet61DoorChange.class); + addIdClassMapping(62, true, false, Packet62LevelSound.class); + addIdClassMapping(63, true, false, Packet63WorldParticles.class); + addIdClassMapping(70, true, false, Packet70GameEvent.class); + addIdClassMapping(71, true, false, Packet71Weather.class); + addIdClassMapping(100, true, false, Packet100OpenWindow.class); + addIdClassMapping(101, true, true, Packet101CloseWindow.class); + addIdClassMapping(102, false, true, Packet102WindowClick.class); + addIdClassMapping(103, true, false, Packet103SetSlot.class); + addIdClassMapping(104, true, false, Packet104WindowItems.class); + addIdClassMapping(105, true, false, Packet105UpdateProgressbar.class); + addIdClassMapping(106, true, true, Packet106Transaction.class); + addIdClassMapping(107, true, true, Packet107CreativeSetSlot.class); + addIdClassMapping(108, false, true, Packet108EnchantItem.class); + addIdClassMapping(130, true, true, Packet130UpdateSign.class); + addIdClassMapping(131, true, false, Packet131MapData.class); + addIdClassMapping(132, true, false, Packet132TileEntityData.class); + addIdClassMapping(200, true, false, Packet200Statistic.class); + addIdClassMapping(201, true, false, Packet201PlayerInfo.class); + addIdClassMapping(202, true, true, Packet202PlayerAbilities.class); + addIdClassMapping(203, true, true, Packet203AutoComplete.class); + addIdClassMapping(204, false, true, Packet204ClientInfo.class); + addIdClassMapping(205, false, true, Packet205ClientCommand.class); + addIdClassMapping(206, true, false, Packet206SetObjective.class); + addIdClassMapping(207, true, false, Packet207SetScore.class); + addIdClassMapping(208, true, false, Packet208SetDisplayObjective.class); + addIdClassMapping(209, true, false, Packet209SetPlayerTeam.class); + addIdClassMapping(250, true, true, Packet250CustomPayload.class); + addIdClassMapping(252, true, true, Packet252SharedKey.class); + addIdClassMapping(253, true, false, Packet253ServerAuthData.class); + addIdClassMapping(254, false, true, Packet254ServerPing.class); + addIdClassMapping(255, true, true, Packet255KickDisconnect.class); + } +} diff --git a/src/main/java/net/minecraft/src/Packet0KeepAlive.java b/src/main/java/net/minecraft/src/Packet0KeepAlive.java new file mode 100644 index 0000000..3baa8d8 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet0KeepAlive.java @@ -0,0 +1,67 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet0KeepAlive extends Packet { + public int randomId; + + public Packet0KeepAlive() { + } + + public Packet0KeepAlive(int par1) { + this.randomId = par1; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleKeepAlive(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.randomId = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.randomId); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 4; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } + + /** + * If this returns true, the packet may be processed on any thread; otherwise it + * is queued for the main thread to handle. + */ + public boolean canProcessAsync() { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/Packet100OpenWindow.java b/src/main/java/net/minecraft/src/Packet100OpenWindow.java new file mode 100644 index 0000000..ae0e6d0 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet100OpenWindow.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet100OpenWindow extends Packet { + public int windowId; + public int inventoryType; + public String windowTitle; + public int slotsCount; + + /** + * If false, the client will look up a string like "window.minecart". If true, + * the client uses what the server provides. + */ + public boolean useProvidedWindowTitle; + + public Packet100OpenWindow() { + } + + public Packet100OpenWindow(int par1, int par2, String par3Str, int par4, boolean par5) { + this.windowId = par1; + this.inventoryType = par2; + this.windowTitle = par3Str; + this.slotsCount = par4; + this.useProvidedWindowTitle = par5; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleOpenWindow(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.windowId = par1DataInputStream.readByte() & 255; + this.inventoryType = par1DataInputStream.readByte() & 255; + this.windowTitle = readString(par1DataInputStream, 32); + this.slotsCount = par1DataInputStream.readByte() & 255; + this.useProvidedWindowTitle = par1DataInputStream.readBoolean(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.windowId & 255); + par1DataOutputStream.writeByte(this.inventoryType & 255); + writeString(this.windowTitle, par1DataOutputStream); + par1DataOutputStream.writeByte(this.slotsCount & 255); + par1DataOutputStream.writeBoolean(this.useProvidedWindowTitle); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 4 + this.windowTitle.length(); + } +} diff --git a/src/main/java/net/minecraft/src/Packet101CloseWindow.java b/src/main/java/net/minecraft/src/Packet101CloseWindow.java new file mode 100644 index 0000000..207ce97 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet101CloseWindow.java @@ -0,0 +1,44 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet101CloseWindow extends Packet { + public int windowId; + + public Packet101CloseWindow() { + } + + public Packet101CloseWindow(int par1) { + this.windowId = par1; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleCloseWindow(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.windowId = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.windowId); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 1; + } +} diff --git a/src/main/java/net/minecraft/src/Packet102WindowClick.java b/src/main/java/net/minecraft/src/Packet102WindowClick.java new file mode 100644 index 0000000..a1a559a --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet102WindowClick.java @@ -0,0 +1,73 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet102WindowClick extends Packet { + /** The id of the window which was clicked. 0 for player inventory. */ + public int window_Id; + + /** The clicked slot (-999 is outside of inventory) */ + public int inventorySlot; + + /** 1 when right-clicking and otherwise 0 */ + public int mouseClick; + + /** A unique number for the action, used for transaction handling */ + public short action; + + /** Item stack for inventory */ + public ItemStack itemStack; + public int holdingShift; + + public Packet102WindowClick() { + } + + public Packet102WindowClick(int par1, int par2, int par3, int par4, ItemStack par5ItemStack, short par6) { + this.window_Id = par1; + this.inventorySlot = par2; + this.mouseClick = par3; + this.itemStack = par5ItemStack != null ? par5ItemStack.copy() : null; + this.action = par6; + this.holdingShift = par4; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleWindowClick(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.window_Id = par1DataInputStream.readByte(); + this.inventorySlot = par1DataInputStream.readShort(); + this.mouseClick = par1DataInputStream.readByte(); + this.action = par1DataInputStream.readShort(); + this.holdingShift = par1DataInputStream.readByte(); + this.itemStack = readItemStack(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.window_Id); + par1DataOutputStream.writeShort(this.inventorySlot); + par1DataOutputStream.writeByte(this.mouseClick); + par1DataOutputStream.writeShort(this.action); + par1DataOutputStream.writeByte(this.holdingShift); + writeItemStack(this.itemStack, par1DataOutputStream); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 11; + } +} diff --git a/src/main/java/net/minecraft/src/Packet103SetSlot.java b/src/main/java/net/minecraft/src/Packet103SetSlot.java new file mode 100644 index 0000000..0b25cb7 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet103SetSlot.java @@ -0,0 +1,57 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet103SetSlot extends Packet { + /** The window which is being updated. 0 for player inventory */ + public int windowId; + + /** Slot that should be updated */ + public int itemSlot; + + /** Item stack */ + public ItemStack myItemStack; + + public Packet103SetSlot() { + } + + public Packet103SetSlot(int par1, int par2, ItemStack par3ItemStack) { + this.windowId = par1; + this.itemSlot = par2; + this.myItemStack = par3ItemStack == null ? par3ItemStack : par3ItemStack.copy(); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSetSlot(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.windowId = par1DataInputStream.readByte(); + this.itemSlot = par1DataInputStream.readShort(); + this.myItemStack = readItemStack(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.windowId); + par1DataOutputStream.writeShort(this.itemSlot); + writeItemStack(this.myItemStack, par1DataOutputStream); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8; + } +} diff --git a/src/main/java/net/minecraft/src/Packet104WindowItems.java b/src/main/java/net/minecraft/src/Packet104WindowItems.java new file mode 100644 index 0000000..41118f5 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet104WindowItems.java @@ -0,0 +1,68 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.List; + +public class Packet104WindowItems extends Packet { + /** + * The id of window which items are being sent for. 0 for player inventory. + */ + public int windowId; + + /** Stack of items */ + public ItemStack[] itemStack; + + public Packet104WindowItems() { + } + + public Packet104WindowItems(int par1, List par2List) { + this.windowId = par1; + this.itemStack = new ItemStack[par2List.size()]; + + for (int var3 = 0; var3 < this.itemStack.length; ++var3) { + ItemStack var4 = (ItemStack) par2List.get(var3); + this.itemStack[var3] = var4 == null ? null : var4.copy(); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.windowId = par1DataInputStream.readByte(); + short var2 = par1DataInputStream.readShort(); + this.itemStack = new ItemStack[var2]; + + for (int var3 = 0; var3 < var2; ++var3) { + this.itemStack[var3] = readItemStack(par1DataInputStream); + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.windowId); + par1DataOutputStream.writeShort(this.itemStack.length); + + for (int var2 = 0; var2 < this.itemStack.length; ++var2) { + writeItemStack(this.itemStack[var2], par1DataOutputStream); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleWindowItems(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 3 + this.itemStack.length * 5; + } +} diff --git a/src/main/java/net/minecraft/src/Packet105UpdateProgressbar.java b/src/main/java/net/minecraft/src/Packet105UpdateProgressbar.java new file mode 100644 index 0000000..c9ea3bd --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet105UpdateProgressbar.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet105UpdateProgressbar extends Packet { + /** The id of the window that the progress bar is in. */ + public int windowId; + + /** + * Which of the progress bars that should be updated. (For furnaces, 0 = + * progress arrow, 1 = fire icon) + */ + public int progressBar; + + /** + * The value of the progress bar. The maximum values vary depending on the + * progress bar. Presumably the values are specified as in-game ticks. Some + * progress bar values increase, while others decrease. For furnaces, 0 is + * empty, full progress arrow = about 180, full fire icon = about 250) + */ + public int progressBarValue; + + public Packet105UpdateProgressbar() { + } + + public Packet105UpdateProgressbar(int par1, int par2, int par3) { + this.windowId = par1; + this.progressBar = par2; + this.progressBarValue = par3; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleUpdateProgressbar(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.windowId = par1DataInputStream.readByte(); + this.progressBar = par1DataInputStream.readShort(); + this.progressBarValue = par1DataInputStream.readShort(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.windowId); + par1DataOutputStream.writeShort(this.progressBar); + par1DataOutputStream.writeShort(this.progressBarValue); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 5; + } +} diff --git a/src/main/java/net/minecraft/src/Packet106Transaction.java b/src/main/java/net/minecraft/src/Packet106Transaction.java new file mode 100644 index 0000000..a45a01f --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet106Transaction.java @@ -0,0 +1,53 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet106Transaction extends Packet { + /** The id of the window that the action occurred in. */ + public int windowId; + public short shortWindowId; + public boolean accepted; + + public Packet106Transaction() { + } + + public Packet106Transaction(int par1, short par2, boolean par3) { + this.windowId = par1; + this.shortWindowId = par2; + this.accepted = par3; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleTransaction(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.windowId = par1DataInputStream.readByte(); + this.shortWindowId = par1DataInputStream.readShort(); + this.accepted = par1DataInputStream.readByte() != 0; + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.windowId); + par1DataOutputStream.writeShort(this.shortWindowId); + par1DataOutputStream.writeByte(this.accepted ? 1 : 0); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 4; + } +} diff --git a/src/main/java/net/minecraft/src/Packet107CreativeSetSlot.java b/src/main/java/net/minecraft/src/Packet107CreativeSetSlot.java new file mode 100644 index 0000000..f35855d --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet107CreativeSetSlot.java @@ -0,0 +1,48 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet107CreativeSetSlot extends Packet { + public int slot; + public ItemStack itemStack; + + public Packet107CreativeSetSlot() { + } + + public Packet107CreativeSetSlot(int par1, ItemStack par2ItemStack) { + this.slot = par1; + this.itemStack = par2ItemStack != null ? par2ItemStack.copy() : null; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleCreativeSetSlot(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.slot = par1DataInputStream.readShort(); + this.itemStack = readItemStack(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeShort(this.slot); + writeItemStack(this.itemStack, par1DataOutputStream); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8; + } +} diff --git a/src/main/java/net/minecraft/src/Packet108EnchantItem.java b/src/main/java/net/minecraft/src/Packet108EnchantItem.java new file mode 100644 index 0000000..843c9e2 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet108EnchantItem.java @@ -0,0 +1,53 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet108EnchantItem extends Packet { + public int windowId; + + /** + * The position of the enchantment on the enchantment table window, starting + * with 0 as the topmost one. + */ + public int enchantment; + + public Packet108EnchantItem() { + } + + public Packet108EnchantItem(int par1, int par2) { + this.windowId = par1; + this.enchantment = par2; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEnchantItem(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.windowId = par1DataInputStream.readByte(); + this.enchantment = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.windowId); + par1DataOutputStream.writeByte(this.enchantment); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2; + } +} diff --git a/src/main/java/net/minecraft/src/Packet10Flying.java b/src/main/java/net/minecraft/src/Packet10Flying.java new file mode 100644 index 0000000..a97deb3 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet10Flying.java @@ -0,0 +1,84 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet10Flying extends Packet { + /** The player's X position. */ + public double xPosition; + + /** The player's Y position. */ + public double yPosition; + + /** The player's Z position. */ + public double zPosition; + + /** The player's stance. (boundingBox.minY) */ + public double stance; + + /** The player's yaw rotation. */ + public float yaw; + + /** The player's pitch rotation. */ + public float pitch; + + /** True if the client is on the ground. */ + public boolean onGround; + + /** Boolean set to true if the player is moving. */ + public boolean moving; + + /** Boolean set to true if the player is rotating. */ + public boolean rotating; + + public Packet10Flying() { + } + + public Packet10Flying(boolean par1) { + this.onGround = par1; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleFlying(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.onGround = par1DataInputStream.read() != 0; + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.write(this.onGround ? 1 : 0); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 1; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/Packet11PlayerPosition.java b/src/main/java/net/minecraft/src/Packet11PlayerPosition.java new file mode 100644 index 0000000..3082190 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet11PlayerPosition.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet11PlayerPosition extends Packet10Flying { + public Packet11PlayerPosition() { + this.moving = true; + } + + public Packet11PlayerPosition(double par1, double par3, double par5, double par7, boolean par9) { + this.xPosition = par1; + this.yPosition = par3; + this.stance = par5; + this.zPosition = par7; + this.onGround = par9; + this.moving = true; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readDouble(); + this.yPosition = par1DataInputStream.readDouble(); + this.stance = par1DataInputStream.readDouble(); + this.zPosition = par1DataInputStream.readDouble(); + super.readPacketData(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeDouble(this.xPosition); + par1DataOutputStream.writeDouble(this.yPosition); + par1DataOutputStream.writeDouble(this.stance); + par1DataOutputStream.writeDouble(this.zPosition); + super.writePacketData(par1DataOutputStream); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 33; + } +} diff --git a/src/main/java/net/minecraft/src/Packet12PlayerLook.java b/src/main/java/net/minecraft/src/Packet12PlayerLook.java new file mode 100644 index 0000000..f3b9d0b --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet12PlayerLook.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet12PlayerLook extends Packet10Flying { + public Packet12PlayerLook() { + this.rotating = true; + } + + public Packet12PlayerLook(float par1, float par2, boolean par3) { + this.yaw = par1; + this.pitch = par2; + this.onGround = par3; + this.rotating = true; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.yaw = par1DataInputStream.readFloat(); + this.pitch = par1DataInputStream.readFloat(); + super.readPacketData(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeFloat(this.yaw); + par1DataOutputStream.writeFloat(this.pitch); + super.writePacketData(par1DataOutputStream); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 9; + } +} diff --git a/src/main/java/net/minecraft/src/Packet130UpdateSign.java b/src/main/java/net/minecraft/src/Packet130UpdateSign.java new file mode 100644 index 0000000..e286d43 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet130UpdateSign.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet130UpdateSign extends Packet { + public int xPosition; + public int yPosition; + public int zPosition; + public String[] signLines; + + public Packet130UpdateSign() { + this.isChunkDataPacket = true; + } + + public Packet130UpdateSign(int par1, int par2, int par3, String[] par4ArrayOfStr) { + this.isChunkDataPacket = true; + this.xPosition = par1; + this.yPosition = par2; + this.zPosition = par3; + this.signLines = new String[] { par4ArrayOfStr[0], par4ArrayOfStr[1], par4ArrayOfStr[2], par4ArrayOfStr[3] }; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readShort(); + this.zPosition = par1DataInputStream.readInt(); + this.signLines = new String[4]; + + for (int var2 = 0; var2 < 4; ++var2) { + this.signLines[var2] = readString(par1DataInputStream, 15); + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeShort(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + + for (int var2 = 0; var2 < 4; ++var2) { + writeString(this.signLines[var2], par1DataOutputStream); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleUpdateSign(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + int var1 = 0; + + for (int var2 = 0; var2 < 4; ++var2) { + var1 += this.signLines[var2].length(); + } + + return var1; + } +} diff --git a/src/main/java/net/minecraft/src/Packet131MapData.java b/src/main/java/net/minecraft/src/Packet131MapData.java new file mode 100644 index 0000000..98d8d73 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet131MapData.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet131MapData extends Packet { + public short itemID; + + /** + * Contains a unique ID for the item that this packet will be populating. + */ + public short uniqueID; + + /** + * Contains a buffer of arbitrary data with which to populate an individual item + * in the world. + */ + public byte[] itemData; + + public Packet131MapData() { + this.isChunkDataPacket = true; + } + + public Packet131MapData(short par1, short par2, byte[] par3ArrayOfByte) { + this.isChunkDataPacket = true; + this.itemID = par1; + this.uniqueID = par2; + this.itemData = par3ArrayOfByte; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.itemID = par1DataInputStream.readShort(); + this.uniqueID = par1DataInputStream.readShort(); + this.itemData = new byte[par1DataInputStream.readUnsignedShort()]; + par1DataInputStream.readFully(this.itemData); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeShort(this.itemID); + par1DataOutputStream.writeShort(this.uniqueID); + par1DataOutputStream.writeShort(this.itemData.length); + par1DataOutputStream.write(this.itemData); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleMapData(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 4 + this.itemData.length; + } +} diff --git a/src/main/java/net/minecraft/src/Packet132TileEntityData.java b/src/main/java/net/minecraft/src/Packet132TileEntityData.java new file mode 100644 index 0000000..2e133c7 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet132TileEntityData.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet132TileEntityData extends Packet { + /** The X position of the tile entity to update. */ + public int xPosition; + + /** The Y position of the tile entity to update. */ + public int yPosition; + + /** The Z position of the tile entity to update. */ + public int zPosition; + + /** The type of update to perform on the tile entity. */ + public int actionType; + + /** Custom parameter 1 passed to the tile entity on update. */ + public NBTTagCompound customParam1; + + public Packet132TileEntityData() { + this.isChunkDataPacket = true; + } + + public Packet132TileEntityData(int par1, int par2, int par3, int par4, NBTTagCompound par5NBTTagCompound) { + this.isChunkDataPacket = true; + this.xPosition = par1; + this.yPosition = par2; + this.zPosition = par3; + this.actionType = par4; + this.customParam1 = par5NBTTagCompound; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readShort(); + this.zPosition = par1DataInputStream.readInt(); + this.actionType = par1DataInputStream.readByte(); + this.customParam1 = readNBTTagCompound(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeShort(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.writeByte((byte) this.actionType); + writeNBTTagCompound(this.customParam1, par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleTileEntityData(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 25; + } +} diff --git a/src/main/java/net/minecraft/src/Packet13PlayerLookMove.java b/src/main/java/net/minecraft/src/Packet13PlayerLookMove.java new file mode 100644 index 0000000..89c960d --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet13PlayerLookMove.java @@ -0,0 +1,57 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet13PlayerLookMove extends Packet10Flying { + public Packet13PlayerLookMove() { + this.rotating = true; + this.moving = true; + } + + public Packet13PlayerLookMove(double par1, double par3, double par5, double par7, float par9, float par10, boolean par11) { + this.xPosition = par1; + this.yPosition = par3; + this.stance = par5; + this.zPosition = par7; + this.yaw = par9; + this.pitch = par10; + this.onGround = par11; + this.rotating = true; + this.moving = true; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readDouble(); + this.yPosition = par1DataInputStream.readDouble(); + this.stance = par1DataInputStream.readDouble(); + this.zPosition = par1DataInputStream.readDouble(); + this.yaw = par1DataInputStream.readFloat(); + this.pitch = par1DataInputStream.readFloat(); + super.readPacketData(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeDouble(this.xPosition); + par1DataOutputStream.writeDouble(this.yPosition); + par1DataOutputStream.writeDouble(this.stance); + par1DataOutputStream.writeDouble(this.zPosition); + par1DataOutputStream.writeFloat(this.yaw); + par1DataOutputStream.writeFloat(this.pitch); + super.writePacketData(par1DataOutputStream); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 41; + } +} diff --git a/src/main/java/net/minecraft/src/Packet14BlockDig.java b/src/main/java/net/minecraft/src/Packet14BlockDig.java new file mode 100644 index 0000000..78dbfc4 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet14BlockDig.java @@ -0,0 +1,69 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet14BlockDig extends Packet { + /** Block X position. */ + public int xPosition; + + /** Block Y position. */ + public int yPosition; + + /** Block Z position. */ + public int zPosition; + + /** Punched face of the block. */ + public int face; + + /** Status of the digging (started, ongoing, broken). */ + public int status; + + public Packet14BlockDig() { + } + + public Packet14BlockDig(int par1, int par2, int par3, int par4, int par5) { + this.status = par1; + this.xPosition = par2; + this.yPosition = par3; + this.zPosition = par4; + this.face = par5; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.status = par1DataInputStream.read(); + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.read(); + this.zPosition = par1DataInputStream.readInt(); + this.face = par1DataInputStream.read(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.write(this.status); + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.write(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.write(this.face); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleBlockDig(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 11; + } +} diff --git a/src/main/java/net/minecraft/src/Packet15Place.java b/src/main/java/net/minecraft/src/Packet15Place.java new file mode 100644 index 0000000..950c452 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet15Place.java @@ -0,0 +1,121 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet15Place extends Packet { + private int xPosition; + private int yPosition; + private int zPosition; + + /** The offset to use for block/item placement. */ + private int direction; + private ItemStack itemStack; + + /** The offset from xPosition where the actual click took place */ + private float xOffset; + + /** The offset from yPosition where the actual click took place */ + private float yOffset; + + /** The offset from zPosition where the actual click took place */ + private float zOffset; + + public Packet15Place() { + } + + public Packet15Place(int par1, int par2, int par3, int par4, ItemStack par5ItemStack, float par6, float par7, float par8) { + this.xPosition = par1; + this.yPosition = par2; + this.zPosition = par3; + this.direction = par4; + this.itemStack = par5ItemStack != null ? par5ItemStack.copy() : null; + this.xOffset = par6; + this.yOffset = par7; + this.zOffset = par8; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.read(); + this.zPosition = par1DataInputStream.readInt(); + this.direction = par1DataInputStream.read(); + this.itemStack = readItemStack(par1DataInputStream); + this.xOffset = (float) par1DataInputStream.read() / 16.0F; + this.yOffset = (float) par1DataInputStream.read() / 16.0F; + this.zOffset = (float) par1DataInputStream.read() / 16.0F; + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.write(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.write(this.direction); + writeItemStack(this.itemStack, par1DataOutputStream); + par1DataOutputStream.write((int) (this.xOffset * 16.0F)); + par1DataOutputStream.write((int) (this.yOffset * 16.0F)); + par1DataOutputStream.write((int) (this.zOffset * 16.0F)); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handlePlace(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 19; + } + + public int getXPosition() { + return this.xPosition; + } + + public int getYPosition() { + return this.yPosition; + } + + public int getZPosition() { + return this.zPosition; + } + + public int getDirection() { + return this.direction; + } + + public ItemStack getItemStack() { + return this.itemStack; + } + + /** + * Returns the offset from xPosition where the actual click took place + */ + public float getXOffset() { + return this.xOffset; + } + + /** + * Returns the offset from yPosition where the actual click took place + */ + public float getYOffset() { + return this.yOffset; + } + + /** + * Returns the offset from zPosition where the actual click took place + */ + public float getZOffset() { + return this.zOffset; + } +} diff --git a/src/main/java/net/minecraft/src/Packet16BlockItemSwitch.java b/src/main/java/net/minecraft/src/Packet16BlockItemSwitch.java new file mode 100644 index 0000000..5e2bc62 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet16BlockItemSwitch.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet16BlockItemSwitch extends Packet { + /** The block/item id to be equipped. */ + public int id; + + public Packet16BlockItemSwitch() { + } + + public Packet16BlockItemSwitch(int par1) { + this.id = par1; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.id = par1DataInputStream.readShort(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeShort(this.id); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleBlockItemSwitch(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/Packet17Sleep.java b/src/main/java/net/minecraft/src/Packet17Sleep.java new file mode 100644 index 0000000..0ad2072 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet17Sleep.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet17Sleep extends Packet { + public int entityID; + public int bedX; + public int bedY; + public int bedZ; + public int field_73622_e; + + public Packet17Sleep() { + } + + public Packet17Sleep(Entity par1Entity, int par2, int par3, int par4, int par5) { + this.field_73622_e = par2; + this.bedX = par3; + this.bedY = par4; + this.bedZ = par5; + this.entityID = par1Entity.entityId; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityID = par1DataInputStream.readInt(); + this.field_73622_e = par1DataInputStream.readByte(); + this.bedX = par1DataInputStream.readInt(); + this.bedY = par1DataInputStream.readByte(); + this.bedZ = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityID); + par1DataOutputStream.writeByte(this.field_73622_e); + par1DataOutputStream.writeInt(this.bedX); + par1DataOutputStream.writeByte(this.bedY); + par1DataOutputStream.writeInt(this.bedZ); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSleep(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 14; + } +} diff --git a/src/main/java/net/minecraft/src/Packet18Animation.java b/src/main/java/net/minecraft/src/Packet18Animation.java new file mode 100644 index 0000000..0f03d61 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet18Animation.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet18Animation extends Packet { + /** The entity ID, in this case it's the player ID. */ + public int entityId; + public int animate; + + public Packet18Animation() { + } + + public Packet18Animation(Entity par1Entity, int par2) { + this.entityId = par1Entity.entityId; + this.animate = par2; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.animate = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.animate); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleAnimation(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 5; + } +} diff --git a/src/main/java/net/minecraft/src/Packet19EntityAction.java b/src/main/java/net/minecraft/src/Packet19EntityAction.java new file mode 100644 index 0000000..c3d78da --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet19EntityAction.java @@ -0,0 +1,51 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet19EntityAction extends Packet { + /** Player ID. */ + public int entityId; + + /** 1=sneak, 2=normal */ + public int state; + + public Packet19EntityAction() { + } + + public Packet19EntityAction(Entity par1Entity, int par2) { + this.entityId = par1Entity.entityId; + this.state = par2; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.state = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.state); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityAction(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 5; + } +} diff --git a/src/main/java/net/minecraft/src/Packet1Login.java b/src/main/java/net/minecraft/src/Packet1Login.java new file mode 100644 index 0000000..7f99313 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet1Login.java @@ -0,0 +1,100 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet1Login extends Packet { + /** The player's entity ID */ + public int clientEntityId = 0; + public WorldType terrainType; + public boolean hardcoreMode; + public EnumGameType gameType; + + /** -1: The Nether, 0: The Overworld, 1: The End */ + public int dimension; + + /** The difficulty setting byte. */ + public byte difficultySetting; + + /** Defaults to 128 */ + public byte worldHeight; + + /** The maximum players. */ + public byte maxPlayers; + + public Packet1Login() { + } + + public Packet1Login(int par1, WorldType par2WorldType, EnumGameType par3EnumGameType, boolean par4, int par5, int par6, int par7, int par8) { + this.clientEntityId = par1; + this.terrainType = par2WorldType; + this.dimension = par5; + this.difficultySetting = (byte) par6; + this.gameType = par3EnumGameType; + this.worldHeight = (byte) par7; + this.maxPlayers = (byte) par8; + this.hardcoreMode = par4; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.clientEntityId = par1DataInputStream.readInt(); + String var2 = readString(par1DataInputStream, 16); + this.terrainType = WorldType.parseWorldType(var2); + + if (this.terrainType == null) { + this.terrainType = WorldType.DEFAULT; + } + + byte var3 = par1DataInputStream.readByte(); + this.hardcoreMode = (var3 & 8) == 8; + int var4 = var3 & -9; + this.gameType = EnumGameType.getByID(var4); + this.dimension = par1DataInputStream.readByte(); + this.difficultySetting = par1DataInputStream.readByte(); + this.worldHeight = par1DataInputStream.readByte(); + this.maxPlayers = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.clientEntityId); + writeString(this.terrainType == null ? "" : this.terrainType.getWorldTypeName(), par1DataOutputStream); + int var2 = this.gameType.getID(); + + if (this.hardcoreMode) { + var2 |= 8; + } + + par1DataOutputStream.writeByte(var2); + par1DataOutputStream.writeByte(this.dimension); + par1DataOutputStream.writeByte(this.difficultySetting); + par1DataOutputStream.writeByte(this.worldHeight); + par1DataOutputStream.writeByte(this.maxPlayers); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleLogin(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + int var1 = 0; + + if (this.terrainType != null) { + var1 = this.terrainType.getWorldTypeName().length(); + } + + return 6 + 2 * var1 + 4 + 4 + 1 + 1 + 1; + } +} diff --git a/src/main/java/net/minecraft/src/Packet200Statistic.java b/src/main/java/net/minecraft/src/Packet200Statistic.java new file mode 100644 index 0000000..48fe5e5 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet200Statistic.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet200Statistic extends Packet { + public int statisticId; + public int amount; + + public Packet200Statistic() { + } + + public Packet200Statistic(int par1, int par2) { + this.statisticId = par1; + this.amount = par2; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleStatistic(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.statisticId = par1DataInputStream.readInt(); + this.amount = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.statisticId); + par1DataOutputStream.writeByte(this.amount); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 6; + } + + /** + * If this returns true, the packet may be processed on any thread; otherwise it + * is queued for the main thread to handle. + */ + public boolean canProcessAsync() { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/Packet201PlayerInfo.java b/src/main/java/net/minecraft/src/Packet201PlayerInfo.java new file mode 100644 index 0000000..f1f0580 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet201PlayerInfo.java @@ -0,0 +1,55 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet201PlayerInfo extends Packet { + /** The player's name. */ + public String playerName; + + /** Byte that tells whether the player is connected. */ + public boolean isConnected; + public int ping; + + public Packet201PlayerInfo() { + } + + public Packet201PlayerInfo(String par1Str, boolean par2, int par3) { + this.playerName = par1Str; + this.isConnected = par2; + this.ping = par3; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.playerName = readString(par1DataInputStream, 16); + this.isConnected = par1DataInputStream.readByte() != 0; + this.ping = par1DataInputStream.readShort(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.playerName, par1DataOutputStream); + par1DataOutputStream.writeByte(this.isConnected ? 1 : 0); + par1DataOutputStream.writeShort(this.ping); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handlePlayerInfo(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return this.playerName.length() + 2 + 1 + 2; + } +} diff --git a/src/main/java/net/minecraft/src/Packet202PlayerAbilities.java b/src/main/java/net/minecraft/src/Packet202PlayerAbilities.java new file mode 100644 index 0000000..b609a08 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet202PlayerAbilities.java @@ -0,0 +1,165 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet202PlayerAbilities extends Packet { + /** Disables player damage. */ + private boolean disableDamage = false; + + /** Indicates whether the player is flying or not. */ + private boolean isFlying = false; + + /** Whether or not to allow the player to fly when they double jump. */ + private boolean allowFlying = false; + + /** + * Used to determine if creative mode is enabled, and therefore if items should + * be depleted on usage + */ + private boolean isCreativeMode = false; + private float flySpeed; + private float walkSpeed; + + public Packet202PlayerAbilities() { + } + + public Packet202PlayerAbilities(PlayerCapabilities par1PlayerCapabilities) { + this.setDisableDamage(par1PlayerCapabilities.disableDamage); + this.setFlying(par1PlayerCapabilities.isFlying); + this.setAllowFlying(par1PlayerCapabilities.allowFlying); + this.setCreativeMode(par1PlayerCapabilities.isCreativeMode); + this.setFlySpeed(par1PlayerCapabilities.getFlySpeed()); + this.setWalkSpeed(par1PlayerCapabilities.getWalkSpeed()); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + byte var2 = par1DataInputStream.readByte(); + this.setDisableDamage((var2 & 1) > 0); + this.setFlying((var2 & 2) > 0); + this.setAllowFlying((var2 & 4) > 0); + this.setCreativeMode((var2 & 8) > 0); + this.setFlySpeed((float) par1DataInputStream.readByte() / 255.0F); + this.setWalkSpeed((float) par1DataInputStream.readByte() / 255.0F); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + byte var2 = 0; + + if (this.getDisableDamage()) { + var2 = (byte) (var2 | 1); + } + + if (this.getFlying()) { + var2 = (byte) (var2 | 2); + } + + if (this.getAllowFlying()) { + var2 = (byte) (var2 | 4); + } + + if (this.isCreativeMode()) { + var2 = (byte) (var2 | 8); + } + + par1DataOutputStream.writeByte(var2); + par1DataOutputStream.writeByte((int) (this.flySpeed * 255.0F)); + par1DataOutputStream.writeByte((int) (this.walkSpeed * 255.0F)); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handlePlayerAbilities(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2; + } + + public boolean getDisableDamage() { + return this.disableDamage; + } + + /** + * Sets whether damage is disabled or not. + */ + public void setDisableDamage(boolean par1) { + this.disableDamage = par1; + } + + public boolean getFlying() { + return this.isFlying; + } + + /** + * Sets whether we're currently flying or not. + */ + public void setFlying(boolean par1) { + this.isFlying = par1; + } + + public boolean getAllowFlying() { + return this.allowFlying; + } + + public void setAllowFlying(boolean par1) { + this.allowFlying = par1; + } + + public boolean isCreativeMode() { + return this.isCreativeMode; + } + + public void setCreativeMode(boolean par1) { + this.isCreativeMode = par1; + } + + public float getFlySpeed() { + return this.flySpeed; + } + + /** + * Sets the flying speed. + */ + public void setFlySpeed(float par1) { + this.flySpeed = par1; + } + + public float getWalkSpeed() { + return this.walkSpeed; + } + + /** + * Sets the walking speed. + */ + public void setWalkSpeed(float par1) { + this.walkSpeed = par1; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/Packet203AutoComplete.java b/src/main/java/net/minecraft/src/Packet203AutoComplete.java new file mode 100644 index 0000000..af00a98 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet203AutoComplete.java @@ -0,0 +1,67 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet203AutoComplete extends Packet { + /** + * Sent by the client containing the text to be autocompleted. Sent by the + * server with possible completions separated by null (two bytes in UTF-16) + */ + private String text; + + public Packet203AutoComplete() { + } + + public Packet203AutoComplete(String par1Str) { + this.text = par1Str; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.text = readString(par1DataInputStream, Packet3Chat.maxChatLength); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.text, par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleAutoComplete(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2 + this.text.length() * 2; + } + + public String getText() { + return this.text; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/Packet204ClientInfo.java b/src/main/java/net/minecraft/src/Packet204ClientInfo.java new file mode 100644 index 0000000..d68f7d0 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet204ClientInfo.java @@ -0,0 +1,103 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet204ClientInfo extends Packet { + private String language; + private int renderDistance; + private int chatVisisble; + private boolean chatColours; + private int gameDifficulty; + private boolean showCape; + + public Packet204ClientInfo() { + } + + public Packet204ClientInfo(String par1Str, int par2, int par3, boolean par4, int par5, boolean par6) { + this.language = par1Str; + this.renderDistance = par2; + this.chatVisisble = par3; + this.chatColours = par4; + this.gameDifficulty = par5; + this.showCape = par6; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.language = readString(par1DataInputStream, 7); + this.renderDistance = par1DataInputStream.readByte(); + byte var2 = par1DataInputStream.readByte(); + this.chatVisisble = var2 & 7; + this.chatColours = (var2 & 8) == 8; + this.gameDifficulty = par1DataInputStream.readByte(); + this.showCape = par1DataInputStream.readBoolean(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.language, par1DataOutputStream); + par1DataOutputStream.writeByte(this.renderDistance); + par1DataOutputStream.writeByte(this.chatVisisble | (this.chatColours ? 1 : 0) << 3); + par1DataOutputStream.writeByte(this.gameDifficulty); + par1DataOutputStream.writeBoolean(this.showCape); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleClientInfo(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 7; + } + + public String getLanguage() { + return this.language; + } + + public int getRenderDistance() { + return this.renderDistance; + } + + public int getChatVisibility() { + return this.chatVisisble; + } + + public boolean getChatColours() { + return this.chatColours; + } + + public int getDifficulty() { + return this.gameDifficulty; + } + + public boolean getShowCape() { + return this.showCape; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/Packet205ClientCommand.java b/src/main/java/net/minecraft/src/Packet205ClientCommand.java new file mode 100644 index 0000000..23d5efe --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet205ClientCommand.java @@ -0,0 +1,48 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet205ClientCommand extends Packet { + /** + * 0 sent to a netLoginHandler starts the server, 1 sent to NetServerHandler + * forces a respawn + */ + public int forceRespawn; + + public Packet205ClientCommand() { + } + + public Packet205ClientCommand(int par1) { + this.forceRespawn = par1; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.forceRespawn = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.forceRespawn & 255); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleClientCommand(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 1; + } +} diff --git a/src/main/java/net/minecraft/src/Packet206SetObjective.java b/src/main/java/net/minecraft/src/Packet206SetObjective.java new file mode 100644 index 0000000..704aad6 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet206SetObjective.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet206SetObjective extends Packet { + public String objectiveName; + public String objectiveDisplayName; + + /** + * 0 to create scoreboard, 1 to remove scoreboard, 2 to update display text. + */ + public int change; + + public Packet206SetObjective() { + } + + public Packet206SetObjective(ScoreObjective par1, int par2) { + this.objectiveName = par1.getName(); + this.objectiveDisplayName = par1.getDisplayName(); + this.change = par2; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.objectiveName = readString(par1DataInputStream, 16); + this.objectiveDisplayName = readString(par1DataInputStream, 32); + this.change = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.objectiveName, par1DataOutputStream); + writeString(this.objectiveDisplayName, par1DataOutputStream); + par1DataOutputStream.writeByte(this.change); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSetObjective(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2 + this.objectiveName.length() + 2 + this.objectiveDisplayName.length() + 1; + } +} diff --git a/src/main/java/net/minecraft/src/Packet207SetScore.java b/src/main/java/net/minecraft/src/Packet207SetScore.java new file mode 100644 index 0000000..3000db0 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet207SetScore.java @@ -0,0 +1,82 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet207SetScore extends Packet { + /** An unique name to be displayed in the list. */ + public String itemName = ""; + + /** + * The unique name for the scoreboard to be updated. Only sent when + * updateOrRemove does not equal 1. + */ + public String scoreName = ""; + + /** + * The score to be displayed next to the entry. Only sent when Update/Remove + * does not equal 1. + */ + public int value = 0; + + /** 0 to create/update an item. 1 to remove an item. */ + public int updateOrRemove = 0; + + public Packet207SetScore() { + } + + public Packet207SetScore(Score par1, int par2) { + this.itemName = par1.func_96653_e(); + this.scoreName = par1.func_96645_d().getName(); + this.value = par1.func_96652_c(); + this.updateOrRemove = par2; + } + + public Packet207SetScore(String par1) { + this.itemName = par1; + this.scoreName = ""; + this.value = 0; + this.updateOrRemove = 1; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.itemName = readString(par1DataInputStream, 16); + this.updateOrRemove = par1DataInputStream.readByte(); + + if (this.updateOrRemove != 1) { + this.scoreName = readString(par1DataInputStream, 16); + this.value = par1DataInputStream.readInt(); + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.itemName, par1DataOutputStream); + par1DataOutputStream.writeByte(this.updateOrRemove); + + if (this.updateOrRemove != 1) { + writeString(this.scoreName, par1DataOutputStream); + par1DataOutputStream.writeInt(this.value); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSetScore(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2 + this.itemName.length() + 2 + this.scoreName.length() + 4 + 1; + } +} diff --git a/src/main/java/net/minecraft/src/Packet208SetDisplayObjective.java b/src/main/java/net/minecraft/src/Packet208SetDisplayObjective.java new file mode 100644 index 0000000..aa121f8 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet208SetDisplayObjective.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet208SetDisplayObjective extends Packet { + /** The position of the scoreboard. 0 = list, 1 = sidebar, 2 = belowName. */ + public int scoreboardPosition; + + /** The unique name for the scoreboard to be displayed. */ + public String scoreName; + + public Packet208SetDisplayObjective() { + } + + public Packet208SetDisplayObjective(int par1, ScoreObjective par2ScoreObjective) { + this.scoreboardPosition = par1; + + if (par2ScoreObjective == null) { + this.scoreName = ""; + } else { + this.scoreName = par2ScoreObjective.getName(); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.scoreboardPosition = par1DataInputStream.readByte(); + this.scoreName = readString(par1DataInputStream, 16); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.scoreboardPosition); + writeString(this.scoreName, par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSetDisplayObjective(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 3 + this.scoreName.length(); + } +} diff --git a/src/main/java/net/minecraft/src/Packet209SetPlayerTeam.java b/src/main/java/net/minecraft/src/Packet209SetPlayerTeam.java new file mode 100644 index 0000000..3dbbe0a --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet209SetPlayerTeam.java @@ -0,0 +1,134 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +public class Packet209SetPlayerTeam extends Packet { + /** A unique name for the team. */ + public String teamName = ""; + + /** Only if mode = 0 or 2. */ + public String teamDisplayName = ""; + + /** + * Only if mode = 0 or 2. Displayed before the players' name that are part of + * this team. + */ + public String teamPrefix = ""; + + /** + * Only if mode = 0 or 2. Displayed after the players' name that are part of + * this team. + */ + public String teamSuffix = ""; + + /** Only if mode = 0 or 3 or 4. Players to be added/remove from the team. */ + public Collection playerNames = new ArrayList(); + + /** + * If 0 then the team is created. If 1 then the team is removed. If 2 the team + * team information is updated. If 3 then new players are added to the team. If + * 4 then players are removed from the team. + */ + public int mode = 0; + + /** Only if mode = 0 or 2. */ + public int friendlyFire; + + public Packet209SetPlayerTeam() { + } + + public Packet209SetPlayerTeam(ScorePlayerTeam par1, int par2) { + this.teamName = par1.func_96661_b(); + this.mode = par2; + + if (par2 == 0 || par2 == 2) { + this.teamDisplayName = par1.func_96669_c(); + this.teamPrefix = par1.func_96668_e(); + this.teamSuffix = par1.func_96663_f(); + this.friendlyFire = par1.func_98299_i(); + } + + if (par2 == 0) { + this.playerNames.addAll(par1.getMembershipCollection()); + } + } + + public Packet209SetPlayerTeam(ScorePlayerTeam par1ScorePlayerTeam, Collection par2Collection, int par3) { + if (par3 != 3 && par3 != 4) { + throw new IllegalArgumentException("Method must be join or leave for player constructor"); + } else if (par2Collection != null && !par2Collection.isEmpty()) { + this.mode = par3; + this.teamName = par1ScorePlayerTeam.func_96661_b(); + this.playerNames.addAll(par2Collection); + } else { + throw new IllegalArgumentException("Players cannot be null/empty"); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.teamName = readString(par1DataInputStream, 16); + this.mode = par1DataInputStream.readByte(); + + if (this.mode == 0 || this.mode == 2) { + this.teamDisplayName = readString(par1DataInputStream, 32); + this.teamPrefix = readString(par1DataInputStream, 16); + this.teamSuffix = readString(par1DataInputStream, 16); + this.friendlyFire = par1DataInputStream.readByte(); + } + + if (this.mode == 0 || this.mode == 3 || this.mode == 4) { + short var2 = par1DataInputStream.readShort(); + + for (int var3 = 0; var3 < var2; ++var3) { + this.playerNames.add(readString(par1DataInputStream, 16)); + } + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.teamName, par1DataOutputStream); + par1DataOutputStream.writeByte(this.mode); + + if (this.mode == 0 || this.mode == 2) { + writeString(this.teamDisplayName, par1DataOutputStream); + writeString(this.teamPrefix, par1DataOutputStream); + writeString(this.teamSuffix, par1DataOutputStream); + par1DataOutputStream.writeByte(this.friendlyFire); + } + + if (this.mode == 0 || this.mode == 3 || this.mode == 4) { + par1DataOutputStream.writeShort(this.playerNames.size()); + Iterator var2 = this.playerNames.iterator(); + + while (var2.hasNext()) { + String var3 = (String) var2.next(); + writeString(var3, par1DataOutputStream); + } + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSetPlayerTeam(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 3 + this.teamName.length(); + } +} diff --git a/src/main/java/net/minecraft/src/Packet20NamedEntitySpawn.java b/src/main/java/net/minecraft/src/Packet20NamedEntitySpawn.java new file mode 100644 index 0000000..810b203 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet20NamedEntitySpawn.java @@ -0,0 +1,102 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.List; + +public class Packet20NamedEntitySpawn extends Packet { + /** The entity ID, in this case it's the player ID. */ + public int entityId; + + /** The player's name. */ + public String name; + + /** The player's X position. */ + public int xPosition; + + /** The player's Y position. */ + public int yPosition; + + /** The player's Z position. */ + public int zPosition; + + /** The player's rotation. */ + public byte rotation; + + /** The player's pitch. */ + public byte pitch; + + /** The current item the player is holding. */ + public int currentItem; + private DataWatcher metadata; + private List metadataWatchableObjects; + + public Packet20NamedEntitySpawn() { + } + + public Packet20NamedEntitySpawn(EntityPlayer par1EntityPlayer) { + this.entityId = par1EntityPlayer.entityId; + this.name = par1EntityPlayer.username; + this.xPosition = MathHelper.floor_double(par1EntityPlayer.posX * 32.0D); + this.yPosition = MathHelper.floor_double(par1EntityPlayer.posY * 32.0D); + this.zPosition = MathHelper.floor_double(par1EntityPlayer.posZ * 32.0D); + this.rotation = (byte) ((int) (par1EntityPlayer.rotationYaw * 256.0F / 360.0F)); + this.pitch = (byte) ((int) (par1EntityPlayer.rotationPitch * 256.0F / 360.0F)); + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + this.currentItem = var2 == null ? 0 : var2.itemID; + this.metadata = par1EntityPlayer.getDataWatcher(); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.name = readString(par1DataInputStream, 16); + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readInt(); + this.zPosition = par1DataInputStream.readInt(); + this.rotation = par1DataInputStream.readByte(); + this.pitch = par1DataInputStream.readByte(); + this.currentItem = par1DataInputStream.readShort(); + this.metadataWatchableObjects = DataWatcher.readWatchableObjects(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + writeString(this.name, par1DataOutputStream); + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeInt(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.writeByte(this.rotation); + par1DataOutputStream.writeByte(this.pitch); + par1DataOutputStream.writeShort(this.currentItem); + this.metadata.writeWatchableObjects(par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleNamedEntitySpawn(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 28; + } + + public List getWatchedMetadata() { + if (this.metadataWatchableObjects == null) { + this.metadataWatchableObjects = this.metadata.getAllWatched(); + } + + return this.metadataWatchableObjects; + } +} diff --git a/src/main/java/net/minecraft/src/Packet22Collect.java b/src/main/java/net/minecraft/src/Packet22Collect.java new file mode 100644 index 0000000..255457e --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet22Collect.java @@ -0,0 +1,51 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet22Collect extends Packet { + /** The entity on the ground that was picked up. */ + public int collectedEntityId; + + /** The entity that picked up the one from the ground. */ + public int collectorEntityId; + + public Packet22Collect() { + } + + public Packet22Collect(int par1, int par2) { + this.collectedEntityId = par1; + this.collectorEntityId = par2; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.collectedEntityId = par1DataInputStream.readInt(); + this.collectorEntityId = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.collectedEntityId); + par1DataOutputStream.writeInt(this.collectorEntityId); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleCollect(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8; + } +} diff --git a/src/main/java/net/minecraft/src/Packet23VehicleSpawn.java b/src/main/java/net/minecraft/src/Packet23VehicleSpawn.java new file mode 100644 index 0000000..abafd42 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet23VehicleSpawn.java @@ -0,0 +1,156 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet23VehicleSpawn extends Packet { + /** Entity ID of the object. */ + public int entityId; + + /** The X position of the object. */ + public int xPosition; + + /** The Y position of the object. */ + public int yPosition; + + /** The Z position of the object. */ + public int zPosition; + + /** + * Not sent if the thrower entity ID is 0. The speed of this fireball along the + * X axis. + */ + public int speedX; + + /** + * Not sent if the thrower entity ID is 0. The speed of this fireball along the + * Y axis. + */ + public int speedY; + + /** + * Not sent if the thrower entity ID is 0. The speed of this fireball along the + * Z axis. + */ + public int speedZ; + + /** The pitch in steps of 2p/256 */ + public int pitch; + + /** The yaw in steps of 2p/256 */ + public int yaw; + + /** The type of object. */ + public int type; + + /** 0 if not a fireball. Otherwise, this is the Entity ID of the thrower. */ + public int throwerEntityId; + + public Packet23VehicleSpawn() { + } + + public Packet23VehicleSpawn(Entity par1Entity, int par2) { + this(par1Entity, par2, 0); + } + + public Packet23VehicleSpawn(Entity par1Entity, int par2, int par3) { + this.entityId = par1Entity.entityId; + this.xPosition = MathHelper.floor_double(par1Entity.posX * 32.0D); + this.yPosition = MathHelper.floor_double(par1Entity.posY * 32.0D); + this.zPosition = MathHelper.floor_double(par1Entity.posZ * 32.0D); + this.pitch = MathHelper.floor_float(par1Entity.rotationPitch * 256.0F / 360.0F); + this.yaw = MathHelper.floor_float(par1Entity.rotationYaw * 256.0F / 360.0F); + this.type = par2; + this.throwerEntityId = par3; + + if (par3 > 0) { + double var4 = par1Entity.motionX; + double var6 = par1Entity.motionY; + double var8 = par1Entity.motionZ; + double var10 = 3.9D; + + if (var4 < -var10) { + var4 = -var10; + } + + if (var6 < -var10) { + var6 = -var10; + } + + if (var8 < -var10) { + var8 = -var10; + } + + if (var4 > var10) { + var4 = var10; + } + + if (var6 > var10) { + var6 = var10; + } + + if (var8 > var10) { + var8 = var10; + } + + this.speedX = (int) (var4 * 8000.0D); + this.speedY = (int) (var6 * 8000.0D); + this.speedZ = (int) (var8 * 8000.0D); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.type = par1DataInputStream.readByte(); + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readInt(); + this.zPosition = par1DataInputStream.readInt(); + this.pitch = par1DataInputStream.readByte(); + this.yaw = par1DataInputStream.readByte(); + this.throwerEntityId = par1DataInputStream.readInt(); + + if (this.throwerEntityId > 0) { + this.speedX = par1DataInputStream.readShort(); + this.speedY = par1DataInputStream.readShort(); + this.speedZ = par1DataInputStream.readShort(); + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.type); + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeInt(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.writeByte(this.pitch); + par1DataOutputStream.writeByte(this.yaw); + par1DataOutputStream.writeInt(this.throwerEntityId); + + if (this.throwerEntityId > 0) { + par1DataOutputStream.writeShort(this.speedX); + par1DataOutputStream.writeShort(this.speedY); + par1DataOutputStream.writeShort(this.speedZ); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleVehicleSpawn(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 21 + this.throwerEntityId > 0 ? 6 : 0; + } +} diff --git a/src/main/java/net/minecraft/src/Packet24MobSpawn.java b/src/main/java/net/minecraft/src/Packet24MobSpawn.java new file mode 100644 index 0000000..50ebb8e --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet24MobSpawn.java @@ -0,0 +1,144 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.List; + +public class Packet24MobSpawn extends Packet { + /** The entity ID. */ + public int entityId; + + /** The type of mob. */ + public int type; + + /** The X position of the entity. */ + public int xPosition; + + /** The Y position of the entity. */ + public int yPosition; + + /** The Z position of the entity. */ + public int zPosition; + public int velocityX; + public int velocityY; + public int velocityZ; + + /** The yaw of the entity. */ + public byte yaw; + + /** The pitch of the entity. */ + public byte pitch; + + /** The yaw of the entity's head. */ + public byte headYaw; + + /** Indexed metadata for Mob, terminated by 0x7F */ + private DataWatcher metaData; + private List metadata; + + public Packet24MobSpawn() { + } + + public Packet24MobSpawn(EntityLiving par1EntityLiving) { + this.entityId = par1EntityLiving.entityId; + this.type = (byte) EntityList.getEntityID(par1EntityLiving); + this.xPosition = par1EntityLiving.myEntitySize.multiplyBy32AndRound(par1EntityLiving.posX); + this.yPosition = MathHelper.floor_double(par1EntityLiving.posY * 32.0D); + this.zPosition = par1EntityLiving.myEntitySize.multiplyBy32AndRound(par1EntityLiving.posZ); + this.yaw = (byte) ((int) (par1EntityLiving.rotationYaw * 256.0F / 360.0F)); + this.pitch = (byte) ((int) (par1EntityLiving.rotationPitch * 256.0F / 360.0F)); + this.headYaw = (byte) ((int) (par1EntityLiving.rotationYawHead * 256.0F / 360.0F)); + double var2 = 3.9D; + double var4 = par1EntityLiving.motionX; + double var6 = par1EntityLiving.motionY; + double var8 = par1EntityLiving.motionZ; + + if (var4 < -var2) { + var4 = -var2; + } + + if (var6 < -var2) { + var6 = -var2; + } + + if (var8 < -var2) { + var8 = -var2; + } + + if (var4 > var2) { + var4 = var2; + } + + if (var6 > var2) { + var6 = var2; + } + + if (var8 > var2) { + var8 = var2; + } + + this.velocityX = (int) (var4 * 8000.0D); + this.velocityY = (int) (var6 * 8000.0D); + this.velocityZ = (int) (var8 * 8000.0D); + this.metaData = par1EntityLiving.getDataWatcher(); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.type = par1DataInputStream.readByte() & 255; + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readInt(); + this.zPosition = par1DataInputStream.readInt(); + this.yaw = par1DataInputStream.readByte(); + this.pitch = par1DataInputStream.readByte(); + this.headYaw = par1DataInputStream.readByte(); + this.velocityX = par1DataInputStream.readShort(); + this.velocityY = par1DataInputStream.readShort(); + this.velocityZ = par1DataInputStream.readShort(); + this.metadata = DataWatcher.readWatchableObjects(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.type & 255); + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeInt(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.writeByte(this.yaw); + par1DataOutputStream.writeByte(this.pitch); + par1DataOutputStream.writeByte(this.headYaw); + par1DataOutputStream.writeShort(this.velocityX); + par1DataOutputStream.writeShort(this.velocityY); + par1DataOutputStream.writeShort(this.velocityZ); + this.metaData.writeWatchableObjects(par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleMobSpawn(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 26; + } + + public List getMetadata() { + if (this.metadata == null) { + this.metadata = this.metaData.getAllWatched(); + } + + return this.metadata; + } +} diff --git a/src/main/java/net/minecraft/src/Packet250CustomPayload.java b/src/main/java/net/minecraft/src/Packet250CustomPayload.java new file mode 100644 index 0000000..e4c66fd --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet250CustomPayload.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet250CustomPayload extends Packet { + /** Name of the 'channel' used to send data */ + public String channel; + + /** Length of the data to be read */ + public int length; + + /** Any data */ + public byte[] data; + + public Packet250CustomPayload() { + } + + public Packet250CustomPayload(String par1Str, byte[] par2ArrayOfByte) { + this.channel = par1Str; + this.data = par2ArrayOfByte; + + if (par2ArrayOfByte != null) { + this.length = par2ArrayOfByte.length; + + if (this.length > 32767) { + throw new IllegalArgumentException("Payload may not be larger than 32k"); + } + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.channel = readString(par1DataInputStream, 20); + this.length = par1DataInputStream.readShort(); + + if (this.length > 0 && this.length < 32767) { + this.data = new byte[this.length]; + par1DataInputStream.readFully(this.data); + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.channel, par1DataOutputStream); + par1DataOutputStream.writeShort((short) this.length); + + if (this.data != null) { + par1DataOutputStream.write(this.data); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleCustomPayload(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2 + this.channel.length() * 2 + 2 + this.length; + } +} diff --git a/src/main/java/net/minecraft/src/Packet252SharedKey.java b/src/main/java/net/minecraft/src/Packet252SharedKey.java new file mode 100644 index 0000000..2574869 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet252SharedKey.java @@ -0,0 +1,41 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet252SharedKey extends Packet { + + public Packet252SharedKey() { + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + readBytesFromStream(par1DataInputStream); + readBytesFromStream(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeByteArray(par1DataOutputStream, new byte[162]); + writeByteArray(par1DataOutputStream, new byte[4]); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSharedKey(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2 + 162 + 2 + 4; + } +} diff --git a/src/main/java/net/minecraft/src/Packet253ServerAuthData.java b/src/main/java/net/minecraft/src/Packet253ServerAuthData.java new file mode 100644 index 0000000..c4f91c6 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet253ServerAuthData.java @@ -0,0 +1,58 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet253ServerAuthData extends Packet { + private String serverId; + private byte[] verifyToken = new byte[0]; + + public Packet253ServerAuthData() { + } + + public Packet253ServerAuthData(String par1Str, byte[] par3ArrayOfByte) { + this.serverId = par1Str; + this.verifyToken = par3ArrayOfByte; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.serverId = readString(par1DataInputStream, 20); + readBytesFromStream(par1DataInputStream); + this.verifyToken = readBytesFromStream(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.serverId, par1DataOutputStream); + writeByteArray(par1DataOutputStream, new byte[0]); + writeByteArray(par1DataOutputStream, this.verifyToken); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleServerAuthData(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2 + this.serverId.length() * 2 + 2 + 0 + 2 + this.verifyToken.length; + } + + public String getServerId() { + return this.serverId; + } + + public byte[] getVerifyToken() { + return this.verifyToken; + } +} diff --git a/src/main/java/net/minecraft/src/Packet254ServerPing.java b/src/main/java/net/minecraft/src/Packet254ServerPing.java new file mode 100644 index 0000000..b71e3a7 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet254ServerPing.java @@ -0,0 +1,41 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet254ServerPing extends Packet { + /** Always 1, unless readByte threw an exception. */ + public int readSuccessfully = 0; + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + try { + this.readSuccessfully = par1DataInputStream.readByte(); + } catch (Throwable var3) { + this.readSuccessfully = 0; + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleServerPing(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 0; + } +} diff --git a/src/main/java/net/minecraft/src/Packet255KickDisconnect.java b/src/main/java/net/minecraft/src/Packet255KickDisconnect.java new file mode 100644 index 0000000..d92da17 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet255KickDisconnect.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet255KickDisconnect extends Packet { + /** Displayed to the client when the connection terminates. */ + public String reason; + + public Packet255KickDisconnect() { + } + + public Packet255KickDisconnect(String par1Str) { + this.reason = par1Str; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.reason = readString(par1DataInputStream, 256); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.reason, par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleKickDisconnect(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return this.reason.length(); + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/Packet25EntityPainting.java b/src/main/java/net/minecraft/src/Packet25EntityPainting.java new file mode 100644 index 0000000..be5fe75 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet25EntityPainting.java @@ -0,0 +1,64 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet25EntityPainting extends Packet { + public int entityId; + public int xPosition; + public int yPosition; + public int zPosition; + public int direction; + public String title; + + public Packet25EntityPainting() { + } + + public Packet25EntityPainting(EntityPainting par1EntityPainting) { + this.entityId = par1EntityPainting.entityId; + this.xPosition = par1EntityPainting.xPosition; + this.yPosition = par1EntityPainting.yPosition; + this.zPosition = par1EntityPainting.zPosition; + this.direction = par1EntityPainting.hangingDirection; + this.title = par1EntityPainting.art.title; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.title = readString(par1DataInputStream, EnumArt.maxArtTitleLength); + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readInt(); + this.zPosition = par1DataInputStream.readInt(); + this.direction = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + writeString(this.title, par1DataOutputStream); + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeInt(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.writeInt(this.direction); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityPainting(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 24; + } +} diff --git a/src/main/java/net/minecraft/src/Packet26EntityExpOrb.java b/src/main/java/net/minecraft/src/Packet26EntityExpOrb.java new file mode 100644 index 0000000..5a0f781 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet26EntityExpOrb.java @@ -0,0 +1,63 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet26EntityExpOrb extends Packet { + /** Entity ID for the XP Orb */ + public int entityId; + public int posX; + public int posY; + public int posZ; + + /** The Orbs Experience points value. */ + public int xpValue; + + public Packet26EntityExpOrb() { + } + + public Packet26EntityExpOrb(EntityXPOrb par1EntityXPOrb) { + this.entityId = par1EntityXPOrb.entityId; + this.posX = MathHelper.floor_double(par1EntityXPOrb.posX * 32.0D); + this.posY = MathHelper.floor_double(par1EntityXPOrb.posY * 32.0D); + this.posZ = MathHelper.floor_double(par1EntityXPOrb.posZ * 32.0D); + this.xpValue = par1EntityXPOrb.getXpValue(); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.posX = par1DataInputStream.readInt(); + this.posY = par1DataInputStream.readInt(); + this.posZ = par1DataInputStream.readInt(); + this.xpValue = par1DataInputStream.readShort(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeInt(this.posX); + par1DataOutputStream.writeInt(this.posY); + par1DataOutputStream.writeInt(this.posZ); + par1DataOutputStream.writeShort(this.xpValue); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityExpOrb(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 18; + } +} diff --git a/src/main/java/net/minecraft/src/Packet28EntityVelocity.java b/src/main/java/net/minecraft/src/Packet28EntityVelocity.java new file mode 100644 index 0000000..8de4383 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet28EntityVelocity.java @@ -0,0 +1,102 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet28EntityVelocity extends Packet { + public int entityId; + public int motionX; + public int motionY; + public int motionZ; + + public Packet28EntityVelocity() { + } + + public Packet28EntityVelocity(Entity par1Entity) { + this(par1Entity.entityId, par1Entity.motionX, par1Entity.motionY, par1Entity.motionZ); + } + + public Packet28EntityVelocity(int par1, double par2, double par4, double par6) { + this.entityId = par1; + double var8 = 3.9D; + + if (par2 < -var8) { + par2 = -var8; + } + + if (par4 < -var8) { + par4 = -var8; + } + + if (par6 < -var8) { + par6 = -var8; + } + + if (par2 > var8) { + par2 = var8; + } + + if (par4 > var8) { + par4 = var8; + } + + if (par6 > var8) { + par6 = var8; + } + + this.motionX = (int) (par2 * 8000.0D); + this.motionY = (int) (par4 * 8000.0D); + this.motionZ = (int) (par6 * 8000.0D); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.motionX = par1DataInputStream.readShort(); + this.motionY = par1DataInputStream.readShort(); + this.motionZ = par1DataInputStream.readShort(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeShort(this.motionX); + par1DataOutputStream.writeShort(this.motionY); + par1DataOutputStream.writeShort(this.motionZ); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityVelocity(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 10; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet28EntityVelocity var2 = (Packet28EntityVelocity) par1Packet; + return var2.entityId == this.entityId; + } +} diff --git a/src/main/java/net/minecraft/src/Packet29DestroyEntity.java b/src/main/java/net/minecraft/src/Packet29DestroyEntity.java new file mode 100644 index 0000000..56f70e7 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet29DestroyEntity.java @@ -0,0 +1,53 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet29DestroyEntity extends Packet { + /** ID of the entity to be destroyed on the client. */ + public int[] entityId; + + public Packet29DestroyEntity() { + } + + public Packet29DestroyEntity(int... par1ArrayOfInteger) { + this.entityId = par1ArrayOfInteger; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = new int[par1DataInputStream.readByte()]; + + for (int var2 = 0; var2 < this.entityId.length; ++var2) { + this.entityId[var2] = par1DataInputStream.readInt(); + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.entityId.length); + + for (int var2 = 0; var2 < this.entityId.length; ++var2) { + par1DataOutputStream.writeInt(this.entityId[var2]); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleDestroyEntity(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 1 + this.entityId.length * 4; + } +} diff --git a/src/main/java/net/minecraft/src/Packet2ClientProtocol.java b/src/main/java/net/minecraft/src/Packet2ClientProtocol.java new file mode 100644 index 0000000..a2ee5ef --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet2ClientProtocol.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet2ClientProtocol extends Packet { + private int protocolVersion; + private String username; + private String serverHost; + private int serverPort; + + public Packet2ClientProtocol() { + } + + public Packet2ClientProtocol(int par1, String par2Str, String par3Str, int par4) { + this.protocolVersion = par1; + this.username = par2Str; + this.serverHost = par3Str; + this.serverPort = par4; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.protocolVersion = par1DataInputStream.readByte(); + this.username = readString(par1DataInputStream, 16); + this.serverHost = readString(par1DataInputStream, 255); + this.serverPort = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.protocolVersion); + writeString(this.username, par1DataOutputStream); + writeString(this.serverHost, par1DataOutputStream); + par1DataOutputStream.writeInt(this.serverPort); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleClientProtocol(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 3 + 2 * this.username.length(); + } + + /** + * Returns the protocol version. + */ + public int getProtocolVersion() { + return this.protocolVersion; + } + + /** + * Returns the username. + */ + public String getUsername() { + return this.username; + } +} diff --git a/src/main/java/net/minecraft/src/Packet30Entity.java b/src/main/java/net/minecraft/src/Packet30Entity.java new file mode 100644 index 0000000..985e8a7 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet30Entity.java @@ -0,0 +1,83 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet30Entity extends Packet { + /** The ID of this entity. */ + public int entityId; + + /** The X axis relative movement. */ + public byte xPosition; + + /** The Y axis relative movement. */ + public byte yPosition; + + /** The Z axis relative movement. */ + public byte zPosition; + + /** The X axis rotation. */ + public byte yaw; + + /** The Y axis rotation. */ + public byte pitch; + + /** Boolean set to true if the entity is rotating. */ + public boolean rotating = false; + + public Packet30Entity() { + } + + public Packet30Entity(int par1) { + this.entityId = par1; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntity(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 4; + } + + public String toString() { + return "Entity_" + super.toString(); + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet30Entity var2 = (Packet30Entity) par1Packet; + return var2.entityId == this.entityId; + } +} diff --git a/src/main/java/net/minecraft/src/Packet31RelEntityMove.java b/src/main/java/net/minecraft/src/Packet31RelEntityMove.java new file mode 100644 index 0000000..21c9fe2 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet31RelEntityMove.java @@ -0,0 +1,44 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet31RelEntityMove extends Packet30Entity { + public Packet31RelEntityMove() { + } + + public Packet31RelEntityMove(int par1, byte par2, byte par3, byte par4) { + super(par1); + this.xPosition = par2; + this.yPosition = par3; + this.zPosition = par4; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + super.readPacketData(par1DataInputStream); + this.xPosition = par1DataInputStream.readByte(); + this.yPosition = par1DataInputStream.readByte(); + this.zPosition = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + super.writePacketData(par1DataOutputStream); + par1DataOutputStream.writeByte(this.xPosition); + par1DataOutputStream.writeByte(this.yPosition); + par1DataOutputStream.writeByte(this.zPosition); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 7; + } +} diff --git a/src/main/java/net/minecraft/src/Packet32EntityLook.java b/src/main/java/net/minecraft/src/Packet32EntityLook.java new file mode 100644 index 0000000..437f106 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet32EntityLook.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet32EntityLook extends Packet30Entity { + public Packet32EntityLook() { + this.rotating = true; + } + + public Packet32EntityLook(int par1, byte par2, byte par3) { + super(par1); + this.yaw = par2; + this.pitch = par3; + this.rotating = true; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + super.readPacketData(par1DataInputStream); + this.yaw = par1DataInputStream.readByte(); + this.pitch = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + super.writePacketData(par1DataOutputStream); + par1DataOutputStream.writeByte(this.yaw); + par1DataOutputStream.writeByte(this.pitch); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 6; + } +} diff --git a/src/main/java/net/minecraft/src/Packet33RelEntityMoveLook.java b/src/main/java/net/minecraft/src/Packet33RelEntityMoveLook.java new file mode 100644 index 0000000..45f6738 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet33RelEntityMoveLook.java @@ -0,0 +1,52 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet33RelEntityMoveLook extends Packet30Entity { + public Packet33RelEntityMoveLook() { + this.rotating = true; + } + + public Packet33RelEntityMoveLook(int par1, byte par2, byte par3, byte par4, byte par5, byte par6) { + super(par1); + this.xPosition = par2; + this.yPosition = par3; + this.zPosition = par4; + this.yaw = par5; + this.pitch = par6; + this.rotating = true; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + super.readPacketData(par1DataInputStream); + this.xPosition = par1DataInputStream.readByte(); + this.yPosition = par1DataInputStream.readByte(); + this.zPosition = par1DataInputStream.readByte(); + this.yaw = par1DataInputStream.readByte(); + this.pitch = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + super.writePacketData(par1DataOutputStream); + par1DataOutputStream.writeByte(this.xPosition); + par1DataOutputStream.writeByte(this.yPosition); + par1DataOutputStream.writeByte(this.zPosition); + par1DataOutputStream.writeByte(this.yaw); + par1DataOutputStream.writeByte(this.pitch); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 9; + } +} diff --git a/src/main/java/net/minecraft/src/Packet34EntityTeleport.java b/src/main/java/net/minecraft/src/Packet34EntityTeleport.java new file mode 100644 index 0000000..20020f3 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet34EntityTeleport.java @@ -0,0 +1,100 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet34EntityTeleport extends Packet { + /** ID of the entity. */ + public int entityId; + + /** X position of the entity. */ + public int xPosition; + + /** Y position of the entity. */ + public int yPosition; + + /** Z position of the entity. */ + public int zPosition; + + /** Yaw of the entity. */ + public byte yaw; + + /** Pitch of the entity. */ + public byte pitch; + + public Packet34EntityTeleport() { + } + + public Packet34EntityTeleport(Entity par1Entity) { + this.entityId = par1Entity.entityId; + this.xPosition = MathHelper.floor_double(par1Entity.posX * 32.0D); + this.yPosition = MathHelper.floor_double(par1Entity.posY * 32.0D); + this.zPosition = MathHelper.floor_double(par1Entity.posZ * 32.0D); + this.yaw = (byte) ((int) (par1Entity.rotationYaw * 256.0F / 360.0F)); + this.pitch = (byte) ((int) (par1Entity.rotationPitch * 256.0F / 360.0F)); + } + + public Packet34EntityTeleport(int par1, int par2, int par3, int par4, byte par5, byte par6) { + this.entityId = par1; + this.xPosition = par2; + this.yPosition = par3; + this.zPosition = par4; + this.yaw = par5; + this.pitch = par6; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readInt(); + this.zPosition = par1DataInputStream.readInt(); + this.yaw = (byte) par1DataInputStream.read(); + this.pitch = (byte) par1DataInputStream.read(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeInt(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.write(this.yaw); + par1DataOutputStream.write(this.pitch); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityTeleport(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 34; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet34EntityTeleport var2 = (Packet34EntityTeleport) par1Packet; + return var2.entityId == this.entityId; + } +} diff --git a/src/main/java/net/minecraft/src/Packet35EntityHeadRotation.java b/src/main/java/net/minecraft/src/Packet35EntityHeadRotation.java new file mode 100644 index 0000000..dbaa9cf --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet35EntityHeadRotation.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet35EntityHeadRotation extends Packet { + public int entityId; + public byte headRotationYaw; + + public Packet35EntityHeadRotation() { + } + + public Packet35EntityHeadRotation(int par1, byte par2) { + this.entityId = par1; + this.headRotationYaw = par2; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.headRotationYaw = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.headRotationYaw); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityHeadRotation(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 5; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet35EntityHeadRotation var2 = (Packet35EntityHeadRotation) par1Packet; + return var2.entityId == this.entityId; + } + + /** + * If this returns true, the packet may be processed on any thread; otherwise it + * is queued for the main thread to handle. + */ + public boolean canProcessAsync() { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/Packet38EntityStatus.java b/src/main/java/net/minecraft/src/Packet38EntityStatus.java new file mode 100644 index 0000000..346c793 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet38EntityStatus.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet38EntityStatus extends Packet { + public int entityId; + + /** 2 for hurt, 3 for dead */ + public byte entityStatus; + + public Packet38EntityStatus() { + } + + public Packet38EntityStatus(int par1, byte par2) { + this.entityId = par1; + this.entityStatus = par2; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.entityStatus = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.entityStatus); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityStatus(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 5; + } +} diff --git a/src/main/java/net/minecraft/src/Packet39AttachEntity.java b/src/main/java/net/minecraft/src/Packet39AttachEntity.java new file mode 100644 index 0000000..d342c10 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet39AttachEntity.java @@ -0,0 +1,64 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet39AttachEntity extends Packet { + public int entityId; + public int vehicleEntityId; + + public Packet39AttachEntity() { + } + + public Packet39AttachEntity(Entity par1Entity, Entity par2Entity) { + this.entityId = par1Entity.entityId; + this.vehicleEntityId = par2Entity != null ? par2Entity.entityId : -1; + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.vehicleEntityId = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeInt(this.vehicleEntityId); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleAttachEntity(this); + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet39AttachEntity var2 = (Packet39AttachEntity) par1Packet; + return var2.entityId == this.entityId; + } +} diff --git a/src/main/java/net/minecraft/src/Packet3Chat.java b/src/main/java/net/minecraft/src/Packet3Chat.java new file mode 100644 index 0000000..0d0dc4d --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet3Chat.java @@ -0,0 +1,76 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet3Chat extends Packet { + /** Maximum number of characters allowed in chat string in each packet. */ + public static int maxChatLength = 119; + + /** The message being sent. */ + public String message; + private boolean isServer; + + public Packet3Chat() { + this.isServer = true; + } + + public Packet3Chat(String par1Str) { + this(par1Str, true); + } + + public Packet3Chat(String par1Str, boolean par2) { + this.isServer = true; + + if (par1Str.length() > maxChatLength) { + par1Str = par1Str.substring(0, maxChatLength); + } + + this.message = par1Str; + this.isServer = par2; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.message = readString(par1DataInputStream, maxChatLength); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.message, par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleChat(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2 + this.message.length() * 2; + } + + /** + * Get whether this is a server + */ + public boolean getIsServer() { + return this.isServer; + } + + /** + * If this returns true, the packet may be processed on any thread; otherwise it + * is queued for the main thread to handle. + */ + public boolean canProcessAsync() { + return !this.message.startsWith("/"); + } +} diff --git a/src/main/java/net/minecraft/src/Packet40EntityMetadata.java b/src/main/java/net/minecraft/src/Packet40EntityMetadata.java new file mode 100644 index 0000000..0b80671 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet40EntityMetadata.java @@ -0,0 +1,58 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.List; + +public class Packet40EntityMetadata extends Packet { + public int entityId; + private List metadata; + + public Packet40EntityMetadata() { + } + + public Packet40EntityMetadata(int par1, DataWatcher par2DataWatcher, boolean par3) { + this.entityId = par1; + + if (par3) { + this.metadata = par2DataWatcher.getAllWatched(); + } else { + this.metadata = par2DataWatcher.unwatchAndReturnAllWatched(); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.metadata = DataWatcher.readWatchableObjects(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + DataWatcher.writeObjectsInListToStream(this.metadata, par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityMetadata(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 5; + } + + public List getMetadata() { + return this.metadata; + } +} diff --git a/src/main/java/net/minecraft/src/Packet41EntityEffect.java b/src/main/java/net/minecraft/src/Packet41EntityEffect.java new file mode 100644 index 0000000..a269d66 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet41EntityEffect.java @@ -0,0 +1,86 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet41EntityEffect extends Packet { + public int entityId; + public byte effectId; + + /** The effect's amplifier. */ + public byte effectAmplifier; + public short duration; + + public Packet41EntityEffect() { + } + + public Packet41EntityEffect(int par1, PotionEffect par2PotionEffect) { + this.entityId = par1; + this.effectId = (byte) (par2PotionEffect.getPotionID() & 255); + this.effectAmplifier = (byte) (par2PotionEffect.getAmplifier() & 255); + + if (par2PotionEffect.getDuration() > 32767) { + this.duration = 32767; + } else { + this.duration = (short) par2PotionEffect.getDuration(); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.effectId = par1DataInputStream.readByte(); + this.effectAmplifier = par1DataInputStream.readByte(); + this.duration = par1DataInputStream.readShort(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.effectId); + par1DataOutputStream.writeByte(this.effectAmplifier); + par1DataOutputStream.writeShort(this.duration); + } + + /** + * Returns true if duration is at maximum, false otherwise. + */ + public boolean isDurationMax() { + return this.duration == 32767; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityEffect(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet41EntityEffect var2 = (Packet41EntityEffect) par1Packet; + return var2.entityId == this.entityId && var2.effectId == this.effectId; + } +} diff --git a/src/main/java/net/minecraft/src/Packet42RemoveEntityEffect.java b/src/main/java/net/minecraft/src/Packet42RemoveEntityEffect.java new file mode 100644 index 0000000..c0b99ab --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet42RemoveEntityEffect.java @@ -0,0 +1,51 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet42RemoveEntityEffect extends Packet { + /** The ID of the entity which an effect is being removed from. */ + public int entityId; + + /** The ID of the effect which is being removed from an entity. */ + public byte effectId; + + public Packet42RemoveEntityEffect() { + } + + public Packet42RemoveEntityEffect(int par1, PotionEffect par2PotionEffect) { + this.entityId = par1; + this.effectId = (byte) (par2PotionEffect.getPotionID() & 255); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.effectId = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.effectId); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleRemoveEntityEffect(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 5; + } +} diff --git a/src/main/java/net/minecraft/src/Packet43Experience.java b/src/main/java/net/minecraft/src/Packet43Experience.java new file mode 100644 index 0000000..674c3eb --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet43Experience.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet43Experience extends Packet { + /** The current experience bar points. */ + public float experience; + + /** The total experience points. */ + public int experienceTotal; + + /** The experience level. */ + public int experienceLevel; + + public Packet43Experience() { + } + + public Packet43Experience(float par1, int par2, int par3) { + this.experience = par1; + this.experienceTotal = par2; + this.experienceLevel = par3; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.experience = par1DataInputStream.readFloat(); + this.experienceLevel = par1DataInputStream.readShort(); + this.experienceTotal = par1DataInputStream.readShort(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeFloat(this.experience); + par1DataOutputStream.writeShort(this.experienceLevel); + par1DataOutputStream.writeShort(this.experienceTotal); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleExperience(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 4; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/Packet4UpdateTime.java b/src/main/java/net/minecraft/src/Packet4UpdateTime.java new file mode 100644 index 0000000..2bb224d --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet4UpdateTime.java @@ -0,0 +1,74 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet4UpdateTime extends Packet { + /** World age in ticks. */ + public long worldAge; + + /** The world time in minutes. */ + public long time; + + public Packet4UpdateTime() { + } + + public Packet4UpdateTime(long par1, long par3) { + this.worldAge = par1; + this.time = par3; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.worldAge = par1DataInputStream.readLong(); + this.time = par1DataInputStream.readLong(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeLong(this.worldAge); + par1DataOutputStream.writeLong(this.time); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleUpdateTime(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 16; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } + + /** + * If this returns true, the packet may be processed on any thread; otherwise it + * is queued for the main thread to handle. + */ + public boolean canProcessAsync() { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/Packet51MapChunk.java b/src/main/java/net/minecraft/src/Packet51MapChunk.java new file mode 100644 index 0000000..75f3272 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet51MapChunk.java @@ -0,0 +1,196 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import net.lax1dude.eaglercraft.EaglerInflater; + +public class Packet51MapChunk extends Packet { + /** The x-position of the transmitted chunk, in chunk coordinates. */ + public int xCh; + + /** The z-position of the transmitted chunk, in chunk coordinates. */ + public int zCh; + + /** + * The y-position of the lowest chunk Section in the transmitted chunk, in chunk + * coordinates. + */ + public int yChMin; + + /** + * The y-position of the highest chunk Section in the transmitted chunk, in + * chunk coordinates. + */ + public int yChMax; + + /** The transmitted chunk data, decompressed. */ + private byte[] chunkData; + + /** The compressed chunk data */ + private byte[] compressedChunkData; + + /** + * Whether to initialize the Chunk before applying the effect of the + * Packet51MapChunk. + */ + public boolean includeInitialize; + + /** The length of the compressed chunk data byte array. */ + private int tempLength; + + /** A temporary storage for the compressed chunk data byte array. */ + private static byte[] temp = new byte[196864]; + + public Packet51MapChunk() { + this.isChunkDataPacket = true; + } + + public Packet51MapChunk(Chunk par1Chunk, boolean par2, int par3) { + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xCh = par1DataInputStream.readInt(); + this.zCh = par1DataInputStream.readInt(); + this.includeInitialize = par1DataInputStream.readBoolean(); + this.yChMin = par1DataInputStream.readShort(); + this.yChMax = par1DataInputStream.readShort(); + this.tempLength = par1DataInputStream.readInt(); + + if (temp.length < this.tempLength) { + temp = new byte[this.tempLength]; + } + + par1DataInputStream.readFully(temp, 0, this.tempLength); + int var2 = 0; + int var3; + + for (var3 = 0; var3 < 16; ++var3) { + var2 += this.yChMin >> var3 & 1; + } + + var3 = 12288 * var2; + + if (this.includeInitialize) { + var3 += 256; + } + + this.compressedChunkData = EaglerInflater.uncompress(temp); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xCh); + par1DataOutputStream.writeInt(this.zCh); + par1DataOutputStream.writeBoolean(this.includeInitialize); + par1DataOutputStream.writeShort((short) (this.yChMin & 65535)); + par1DataOutputStream.writeShort((short) (this.yChMax & 65535)); + par1DataOutputStream.writeInt(this.tempLength); + par1DataOutputStream.write(this.chunkData, 0, this.tempLength); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleMapChunk(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 17 + this.tempLength; + } + + public byte[] getCompressedChunkData() { + return this.compressedChunkData; + } + + public static Packet51MapChunkData getMapChunkData(Chunk par0Chunk, boolean par1, int par2) { + int var3 = 0; + ExtendedBlockStorage[] var4 = par0Chunk.getBlockStorageArray(); + int var5 = 0; + Packet51MapChunkData var6 = new Packet51MapChunkData(); + byte[] var7 = temp; + + if (par1) { + par0Chunk.sendUpdates = true; + } + + int var8; + + for (var8 = 0; var8 < var4.length; ++var8) { + if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0) { + var6.chunkExistFlag |= 1 << var8; + + if (var4[var8].getBlockMSBArray() != null) { + var6.chunkHasAddSectionFlag |= 1 << var8; + ++var5; + } + } + } + + for (var8 = 0; var8 < var4.length; ++var8) { + if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0) { + byte[] var9 = var4[var8].getBlockLSBArray(); + System.arraycopy(var9, 0, var7, var3, var9.length); + var3 += var9.length; + } + } + + NibbleArray var10; + + for (var8 = 0; var8 < var4.length; ++var8) { + if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0) { + var10 = var4[var8].getMetadataArray(); + System.arraycopy(var10.data, 0, var7, var3, var10.data.length); + var3 += var10.data.length; + } + } + + for (var8 = 0; var8 < var4.length; ++var8) { + if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0) { + var10 = var4[var8].getBlocklightArray(); + System.arraycopy(var10.data, 0, var7, var3, var10.data.length); + var3 += var10.data.length; + } + } + + if (!par0Chunk.worldObj.provider.hasNoSky) { + for (var8 = 0; var8 < var4.length; ++var8) { + if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0) { + var10 = var4[var8].getSkylightArray(); + System.arraycopy(var10.data, 0, var7, var3, var10.data.length); + var3 += var10.data.length; + } + } + } + + if (var5 > 0) { + for (var8 = 0; var8 < var4.length; ++var8) { + if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && var4[var8].getBlockMSBArray() != null && (par2 & 1 << var8) != 0) { + var10 = var4[var8].getBlockMSBArray(); + System.arraycopy(var10.data, 0, var7, var3, var10.data.length); + var3 += var10.data.length; + } + } + } + + if (par1) { + byte[] var11 = par0Chunk.getBiomeArray(); + System.arraycopy(var11, 0, var7, var3, var11.length); + var3 += var11.length; + } + + var6.compressedData = new byte[var3]; + System.arraycopy(var7, 0, var6.compressedData, 0, var3); + return var6; + } +} diff --git a/src/main/java/net/minecraft/src/Packet51MapChunkData.java b/src/main/java/net/minecraft/src/Packet51MapChunkData.java new file mode 100644 index 0000000..3aecfd3 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet51MapChunkData.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +public class Packet51MapChunkData { + public byte[] compressedData; + public int chunkExistFlag; + public int chunkHasAddSectionFlag; +} diff --git a/src/main/java/net/minecraft/src/Packet52MultiBlockChange.java b/src/main/java/net/minecraft/src/Packet52MultiBlockChange.java new file mode 100644 index 0000000..19ca3a4 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet52MultiBlockChange.java @@ -0,0 +1,109 @@ +package net.minecraft.src; + +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet52MultiBlockChange extends Packet { + /** Chunk X position. */ + public int xPosition; + + /** Chunk Z position. */ + public int zPosition; + + /** The metadata for each block changed. */ + public byte[] metadataArray; + + /** The size of the arrays. */ + public int size; + private static byte[] field_73449_e = new byte[0]; + + public Packet52MultiBlockChange() { + this.isChunkDataPacket = true; + } + + public Packet52MultiBlockChange(int par1, int par2, short[] par3ArrayOfShort, int par4, World par5World) { + this.isChunkDataPacket = true; + this.xPosition = par1; + this.zPosition = par2; + this.size = par4; + int var6 = 4 * par4; + Chunk var7 = par5World.getChunkFromChunkCoords(par1, par2); + + try { + if (par4 >= 64) { + this.field_98193_m.logInfo("ChunkTilesUpdatePacket compress " + par4); + + if (field_73449_e.length < var6) { + field_73449_e = new byte[var6]; + } + } else { + ByteArrayOutputStream var8 = new ByteArrayOutputStream(var6); + DataOutputStream var9 = new DataOutputStream(var8); + + for (int var10 = 0; var10 < par4; ++var10) { + int var11 = par3ArrayOfShort[var10] >> 12 & 15; + int var12 = par3ArrayOfShort[var10] >> 8 & 15; + int var13 = par3ArrayOfShort[var10] & 255; + var9.writeShort(par3ArrayOfShort[var10]); + var9.writeShort((short) ((var7.getBlockID(var11, var13, var12) & 4095) << 4 | var7.getBlockMetadata(var11, var13, var12) & 15)); + } + + this.metadataArray = var8.toByteArray(); + + if (this.metadataArray.length != var6) { + throw new RuntimeException("Expected length " + var6 + " doesn\'t match received length " + this.metadataArray.length); + } + } + } catch (IOException var14) { + this.field_98193_m.logSevereException("Couldn\'t create chunk packet", var14); + this.metadataArray = null; + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readInt(); + this.zPosition = par1DataInputStream.readInt(); + this.size = par1DataInputStream.readShort() & 65535; + int var2 = par1DataInputStream.readInt(); + + if (var2 > 0) { + this.metadataArray = new byte[var2]; + par1DataInputStream.readFully(this.metadataArray); + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.writeShort((short) this.size); + + if (this.metadataArray != null) { + par1DataOutputStream.writeInt(this.metadataArray.length); + par1DataOutputStream.write(this.metadataArray); + } else { + par1DataOutputStream.writeInt(0); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleMultiBlockChange(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 10 + this.size * 4; + } +} diff --git a/src/main/java/net/minecraft/src/Packet53BlockChange.java b/src/main/java/net/minecraft/src/Packet53BlockChange.java new file mode 100644 index 0000000..b23ecd2 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet53BlockChange.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet53BlockChange extends Packet { + /** Block X position. */ + public int xPosition; + + /** Block Y position. */ + public int yPosition; + + /** Block Z position. */ + public int zPosition; + + /** The new block type for the block. */ + public int type; + + /** Metadata of the block. */ + public int metadata; + + public Packet53BlockChange() { + this.isChunkDataPacket = true; + } + + public Packet53BlockChange(int par1, int par2, int par3, World par4World) { + this.isChunkDataPacket = true; + this.xPosition = par1; + this.yPosition = par2; + this.zPosition = par3; + this.type = par4World.getBlockId(par1, par2, par3); + this.metadata = par4World.getBlockMetadata(par1, par2, par3); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.read(); + this.zPosition = par1DataInputStream.readInt(); + this.type = par1DataInputStream.readShort(); + this.metadata = par1DataInputStream.read(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.write(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.writeShort(this.type); + par1DataOutputStream.write(this.metadata); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleBlockChange(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 11; + } +} diff --git a/src/main/java/net/minecraft/src/Packet54PlayNoteBlock.java b/src/main/java/net/minecraft/src/Packet54PlayNoteBlock.java new file mode 100644 index 0000000..f6a1d32 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet54PlayNoteBlock.java @@ -0,0 +1,73 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet54PlayNoteBlock extends Packet { + public int xLocation; + public int yLocation; + public int zLocation; + + /** 1=Double Bass, 2=Snare Drum, 3=Clicks / Sticks, 4=Bass Drum, 5=Harp */ + public int instrumentType; + + /** + * The pitch of the note (between 0-24 inclusive where 0 is the lowest and 24 is + * the highest). + */ + public int pitch; + + /** The block ID this action is set for. */ + public int blockId; + + public Packet54PlayNoteBlock() { + } + + public Packet54PlayNoteBlock(int par1, int par2, int par3, int par4, int par5, int par6) { + this.xLocation = par1; + this.yLocation = par2; + this.zLocation = par3; + this.instrumentType = par5; + this.pitch = par6; + this.blockId = par4; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xLocation = par1DataInputStream.readInt(); + this.yLocation = par1DataInputStream.readShort(); + this.zLocation = par1DataInputStream.readInt(); + this.instrumentType = par1DataInputStream.read(); + this.pitch = par1DataInputStream.read(); + this.blockId = par1DataInputStream.readShort() & 4095; + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xLocation); + par1DataOutputStream.writeShort(this.yLocation); + par1DataOutputStream.writeInt(this.zLocation); + par1DataOutputStream.write(this.instrumentType); + par1DataOutputStream.write(this.pitch); + par1DataOutputStream.writeShort(this.blockId & 4095); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleBlockEvent(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 14; + } +} diff --git a/src/main/java/net/minecraft/src/Packet55BlockDestroy.java b/src/main/java/net/minecraft/src/Packet55BlockDestroy.java new file mode 100644 index 0000000..ac754c6 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet55BlockDestroy.java @@ -0,0 +1,120 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet55BlockDestroy extends Packet { + /** Entity breaking the block */ + private int entityId; + + /** X posiiton of the block */ + private int posX; + + /** Y position of the block */ + private int posY; + + /** Z position of the block */ + private int posZ; + + /** How far destroyed this block is */ + private int destroyedStage; + + public Packet55BlockDestroy() { + } + + public Packet55BlockDestroy(int par1, int par2, int par3, int par4, int par5) { + this.entityId = par1; + this.posX = par2; + this.posY = par3; + this.posZ = par4; + this.destroyedStage = par5; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.posX = par1DataInputStream.readInt(); + this.posY = par1DataInputStream.readInt(); + this.posZ = par1DataInputStream.readInt(); + this.destroyedStage = par1DataInputStream.read(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeInt(this.posX); + par1DataOutputStream.writeInt(this.posY); + par1DataOutputStream.writeInt(this.posZ); + par1DataOutputStream.write(this.destroyedStage); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleBlockDestroy(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 13; + } + + /** + * Gets the ID of the entity breaking the block + */ + public int getEntityId() { + return this.entityId; + } + + /** + * Gets the X position of the block + */ + public int getPosX() { + return this.posX; + } + + /** + * Gets the Y position of the block + */ + public int getPosY() { + return this.posY; + } + + /** + * Gets the Z position of the block + */ + public int getPosZ() { + return this.posZ; + } + + /** + * Gets how far destroyed this block is + */ + public int getDestroyedStage() { + return this.destroyedStage; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet55BlockDestroy var2 = (Packet55BlockDestroy) par1Packet; + return var2.entityId == this.entityId; + } +} diff --git a/src/main/java/net/minecraft/src/Packet56MapChunks.java b/src/main/java/net/minecraft/src/Packet56MapChunks.java new file mode 100644 index 0000000..7da3957 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet56MapChunks.java @@ -0,0 +1,131 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.List; + +import net.lax1dude.eaglercraft.EaglerInflater; + +public class Packet56MapChunks extends Packet { + private int[] chunkPostX; + private int[] chunkPosZ; + public int[] field_73590_a; + public int[] field_73588_b; + + /** The compressed chunk data buffer */ + private byte[] chunkDataBuffer; + private byte[][] field_73584_f; + + /** total size of the compressed data */ + private int dataLength; + + /** + * Whether or not the chunk data contains a light nibble array. This is true in + * the main world, false in the end + nether. + */ + private boolean skyLightSent; + private static byte[] chunkDataNotCompressed = new byte[0]; + + public Packet56MapChunks() { + } + + public Packet56MapChunks(List par1List) { + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + short var2 = par1DataInputStream.readShort(); + this.dataLength = par1DataInputStream.readInt(); + this.skyLightSent = par1DataInputStream.readBoolean(); + this.chunkPostX = new int[var2]; + this.chunkPosZ = new int[var2]; + this.field_73590_a = new int[var2]; + this.field_73588_b = new int[var2]; + this.field_73584_f = new byte[var2][]; + + if (chunkDataNotCompressed.length < this.dataLength) { + chunkDataNotCompressed = new byte[this.dataLength]; + } + + par1DataInputStream.readFully(chunkDataNotCompressed, 0, this.dataLength); + byte[] var3 = EaglerInflater.uncompress(chunkDataNotCompressed); + + int var5 = 0; + + for (int var6 = 0; var6 < var2; ++var6) { + this.chunkPostX[var6] = par1DataInputStream.readInt(); + this.chunkPosZ[var6] = par1DataInputStream.readInt(); + this.field_73590_a[var6] = par1DataInputStream.readShort(); + this.field_73588_b[var6] = par1DataInputStream.readShort(); + int var7 = 0; + int var8 = 0; + int var9; + + for (var9 = 0; var9 < 16; ++var9) { + var7 += this.field_73590_a[var6] >> var9 & 1; + var8 += this.field_73588_b[var6] >> var9 & 1; + } + + var9 = 2048 * 4 * var7 + 256; + var9 += 2048 * var8; + + if (this.skyLightSent) { + var9 += 2048 * var7; + } + + this.field_73584_f[var6] = new byte[var9]; + System.arraycopy(var3, var5, this.field_73584_f[var6], 0, var9); + var5 += var9; + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeShort(this.chunkPostX.length); + par1DataOutputStream.writeInt(this.dataLength); + par1DataOutputStream.writeBoolean(this.skyLightSent); + par1DataOutputStream.write(this.chunkDataBuffer, 0, this.dataLength); + + for (int var2 = 0; var2 < this.chunkPostX.length; ++var2) { + par1DataOutputStream.writeInt(this.chunkPostX[var2]); + par1DataOutputStream.writeInt(this.chunkPosZ[var2]); + par1DataOutputStream.writeShort((short) (this.field_73590_a[var2] & 65535)); + par1DataOutputStream.writeShort((short) (this.field_73588_b[var2] & 65535)); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleMapChunks(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 6 + this.dataLength + 12 * this.getNumberOfChunkInPacket(); + } + + public int getChunkPosX(int par1) { + return this.chunkPostX[par1]; + } + + public int getChunkPosZ(int par1) { + return this.chunkPosZ[par1]; + } + + public int getNumberOfChunkInPacket() { + return this.chunkPostX.length; + } + + public byte[] getChunkCompressedData(int par1) { + return this.field_73584_f[par1]; + } +} diff --git a/src/main/java/net/minecraft/src/Packet5PlayerInventory.java b/src/main/java/net/minecraft/src/Packet5PlayerInventory.java new file mode 100644 index 0000000..48fe6a8 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet5PlayerInventory.java @@ -0,0 +1,80 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet5PlayerInventory extends Packet { + /** Entity ID of the object. */ + public int entityID; + + /** Equipment slot: 0=held, 1-4=armor slot */ + public int slot; + + /** The item in the slot format (an ItemStack) */ + private ItemStack itemSlot; + + public Packet5PlayerInventory() { + } + + public Packet5PlayerInventory(int par1, int par2, ItemStack par3ItemStack) { + this.entityID = par1; + this.slot = par2; + this.itemSlot = par3ItemStack == null ? null : par3ItemStack.copy(); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityID = par1DataInputStream.readInt(); + this.slot = par1DataInputStream.readShort(); + this.itemSlot = readItemStack(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityID); + par1DataOutputStream.writeShort(this.slot); + writeItemStack(this.itemSlot, par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handlePlayerInventory(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8; + } + + /** + * Gets the item in the slot format (an ItemStack) + */ + public ItemStack getItemSlot() { + return this.itemSlot; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet5PlayerInventory var2 = (Packet5PlayerInventory) par1Packet; + return var2.entityID == this.entityID && var2.slot == this.slot; + } +} diff --git a/src/main/java/net/minecraft/src/Packet60Explosion.java b/src/main/java/net/minecraft/src/Packet60Explosion.java new file mode 100644 index 0000000..271dfc6 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet60Explosion.java @@ -0,0 +1,132 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class Packet60Explosion extends Packet { + public double explosionX; + public double explosionY; + public double explosionZ; + public float explosionSize; + public List chunkPositionRecords; + + /** X velocity of the player being pushed by the explosion */ + private float playerVelocityX; + + /** Y velocity of the player being pushed by the explosion */ + private float playerVelocityY; + + /** Z velocity of the player being pushed by the explosion */ + private float playerVelocityZ; + + public Packet60Explosion() { + } + + public Packet60Explosion(double par1, double par3, double par5, float par7, List par8List, Vec3 par9Vec3) { + this.explosionX = par1; + this.explosionY = par3; + this.explosionZ = par5; + this.explosionSize = par7; + this.chunkPositionRecords = new ArrayList(par8List); + + if (par9Vec3 != null) { + this.playerVelocityX = (float) par9Vec3.xCoord; + this.playerVelocityY = (float) par9Vec3.yCoord; + this.playerVelocityZ = (float) par9Vec3.zCoord; + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.explosionX = par1DataInputStream.readDouble(); + this.explosionY = par1DataInputStream.readDouble(); + this.explosionZ = par1DataInputStream.readDouble(); + this.explosionSize = par1DataInputStream.readFloat(); + int var2 = par1DataInputStream.readInt(); + this.chunkPositionRecords = new ArrayList(var2); + int var3 = (int) this.explosionX; + int var4 = (int) this.explosionY; + int var5 = (int) this.explosionZ; + + for (int var6 = 0; var6 < var2; ++var6) { + int var7 = par1DataInputStream.readByte() + var3; + int var8 = par1DataInputStream.readByte() + var4; + int var9 = par1DataInputStream.readByte() + var5; + this.chunkPositionRecords.add(new ChunkPosition(var7, var8, var9)); + } + + this.playerVelocityX = par1DataInputStream.readFloat(); + this.playerVelocityY = par1DataInputStream.readFloat(); + this.playerVelocityZ = par1DataInputStream.readFloat(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeDouble(this.explosionX); + par1DataOutputStream.writeDouble(this.explosionY); + par1DataOutputStream.writeDouble(this.explosionZ); + par1DataOutputStream.writeFloat(this.explosionSize); + par1DataOutputStream.writeInt(this.chunkPositionRecords.size()); + int var2 = (int) this.explosionX; + int var3 = (int) this.explosionY; + int var4 = (int) this.explosionZ; + Iterator var5 = this.chunkPositionRecords.iterator(); + + while (var5.hasNext()) { + ChunkPosition var6 = (ChunkPosition) var5.next(); + int var7 = var6.x - var2; + int var8 = var6.y - var3; + int var9 = var6.z - var4; + par1DataOutputStream.writeByte(var7); + par1DataOutputStream.writeByte(var8); + par1DataOutputStream.writeByte(var9); + } + + par1DataOutputStream.writeFloat(this.playerVelocityX); + par1DataOutputStream.writeFloat(this.playerVelocityY); + par1DataOutputStream.writeFloat(this.playerVelocityZ); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleExplosion(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 32 + this.chunkPositionRecords.size() * 3 + 3; + } + + /** + * Gets the X velocity of the player being pushed by the explosion. + */ + public float getPlayerVelocityX() { + return this.playerVelocityX; + } + + /** + * Gets the Y velocity of the player being pushed by the explosion. + */ + public float getPlayerVelocityY() { + return this.playerVelocityY; + } + + /** + * Gets the Z velocity of the player being pushed by the explosion. + */ + public float getPlayerVelocityZ() { + return this.playerVelocityZ; + } +} diff --git a/src/main/java/net/minecraft/src/Packet61DoorChange.java b/src/main/java/net/minecraft/src/Packet61DoorChange.java new file mode 100644 index 0000000..9b1a82a --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet61DoorChange.java @@ -0,0 +1,68 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet61DoorChange extends Packet { + public int sfxID; + public int auxData; + public int posX; + public int posY; + public int posZ; + private boolean disableRelativeVolume; + + public Packet61DoorChange() { + } + + public Packet61DoorChange(int par1, int par2, int par3, int par4, int par5, boolean par6) { + this.sfxID = par1; + this.posX = par2; + this.posY = par3; + this.posZ = par4; + this.auxData = par5; + this.disableRelativeVolume = par6; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.sfxID = par1DataInputStream.readInt(); + this.posX = par1DataInputStream.readInt(); + this.posY = par1DataInputStream.readByte() & 255; + this.posZ = par1DataInputStream.readInt(); + this.auxData = par1DataInputStream.readInt(); + this.disableRelativeVolume = par1DataInputStream.readBoolean(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.sfxID); + par1DataOutputStream.writeInt(this.posX); + par1DataOutputStream.writeByte(this.posY & 255); + par1DataOutputStream.writeInt(this.posZ); + par1DataOutputStream.writeInt(this.auxData); + par1DataOutputStream.writeBoolean(this.disableRelativeVolume); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleDoorChange(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 21; + } + + public boolean getRelativeVolumeDisabled() { + return this.disableRelativeVolume; + } +} diff --git a/src/main/java/net/minecraft/src/Packet62LevelSound.java b/src/main/java/net/minecraft/src/Packet62LevelSound.java new file mode 100644 index 0000000..b00847e --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet62LevelSound.java @@ -0,0 +1,110 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet62LevelSound extends Packet { + /** e.g. step.grass */ + private String soundName; + + /** Effect X multiplied by 8 */ + private int effectX; + + /** Effect Y multiplied by 8 */ + private int effectY = Integer.MAX_VALUE; + + /** Effect Z multiplied by 8 */ + private int effectZ; + + /** 1 is 100%. Can be more. */ + private float volume; + + /** 63 is 100%. Can be more. */ + private int pitch; + + public Packet62LevelSound() { + } + + public Packet62LevelSound(String par1Str, double par2, double par4, double par6, float par8, float par9) { + this.soundName = par1Str; + this.effectX = (int) (par2 * 8.0D); + this.effectY = (int) (par4 * 8.0D); + this.effectZ = (int) (par6 * 8.0D); + this.volume = par8; + this.pitch = (int) (par9 * 63.0F); + + if (this.pitch < 0) { + this.pitch = 0; + } + + if (this.pitch > 255) { + this.pitch = 255; + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.soundName = readString(par1DataInputStream, 32); + this.effectX = par1DataInputStream.readInt(); + this.effectY = par1DataInputStream.readInt(); + this.effectZ = par1DataInputStream.readInt(); + this.volume = par1DataInputStream.readFloat(); + this.pitch = par1DataInputStream.readUnsignedByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.soundName, par1DataOutputStream); + par1DataOutputStream.writeInt(this.effectX); + par1DataOutputStream.writeInt(this.effectY); + par1DataOutputStream.writeInt(this.effectZ); + par1DataOutputStream.writeFloat(this.volume); + par1DataOutputStream.writeByte(this.pitch); + } + + public String getSoundName() { + return this.soundName; + } + + public double getEffectX() { + return (double) ((float) this.effectX / 8.0F); + } + + public double getEffectY() { + return (double) ((float) this.effectY / 8.0F); + } + + public double getEffectZ() { + return (double) ((float) this.effectZ / 8.0F); + } + + public float getVolume() { + return this.volume; + } + + /** + * Gets the pitch divided by 63 (63 is 100%) + */ + public float getPitch() { + return (float) this.pitch / 63.0F; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleLevelSound(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 24; + } +} diff --git a/src/main/java/net/minecraft/src/Packet63WorldParticles.java b/src/main/java/net/minecraft/src/Packet63WorldParticles.java new file mode 100644 index 0000000..b0e2579 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet63WorldParticles.java @@ -0,0 +1,153 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet63WorldParticles extends Packet { + /** + * The name of the particle to create. A list can be found at + * https://gist.github.com/thinkofdeath/5110835 + */ + private String particleName; + + /** X position of the particle. */ + private float posX; + + /** Y position of the particle. */ + private float posY; + + /** Z position of the particle. */ + private float posZ; + + /** + * This is added to the X position after being multiplied by + * random.nextGaussian() + */ + private float offsetX; + + /** + * This is added to the Y position after being multiplied by + * random.nextGaussian() + */ + private float offsetY; + + /** + * This is added to the Z position after being multiplied by + * random.nextGaussian() + */ + private float offsetZ; + + /** The speed of each particle. */ + private float speed; + + /** The number of particles to create. */ + private int quantity; + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.particleName = readString(par1DataInputStream, 64); + this.posX = par1DataInputStream.readFloat(); + this.posY = par1DataInputStream.readFloat(); + this.posZ = par1DataInputStream.readFloat(); + this.offsetX = par1DataInputStream.readFloat(); + this.offsetY = par1DataInputStream.readFloat(); + this.offsetZ = par1DataInputStream.readFloat(); + this.speed = par1DataInputStream.readFloat(); + this.quantity = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.particleName, par1DataOutputStream); + par1DataOutputStream.writeFloat(this.posX); + par1DataOutputStream.writeFloat(this.posY); + par1DataOutputStream.writeFloat(this.posZ); + par1DataOutputStream.writeFloat(this.offsetX); + par1DataOutputStream.writeFloat(this.offsetY); + par1DataOutputStream.writeFloat(this.offsetZ); + par1DataOutputStream.writeFloat(this.speed); + par1DataOutputStream.writeInt(this.quantity); + } + + public String getParticleName() { + return this.particleName; + } + + /** + * Gets the X position of the particle. + */ + public double getPositionX() { + return (double) this.posX; + } + + /** + * Gets the Y position of the particle. + */ + public double getPositionY() { + return (double) this.posY; + } + + /** + * Gets the Z position of the particle. + */ + public double getPositionZ() { + return (double) this.posZ; + } + + /** + * This is added to the X position after being multiplied by + * random.nextGaussian() + */ + public float getOffsetX() { + return this.offsetX; + } + + /** + * This is added to the Y position after being multiplied by + * random.nextGaussian() + */ + public float getOffsetY() { + return this.offsetY; + } + + /** + * This is added to the Z position after being multiplied by + * random.nextGaussian() + */ + public float getOffsetZ() { + return this.offsetZ; + } + + /** + * Gets the speed of the particles. + */ + public float getSpeed() { + return this.speed; + } + + /** + * Gets the number of particles to create. + */ + public int getQuantity() { + return this.quantity; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleWorldParticles(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 64; + } +} diff --git a/src/main/java/net/minecraft/src/Packet6SpawnPosition.java b/src/main/java/net/minecraft/src/Packet6SpawnPosition.java new file mode 100644 index 0000000..5f0380b --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet6SpawnPosition.java @@ -0,0 +1,80 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet6SpawnPosition extends Packet { + /** X coordinate of spawn. */ + public int xPosition; + + /** Y coordinate of spawn. */ + public int yPosition; + + /** Z coordinate of spawn. */ + public int zPosition; + + public Packet6SpawnPosition() { + } + + public Packet6SpawnPosition(int par1, int par2, int par3) { + this.xPosition = par1; + this.yPosition = par2; + this.zPosition = par3; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readInt(); + this.zPosition = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeInt(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSpawnPosition(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 12; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } + + /** + * If this returns true, the packet may be processed on any thread; otherwise it + * is queued for the main thread to handle. + */ + public boolean canProcessAsync() { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/Packet70GameEvent.java b/src/main/java/net/minecraft/src/Packet70GameEvent.java new file mode 100644 index 0000000..9101404 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet70GameEvent.java @@ -0,0 +1,59 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet70GameEvent extends Packet { + /** + * The client prints clientMessage[eventType] to chat when this packet is + * received. + */ + public static final String[] clientMessage = new String[] { "tile.bed.notValid", null, null, "gameMode.changed" }; + + /** 0: Invalid bed, 1: Rain starts, 2: Rain stops, 3: Game mode changed. */ + public int eventType; + + /** + * When reason==3, the game mode to set. See EnumGameType for a list of values. + */ + public int gameMode; + + public Packet70GameEvent() { + } + + public Packet70GameEvent(int par1, int par2) { + this.eventType = par1; + this.gameMode = par2; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.eventType = par1DataInputStream.readByte(); + this.gameMode = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.eventType); + par1DataOutputStream.writeByte(this.gameMode); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleGameEvent(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2; + } +} diff --git a/src/main/java/net/minecraft/src/Packet71Weather.java b/src/main/java/net/minecraft/src/Packet71Weather.java new file mode 100644 index 0000000..6890ebd --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet71Weather.java @@ -0,0 +1,63 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet71Weather extends Packet { + public int entityID; + public int posX; + public int posY; + public int posZ; + public int isLightningBolt; + + public Packet71Weather() { + } + + public Packet71Weather(Entity par1Entity) { + this.entityID = par1Entity.entityId; + this.posX = MathHelper.floor_double(par1Entity.posX * 32.0D); + this.posY = MathHelper.floor_double(par1Entity.posY * 32.0D); + this.posZ = MathHelper.floor_double(par1Entity.posZ * 32.0D); + + if (par1Entity instanceof EntityLightningBolt) { + this.isLightningBolt = 1; + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityID = par1DataInputStream.readInt(); + this.isLightningBolt = par1DataInputStream.readByte(); + this.posX = par1DataInputStream.readInt(); + this.posY = par1DataInputStream.readInt(); + this.posZ = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityID); + par1DataOutputStream.writeByte(this.isLightningBolt); + par1DataOutputStream.writeInt(this.posX); + par1DataOutputStream.writeInt(this.posY); + par1DataOutputStream.writeInt(this.posZ); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleWeather(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 17; + } +} diff --git a/src/main/java/net/minecraft/src/Packet7UseEntity.java b/src/main/java/net/minecraft/src/Packet7UseEntity.java new file mode 100644 index 0000000..4e30f57 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet7UseEntity.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet7UseEntity extends Packet { + /** The entity of the player (ignored by the server) */ + public int playerEntityId; + + /** The entity the player is interacting with */ + public int targetEntity; + + /** + * Seems to be true when the player is pointing at an entity and left-clicking + * and false when right-clicking. + */ + public int isLeftClick; + + public Packet7UseEntity() { + } + + public Packet7UseEntity(int par1, int par2, int par3) { + this.playerEntityId = par1; + this.targetEntity = par2; + this.isLeftClick = par3; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.playerEntityId = par1DataInputStream.readInt(); + this.targetEntity = par1DataInputStream.readInt(); + this.isLeftClick = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.playerEntityId); + par1DataOutputStream.writeInt(this.targetEntity); + par1DataOutputStream.writeByte(this.isLeftClick); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleUseEntity(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 9; + } +} diff --git a/src/main/java/net/minecraft/src/Packet8UpdateHealth.java b/src/main/java/net/minecraft/src/Packet8UpdateHealth.java new file mode 100644 index 0000000..7a84208 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet8UpdateHealth.java @@ -0,0 +1,73 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet8UpdateHealth extends Packet { + /** Variable used for incoming health packets */ + public int healthMP; + public int food; + + /** + * Players logging on get a saturation of 5.0. Eating food increases the + * saturation as well as the food bar. + */ + public float foodSaturation; + + public Packet8UpdateHealth() { + } + + public Packet8UpdateHealth(int par1, int par2, float par3) { + this.healthMP = par1; + this.food = par2; + this.foodSaturation = par3; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.healthMP = par1DataInputStream.readShort(); + this.food = par1DataInputStream.readShort(); + this.foodSaturation = par1DataInputStream.readFloat(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeShort(this.healthMP); + par1DataOutputStream.writeShort(this.food); + par1DataOutputStream.writeFloat(this.foodSaturation); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleUpdateHealth(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/Packet9Respawn.java b/src/main/java/net/minecraft/src/Packet9Respawn.java new file mode 100644 index 0000000..ecfdb65 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet9Respawn.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet9Respawn extends Packet { + public int respawnDimension; + + /** + * The difficulty setting. 0 through 3 for peaceful, easy, normal, hard. The + * client always sends 1. + */ + public int difficulty; + + /** Defaults to 128 */ + public int worldHeight; + public EnumGameType gameType; + public WorldType terrainType; + + public Packet9Respawn() { + } + + public Packet9Respawn(int par1, byte par2, WorldType par3WorldType, int par4, EnumGameType par5EnumGameType) { + this.respawnDimension = par1; + this.difficulty = par2; + this.worldHeight = par4; + this.gameType = par5EnumGameType; + this.terrainType = par3WorldType; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleRespawn(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.respawnDimension = par1DataInputStream.readInt(); + this.difficulty = par1DataInputStream.readByte(); + this.gameType = EnumGameType.getByID(par1DataInputStream.readByte()); + this.worldHeight = par1DataInputStream.readShort(); + String var2 = readString(par1DataInputStream, 16); + this.terrainType = WorldType.parseWorldType(var2); + + if (this.terrainType == null) { + this.terrainType = WorldType.DEFAULT; + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.respawnDimension); + par1DataOutputStream.writeByte(this.difficulty); + par1DataOutputStream.writeByte(this.gameType.getID()); + par1DataOutputStream.writeShort(this.worldHeight); + writeString(this.terrainType.getWorldTypeName(), par1DataOutputStream); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8 + (this.terrainType == null ? 0 : this.terrainType.getWorldTypeName().length()); + } +} diff --git a/src/main/java/net/minecraft/src/PacketCount.java b/src/main/java/net/minecraft/src/PacketCount.java new file mode 100644 index 0000000..6c7ad8a --- /dev/null +++ b/src/main/java/net/minecraft/src/PacketCount.java @@ -0,0 +1,34 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.Map; + +public class PacketCount { + /** If false, countPacket does nothing */ + public static boolean allowCounting = true; + + /** A count of the total number of each packet sent grouped by IDs. */ + private static final Map packetCountForID = new HashMap(); + + /** A count of the total size of each packet sent grouped by IDs. */ + private static final Map sizeCountForID = new HashMap(); + + /** Used to make threads queue to add packets */ + private static final Object lock = new Object(); + + public static void countPacket(int par0, long par1) { + if (allowCounting) { + Object var3 = lock; + + synchronized (lock) { + if (packetCountForID.containsKey(Integer.valueOf(par0))) { + packetCountForID.put(Integer.valueOf(par0), Long.valueOf(((Long) packetCountForID.get(Integer.valueOf(par0))).longValue() + 1L)); + sizeCountForID.put(Integer.valueOf(par0), Long.valueOf(((Long) sizeCountForID.get(Integer.valueOf(par0))).longValue() + par1)); + } else { + packetCountForID.put(Integer.valueOf(par0), Long.valueOf(1L)); + sizeCountForID.put(Integer.valueOf(par0), Long.valueOf(par1)); + } + } + } + } +} diff --git a/src/main/java/net/minecraft/src/Particle.java b/src/main/java/net/minecraft/src/Particle.java new file mode 100644 index 0000000..2167605 --- /dev/null +++ b/src/main/java/net/minecraft/src/Particle.java @@ -0,0 +1,59 @@ +package net.minecraft.src; + +import java.util.Random; + +public class Particle { + private static Random rand = new Random(); + public double posX; + public double posY; + public double prevPosX; + public double prevPosY; + public double velocityX; + public double velocityY; + public double accelScale; + public boolean isDead; + public int timeTick; + public int timeLimit; + public double tintRed; + public double tintGreen; + public double tintBlue; + public double tintAlpha; + public double prevTintRed; + public double prevTintGreen; + public double prevTintBlue; + public double prevTintAlpha; + + public void update(GuiParticle par1GuiParticle) { + this.posX += this.velocityX; + this.posY += this.velocityY; + this.velocityX *= this.accelScale; + this.velocityY *= this.accelScale; + this.velocityY += 0.1D; + + if (++this.timeTick > this.timeLimit) { + this.setDead(); + } + + this.tintAlpha = 2.0D - (double) this.timeTick / (double) this.timeLimit * 2.0D; + + if (this.tintAlpha > 1.0D) { + this.tintAlpha = 1.0D; + } + + this.tintAlpha *= this.tintAlpha; + this.tintAlpha *= 0.5D; + } + + public void preUpdate() { + this.prevTintRed = this.tintRed; + this.prevTintGreen = this.tintGreen; + this.prevTintBlue = this.tintBlue; + this.prevTintAlpha = this.tintAlpha; + this.prevPosX = this.posX; + this.prevPosY = this.posY; + } + + public void setDead() { + this.isDead = true; + } +} diff --git a/src/main/java/net/minecraft/src/Path.java b/src/main/java/net/minecraft/src/Path.java new file mode 100644 index 0000000..fad8d41 --- /dev/null +++ b/src/main/java/net/minecraft/src/Path.java @@ -0,0 +1,147 @@ +package net.minecraft.src; + +public class Path { + /** Contains the points in this path */ + private PathPoint[] pathPoints = new PathPoint[1024]; + + /** The number of points in this path */ + private int count = 0; + + /** + * Adds a point to the path + */ + public PathPoint addPoint(PathPoint par1PathPoint) { + if (par1PathPoint.index >= 0) { + throw new IllegalStateException("OW KNOWS!"); + } else { + if (this.count == this.pathPoints.length) { + PathPoint[] var2 = new PathPoint[this.count << 1]; + System.arraycopy(this.pathPoints, 0, var2, 0, this.count); + this.pathPoints = var2; + } + + this.pathPoints[this.count] = par1PathPoint; + par1PathPoint.index = this.count; + this.sortBack(this.count++); + return par1PathPoint; + } + } + + /** + * Clears the path + */ + public void clearPath() { + this.count = 0; + } + + /** + * Returns and removes the first point in the path + */ + public PathPoint dequeue() { + PathPoint var1 = this.pathPoints[0]; + this.pathPoints[0] = this.pathPoints[--this.count]; + this.pathPoints[this.count] = null; + + if (this.count > 0) { + this.sortForward(0); + } + + var1.index = -1; + return var1; + } + + /** + * Changes the provided point's distance to target + */ + public void changeDistance(PathPoint par1PathPoint, float par2) { + float var3 = par1PathPoint.distanceToTarget; + par1PathPoint.distanceToTarget = par2; + + if (par2 < var3) { + this.sortBack(par1PathPoint.index); + } else { + this.sortForward(par1PathPoint.index); + } + } + + /** + * Sorts a point to the left + */ + private void sortBack(int par1) { + PathPoint var2 = this.pathPoints[par1]; + int var4; + + for (float var3 = var2.distanceToTarget; par1 > 0; par1 = var4) { + var4 = par1 - 1 >> 1; + PathPoint var5 = this.pathPoints[var4]; + + if (var3 >= var5.distanceToTarget) { + break; + } + + this.pathPoints[par1] = var5; + var5.index = par1; + } + + this.pathPoints[par1] = var2; + var2.index = par1; + } + + /** + * Sorts a point to the right + */ + private void sortForward(int par1) { + PathPoint var2 = this.pathPoints[par1]; + float var3 = var2.distanceToTarget; + + while (true) { + int var4 = 1 + (par1 << 1); + int var5 = var4 + 1; + + if (var4 >= this.count) { + break; + } + + PathPoint var6 = this.pathPoints[var4]; + float var7 = var6.distanceToTarget; + PathPoint var8; + float var9; + + if (var5 >= this.count) { + var8 = null; + var9 = Float.POSITIVE_INFINITY; + } else { + var8 = this.pathPoints[var5]; + var9 = var8.distanceToTarget; + } + + if (var7 < var9) { + if (var7 >= var3) { + break; + } + + this.pathPoints[par1] = var6; + var6.index = par1; + par1 = var4; + } else { + if (var9 >= var3) { + break; + } + + this.pathPoints[par1] = var8; + var8.index = par1; + par1 = var5; + } + } + + this.pathPoints[par1] = var2; + var2.index = par1; + } + + /** + * Returns true if this path contains no points + */ + public boolean isPathEmpty() { + return this.count == 0; + } +} diff --git a/src/main/java/net/minecraft/src/PathEntity.java b/src/main/java/net/minecraft/src/PathEntity.java new file mode 100644 index 0000000..65b2cb5 --- /dev/null +++ b/src/main/java/net/minecraft/src/PathEntity.java @@ -0,0 +1,107 @@ +package net.minecraft.src; + +public class PathEntity { + /** The actual points in the path */ + private final PathPoint[] points; + + /** PathEntity Array Index the Entity is currently targeting */ + private int currentPathIndex; + + /** The total length of the path */ + private int pathLength; + + public PathEntity(PathPoint[] par1ArrayOfPathPoint) { + this.points = par1ArrayOfPathPoint; + this.pathLength = par1ArrayOfPathPoint.length; + } + + /** + * Directs this path to the next point in its array + */ + public void incrementPathIndex() { + ++this.currentPathIndex; + } + + /** + * Returns true if this path has reached the end + */ + public boolean isFinished() { + return this.currentPathIndex >= this.pathLength; + } + + /** + * returns the last PathPoint of the Array + */ + public PathPoint getFinalPathPoint() { + return this.pathLength > 0 ? this.points[this.pathLength - 1] : null; + } + + /** + * return the PathPoint located at the specified PathIndex, usually the current + * one + */ + public PathPoint getPathPointFromIndex(int par1) { + return this.points[par1]; + } + + public int getCurrentPathLength() { + return this.pathLength; + } + + public void setCurrentPathLength(int par1) { + this.pathLength = par1; + } + + public int getCurrentPathIndex() { + return this.currentPathIndex; + } + + public void setCurrentPathIndex(int par1) { + this.currentPathIndex = par1; + } + + /** + * Gets the vector of the PathPoint associated with the given index. + */ + public Vec3 getVectorFromIndex(Entity par1Entity, int par2) { + double var3 = (double) this.points[par2].xCoord + (double) ((int) (par1Entity.width + 1.0F)) * 0.5D; + double var5 = (double) this.points[par2].yCoord; + double var7 = (double) this.points[par2].zCoord + (double) ((int) (par1Entity.width + 1.0F)) * 0.5D; + return par1Entity.worldObj.getWorldVec3Pool().getVecFromPool(var3, var5, var7); + } + + /** + * returns the current PathEntity target node as Vec3D + */ + public Vec3 getPosition(Entity par1Entity) { + return this.getVectorFromIndex(par1Entity, this.currentPathIndex); + } + + /** + * Returns true if the EntityPath are the same. Non instance related equals. + */ + public boolean isSamePath(PathEntity par1PathEntity) { + if (par1PathEntity == null) { + return false; + } else if (par1PathEntity.points.length != this.points.length) { + return false; + } else { + for (int var2 = 0; var2 < this.points.length; ++var2) { + if (this.points[var2].xCoord != par1PathEntity.points[var2].xCoord || this.points[var2].yCoord != par1PathEntity.points[var2].yCoord || this.points[var2].zCoord != par1PathEntity.points[var2].zCoord) { + return false; + } + } + + return true; + } + } + + /** + * Returns true if the final PathPoint in the PathEntity is equal to Vec3D + * coords. + */ + public boolean isDestinationSame(Vec3 par1Vec3) { + PathPoint var2 = this.getFinalPathPoint(); + return var2 == null ? false : var2.xCoord == (int) par1Vec3.xCoord && var2.zCoord == (int) par1Vec3.zCoord; + } +} diff --git a/src/main/java/net/minecraft/src/PathFinder.java b/src/main/java/net/minecraft/src/PathFinder.java new file mode 100644 index 0000000..e4b5480 --- /dev/null +++ b/src/main/java/net/minecraft/src/PathFinder.java @@ -0,0 +1,332 @@ +package net.minecraft.src; + +public class PathFinder { + /** Used to find obstacles */ + private IBlockAccess worldMap; + + /** The path being generated */ + private Path path = new Path(); + + /** The points in the path */ + private IntHashMap pointMap = new IntHashMap(); + + /** Selection of path points to add to the path */ + private PathPoint[] pathOptions = new PathPoint[32]; + + /** should the PathFinder go through wodden door blocks */ + private boolean isWoddenDoorAllowed; + + /** + * should the PathFinder disregard BlockMovement type materials in its path + */ + private boolean isMovementBlockAllowed; + private boolean isPathingInWater; + + /** tells the FathFinder to not stop pathing underwater */ + private boolean canEntityDrown; + + public PathFinder(IBlockAccess par1IBlockAccess, boolean par2, boolean par3, boolean par4, boolean par5) { + this.worldMap = par1IBlockAccess; + this.isWoddenDoorAllowed = par2; + this.isMovementBlockAllowed = par3; + this.isPathingInWater = par4; + this.canEntityDrown = par5; + } + + /** + * Creates a path from one entity to another within a minimum distance + */ + public PathEntity createEntityPathTo(Entity par1Entity, Entity par2Entity, float par3) { + return this.createEntityPathTo(par1Entity, par2Entity.posX, par2Entity.boundingBox.minY, par2Entity.posZ, par3); + } + + /** + * Creates a path from an entity to a specified location within a minimum + * distance + */ + public PathEntity createEntityPathTo(Entity par1Entity, int par2, int par3, int par4, float par5) { + return this.createEntityPathTo(par1Entity, (double) ((float) par2 + 0.5F), (double) ((float) par3 + 0.5F), (double) ((float) par4 + 0.5F), par5); + } + + /** + * Internal implementation of creating a path from an entity to a point + */ + private PathEntity createEntityPathTo(Entity par1Entity, double par2, double par4, double par6, float par8) { + this.path.clearPath(); + this.pointMap.clearMap(); + boolean var9 = this.isPathingInWater; + int var10 = MathHelper.floor_double(par1Entity.boundingBox.minY + 0.5D); + + if (this.canEntityDrown && par1Entity.isInWater()) { + var10 = (int) par1Entity.boundingBox.minY; + + for (int var11 = this.worldMap.getBlockId(MathHelper.floor_double(par1Entity.posX), var10, MathHelper.floor_double(par1Entity.posZ)); var11 == Block.waterMoving.blockID + || var11 == Block.waterStill.blockID; var11 = this.worldMap.getBlockId(MathHelper.floor_double(par1Entity.posX), var10, MathHelper.floor_double(par1Entity.posZ))) { + ++var10; + } + + var9 = this.isPathingInWater; + this.isPathingInWater = false; + } else { + var10 = MathHelper.floor_double(par1Entity.boundingBox.minY + 0.5D); + } + + PathPoint var15 = this.openPoint(MathHelper.floor_double(par1Entity.boundingBox.minX), var10, MathHelper.floor_double(par1Entity.boundingBox.minZ)); + PathPoint var12 = this.openPoint(MathHelper.floor_double(par2 - (double) (par1Entity.width / 2.0F)), MathHelper.floor_double(par4), MathHelper.floor_double(par6 - (double) (par1Entity.width / 2.0F))); + PathPoint var13 = new PathPoint(MathHelper.floor_float(par1Entity.width + 1.0F), MathHelper.floor_float(par1Entity.height + 1.0F), MathHelper.floor_float(par1Entity.width + 1.0F)); + PathEntity var14 = this.addToPath(par1Entity, var15, var12, var13, par8); + this.isPathingInWater = var9; + return var14; + } + + /** + * Adds a path from start to end and returns the whole path (args: unused, + * start, end, unused, maxDistance) + */ + private PathEntity addToPath(Entity par1Entity, PathPoint par2PathPoint, PathPoint par3PathPoint, PathPoint par4PathPoint, float par5) { + par2PathPoint.totalPathDistance = 0.0F; + par2PathPoint.distanceToNext = par2PathPoint.func_75832_b(par3PathPoint); + par2PathPoint.distanceToTarget = par2PathPoint.distanceToNext; + this.path.clearPath(); + this.path.addPoint(par2PathPoint); + PathPoint var6 = par2PathPoint; + + while (!this.path.isPathEmpty()) { + PathPoint var7 = this.path.dequeue(); + + if (var7.equals(par3PathPoint)) { + return this.createEntityPath(par2PathPoint, par3PathPoint); + } + + if (var7.func_75832_b(par3PathPoint) < var6.func_75832_b(par3PathPoint)) { + var6 = var7; + } + + var7.isFirst = true; + int var8 = this.findPathOptions(par1Entity, var7, par4PathPoint, par3PathPoint, par5); + + for (int var9 = 0; var9 < var8; ++var9) { + PathPoint var10 = this.pathOptions[var9]; + float var11 = var7.totalPathDistance + var7.func_75832_b(var10); + + if (!var10.isAssigned() || var11 < var10.totalPathDistance) { + var10.previous = var7; + var10.totalPathDistance = var11; + var10.distanceToNext = var10.func_75832_b(par3PathPoint); + + if (var10.isAssigned()) { + this.path.changeDistance(var10, var10.totalPathDistance + var10.distanceToNext); + } else { + var10.distanceToTarget = var10.totalPathDistance + var10.distanceToNext; + this.path.addPoint(var10); + } + } + } + } + + if (var6 == par2PathPoint) { + return null; + } else { + return this.createEntityPath(par2PathPoint, var6); + } + } + + /** + * populates pathOptions with available points and returns the number of options + * found (args: unused1, currentPoint, unused2, targetPoint, maxDistance) + */ + private int findPathOptions(Entity par1Entity, PathPoint par2PathPoint, PathPoint par3PathPoint, PathPoint par4PathPoint, float par5) { + int var6 = 0; + byte var7 = 0; + + if (this.getVerticalOffset(par1Entity, par2PathPoint.xCoord, par2PathPoint.yCoord + 1, par2PathPoint.zCoord, par3PathPoint) == 1) { + var7 = 1; + } + + PathPoint var8 = this.getSafePoint(par1Entity, par2PathPoint.xCoord, par2PathPoint.yCoord, par2PathPoint.zCoord + 1, par3PathPoint, var7); + PathPoint var9 = this.getSafePoint(par1Entity, par2PathPoint.xCoord - 1, par2PathPoint.yCoord, par2PathPoint.zCoord, par3PathPoint, var7); + PathPoint var10 = this.getSafePoint(par1Entity, par2PathPoint.xCoord + 1, par2PathPoint.yCoord, par2PathPoint.zCoord, par3PathPoint, var7); + PathPoint var11 = this.getSafePoint(par1Entity, par2PathPoint.xCoord, par2PathPoint.yCoord, par2PathPoint.zCoord - 1, par3PathPoint, var7); + + if (var8 != null && !var8.isFirst && var8.distanceTo(par4PathPoint) < par5) { + this.pathOptions[var6++] = var8; + } + + if (var9 != null && !var9.isFirst && var9.distanceTo(par4PathPoint) < par5) { + this.pathOptions[var6++] = var9; + } + + if (var10 != null && !var10.isFirst && var10.distanceTo(par4PathPoint) < par5) { + this.pathOptions[var6++] = var10; + } + + if (var11 != null && !var11.isFirst && var11.distanceTo(par4PathPoint) < par5) { + this.pathOptions[var6++] = var11; + } + + return var6; + } + + /** + * Returns a point that the entity can safely move to + */ + private PathPoint getSafePoint(Entity par1Entity, int par2, int par3, int par4, PathPoint par5PathPoint, int par6) { + PathPoint var7 = null; + int var8 = this.getVerticalOffset(par1Entity, par2, par3, par4, par5PathPoint); + + if (var8 == 2) { + return this.openPoint(par2, par3, par4); + } else { + if (var8 == 1) { + var7 = this.openPoint(par2, par3, par4); + } + + if (var7 == null && par6 > 0 && var8 != -3 && var8 != -4 && this.getVerticalOffset(par1Entity, par2, par3 + par6, par4, par5PathPoint) == 1) { + var7 = this.openPoint(par2, par3 + par6, par4); + par3 += par6; + } + + if (var7 != null) { + int var9 = 0; + int var10 = 0; + + while (par3 > 0) { + var10 = this.getVerticalOffset(par1Entity, par2, par3 - 1, par4, par5PathPoint); + + if (this.isPathingInWater && var10 == -1) { + return null; + } + + if (var10 != 1) { + break; + } + + if (var9++ >= par1Entity.func_82143_as()) { + return null; + } + + --par3; + + if (par3 > 0) { + var7 = this.openPoint(par2, par3, par4); + } + } + + if (var10 == -2) { + return null; + } + } + + return var7; + } + } + + /** + * Returns a mapped point or creates and adds one + */ + private final PathPoint openPoint(int par1, int par2, int par3) { + int var4 = PathPoint.makeHash(par1, par2, par3); + PathPoint var5 = (PathPoint) this.pointMap.lookup(var4); + + if (var5 == null) { + var5 = new PathPoint(par1, par2, par3); + this.pointMap.addKey(var4, var5); + } + + return var5; + } + + /** + * Checks if an entity collides with blocks at a position. Returns 1 if clear, 0 + * for colliding with any solid block, -1 for water(if avoiding water) but + * otherwise clear, -2 for lava, -3 for fence, -4 for closed trapdoor, 2 if + * otherwise clear except for open trapdoor or water(if not avoiding) + */ + public int getVerticalOffset(Entity par1Entity, int par2, int par3, int par4, PathPoint par5PathPoint) { + return func_82565_a(par1Entity, par2, par3, par4, par5PathPoint, this.isPathingInWater, this.isMovementBlockAllowed, this.isWoddenDoorAllowed); + } + + public static int func_82565_a(Entity par0Entity, int par1, int par2, int par3, PathPoint par4PathPoint, boolean par5, boolean par6, boolean par7) { + boolean var8 = false; + + for (int var9 = par1; var9 < par1 + par4PathPoint.xCoord; ++var9) { + for (int var10 = par2; var10 < par2 + par4PathPoint.yCoord; ++var10) { + for (int var11 = par3; var11 < par3 + par4PathPoint.zCoord; ++var11) { + int var12 = par0Entity.worldObj.getBlockId(var9, var10, var11); + + if (var12 > 0) { + if (var12 == Block.trapdoor.blockID) { + var8 = true; + } else if (var12 != Block.waterMoving.blockID && var12 != Block.waterStill.blockID) { + if (!par7 && var12 == Block.doorWood.blockID) { + return 0; + } + } else { + if (par5) { + return -1; + } + + var8 = true; + } + + Block var13 = Block.blocksList[var12]; + int var14 = var13.getRenderType(); + + if (par0Entity.worldObj.blockGetRenderType(var9, var10, var11) == 9) { + int var18 = MathHelper.floor_double(par0Entity.posX); + int var16 = MathHelper.floor_double(par0Entity.posY); + int var17 = MathHelper.floor_double(par0Entity.posZ); + + if (par0Entity.worldObj.blockGetRenderType(var18, var16, var17) != 9 && par0Entity.worldObj.blockGetRenderType(var18, var16 - 1, var17) != 9) { + return -3; + } + } else if (!var13.getBlocksMovement(par0Entity.worldObj, var9, var10, var11) && (!par6 || var12 != Block.doorWood.blockID)) { + if (var14 == 11 || var12 == Block.fenceGate.blockID || var14 == 32) { + return -3; + } + + if (var12 == Block.trapdoor.blockID) { + return -4; + } + + Material var15 = var13.blockMaterial; + + if (var15 != Material.lava) { + return 0; + } + + if (!par0Entity.handleLavaMovement()) { + return -2; + } + } + } + } + } + } + + return var8 ? 2 : 1; + } + + /** + * Returns a new PathEntity for a given start and end point + */ + private PathEntity createEntityPath(PathPoint par1PathPoint, PathPoint par2PathPoint) { + int var3 = 1; + PathPoint var4; + + for (var4 = par2PathPoint; var4.previous != null; var4 = var4.previous) { + ++var3; + } + + PathPoint[] var5 = new PathPoint[var3]; + var4 = par2PathPoint; + --var3; + + for (var5[var3] = par2PathPoint; var4.previous != null; var5[var3] = var4) { + var4 = var4.previous; + --var3; + } + + return new PathEntity(var5); + } +} diff --git a/src/main/java/net/minecraft/src/PathNavigate.java b/src/main/java/net/minecraft/src/PathNavigate.java new file mode 100644 index 0000000..189bc54 --- /dev/null +++ b/src/main/java/net/minecraft/src/PathNavigate.java @@ -0,0 +1,446 @@ +package net.minecraft.src; + + + +public class PathNavigate { + private EntityLiving theEntity; + private World worldObj; + + /** The PathEntity being followed. */ + private PathEntity currentPath; + private float speed; + + /** + * The number of blocks (extra) +/- in each axis that get pulled out as cache + * for the pathfinder's search space + */ + private float pathSearchRange; + private boolean noSunPathfind = false; + + /** Time, in number of ticks, following the current path */ + private int totalTicks; + + /** + * The time when the last position check was done (to detect successful + * movement) + */ + private int ticksAtLastPos; + + /** + * Coordinates of the entity's position last time a check was done (part of + * monitoring getting 'stuck') + */ + private Vec3 lastPosCheck = Vec3.createVectorHelper(0.0D, 0.0D, 0.0D); + + /** + * Specifically, if a wooden door block is even considered to be passable by the + * pathfinder + */ + private boolean canPassOpenWoodenDoors = true; + + /** If door blocks are considered passable even when closed */ + private boolean canPassClosedWoodenDoors = false; + + /** If water blocks are avoided (at least by the pathfinder) */ + private boolean avoidsWater = false; + + /** + * If the entity can swim. Swimming AI enables this and the pathfinder will also + * cause the entity to swim straight upwards when underwater + */ + private boolean canSwim = false; + + public PathNavigate(EntityLiving par1EntityLiving, World par2World, float par3) { + this.theEntity = par1EntityLiving; + this.worldObj = par2World; + this.pathSearchRange = par3; + } + + public void setAvoidsWater(boolean par1) { + this.avoidsWater = par1; + } + + public boolean getAvoidsWater() { + return this.avoidsWater; + } + + public void setBreakDoors(boolean par1) { + this.canPassClosedWoodenDoors = par1; + } + + /** + * Sets if the entity can enter open doors + */ + public void setEnterDoors(boolean par1) { + this.canPassOpenWoodenDoors = par1; + } + + /** + * Returns true if the entity can break doors, false otherwise + */ + public boolean getCanBreakDoors() { + return this.canPassClosedWoodenDoors; + } + + /** + * Sets if the path should avoid sunlight + */ + public void setAvoidSun(boolean par1) { + this.noSunPathfind = par1; + } + + /** + * Sets the speed + */ + public void setSpeed(float par1) { + this.speed = par1; + } + + /** + * Sets if the entity can swim + */ + public void setCanSwim(boolean par1) { + this.canSwim = par1; + } + + /** + * Returns the path to the given coordinates + */ + public PathEntity getPathToXYZ(double par1, double par3, double par5) { + return !this.canNavigate() ? null + : this.worldObj.getEntityPathToXYZ(this.theEntity, MathHelper.floor_double(par1), (int) par3, MathHelper.floor_double(par5), this.pathSearchRange, this.canPassOpenWoodenDoors, this.canPassClosedWoodenDoors, this.avoidsWater, + this.canSwim); + } + + /** + * Try to find and set a path to XYZ. Returns true if successful. + */ + public boolean tryMoveToXYZ(double par1, double par3, double par5, float par7) { + PathEntity var8 = this.getPathToXYZ((double) MathHelper.floor_double(par1), (double) ((int) par3), (double) MathHelper.floor_double(par5)); + return this.setPath(var8, par7); + } + + /** + * Returns the path to the given EntityLiving + */ + public PathEntity getPathToEntityLiving(EntityLiving par1EntityLiving) { + return !this.canNavigate() ? null : this.worldObj.getPathEntityToEntity(this.theEntity, par1EntityLiving, this.pathSearchRange, this.canPassOpenWoodenDoors, this.canPassClosedWoodenDoors, this.avoidsWater, this.canSwim); + } + + /** + * Try to find and set a path to EntityLiving. Returns true if successful. + */ + public boolean tryMoveToEntityLiving(EntityLiving par1EntityLiving, float par2) { + PathEntity var3 = this.getPathToEntityLiving(par1EntityLiving); + return var3 != null ? this.setPath(var3, par2) : false; + } + + /** + * sets the active path data if path is 100% unique compared to old path, checks + * to adjust path for sun avoiding ents and stores end coords + */ + public boolean setPath(PathEntity par1PathEntity, float par2) { + if (par1PathEntity == null) { + this.currentPath = null; + return false; + } else { + if (!par1PathEntity.isSamePath(this.currentPath)) { + this.currentPath = par1PathEntity; + } + + if (this.noSunPathfind) { + this.removeSunnyPath(); + } + + if (this.currentPath.getCurrentPathLength() == 0) { + return false; + } else { + this.speed = par2; + Vec3 var3 = this.getEntityPosition(); + this.ticksAtLastPos = this.totalTicks; + this.lastPosCheck.xCoord = var3.xCoord; + this.lastPosCheck.yCoord = var3.yCoord; + this.lastPosCheck.zCoord = var3.zCoord; + return true; + } + } + } + + /** + * gets the actively used PathEntity + */ + public PathEntity getPath() { + return this.currentPath; + } + + public void onUpdateNavigation() { + ++this.totalTicks; + + if (!this.noPath()) { + if (this.canNavigate()) { + this.pathFollow(); + } + + if (!this.noPath()) { + Vec3 var1 = this.currentPath.getPosition(this.theEntity); + + if (var1 != null) { + this.theEntity.getMoveHelper().setMoveTo(var1.xCoord, var1.yCoord, var1.zCoord, this.speed); + } + } + } + } + + private void pathFollow() { + Vec3 var1 = this.getEntityPosition(); + int var2 = this.currentPath.getCurrentPathLength(); + + for (int var3 = this.currentPath.getCurrentPathIndex(); var3 < this.currentPath.getCurrentPathLength(); ++var3) { + if (this.currentPath.getPathPointFromIndex(var3).yCoord != (int) var1.yCoord) { + var2 = var3; + break; + } + } + + float var8 = this.theEntity.width * this.theEntity.width; + int var4; + + for (var4 = this.currentPath.getCurrentPathIndex(); var4 < var2; ++var4) { + if (var1.squareDistanceTo(this.currentPath.getVectorFromIndex(this.theEntity, var4)) < (double) var8) { + this.currentPath.setCurrentPathIndex(var4 + 1); + } + } + + var4 = MathHelper.ceiling_float_int(this.theEntity.width); + int var5 = (int) this.theEntity.height + 1; + int var6 = var4; + + for (int var7 = var2 - 1; var7 >= this.currentPath.getCurrentPathIndex(); --var7) { + if (this.isDirectPathBetweenPoints(var1, this.currentPath.getVectorFromIndex(this.theEntity, var7), var4, var5, var6)) { + this.currentPath.setCurrentPathIndex(var7); + break; + } + } + + if (this.totalTicks - this.ticksAtLastPos > 100) { + if (var1.squareDistanceTo(this.lastPosCheck) < 2.25D) { + this.clearPathEntity(); + } + + this.ticksAtLastPos = this.totalTicks; + this.lastPosCheck.xCoord = var1.xCoord; + this.lastPosCheck.yCoord = var1.yCoord; + this.lastPosCheck.zCoord = var1.zCoord; + } + } + + /** + * If null path or reached the end + */ + public boolean noPath() { + return this.currentPath == null || this.currentPath.isFinished(); + } + + /** + * sets active PathEntity to null + */ + public void clearPathEntity() { + this.currentPath = null; + } + + private Vec3 getEntityPosition() { + return this.worldObj.getWorldVec3Pool().getVecFromPool(this.theEntity.posX, (double) this.getPathableYPos(), this.theEntity.posZ); + } + + /** + * Gets the safe pathing Y position for the entity depending on if it can path + * swim or not + */ + private int getPathableYPos() { + if (this.theEntity.isInWater() && this.canSwim) { + int var1 = (int) this.theEntity.boundingBox.minY; + int var2 = this.worldObj.getBlockId(MathHelper.floor_double(this.theEntity.posX), var1, MathHelper.floor_double(this.theEntity.posZ)); + int var3 = 0; + + do { + if (var2 != Block.waterMoving.blockID && var2 != Block.waterStill.blockID) { + return var1; + } + + ++var1; + var2 = this.worldObj.getBlockId(MathHelper.floor_double(this.theEntity.posX), var1, MathHelper.floor_double(this.theEntity.posZ)); + ++var3; + } while (var3 <= 16); + + return (int) this.theEntity.boundingBox.minY; + } else { + return (int) (this.theEntity.boundingBox.minY + 0.5D); + } + } + + /** + * If on ground or swimming and can swim + */ + private boolean canNavigate() { + return this.theEntity.onGround || this.canSwim && this.isInFluid(); + } + + /** + * Returns true if the entity is in water or lava, false otherwise + */ + private boolean isInFluid() { + return this.theEntity.isInWater() || this.theEntity.handleLavaMovement(); + } + + /** + * Trims path data from the end to the first sun covered block + */ + private void removeSunnyPath() { + if (!this.worldObj.canBlockSeeTheSky(MathHelper.floor_double(this.theEntity.posX), (int) (this.theEntity.boundingBox.minY + 0.5D), MathHelper.floor_double(this.theEntity.posZ))) { + for (int var1 = 0; var1 < this.currentPath.getCurrentPathLength(); ++var1) { + PathPoint var2 = this.currentPath.getPathPointFromIndex(var1); + + if (this.worldObj.canBlockSeeTheSky(var2.xCoord, var2.yCoord, var2.zCoord)) { + this.currentPath.setCurrentPathLength(var1 - 1); + return; + } + } + } + } + + /** + * Returns true when an entity of specified size could safely walk in a straight + * line between the two points. Args: pos1, pos2, entityXSize, entityYSize, + * entityZSize + */ + private boolean isDirectPathBetweenPoints(Vec3 par1Vec3, Vec3 par2Vec3, int par3, int par4, int par5) { + int var6 = MathHelper.floor_double(par1Vec3.xCoord); + int var7 = MathHelper.floor_double(par1Vec3.zCoord); + double var8 = par2Vec3.xCoord - par1Vec3.xCoord; + double var10 = par2Vec3.zCoord - par1Vec3.zCoord; + double var12 = var8 * var8 + var10 * var10; + + if (var12 < 1.0E-8D) { + return false; + } else { + double var14 = 1.0D / Math.sqrt(var12); + var8 *= var14; + var10 *= var14; + par3 += 2; + par5 += 2; + + if (!this.isSafeToStandAt(var6, (int) par1Vec3.yCoord, var7, par3, par4, par5, par1Vec3, var8, var10)) { + return false; + } else { + par3 -= 2; + par5 -= 2; + double var16 = 1.0D / Math.abs(var8); + double var18 = 1.0D / Math.abs(var10); + double var20 = (double) (var6 * 1) - par1Vec3.xCoord; + double var22 = (double) (var7 * 1) - par1Vec3.zCoord; + + if (var8 >= 0.0D) { + ++var20; + } + + if (var10 >= 0.0D) { + ++var22; + } + + var20 /= var8; + var22 /= var10; + int var24 = var8 < 0.0D ? -1 : 1; + int var25 = var10 < 0.0D ? -1 : 1; + int var26 = MathHelper.floor_double(par2Vec3.xCoord); + int var27 = MathHelper.floor_double(par2Vec3.zCoord); + int var28 = var26 - var6; + int var29 = var27 - var7; + + do { + if (var28 * var24 <= 0 && var29 * var25 <= 0) { + return true; + } + + if (var20 < var22) { + var20 += var16; + var6 += var24; + var28 = var26 - var6; + } else { + var22 += var18; + var7 += var25; + var29 = var27 - var7; + } + } while (this.isSafeToStandAt(var6, (int) par1Vec3.yCoord, var7, par3, par4, par5, par1Vec3, var8, var10)); + + return false; + } + } + } + + /** + * Returns true when an entity could stand at a position, including solid blocks + * under the entire entity. Args: xOffset, yOffset, zOffset, entityXSize, + * entityYSize, entityZSize, originPosition, vecX, vecZ + */ + private boolean isSafeToStandAt(int par1, int par2, int par3, int par4, int par5, int par6, Vec3 par7Vec3, double par8, double par10) { + int var12 = par1 - par4 / 2; + int var13 = par3 - par6 / 2; + + if (!this.isPositionClear(var12, par2, var13, par4, par5, par6, par7Vec3, par8, par10)) { + return false; + } else { + for (int var14 = var12; var14 < var12 + par4; ++var14) { + for (int var15 = var13; var15 < var13 + par6; ++var15) { + double var16 = (double) var14 + 0.5D - par7Vec3.xCoord; + double var18 = (double) var15 + 0.5D - par7Vec3.zCoord; + + if (var16 * par8 + var18 * par10 >= 0.0D) { + int var20 = this.worldObj.getBlockId(var14, par2 - 1, var15); + + if (var20 <= 0) { + return false; + } + + Material var21 = Block.blocksList[var20].blockMaterial; + + if (var21 == Material.water && !this.theEntity.isInWater()) { + return false; + } + + if (var21 == Material.lava) { + return false; + } + } + } + } + + return true; + } + } + + /** + * Returns true if an entity does not collide with any solid blocks at the + * position. Args: xOffset, yOffset, zOffset, entityXSize, entityYSize, + * entityZSize, originPosition, vecX, vecZ + */ + private boolean isPositionClear(int par1, int par2, int par3, int par4, int par5, int par6, Vec3 par7Vec3, double par8, double par10) { + for (int var12 = par1; var12 < par1 + par4; ++var12) { + for (int var13 = par2; var13 < par2 + par5; ++var13) { + for (int var14 = par3; var14 < par3 + par6; ++var14) { + double var15 = (double) var12 + 0.5D - par7Vec3.xCoord; + double var17 = (double) var14 + 0.5D - par7Vec3.zCoord; + + if (var15 * par8 + var17 * par10 >= 0.0D) { + int var19 = this.worldObj.getBlockId(var12, var13, var14); + + if (var19 > 0 && !Block.blocksList[var19].getBlocksMovement(this.worldObj, var12, var13, var14)) { + return false; + } + } + } + } + } + + return true; + } +} diff --git a/src/main/java/net/minecraft/src/PathPoint.java b/src/main/java/net/minecraft/src/PathPoint.java new file mode 100644 index 0000000..16be18d --- /dev/null +++ b/src/main/java/net/minecraft/src/PathPoint.java @@ -0,0 +1,85 @@ +package net.minecraft.src; + +public class PathPoint { + /** The x coordinate of this point */ + public final int xCoord; + + /** The y coordinate of this point */ + public final int yCoord; + + /** The z coordinate of this point */ + public final int zCoord; + + /** A hash of the coordinates used to identify this point */ + private final int hash; + + /** The index of this point in its assigned path */ + int index = -1; + + /** The distance along the path to this point */ + float totalPathDistance; + + /** The linear distance to the next point */ + float distanceToNext; + + /** The distance to the target */ + float distanceToTarget; + + /** The point preceding this in its assigned path */ + PathPoint previous; + + /** Indicates this is the origin */ + public boolean isFirst = false; + + public PathPoint(int par1, int par2, int par3) { + this.xCoord = par1; + this.yCoord = par2; + this.zCoord = par3; + this.hash = makeHash(par1, par2, par3); + } + + public static int makeHash(int par0, int par1, int par2) { + return par1 & 255 | (par0 & 32767) << 8 | (par2 & 32767) << 24 | (par0 < 0 ? Integer.MIN_VALUE : 0) | (par2 < 0 ? 32768 : 0); + } + + /** + * Returns the linear distance to another path point + */ + public float distanceTo(PathPoint par1PathPoint) { + float var2 = (float) (par1PathPoint.xCoord - this.xCoord); + float var3 = (float) (par1PathPoint.yCoord - this.yCoord); + float var4 = (float) (par1PathPoint.zCoord - this.zCoord); + return MathHelper.sqrt_float(var2 * var2 + var3 * var3 + var4 * var4); + } + + public float func_75832_b(PathPoint par1PathPoint) { + float var2 = (float) (par1PathPoint.xCoord - this.xCoord); + float var3 = (float) (par1PathPoint.yCoord - this.yCoord); + float var4 = (float) (par1PathPoint.zCoord - this.zCoord); + return var2 * var2 + var3 * var3 + var4 * var4; + } + + public boolean equals(Object par1Obj) { + if (!(par1Obj instanceof PathPoint)) { + return false; + } else { + PathPoint var2 = (PathPoint) par1Obj; + return this.hash == var2.hash && this.xCoord == var2.xCoord && this.yCoord == var2.yCoord && this.zCoord == var2.zCoord; + } + } + + public int hashCode() { + return this.hash; + } + + /** + * Returns true if this point has already been assigned to a path + */ + public boolean isAssigned() { + return this.index >= 0; + } + + public String toString() { + return this.xCoord + ", " + this.yCoord + ", " + this.zCoord; + } +} diff --git a/src/main/java/net/minecraft/src/PlayerCapabilities.java b/src/main/java/net/minecraft/src/PlayerCapabilities.java new file mode 100644 index 0000000..949168f --- /dev/null +++ b/src/main/java/net/minecraft/src/PlayerCapabilities.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +public class PlayerCapabilities { + /** Disables player damage. */ + public boolean disableDamage = false; + + /** Sets/indicates whether the player is flying. */ + public boolean isFlying = false; + + /** whether or not to allow the player to fly when they double jump. */ + public boolean allowFlying = false; + + /** + * Used to determine if creative mode is enabled, and therefore if items should + * be depleted on usage + */ + public boolean isCreativeMode = false; + + /** Indicates whether the player is allowed to modify the surroundings */ + public boolean allowEdit = true; + private float flySpeed = 0.05F; + private float walkSpeed = 0.1F; + + public void writeCapabilitiesToNBT(NBTTagCompound par1NBTTagCompound) { + NBTTagCompound var2 = new NBTTagCompound(); + var2.setBoolean("invulnerable", this.disableDamage); + var2.setBoolean("flying", this.isFlying); + var2.setBoolean("mayfly", this.allowFlying); + var2.setBoolean("instabuild", this.isCreativeMode); + var2.setBoolean("mayBuild", this.allowEdit); + var2.setFloat("flySpeed", this.flySpeed); + var2.setFloat("walkSpeed", this.walkSpeed); + par1NBTTagCompound.setTag("abilities", var2); + } + + public void readCapabilitiesFromNBT(NBTTagCompound par1NBTTagCompound) { + if (par1NBTTagCompound.hasKey("abilities")) { + NBTTagCompound var2 = par1NBTTagCompound.getCompoundTag("abilities"); + this.disableDamage = var2.getBoolean("invulnerable"); + this.isFlying = var2.getBoolean("flying"); + this.allowFlying = var2.getBoolean("mayfly"); + this.isCreativeMode = var2.getBoolean("instabuild"); + + if (var2.hasKey("flySpeed")) { + this.flySpeed = var2.getFloat("flySpeed"); + this.walkSpeed = var2.getFloat("walkSpeed"); + } + + if (var2.hasKey("mayBuild")) { + this.allowEdit = var2.getBoolean("mayBuild"); + } + } + } + + public float getFlySpeed() { + return this.flySpeed; + } + + public void setFlySpeed(float par1) { + this.flySpeed = par1; + } + + public float getWalkSpeed() { + return this.walkSpeed; + } + + public void setPlayerWalkSpeed(float par1) { + this.walkSpeed = par1; + } +} diff --git a/src/main/java/net/minecraft/src/PlayerControllerMP.java b/src/main/java/net/minecraft/src/PlayerControllerMP.java new file mode 100644 index 0000000..ebc30c3 --- /dev/null +++ b/src/main/java/net/minecraft/src/PlayerControllerMP.java @@ -0,0 +1,415 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerProfile; +import net.minecraft.client.Minecraft; + +public class PlayerControllerMP { + /** The Minecraft instance. */ + private final Minecraft mc; + private final NetClientHandler netClientHandler; + + /** PosX of the current block being destroyed */ + private int currentBlockX = -1; + + /** PosY of the current block being destroyed */ + private int currentBlockY = -1; + + /** PosZ of the current block being destroyed */ + private int currentblockZ = -1; + private ItemStack field_85183_f = null; + + /** Current block damage (MP) */ + private float curBlockDamageMP = 0.0F; + + /** + * Tick counter, when it hits 4 it resets back to 0 and plays the step sound + */ + private float stepSoundTickCounter = 0.0F; + + /** + * Delays the first damage on the block after the first click on the block + */ + private int blockHitDelay = 0; + + /** Tells if the player is hitting a block */ + private boolean isHittingBlock = false; + + /** Current game type for the player */ + private EnumGameType currentGameType; + + /** Index of the current item held by the player in the inventory hotbar */ + private int currentPlayerItem; + + public PlayerControllerMP(Minecraft par1Minecraft, NetClientHandler par2NetClientHandler) { + this.currentGameType = EnumGameType.SURVIVAL; + this.currentPlayerItem = 0; + this.mc = par1Minecraft; + this.netClientHandler = par2NetClientHandler; + } + + /** + * Block dig operation in creative mode (instantly digs the block). + */ + public static void clickBlockCreative(Minecraft par0Minecraft, PlayerControllerMP par1PlayerControllerMP, int par2, int par3, int par4, int par5) { + if (!par0Minecraft.theWorld.extinguishFire(par0Minecraft.thePlayer, par2, par3, par4, par5)) { + par1PlayerControllerMP.onPlayerDestroyBlock(par2, par3, par4, par5); + } + } + + /** + * Sets player capabilities depending on current gametype. params: player + */ + public void setPlayerCapabilities(EntityPlayer par1EntityPlayer) { + this.currentGameType.configurePlayerCapabilities(par1EntityPlayer.capabilities); + } + + /** + * If modified to return true, the player spins around slowly around (0, 68.5, + * 0). The GUI is disabled, the view is set to first person, and both chat and + * menu are disabled. Unless the server is modified to ignore illegal stances, + * attempting to enter a world at all will result in an immediate kick due to an + * illegal stance. Appears to be left-over debug, or demo code. + */ + public boolean enableEverythingIsScrewedUpMode() { + return false; + } + + /** + * Sets the game type for the player. + */ + public void setGameType(EnumGameType par1EnumGameType) { + this.currentGameType = par1EnumGameType; + this.currentGameType.configurePlayerCapabilities(this.mc.thePlayer.capabilities); + } + + /** + * Flips the player around. Args: player + */ + public void flipPlayer(EntityPlayer par1EntityPlayer) { + par1EntityPlayer.rotationYaw = -180.0F; + } + + public boolean shouldDrawHUD() { + return this.currentGameType.isSurvivalOrAdventure(); + } + + /** + * Called when a player completes the destruction of a block + */ + public boolean onPlayerDestroyBlock(int par1, int par2, int par3, int par4) { + if (this.currentGameType.isAdventure() && !this.mc.thePlayer.canCurrentToolHarvestBlock(par1, par2, par3)) { + return false; + } else { + WorldClient var5 = this.mc.theWorld; + Block var6 = Block.blocksList[var5.getBlockId(par1, par2, par3)]; + + if (var6 == null) { + return false; + } else { + var5.playAuxSFX(2001, par1, par2, par3, var6.blockID + (var5.getBlockMetadata(par1, par2, par3) << 12)); + int var7 = var5.getBlockMetadata(par1, par2, par3); + boolean var8 = var5.setBlockToAir(par1, par2, par3); + + if (var8) { + var6.onBlockDestroyedByPlayer(var5, par1, par2, par3, var7); + } + + this.currentBlockY = -1; + + if (!this.currentGameType.isCreative()) { + ItemStack var9 = this.mc.thePlayer.getCurrentEquippedItem(); + + if (var9 != null) { + var9.onBlockDestroyed(var5, var6.blockID, par1, par2, par3, this.mc.thePlayer); + + if (var9.stackSize == 0) { + this.mc.thePlayer.destroyCurrentEquippedItem(); + } + } + } + + return var8; + } + } + } + + /** + * Called by Minecraft class when the player is hitting a block with an item. + * Args: x, y, z, side + */ + public void clickBlock(int par1, int par2, int par3, int par4) { + if (!this.currentGameType.isAdventure() || this.mc.thePlayer.canCurrentToolHarvestBlock(par1, par2, par3)) { + if (this.currentGameType.isCreative()) { + this.netClientHandler.addToSendQueue(new Packet14BlockDig(0, par1, par2, par3, par4)); + clickBlockCreative(this.mc, this, par1, par2, par3, par4); + this.blockHitDelay = 5; + } else if (!this.isHittingBlock || !this.sameToolAndBlock(par1, par2, par3)) { + if (this.isHittingBlock) { + this.netClientHandler.addToSendQueue(new Packet14BlockDig(1, this.currentBlockX, this.currentBlockY, this.currentblockZ, par4)); + } + + this.netClientHandler.addToSendQueue(new Packet14BlockDig(0, par1, par2, par3, par4)); + int var5 = this.mc.theWorld.getBlockId(par1, par2, par3); + + if (var5 > 0 && this.curBlockDamageMP == 0.0F) { + Block.blocksList[var5].onBlockClicked(this.mc.theWorld, par1, par2, par3, this.mc.thePlayer); + } + + if (var5 > 0 && Block.blocksList[var5].getPlayerRelativeBlockHardness(this.mc.thePlayer, this.mc.thePlayer.worldObj, par1, par2, par3) >= 1.0F) { + this.onPlayerDestroyBlock(par1, par2, par3, par4); + } else { + this.isHittingBlock = true; + this.currentBlockX = par1; + this.currentBlockY = par2; + this.currentblockZ = par3; + this.field_85183_f = this.mc.thePlayer.getHeldItem(); + this.curBlockDamageMP = 0.0F; + this.stepSoundTickCounter = 0.0F; + this.mc.theWorld.destroyBlockInWorldPartially(this.mc.thePlayer.entityId, this.currentBlockX, this.currentBlockY, this.currentblockZ, (int) (this.curBlockDamageMP * 10.0F) - 1); + } + } + } + } + + /** + * Resets current block damage and isHittingBlock + */ + public void resetBlockRemoving() { + if (this.isHittingBlock) { + this.netClientHandler.addToSendQueue(new Packet14BlockDig(1, this.currentBlockX, this.currentBlockY, this.currentblockZ, -1)); + } + + this.isHittingBlock = false; + this.curBlockDamageMP = 0.0F; + this.mc.theWorld.destroyBlockInWorldPartially(this.mc.thePlayer.entityId, this.currentBlockX, this.currentBlockY, this.currentblockZ, -1); + } + + /** + * Called when a player damages a block and updates damage counters + */ + public void onPlayerDamageBlock(int par1, int par2, int par3, int par4) { + this.syncCurrentPlayItem(); + + if (this.blockHitDelay > 0) { + --this.blockHitDelay; + } else if (this.currentGameType.isCreative()) { + this.blockHitDelay = 5; + this.netClientHandler.addToSendQueue(new Packet14BlockDig(0, par1, par2, par3, par4)); + clickBlockCreative(this.mc, this, par1, par2, par3, par4); + } else { + if (this.sameToolAndBlock(par1, par2, par3)) { + int var5 = this.mc.theWorld.getBlockId(par1, par2, par3); + + if (var5 == 0) { + this.isHittingBlock = false; + return; + } + + Block var6 = Block.blocksList[var5]; + this.curBlockDamageMP += var6.getPlayerRelativeBlockHardness(this.mc.thePlayer, this.mc.thePlayer.worldObj, par1, par2, par3); + + if (this.stepSoundTickCounter % 4.0F == 0.0F && var6 != null) { + this.mc.sndManager.playSound(var6.stepSound.getStepSound(), (float) par1 + 0.5F, (float) par2 + 0.5F, (float) par3 + 0.5F, (var6.stepSound.getVolume() + 1.0F) / 8.0F, var6.stepSound.getPitch() * 0.5F); + } + + ++this.stepSoundTickCounter; + + if (this.curBlockDamageMP >= 1.0F) { + this.isHittingBlock = false; + this.netClientHandler.addToSendQueue(new Packet14BlockDig(2, par1, par2, par3, par4)); + this.onPlayerDestroyBlock(par1, par2, par3, par4); + this.curBlockDamageMP = 0.0F; + this.stepSoundTickCounter = 0.0F; + this.blockHitDelay = 5; + } + + this.mc.theWorld.destroyBlockInWorldPartially(this.mc.thePlayer.entityId, this.currentBlockX, this.currentBlockY, this.currentblockZ, (int) (this.curBlockDamageMP * 10.0F) - 1); + } else { + this.clickBlock(par1, par2, par3, par4); + } + } + } + + /** + * player reach distance = 4F + */ + public float getBlockReachDistance() { + return this.currentGameType.isCreative() ? 5.0F : 4.5F; + } + + public void updateController() { + this.syncCurrentPlayItem(); + this.mc.sndManager.playRandomMusicIfReady(); + } + + private boolean sameToolAndBlock(int par1, int par2, int par3) { + ItemStack var4 = this.mc.thePlayer.getHeldItem(); + boolean var5 = this.field_85183_f == null && var4 == null; + + if (this.field_85183_f != null && var4 != null) { + var5 = var4.itemID == this.field_85183_f.itemID && ItemStack.areItemStackTagsEqual(var4, this.field_85183_f) && (var4.isItemStackDamageable() || var4.getItemDamage() == this.field_85183_f.getItemDamage()); + } + + return par1 == this.currentBlockX && par2 == this.currentBlockY && par3 == this.currentblockZ && var5; + } + + /** + * Syncs the current player item with the server + */ + private void syncCurrentPlayItem() { + int var1 = this.mc.thePlayer.inventory.currentItem; + + if (var1 != this.currentPlayerItem) { + this.currentPlayerItem = var1; + this.netClientHandler.addToSendQueue(new Packet16BlockItemSwitch(this.currentPlayerItem)); + } + } + + /** + * Handles a players right click. Args: player, world, x, y, z, side, hitVec + */ + public boolean onPlayerRightClick(EntityPlayer par1EntityPlayer, World par2World, ItemStack par3ItemStack, int par4, int par5, int par6, int par7, Vec3 par8Vec3) { + this.syncCurrentPlayItem(); + float var9 = (float) par8Vec3.xCoord - (float) par4; + float var10 = (float) par8Vec3.yCoord - (float) par5; + float var11 = (float) par8Vec3.zCoord - (float) par6; + boolean var12 = false; + int var13; + + if (!par1EntityPlayer.isSneaking() || par1EntityPlayer.getHeldItem() == null) { + var13 = par2World.getBlockId(par4, par5, par6); + + if (var13 > 0 && Block.blocksList[var13].onBlockActivated(par2World, par4, par5, par6, par1EntityPlayer, par7, var9, var10, var11)) { + var12 = true; + } + } + + if (!var12 && par3ItemStack != null && par3ItemStack.getItem() instanceof ItemBlock) { + ItemBlock var16 = (ItemBlock) par3ItemStack.getItem(); + + if (!var16.canPlaceItemBlockOnSide(par2World, par4, par5, par6, par7, par1EntityPlayer, par3ItemStack)) { + return false; + } + } + + this.netClientHandler.addToSendQueue(new Packet15Place(par4, par5, par6, par7, par1EntityPlayer.inventory.getCurrentItem(), var9, var10, var11)); + + if (var12) { + return true; + } else if (par3ItemStack == null) { + return false; + } else if (this.currentGameType.isCreative()) { + var13 = par3ItemStack.getItemDamage(); + int var14 = par3ItemStack.stackSize; + boolean var15 = par3ItemStack.tryPlaceItemIntoWorld(par1EntityPlayer, par2World, par4, par5, par6, par7, var9, var10, var11); + par3ItemStack.setItemDamage(var13); + par3ItemStack.stackSize = var14; + return var15; + } else { + return par3ItemStack.tryPlaceItemIntoWorld(par1EntityPlayer, par2World, par4, par5, par6, par7, var9, var10, var11); + } + } + + /** + * Notifies the server of things like consuming food, etc... + */ + public boolean sendUseItem(EntityPlayer par1EntityPlayer, World par2World, ItemStack par3ItemStack) { + this.syncCurrentPlayItem(); + this.netClientHandler.addToSendQueue(new Packet15Place(-1, -1, -1, 255, par1EntityPlayer.inventory.getCurrentItem(), 0.0F, 0.0F, 0.0F)); + int var4 = par3ItemStack.stackSize; + ItemStack var5 = par3ItemStack.useItemRightClick(par2World, par1EntityPlayer); + + if (var5 == par3ItemStack && (var5 == null || var5.stackSize == var4)) { + return false; + } else { + par1EntityPlayer.inventory.mainInventory[par1EntityPlayer.inventory.currentItem] = var5; + + if (var5.stackSize == 0) { + par1EntityPlayer.inventory.mainInventory[par1EntityPlayer.inventory.currentItem] = null; + } + + return true; + } + } + + public EntityClientPlayerMP func_78754_a(World par1World) { + return new EntityClientPlayerMP(this.mc, par1World, EaglerProfile.username, this.netClientHandler); + } + + /** + * Attacks an entity + */ + public void attackEntity(EntityPlayer par1EntityPlayer, Entity par2Entity) { + this.syncCurrentPlayItem(); + this.netClientHandler.addToSendQueue(new Packet7UseEntity(par1EntityPlayer.entityId, par2Entity.entityId, 1)); + par1EntityPlayer.attackTargetEntityWithCurrentItem(par2Entity); + } + + public boolean func_78768_b(EntityPlayer par1EntityPlayer, Entity par2Entity) { + this.syncCurrentPlayItem(); + this.netClientHandler.addToSendQueue(new Packet7UseEntity(par1EntityPlayer.entityId, par2Entity.entityId, 0)); + return par1EntityPlayer.interactWith(par2Entity); + } + + public ItemStack windowClick(int par1, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + short var6 = par5EntityPlayer.openContainer.getNextTransactionID(par5EntityPlayer.inventory); + ItemStack var7 = par5EntityPlayer.openContainer.slotClick(par2, par3, par4, par5EntityPlayer); + this.netClientHandler.addToSendQueue(new Packet102WindowClick(par1, par2, par3, par4, var7, var6)); + return var7; + } + + /** + * GuiEnchantment uses this during multiplayer to tell PlayerControllerMP to + * send a packet indicating the enchantment action the player has taken. + */ + public void sendEnchantPacket(int par1, int par2) { + this.netClientHandler.addToSendQueue(new Packet108EnchantItem(par1, par2)); + } + + /** + * Used in PlayerControllerMP to update the server with an ItemStack in a slot. + */ + public void sendSlotPacket(ItemStack par1ItemStack, int par2) { + if (this.currentGameType.isCreative()) { + this.netClientHandler.addToSendQueue(new Packet107CreativeSetSlot(par2, par1ItemStack)); + } + } + + public void func_78752_a(ItemStack par1ItemStack) { + if (this.currentGameType.isCreative() && par1ItemStack != null) { + this.netClientHandler.addToSendQueue(new Packet107CreativeSetSlot(-1, par1ItemStack)); + } + } + + public void onStoppedUsingItem(EntityPlayer par1EntityPlayer) { + this.syncCurrentPlayItem(); + this.netClientHandler.addToSendQueue(new Packet14BlockDig(5, 0, 0, 0, 255)); + par1EntityPlayer.stopUsingItem(); + } + + public boolean func_78763_f() { + return true; + } + + /** + * Checks if the player is not creative, used for checking if it should break a + * block instantly + */ + public boolean isNotCreative() { + return !this.currentGameType.isCreative(); + } + + /** + * returns true if player is in creative mode + */ + public boolean isInCreativeMode() { + return this.currentGameType.isCreative(); + } + + /** + * true for hitting entities far away. + */ + public boolean extendedReach() { + return this.currentGameType.isCreative(); + } +} diff --git a/src/main/java/net/minecraft/src/PositionImpl.java b/src/main/java/net/minecraft/src/PositionImpl.java new file mode 100644 index 0000000..048e927 --- /dev/null +++ b/src/main/java/net/minecraft/src/PositionImpl.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +public class PositionImpl implements IPosition { + protected final double x; + protected final double y; + protected final double z; + + public PositionImpl(double par1, double par3, double par5) { + this.x = par1; + this.y = par3; + this.z = par5; + } + + public double getX() { + return this.x; + } + + public double getY() { + return this.y; + } + + public double getZ() { + return this.z; + } +} diff --git a/src/main/java/net/minecraft/src/PositionTextureVertex.java b/src/main/java/net/minecraft/src/PositionTextureVertex.java new file mode 100644 index 0000000..c57e139 --- /dev/null +++ b/src/main/java/net/minecraft/src/PositionTextureVertex.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class PositionTextureVertex { + public Vec3 vector3D; + public float texturePositionX; + public float texturePositionY; + + public PositionTextureVertex(float par1, float par2, float par3, float par4, float par5) { + this(Vec3.createVectorHelper((double) par1, (double) par2, (double) par3), par4, par5); + } + + public PositionTextureVertex setTexturePosition(float par1, float par2) { + return new PositionTextureVertex(this, par1, par2); + } + + public PositionTextureVertex(PositionTextureVertex par1PositionTextureVertex, float par2, float par3) { + this.vector3D = par1PositionTextureVertex.vector3D; + this.texturePositionX = par2; + this.texturePositionY = par3; + } + + public PositionTextureVertex(Vec3 par1Vec3, float par2, float par3) { + this.vector3D = par1Vec3; + this.texturePositionX = par2; + this.texturePositionY = par3; + } +} diff --git a/src/main/java/net/minecraft/src/Potion.java b/src/main/java/net/minecraft/src/Potion.java new file mode 100644 index 0000000..9456277 --- /dev/null +++ b/src/main/java/net/minecraft/src/Potion.java @@ -0,0 +1,245 @@ +package net.minecraft.src; + +public class Potion { + /** The array of potion types. */ + public static final Potion[] potionTypes = new Potion[32]; + public static final Potion field_76423_b = null; + public static final Potion moveSpeed = (new Potion(1, false, 8171462)).setPotionName("potion.moveSpeed").setIconIndex(0, 0); + public static final Potion moveSlowdown = (new Potion(2, true, 5926017)).setPotionName("potion.moveSlowdown").setIconIndex(1, 0); + public static final Potion digSpeed = (new Potion(3, false, 14270531)).setPotionName("potion.digSpeed").setIconIndex(2, 0).setEffectiveness(1.5D); + public static final Potion digSlowdown = (new Potion(4, true, 4866583)).setPotionName("potion.digSlowDown").setIconIndex(3, 0); + public static final Potion damageBoost = (new Potion(5, false, 9643043)).setPotionName("potion.damageBoost").setIconIndex(4, 0); + public static final Potion heal = (new PotionHealth(6, false, 16262179)).setPotionName("potion.heal"); + public static final Potion harm = (new PotionHealth(7, true, 4393481)).setPotionName("potion.harm"); + public static final Potion jump = (new Potion(8, false, 7889559)).setPotionName("potion.jump").setIconIndex(2, 1); + public static final Potion confusion = (new Potion(9, true, 5578058)).setPotionName("potion.confusion").setIconIndex(3, 1).setEffectiveness(0.25D); + + /** The regeneration Potion object. */ + public static final Potion regeneration = (new Potion(10, false, 13458603)).setPotionName("potion.regeneration").setIconIndex(7, 0).setEffectiveness(0.25D); + public static final Potion resistance = (new Potion(11, false, 10044730)).setPotionName("potion.resistance").setIconIndex(6, 1); + + /** The fire resistance Potion object. */ + public static final Potion fireResistance = (new Potion(12, false, 14981690)).setPotionName("potion.fireResistance").setIconIndex(7, 1); + + /** The water breathing Potion object. */ + public static final Potion waterBreathing = (new Potion(13, false, 3035801)).setPotionName("potion.waterBreathing").setIconIndex(0, 2); + + /** The invisibility Potion object. */ + public static final Potion invisibility = (new Potion(14, false, 8356754)).setPotionName("potion.invisibility").setIconIndex(0, 1); + + /** The blindness Potion object. */ + public static final Potion blindness = (new Potion(15, true, 2039587)).setPotionName("potion.blindness").setIconIndex(5, 1).setEffectiveness(0.25D); + + /** The night vision Potion object. */ + public static final Potion nightVision = (new Potion(16, false, 2039713)).setPotionName("potion.nightVision").setIconIndex(4, 1); + + /** The hunger Potion object. */ + public static final Potion hunger = (new Potion(17, true, 5797459)).setPotionName("potion.hunger").setIconIndex(1, 1); + + /** The weakness Potion object. */ + public static final Potion weakness = (new Potion(18, true, 4738376)).setPotionName("potion.weakness").setIconIndex(5, 0); + + /** The poison Potion object. */ + public static final Potion poison = (new Potion(19, true, 5149489)).setPotionName("potion.poison").setIconIndex(6, 0).setEffectiveness(0.25D); + + /** The wither Potion object. */ + public static final Potion wither = (new Potion(20, true, 3484199)).setPotionName("potion.wither").setIconIndex(1, 2).setEffectiveness(0.25D); + public static final Potion field_76434_w = null; + public static final Potion field_76444_x = null; + public static final Potion field_76443_y = null; + public static final Potion field_76442_z = null; + public static final Potion field_76409_A = null; + public static final Potion field_76410_B = null; + public static final Potion field_76411_C = null; + public static final Potion field_76405_D = null; + public static final Potion field_76406_E = null; + public static final Potion field_76407_F = null; + public static final Potion field_76408_G = null; + + /** The Id of a Potion object. */ + public final int id; + + /** The name of the Potion. */ + private String name = ""; + + /** The index for the icon displayed when the potion effect is active. */ + private int statusIconIndex = -1; + + /** + * This field indicated if the effect is 'bad' - negative - for the entity. + */ + private final boolean isBadEffect; + private double effectiveness; + private boolean usable; + + /** Is the color of the liquid for this potion. */ + private final int liquidColor; + + protected Potion(int par1, boolean par2, int par3) { + this.id = par1; + potionTypes[par1] = this; + this.isBadEffect = par2; + + if (par2) { + this.effectiveness = 0.5D; + } else { + this.effectiveness = 1.0D; + } + + this.liquidColor = par3; + } + + /** + * Sets the index for the icon displayed in the player's inventory when the + * status is active. + */ + protected Potion setIconIndex(int par1, int par2) { + this.statusIconIndex = par1 + par2 * 8; + return this; + } + + /** + * returns the ID of the potion + */ + public int getId() { + return this.id; + } + + public void performEffect(EntityLiving par1EntityLiving, int par2) { + if (this.id == regeneration.id) { + if (par1EntityLiving.getHealth() < par1EntityLiving.getMaxHealth()) { + par1EntityLiving.heal(1); + } + } else if (this.id == poison.id) { + if (par1EntityLiving.getHealth() > 1) { + par1EntityLiving.attackEntityFrom(DamageSource.magic, 1); + } + } else if (this.id == wither.id) { + par1EntityLiving.attackEntityFrom(DamageSource.wither, 1); + } else if (this.id == hunger.id && par1EntityLiving instanceof EntityPlayer) { + ((EntityPlayer) par1EntityLiving).addExhaustion(0.025F * (float) (par2 + 1)); + } else if ((this.id != heal.id || par1EntityLiving.isEntityUndead()) && (this.id != harm.id || !par1EntityLiving.isEntityUndead())) { + if (this.id == harm.id && !par1EntityLiving.isEntityUndead() || this.id == heal.id && par1EntityLiving.isEntityUndead()) { + par1EntityLiving.attackEntityFrom(DamageSource.magic, 6 << par2); + } + } else { + par1EntityLiving.heal(6 << par2); + } + } + + /** + * Hits the provided entity with this potion's instant effect. + */ + public void affectEntity(EntityLiving par1EntityLiving, EntityLiving par2EntityLiving, int par3, double par4) { + int var6; + + if ((this.id != heal.id || par2EntityLiving.isEntityUndead()) && (this.id != harm.id || !par2EntityLiving.isEntityUndead())) { + if (this.id == harm.id && !par2EntityLiving.isEntityUndead() || this.id == heal.id && par2EntityLiving.isEntityUndead()) { + var6 = (int) (par4 * (double) (6 << par3) + 0.5D); + + if (par1EntityLiving == null) { + par2EntityLiving.attackEntityFrom(DamageSource.magic, var6); + } else { + par2EntityLiving.attackEntityFrom(DamageSource.causeIndirectMagicDamage(par2EntityLiving, par1EntityLiving), var6); + } + } + } else { + var6 = (int) (par4 * (double) (6 << par3) + 0.5D); + par2EntityLiving.heal(var6); + } + } + + /** + * Returns true if the potion has an instant effect instead of a continuous one + * (eg Harming) + */ + public boolean isInstant() { + return false; + } + + /** + * checks if Potion effect is ready to be applied this tick. + */ + public boolean isReady(int par1, int par2) { + int var3; + + if (this.id != regeneration.id && this.id != poison.id) { + if (this.id == wither.id) { + var3 = 40 >> par2; + return var3 > 0 ? par1 % var3 == 0 : true; + } else { + return this.id == hunger.id; + } + } else { + var3 = 25 >> par2; + return var3 > 0 ? par1 % var3 == 0 : true; + } + } + + /** + * Set the potion name. + */ + public Potion setPotionName(String par1Str) { + this.name = par1Str; + return this; + } + + /** + * returns the name of the potion + */ + public String getName() { + return this.name; + } + + /** + * Returns true if the potion has a associated status icon to display in then + * inventory when active. + */ + public boolean hasStatusIcon() { + return this.statusIconIndex >= 0; + } + + /** + * Returns the index for the icon to display when the potion is active. + */ + public int getStatusIconIndex() { + return this.statusIconIndex; + } + + /** + * This method returns true if the potion effect is bad - negative - for the + * entity. + */ + public boolean isBadEffect() { + return this.isBadEffect; + } + + public static String getDurationString(PotionEffect par0PotionEffect) { + if (par0PotionEffect.getIsPotionDurationMax()) { + return "**:**"; + } else { + int var1 = par0PotionEffect.getDuration(); + return StringUtils.ticksToElapsedTime(var1); + } + } + + protected Potion setEffectiveness(double par1) { + this.effectiveness = par1; + return this; + } + + public double getEffectiveness() { + return this.effectiveness; + } + + public boolean isUsable() { + return this.usable; + } + + /** + * Returns the color of the potion liquid. + */ + public int getLiquidColor() { + return this.liquidColor; + } +} diff --git a/src/main/java/net/minecraft/src/PotionEffect.java b/src/main/java/net/minecraft/src/PotionEffect.java new file mode 100644 index 0000000..6293d56 --- /dev/null +++ b/src/main/java/net/minecraft/src/PotionEffect.java @@ -0,0 +1,183 @@ +package net.minecraft.src; + +public class PotionEffect { + /** ID value of the potion this effect matches. */ + private int potionID; + + /** The duration of the potion effect */ + private int duration; + + /** The amplifier of the potion effect */ + private int amplifier; + + /** Whether the potion is a splash potion */ + private boolean isSplashPotion; + + /** Whether the potion effect came from a beacon */ + private boolean isAmbient; + + /** True if potion effect duration is at maximum, false otherwise. */ + private boolean isPotionDurationMax; + + public PotionEffect(int par1, int par2) { + this(par1, par2, 0); + } + + public PotionEffect(int par1, int par2, int par3) { + this(par1, par2, par3, false); + } + + public PotionEffect(int par1, int par2, int par3, boolean par4) { + this.potionID = par1; + this.duration = par2; + this.amplifier = par3; + this.isAmbient = par4; + } + + public PotionEffect(PotionEffect par1PotionEffect) { + this.potionID = par1PotionEffect.potionID; + this.duration = par1PotionEffect.duration; + this.amplifier = par1PotionEffect.amplifier; + } + + /** + * merges the input PotionEffect into this one if this.amplifier <= + * tomerge.amplifier. The duration in the supplied potion effect is assumed to + * be greater. + */ + public void combine(PotionEffect par1PotionEffect) { + if (this.potionID != par1PotionEffect.potionID) { + System.err.println("This method should only be called for matching effects!"); + } + + if (par1PotionEffect.amplifier > this.amplifier) { + this.amplifier = par1PotionEffect.amplifier; + this.duration = par1PotionEffect.duration; + } else if (par1PotionEffect.amplifier == this.amplifier && this.duration < par1PotionEffect.duration) { + this.duration = par1PotionEffect.duration; + } else if (!par1PotionEffect.isAmbient && this.isAmbient) { + this.isAmbient = par1PotionEffect.isAmbient; + } + } + + /** + * Retrieve the ID of the potion this effect matches. + */ + public int getPotionID() { + return this.potionID; + } + + public int getDuration() { + return this.duration; + } + + public int getAmplifier() { + return this.amplifier; + } + + public boolean isSplashPotionEffect() { + return this.isSplashPotion; + } + + /** + * Set whether this potion is a splash potion. + */ + public void setSplashPotion(boolean par1) { + this.isSplashPotion = par1; + } + + /** + * Gets whether this potion effect originated from a beacon + */ + public boolean getIsAmbient() { + return this.isAmbient; + } + + public boolean onUpdate(EntityLiving par1EntityLiving) { + if (this.duration > 0) { + if (Potion.potionTypes[this.potionID].isReady(this.duration, this.amplifier)) { + this.performEffect(par1EntityLiving); + } + + this.deincrementDuration(); + } + + return this.duration > 0; + } + + private int deincrementDuration() { + return --this.duration; + } + + public void performEffect(EntityLiving par1EntityLiving) { + if (this.duration > 0) { + Potion.potionTypes[this.potionID].performEffect(par1EntityLiving, this.amplifier); + } + } + + public String getEffectName() { + return Potion.potionTypes[this.potionID].getName(); + } + + public int hashCode() { + return this.potionID; + } + + public String toString() { + String var1 = ""; + + if (this.getAmplifier() > 0) { + var1 = this.getEffectName() + " x " + (this.getAmplifier() + 1) + ", Duration: " + this.getDuration(); + } else { + var1 = this.getEffectName() + ", Duration: " + this.getDuration(); + } + + if (this.isSplashPotion) { + var1 = var1 + ", Splash: true"; + } + + return Potion.potionTypes[this.potionID].isUsable() ? "(" + var1 + ")" : var1; + } + + public boolean equals(Object par1Obj) { + if (!(par1Obj instanceof PotionEffect)) { + return false; + } else { + PotionEffect var2 = (PotionEffect) par1Obj; + return this.potionID == var2.potionID && this.amplifier == var2.amplifier && this.duration == var2.duration && this.isSplashPotion == var2.isSplashPotion && this.isAmbient == var2.isAmbient; + } + } + + /** + * Write a custom potion effect to a potion item's NBT data. + */ + public NBTTagCompound writeCustomPotionEffectToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setByte("Id", (byte) this.getPotionID()); + par1NBTTagCompound.setByte("Amplifier", (byte) this.getAmplifier()); + par1NBTTagCompound.setInteger("Duration", this.getDuration()); + par1NBTTagCompound.setBoolean("Ambient", this.getIsAmbient()); + return par1NBTTagCompound; + } + + /** + * Read a custom potion effect from a potion item's NBT data. + */ + public static PotionEffect readCustomPotionEffectFromNBT(NBTTagCompound par0NBTTagCompound) { + byte var1 = par0NBTTagCompound.getByte("Id"); + byte var2 = par0NBTTagCompound.getByte("Amplifier"); + int var3 = par0NBTTagCompound.getInteger("Duration"); + boolean var4 = par0NBTTagCompound.getBoolean("Ambient"); + return new PotionEffect(var1, var3, var2, var4); + } + + /** + * Toggle the isPotionDurationMax field. + */ + public void setPotionDurationMax(boolean par1) { + this.isPotionDurationMax = par1; + } + + public boolean getIsPotionDurationMax() { + return this.isPotionDurationMax; + } +} diff --git a/src/main/java/net/minecraft/src/PotionHealth.java b/src/main/java/net/minecraft/src/PotionHealth.java new file mode 100644 index 0000000..474dbe5 --- /dev/null +++ b/src/main/java/net/minecraft/src/PotionHealth.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +public class PotionHealth extends Potion { + public PotionHealth(int par1, boolean par2, int par3) { + super(par1, par2, par3); + } + + /** + * Returns true if the potion has an instant effect instead of a continuous one + * (eg Harming) + */ + public boolean isInstant() { + return true; + } + + /** + * checks if Potion effect is ready to be applied this tick. + */ + public boolean isReady(int par1, int par2) { + return par1 >= 1; + } +} diff --git a/src/main/java/net/minecraft/src/PotionHelper.java b/src/main/java/net/minecraft/src/PotionHelper.java new file mode 100644 index 0000000..4df2e60 --- /dev/null +++ b/src/main/java/net/minecraft/src/PotionHelper.java @@ -0,0 +1,493 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + + + +public class PotionHelper { + public static final String field_77924_a = null; + public static final String sugarEffect; + public static final String ghastTearEffect = "+0-1-2-3&4-4+13"; + public static final String spiderEyeEffect; + public static final String fermentedSpiderEyeEffect; + public static final String speckledMelonEffect; + public static final String blazePowderEffect; + public static final String magmaCreamEffect; + public static final String redstoneEffect; + public static final String glowstoneEffect; + public static final String gunpowderEffect; + public static final String goldenCarrotEffect; + private static final HashMap potionRequirements = new HashMap(); + + /** Potion effect amplifier map */ + private static final HashMap potionAmplifiers = new HashMap(); + private static final HashMap field_77925_n; + + /** An array of possible potion prefix names, as translation IDs. */ + private static final String[] potionPrefixes; + + /** + * Is the bit given set to 1? + */ + public static boolean checkFlag(int par0, int par1) { + return (par0 & 1 << par1) != 0; + } + + /** + * Returns 1 if the flag is set, 0 if it is not set. + */ + private static int isFlagSet(int par0, int par1) { + return checkFlag(par0, par1) ? 1 : 0; + } + + /** + * Returns 0 if the flag is set, 1 if it is not set. + */ + private static int isFlagUnset(int par0, int par1) { + return checkFlag(par0, par1) ? 0 : 1; + } + + public static int func_77909_a(int par0) { + return func_77908_a(par0, 5, 4, 3, 2, 1); + } + + /** + * Given a {@link Collection}<{@link PotionEffect}> will return an Integer + * color. + */ + public static int calcPotionLiquidColor(Collection par0Collection) { + int var1 = 3694022; + + if (par0Collection != null && !par0Collection.isEmpty()) { + float var2 = 0.0F; + float var3 = 0.0F; + float var4 = 0.0F; + float var5 = 0.0F; + Iterator var6 = par0Collection.iterator(); + + while (var6.hasNext()) { + PotionEffect var7 = (PotionEffect) var6.next(); + int var8 = Potion.potionTypes[var7.getPotionID()].getLiquidColor(); + + for (int var9 = 0; var9 <= var7.getAmplifier(); ++var9) { + var2 += (float) (var8 >> 16 & 255) / 255.0F; + var3 += (float) (var8 >> 8 & 255) / 255.0F; + var4 += (float) (var8 >> 0 & 255) / 255.0F; + ++var5; + } + } + + var2 = var2 / var5 * 255.0F; + var3 = var3 / var5 * 255.0F; + var4 = var4 / var5 * 255.0F; + return (int) var2 << 16 | (int) var3 << 8 | (int) var4; + } else { + return var1; + } + } + + public static boolean func_82817_b(Collection par0Collection) { + Iterator var1 = par0Collection.iterator(); + PotionEffect var2; + + do { + if (!var1.hasNext()) { + return true; + } + + var2 = (PotionEffect) var1.next(); + } while (var2.getIsAmbient()); + + return false; + } + + public static int func_77915_a(int par0, boolean par1) { + if (!par1) { + if (field_77925_n.containsKey(Integer.valueOf(par0))) { + return ((Integer) field_77925_n.get(Integer.valueOf(par0))).intValue(); + } else { + int var2 = calcPotionLiquidColor(getPotionEffects(par0, false)); + field_77925_n.put(Integer.valueOf(par0), Integer.valueOf(var2)); + return var2; + } + } else { + return calcPotionLiquidColor(getPotionEffects(par0, par1)); + } + } + + public static String func_77905_c(int par0) { + int var1 = func_77909_a(par0); + return potionPrefixes[var1]; + } + + private static int func_77904_a(boolean par0, boolean par1, boolean par2, int par3, int par4, int par5, int par6) { + int var7 = 0; + + if (par0) { + var7 = isFlagUnset(par6, par4); + } else if (par3 != -1) { + if (par3 == 0 && countSetFlags(par6) == par4) { + var7 = 1; + } else if (par3 == 1 && countSetFlags(par6) > par4) { + var7 = 1; + } else if (par3 == 2 && countSetFlags(par6) < par4) { + var7 = 1; + } + } else { + var7 = isFlagSet(par6, par4); + } + + if (par1) { + var7 *= par5; + } + + if (par2) { + var7 *= -1; + } + + return var7; + } + + /** + * Count the number of bits in an integer set to ON. + */ + private static int countSetFlags(int par0) { + int var1; + + for (var1 = 0; par0 > 0; ++var1) { + par0 &= par0 - 1; + } + + return var1; + } + + private static int parsePotionEffects(String par0Str, int par1, int par2, int par3) { + if (par1 < par0Str.length() && par2 >= 0 && par1 < par2) { + int var4 = par0Str.indexOf(124, par1); + int var5; + int var17; + + if (var4 >= 0 && var4 < par2) { + var5 = parsePotionEffects(par0Str, par1, var4 - 1, par3); + + if (var5 > 0) { + return var5; + } else { + var17 = parsePotionEffects(par0Str, var4 + 1, par2, par3); + return var17 > 0 ? var17 : 0; + } + } else { + var5 = par0Str.indexOf(38, par1); + + if (var5 >= 0 && var5 < par2) { + var17 = parsePotionEffects(par0Str, par1, var5 - 1, par3); + + if (var17 <= 0) { + return 0; + } else { + int var18 = parsePotionEffects(par0Str, var5 + 1, par2, par3); + return var18 <= 0 ? 0 : (var17 > var18 ? var17 : var18); + } + } else { + boolean var6 = false; + boolean var7 = false; + boolean var8 = false; + boolean var9 = false; + boolean var10 = false; + byte var11 = -1; + int var12 = 0; + int var13 = 0; + int var14 = 0; + + for (int var15 = par1; var15 < par2; ++var15) { + char var16 = par0Str.charAt(var15); + + if (var16 >= 48 && var16 <= 57) { + if (var6) { + var13 = var16 - 48; + var7 = true; + } else { + var12 *= 10; + var12 += var16 - 48; + var8 = true; + } + } else if (var16 == 42) { + var6 = true; + } else if (var16 == 33) { + if (var8) { + var14 += func_77904_a(var9, var7, var10, var11, var12, var13, par3); + var9 = false; + var10 = false; + var6 = false; + var7 = false; + var8 = false; + var13 = 0; + var12 = 0; + var11 = -1; + } + + var9 = true; + } else if (var16 == 45) { + if (var8) { + var14 += func_77904_a(var9, var7, var10, var11, var12, var13, par3); + var9 = false; + var10 = false; + var6 = false; + var7 = false; + var8 = false; + var13 = 0; + var12 = 0; + var11 = -1; + } + + var10 = true; + } else if (var16 != 61 && var16 != 60 && var16 != 62) { + if (var16 == 43 && var8) { + var14 += func_77904_a(var9, var7, var10, var11, var12, var13, par3); + var9 = false; + var10 = false; + var6 = false; + var7 = false; + var8 = false; + var13 = 0; + var12 = 0; + var11 = -1; + } + } else { + if (var8) { + var14 += func_77904_a(var9, var7, var10, var11, var12, var13, par3); + var9 = false; + var10 = false; + var6 = false; + var7 = false; + var8 = false; + var13 = 0; + var12 = 0; + var11 = -1; + } + + if (var16 == 61) { + var11 = 0; + } else if (var16 == 60) { + var11 = 2; + } else if (var16 == 62) { + var11 = 1; + } + } + } + + if (var8) { + var14 += func_77904_a(var9, var7, var10, var11, var12, var13, par3); + } + + return var14; + } + } + } else { + return 0; + } + } + + /** + * Returns a list of effects for the specified potion damage value. + */ + public static List getPotionEffects(int par0, boolean par1) { + ArrayList var2 = null; + Potion[] var3 = Potion.potionTypes; + int var4 = var3.length; + + for (int var5 = 0; var5 < var4; ++var5) { + Potion var6 = var3[var5]; + + if (var6 != null && (!var6.isUsable() || par1)) { + String var7 = (String) potionRequirements.get(Integer.valueOf(var6.getId())); + + if (var7 != null) { + int var8 = parsePotionEffects(var7, 0, var7.length(), par0); + + if (var8 > 0) { + int var9 = 0; + String var10 = (String) potionAmplifiers.get(Integer.valueOf(var6.getId())); + + if (var10 != null) { + var9 = parsePotionEffects(var10, 0, var10.length(), par0); + + if (var9 < 0) { + var9 = 0; + } + } + + if (var6.isInstant()) { + var8 = 1; + } else { + var8 = 1200 * (var8 * 3 + (var8 - 1) * 2); + var8 >>= var9; + var8 = (int) Math.round((double) var8 * var6.getEffectiveness()); + + if ((par0 & 16384) != 0) { + var8 = (int) Math.round((double) var8 * 0.75D + 0.5D); + } + } + + if (var2 == null) { + var2 = new ArrayList(); + } + + PotionEffect var11 = new PotionEffect(var6.getId(), var8, var9); + + if ((par0 & 16384) != 0) { + var11.setSplashPotion(true); + } + + var2.add(var11); + } + } + } + } + + return var2; + } + + /** + * Does bit operations for brewPotionData, given data, the index of the bit + * being operated upon, whether the bit will be removed, whether the bit will be + * toggled (NOT), or whether the data field will be set to 0 if the bit is not + * present. + */ + private static int brewBitOperations(int par0, int par1, boolean par2, boolean par3, boolean par4) { + if (par4) { + if (!checkFlag(par0, par1)) { + return 0; + } + } else if (par2) { + par0 &= ~(1 << par1); + } else if (par3) { + if ((par0 & 1 << par1) == 0) { + par0 |= 1 << par1; + } else { + par0 &= ~(1 << par1); + } + } else { + par0 |= 1 << par1; + } + + return par0; + } + + /** + * Generate a data value for a potion, given its previous data value and the + * encoded string of new effects it will receive + */ + public static int applyIngredient(int par0, String par1Str) { + byte var2 = 0; + int var3 = par1Str.length(); + boolean var4 = false; + boolean var5 = false; + boolean var6 = false; + boolean var7 = false; + int var8 = 0; + + for (int var9 = var2; var9 < var3; ++var9) { + char var10 = par1Str.charAt(var9); + + if (var10 >= 48 && var10 <= 57) { + var8 *= 10; + var8 += var10 - 48; + var4 = true; + } else if (var10 == 33) { + if (var4) { + par0 = brewBitOperations(par0, var8, var6, var5, var7); + var7 = false; + var5 = false; + var6 = false; + var4 = false; + var8 = 0; + } + + var5 = true; + } else if (var10 == 45) { + if (var4) { + par0 = brewBitOperations(par0, var8, var6, var5, var7); + var7 = false; + var5 = false; + var6 = false; + var4 = false; + var8 = 0; + } + + var6 = true; + } else if (var10 == 43) { + if (var4) { + par0 = brewBitOperations(par0, var8, var6, var5, var7); + var7 = false; + var5 = false; + var6 = false; + var4 = false; + var8 = 0; + } + } else if (var10 == 38) { + if (var4) { + par0 = brewBitOperations(par0, var8, var6, var5, var7); + var7 = false; + var5 = false; + var6 = false; + var4 = false; + var8 = 0; + } + + var7 = true; + } + } + + if (var4) { + par0 = brewBitOperations(par0, var8, var6, var5, var7); + } + + return par0 & 32767; + } + + public static int func_77908_a(int par0, int par1, int par2, int par3, int par4, int par5) { + return (checkFlag(par0, par1) ? 16 : 0) | (checkFlag(par0, par2) ? 8 : 0) | (checkFlag(par0, par3) ? 4 : 0) | (checkFlag(par0, par4) ? 2 : 0) | (checkFlag(par0, par5) ? 1 : 0); + } + + static { + potionRequirements.put(Integer.valueOf(Potion.regeneration.getId()), "0 & !1 & !2 & !3 & 0+6"); + sugarEffect = "-0+1-2-3&4-4+13"; + potionRequirements.put(Integer.valueOf(Potion.moveSpeed.getId()), "!0 & 1 & !2 & !3 & 1+6"); + magmaCreamEffect = "+0+1-2-3&4-4+13"; + potionRequirements.put(Integer.valueOf(Potion.fireResistance.getId()), "0 & 1 & !2 & !3 & 0+6"); + speckledMelonEffect = "+0-1+2-3&4-4+13"; + potionRequirements.put(Integer.valueOf(Potion.heal.getId()), "0 & !1 & 2 & !3"); + spiderEyeEffect = "-0-1+2-3&4-4+13"; + potionRequirements.put(Integer.valueOf(Potion.poison.getId()), "!0 & !1 & 2 & !3 & 2+6"); + fermentedSpiderEyeEffect = "-0+3-4+13"; + potionRequirements.put(Integer.valueOf(Potion.weakness.getId()), "!0 & !1 & !2 & 3 & 3+6"); + potionRequirements.put(Integer.valueOf(Potion.harm.getId()), "!0 & !1 & 2 & 3"); + potionRequirements.put(Integer.valueOf(Potion.moveSlowdown.getId()), "!0 & 1 & !2 & 3 & 3+6"); + blazePowderEffect = "+0-1-2+3&4-4+13"; + potionRequirements.put(Integer.valueOf(Potion.damageBoost.getId()), "0 & !1 & !2 & 3 & 3+6"); + goldenCarrotEffect = "-0+1+2-3+13&4-4"; + potionRequirements.put(Integer.valueOf(Potion.nightVision.getId()), "!0 & 1 & 2 & !3 & 2+6"); + potionRequirements.put(Integer.valueOf(Potion.invisibility.getId()), "!0 & 1 & 2 & 3 & 2+6"); + glowstoneEffect = "+5-6-7"; + potionAmplifiers.put(Integer.valueOf(Potion.moveSpeed.getId()), "5"); + potionAmplifiers.put(Integer.valueOf(Potion.digSpeed.getId()), "5"); + potionAmplifiers.put(Integer.valueOf(Potion.damageBoost.getId()), "5"); + potionAmplifiers.put(Integer.valueOf(Potion.regeneration.getId()), "5"); + potionAmplifiers.put(Integer.valueOf(Potion.harm.getId()), "5"); + potionAmplifiers.put(Integer.valueOf(Potion.heal.getId()), "5"); + potionAmplifiers.put(Integer.valueOf(Potion.resistance.getId()), "5"); + potionAmplifiers.put(Integer.valueOf(Potion.poison.getId()), "5"); + redstoneEffect = "-5+6-7"; + gunpowderEffect = "+14&13-13"; + field_77925_n = new HashMap(); + potionPrefixes = new String[] { "potion.prefix.mundane", "potion.prefix.uninteresting", "potion.prefix.bland", "potion.prefix.clear", "potion.prefix.milky", "potion.prefix.diffuse", "potion.prefix.artless", "potion.prefix.thin", + "potion.prefix.awkward", "potion.prefix.flat", "potion.prefix.bulky", "potion.prefix.bungling", "potion.prefix.buttered", "potion.prefix.smooth", "potion.prefix.suave", "potion.prefix.debonair", "potion.prefix.thick", + "potion.prefix.elegant", "potion.prefix.fancy", "potion.prefix.charming", "potion.prefix.dashing", "potion.prefix.refined", "potion.prefix.cordial", "potion.prefix.sparkling", "potion.prefix.potent", "potion.prefix.foul", + "potion.prefix.odorless", "potion.prefix.rank", "potion.prefix.harsh", "potion.prefix.acrid", "potion.prefix.gross", "potion.prefix.stinky" }; + } +} diff --git a/src/main/java/net/minecraft/src/Profiler.java b/src/main/java/net/minecraft/src/Profiler.java new file mode 100644 index 0000000..6643f23 --- /dev/null +++ b/src/main/java/net/minecraft/src/Profiler.java @@ -0,0 +1,153 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class Profiler { + /** List of parent sections */ + private final List sectionList = new ArrayList(); + + /** List of timestamps (System.nanoTime) */ + private final List timestampList = new ArrayList(); + + /** Flag profiling enabled */ + public boolean profilingEnabled = false; + + /** Current profiling section */ + private String profilingSection = ""; + + /** Profiling map */ + private final Map profilingMap = new HashMap(); + + /** + * Clear profiling. + */ + public void clearProfiling() { + this.profilingMap.clear(); + this.profilingSection = ""; + this.sectionList.clear(); + } + + /** + * Start section + */ + public void startSection(String par1Str) { + if (this.profilingEnabled) { + if (this.profilingSection.length() > 0) { + this.profilingSection = this.profilingSection + "."; + } + + this.profilingSection = this.profilingSection + par1Str; + this.sectionList.add(this.profilingSection); + this.timestampList.add(Long.valueOf(System.nanoTime())); + } + } + + /** + * End section + */ + public void endSection() { + if (this.profilingEnabled) { + long var1 = System.nanoTime(); + long var3 = ((Long) this.timestampList.remove(this.timestampList.size() - 1)).longValue(); + this.sectionList.remove(this.sectionList.size() - 1); + long var5 = var1 - var3; + + if (this.profilingMap.containsKey(this.profilingSection)) { + this.profilingMap.put(this.profilingSection, Long.valueOf(((Long) this.profilingMap.get(this.profilingSection)).longValue() + var5)); + } else { + this.profilingMap.put(this.profilingSection, Long.valueOf(var5)); + } + + if (var5 > 100000000L) { + System.out.println("Something\'s taking too long! \'" + this.profilingSection + "\' took aprox " + (double) var5 / 1000000.0D + " ms"); + } + + this.profilingSection = !this.sectionList.isEmpty() ? (String) this.sectionList.get(this.sectionList.size() - 1) : ""; + } + } + + /** + * Get profiling data + */ + public List getProfilingData(String par1Str) { + if (!this.profilingEnabled) { + return null; + } else { + long var3 = this.profilingMap.containsKey("root") ? ((Long) this.profilingMap.get("root")).longValue() : 0L; + long var5 = this.profilingMap.containsKey(par1Str) ? ((Long) this.profilingMap.get(par1Str)).longValue() : -1L; + ArrayList var7 = new ArrayList(); + + if (par1Str.length() > 0) { + par1Str = par1Str + "."; + } + + long var8 = 0L; + Iterator var10 = this.profilingMap.keySet().iterator(); + + while (var10.hasNext()) { + String var11 = (String) var10.next(); + + if (var11.length() > par1Str.length() && var11.startsWith(par1Str) && var11.indexOf(".", par1Str.length() + 1) < 0) { + var8 += ((Long) this.profilingMap.get(var11)).longValue(); + } + } + + float var20 = (float) var8; + + if (var8 < var5) { + var8 = var5; + } + + if (var3 < var8) { + var3 = var8; + } + + Iterator var21 = this.profilingMap.keySet().iterator(); + String var12; + + while (var21.hasNext()) { + var12 = (String) var21.next(); + + if (var12.length() > par1Str.length() && var12.startsWith(par1Str) && var12.indexOf(".", par1Str.length() + 1) < 0) { + long var13 = ((Long) this.profilingMap.get(var12)).longValue(); + double var15 = (double) var13 * 100.0D / (double) var8; + double var17 = (double) var13 * 100.0D / (double) var3; + String var19 = var12.substring(par1Str.length()); + var7.add(new ProfilerResult(var19, var15, var17)); + } + } + + var21 = this.profilingMap.keySet().iterator(); + + while (var21.hasNext()) { + var12 = (String) var21.next(); + this.profilingMap.put(var12, Long.valueOf(((Long) this.profilingMap.get(var12)).longValue() * 999L / 1000L)); + } + + if ((float) var8 > var20) { + var7.add(new ProfilerResult("unspecified", (double) ((float) var8 - var20) * 100.0D / (double) var8, (double) ((float) var8 - var20) * 100.0D / (double) var3)); + } + + Collections.sort(var7); + var7.add(0, new ProfilerResult(par1Str, 100.0D, (double) var8 * 100.0D / (double) var3)); + return var7; + } + } + + /** + * End current section and start a new section + */ + public void endStartSection(String par1Str) { + this.endSection(); + this.startSection(par1Str); + } + + public String getNameOfLastSection() { + return this.sectionList.size() == 0 ? "[UNKNOWN]" : (String) this.sectionList.get(this.sectionList.size() - 1); + } +} diff --git a/src/main/java/net/minecraft/src/ProfilerResult.java b/src/main/java/net/minecraft/src/ProfilerResult.java new file mode 100644 index 0000000..3dfd80e --- /dev/null +++ b/src/main/java/net/minecraft/src/ProfilerResult.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +public final class ProfilerResult implements Comparable { + public double field_76332_a; + public double field_76330_b; + public String field_76331_c; + + public ProfilerResult(String par1Str, double par2, double par4) { + this.field_76331_c = par1Str; + this.field_76332_a = par2; + this.field_76330_b = par4; + } + + public int func_76328_a(ProfilerResult par1ProfilerResult) { + return par1ProfilerResult.field_76332_a < this.field_76332_a ? -1 : (par1ProfilerResult.field_76332_a > this.field_76332_a ? 1 : par1ProfilerResult.field_76331_c.compareTo(this.field_76331_c)); + } + + public int func_76329_a() { + return (this.field_76331_c.hashCode() & 11184810) + 4473924; + } + + public int compareTo(Object par1Obj) { + return this.func_76328_a((ProfilerResult) par1Obj); + } +} diff --git a/src/main/java/net/minecraft/src/RandomPositionGenerator.java b/src/main/java/net/minecraft/src/RandomPositionGenerator.java new file mode 100644 index 0000000..db51fa3 --- /dev/null +++ b/src/main/java/net/minecraft/src/RandomPositionGenerator.java @@ -0,0 +1,95 @@ +package net.minecraft.src; + +import java.util.Random; + +public class RandomPositionGenerator { + /** + * used to store a driection when the user passes a point to move towards or + * away from. WARNING: NEVER THREAD SAFE. MULTIPLE findTowards and findAway + * calls, will share this var + */ + private static Vec3 staticVector = Vec3.createVectorHelper(0.0D, 0.0D, 0.0D); + + /** + * finds a random target within par1(x,z) and par2 (y) blocks + */ + public static Vec3 findRandomTarget(EntityCreature par0EntityCreature, int par1, int par2) { + return findRandomTargetBlock(par0EntityCreature, par1, par2, (Vec3) null); + } + + /** + * finds a random target within par1(x,z) and par2 (y) blocks in the direction + * of the point par3 + */ + public static Vec3 findRandomTargetBlockTowards(EntityCreature par0EntityCreature, int par1, int par2, Vec3 par3Vec3) { + staticVector.xCoord = par3Vec3.xCoord - par0EntityCreature.posX; + staticVector.yCoord = par3Vec3.yCoord - par0EntityCreature.posY; + staticVector.zCoord = par3Vec3.zCoord - par0EntityCreature.posZ; + return findRandomTargetBlock(par0EntityCreature, par1, par2, staticVector); + } + + /** + * finds a random target within par1(x,z) and par2 (y) blocks in the reverse + * direction of the point par3 + */ + public static Vec3 findRandomTargetBlockAwayFrom(EntityCreature par0EntityCreature, int par1, int par2, Vec3 par3Vec3) { + staticVector.xCoord = par0EntityCreature.posX - par3Vec3.xCoord; + staticVector.yCoord = par0EntityCreature.posY - par3Vec3.yCoord; + staticVector.zCoord = par0EntityCreature.posZ - par3Vec3.zCoord; + return findRandomTargetBlock(par0EntityCreature, par1, par2, staticVector); + } + + /** + * searches 10 blocks at random in a within par1(x,z) and par2 (y) distance, + * ignores those not in the direction of par3Vec3, then points to the tile for + * which creature.getBlockPathWeight returns the highest number + */ + private static Vec3 findRandomTargetBlock(EntityCreature par0EntityCreature, int par1, int par2, Vec3 par3Vec3) { + Random var4 = par0EntityCreature.getRNG(); + boolean var5 = false; + int var6 = 0; + int var7 = 0; + int var8 = 0; + float var9 = -99999.0F; + boolean var10; + + if (par0EntityCreature.hasHome()) { + double var11 = (double) (par0EntityCreature.getHomePosition().getDistanceSquared(MathHelper.floor_double(par0EntityCreature.posX), MathHelper.floor_double(par0EntityCreature.posY), + MathHelper.floor_double(par0EntityCreature.posZ)) + 4.0F); + double var13 = (double) (par0EntityCreature.getMaximumHomeDistance() + (float) par1); + var10 = var11 < var13 * var13; + } else { + var10 = false; + } + + for (int var16 = 0; var16 < 10; ++var16) { + int var12 = var4.nextInt(2 * par1) - par1; + int var17 = var4.nextInt(2 * par2) - par2; + int var14 = var4.nextInt(2 * par1) - par1; + + if (par3Vec3 == null || (double) var12 * par3Vec3.xCoord + (double) var14 * par3Vec3.zCoord >= 0.0D) { + var12 += MathHelper.floor_double(par0EntityCreature.posX); + var17 += MathHelper.floor_double(par0EntityCreature.posY); + var14 += MathHelper.floor_double(par0EntityCreature.posZ); + + if (!var10 || par0EntityCreature.isWithinHomeDistance(var12, var17, var14)) { + float var15 = par0EntityCreature.getBlockPathWeight(var12, var17, var14); + + if (var15 > var9) { + var9 = var15; + var6 = var12; + var7 = var17; + var8 = var14; + var5 = true; + } + } + } + } + + if (var5) { + return par0EntityCreature.worldObj.getWorldVec3Pool().getVecFromPool((double) var6, (double) var7, (double) var8); + } else { + return null; + } + } +} diff --git a/src/main/java/net/minecraft/src/RecipeFireworks.java b/src/main/java/net/minecraft/src/RecipeFireworks.java new file mode 100644 index 0000000..8693336 --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipeFireworks.java @@ -0,0 +1,180 @@ +package net.minecraft.src; + +import java.util.ArrayList; + +public class RecipeFireworks implements IRecipe { + private ItemStack field_92102_a; + + /** + * Used to check if a recipe matches current crafting inventory + */ + public boolean matches(InventoryCrafting par1InventoryCrafting, World par2World) { + this.field_92102_a = null; + int var3 = 0; + int var4 = 0; + int var5 = 0; + int var6 = 0; + int var7 = 0; + int var8 = 0; + + for (int var9 = 0; var9 < par1InventoryCrafting.getSizeInventory(); ++var9) { + ItemStack var10 = par1InventoryCrafting.getStackInSlot(var9); + + if (var10 != null) { + if (var10.itemID == Item.gunpowder.itemID) { + ++var4; + } else if (var10.itemID == Item.fireworkCharge.itemID) { + ++var6; + } else if (var10.itemID == Item.dyePowder.itemID) { + ++var5; + } else if (var10.itemID == Item.paper.itemID) { + ++var3; + } else if (var10.itemID == Item.lightStoneDust.itemID) { + ++var7; + } else if (var10.itemID == Item.diamond.itemID) { + ++var7; + } else if (var10.itemID == Item.fireballCharge.itemID) { + ++var8; + } else if (var10.itemID == Item.feather.itemID) { + ++var8; + } else if (var10.itemID == Item.goldNugget.itemID) { + ++var8; + } else { + if (var10.itemID != Item.skull.itemID) { + return false; + } + + ++var8; + } + } + } + + var7 += var5 + var8; + + if (var4 <= 3 && var3 <= 1) { + NBTTagCompound var16; + NBTTagCompound var19; + + if (var4 >= 1 && var3 == 1 && var7 == 0) { + this.field_92102_a = new ItemStack(Item.firework); + + if (var6 > 0) { + var16 = new NBTTagCompound(); + var19 = new NBTTagCompound("Fireworks"); + NBTTagList var25 = new NBTTagList("Explosions"); + + for (int var22 = 0; var22 < par1InventoryCrafting.getSizeInventory(); ++var22) { + ItemStack var26 = par1InventoryCrafting.getStackInSlot(var22); + + if (var26 != null && var26.itemID == Item.fireworkCharge.itemID && var26.hasTagCompound() && var26.getTagCompound().hasKey("Explosion")) { + var25.appendTag(var26.getTagCompound().getCompoundTag("Explosion")); + } + } + + var19.setTag("Explosions", var25); + var19.setByte("Flight", (byte) var4); + var16.setTag("Fireworks", var19); + this.field_92102_a.setTagCompound(var16); + } + + return true; + } else if (var4 == 1 && var3 == 0 && var6 == 0 && var5 > 0 && var8 <= 1) { + this.field_92102_a = new ItemStack(Item.fireworkCharge); + var16 = new NBTTagCompound(); + var19 = new NBTTagCompound("Explosion"); + byte var23 = 0; + ArrayList var12 = new ArrayList(); + + for (int var13 = 0; var13 < par1InventoryCrafting.getSizeInventory(); ++var13) { + ItemStack var14 = par1InventoryCrafting.getStackInSlot(var13); + + if (var14 != null) { + if (var14.itemID == Item.dyePowder.itemID) { + var12.add(Integer.valueOf(ItemDye.dyeColors[var14.getItemDamage()])); + } else if (var14.itemID == Item.lightStoneDust.itemID) { + var19.setBoolean("Flicker", true); + } else if (var14.itemID == Item.diamond.itemID) { + var19.setBoolean("Trail", true); + } else if (var14.itemID == Item.fireballCharge.itemID) { + var23 = 1; + } else if (var14.itemID == Item.feather.itemID) { + var23 = 4; + } else if (var14.itemID == Item.goldNugget.itemID) { + var23 = 2; + } else if (var14.itemID == Item.skull.itemID) { + var23 = 3; + } + } + } + + int[] var24 = new int[var12.size()]; + + for (int var27 = 0; var27 < var24.length; ++var27) { + var24[var27] = ((Integer) var12.get(var27)).intValue(); + } + + var19.setIntArray("Colors", var24); + var19.setByte("Type", var23); + var16.setTag("Explosion", var19); + this.field_92102_a.setTagCompound(var16); + return true; + } else if (var4 == 0 && var3 == 0 && var6 == 1 && var5 > 0 && var5 == var7) { + ArrayList var15 = new ArrayList(); + + for (int var17 = 0; var17 < par1InventoryCrafting.getSizeInventory(); ++var17) { + ItemStack var11 = par1InventoryCrafting.getStackInSlot(var17); + + if (var11 != null) { + if (var11.itemID == Item.dyePowder.itemID) { + var15.add(Integer.valueOf(ItemDye.dyeColors[var11.getItemDamage()])); + } else if (var11.itemID == Item.fireworkCharge.itemID) { + this.field_92102_a = var11.copy(); + this.field_92102_a.stackSize = 1; + } + } + } + + int[] var18 = new int[var15.size()]; + + for (int var20 = 0; var20 < var18.length; ++var20) { + var18[var20] = ((Integer) var15.get(var20)).intValue(); + } + + if (this.field_92102_a != null && this.field_92102_a.hasTagCompound()) { + NBTTagCompound var21 = this.field_92102_a.getTagCompound().getCompoundTag("Explosion"); + + if (var21 == null) { + return false; + } else { + var21.setIntArray("FadeColors", var18); + return true; + } + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + } + + /** + * Returns an Item that is the result of this recipe + */ + public ItemStack getCraftingResult(InventoryCrafting par1InventoryCrafting) { + return this.field_92102_a.copy(); + } + + /** + * Returns the size of the recipe area + */ + public int getRecipeSize() { + return 10; + } + + public ItemStack getRecipeOutput() { + return this.field_92102_a; + } +} diff --git a/src/main/java/net/minecraft/src/RecipeSorter.java b/src/main/java/net/minecraft/src/RecipeSorter.java new file mode 100644 index 0000000..229449f --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipeSorter.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +import java.util.Comparator; + +class RecipeSorter implements Comparator { + final CraftingManager craftingManager; + + RecipeSorter(CraftingManager par1CraftingManager) { + this.craftingManager = par1CraftingManager; + } + + public int compareRecipes(IRecipe par1IRecipe, IRecipe par2IRecipe) { + return par1IRecipe instanceof ShapelessRecipes && par2IRecipe instanceof ShapedRecipes ? 1 + : (par2IRecipe instanceof ShapelessRecipes && par1IRecipe instanceof ShapedRecipes ? -1 + : (par2IRecipe.getRecipeSize() < par1IRecipe.getRecipeSize() ? -1 : (par2IRecipe.getRecipeSize() > par1IRecipe.getRecipeSize() ? 1 : 0))); + } + + public int compare(Object par1Obj, Object par2Obj) { + return this.compareRecipes((IRecipe) par1Obj, (IRecipe) par2Obj); + } +} diff --git a/src/main/java/net/minecraft/src/RecipesArmor.java b/src/main/java/net/minecraft/src/RecipesArmor.java new file mode 100644 index 0000000..4e42ef3 --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesArmor.java @@ -0,0 +1,26 @@ +package net.minecraft.src; + +public class RecipesArmor { + private String[][] recipePatterns = new String[][] { { "XXX", "X X" }, { "X X", "XXX", "XXX" }, { "XXX", "X X", "X X" }, { "X X", "X X" } }; + private Object[][] recipeItems; + + public RecipesArmor() { + this.recipeItems = new Object[][] { { Item.leather, Block.fire, Item.ingotIron, Item.diamond, Item.ingotGold }, { Item.helmetLeather, Item.helmetChain, Item.helmetIron, Item.helmetDiamond, Item.helmetGold }, + { Item.plateLeather, Item.plateChain, Item.plateIron, Item.plateDiamond, Item.plateGold }, { Item.legsLeather, Item.legsChain, Item.legsIron, Item.legsDiamond, Item.legsGold }, + { Item.bootsLeather, Item.bootsChain, Item.bootsIron, Item.bootsDiamond, Item.bootsGold } }; + } + + /** + * Adds the armor recipes to the CraftingManager. + */ + public void addRecipes(CraftingManager par1CraftingManager) { + for (int var2 = 0; var2 < this.recipeItems[0].length; ++var2) { + Object var3 = this.recipeItems[0][var2]; + + for (int var4 = 0; var4 < this.recipeItems.length - 1; ++var4) { + Item var5 = (Item) this.recipeItems[var4 + 1][var2]; + par1CraftingManager.addRecipe(new ItemStack(var5), new Object[] { this.recipePatterns[var4], 'X', var3 }); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/RecipesArmorDyes.java b/src/main/java/net/minecraft/src/RecipesArmorDyes.java new file mode 100644 index 0000000..18d155c --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesArmorDyes.java @@ -0,0 +1,126 @@ +package net.minecraft.src; + +import java.util.ArrayList; + + + +public class RecipesArmorDyes implements IRecipe { + /** + * Used to check if a recipe matches current crafting inventory + */ + public boolean matches(InventoryCrafting par1InventoryCrafting, World par2World) { + ItemStack var3 = null; + ArrayList var4 = new ArrayList(); + + for (int var5 = 0; var5 < par1InventoryCrafting.getSizeInventory(); ++var5) { + ItemStack var6 = par1InventoryCrafting.getStackInSlot(var5); + + if (var6 != null) { + if (var6.getItem() instanceof ItemArmor) { + ItemArmor var7 = (ItemArmor) var6.getItem(); + + if (var7.getArmorMaterial() != EnumArmorMaterial.CLOTH || var3 != null) { + return false; + } + + var3 = var6; + } else { + if (var6.itemID != Item.dyePowder.itemID) { + return false; + } + + var4.add(var6); + } + } + } + + return var3 != null && !var4.isEmpty(); + } + + /** + * Returns an Item that is the result of this recipe + */ + public ItemStack getCraftingResult(InventoryCrafting par1InventoryCrafting) { + ItemStack var2 = null; + int[] var3 = new int[3]; + int var4 = 0; + int var5 = 0; + ItemArmor var6 = null; + int var7; + int var9; + float var10; + float var11; + int var17; + + for (var7 = 0; var7 < par1InventoryCrafting.getSizeInventory(); ++var7) { + ItemStack var8 = par1InventoryCrafting.getStackInSlot(var7); + + if (var8 != null) { + if (var8.getItem() instanceof ItemArmor) { + var6 = (ItemArmor) var8.getItem(); + + if (var6.getArmorMaterial() != EnumArmorMaterial.CLOTH || var2 != null) { + return null; + } + + var2 = var8.copy(); + var2.stackSize = 1; + + if (var6.hasColor(var8)) { + var9 = var6.getColor(var2); + var10 = (float) (var9 >> 16 & 255) / 255.0F; + var11 = (float) (var9 >> 8 & 255) / 255.0F; + float var12 = (float) (var9 & 255) / 255.0F; + var4 = (int) ((float) var4 + Math.max(var10, Math.max(var11, var12)) * 255.0F); + var3[0] = (int) ((float) var3[0] + var10 * 255.0F); + var3[1] = (int) ((float) var3[1] + var11 * 255.0F); + var3[2] = (int) ((float) var3[2] + var12 * 255.0F); + ++var5; + } + } else { + if (var8.itemID != Item.dyePowder.itemID) { + return null; + } + + float[] var14 = EntitySheep.fleeceColorTable[BlockCloth.getBlockFromDye(var8.getItemDamage())]; + int var15 = (int) (var14[0] * 255.0F); + int var16 = (int) (var14[1] * 255.0F); + var17 = (int) (var14[2] * 255.0F); + var4 += Math.max(var15, Math.max(var16, var17)); + var3[0] += var15; + var3[1] += var16; + var3[2] += var17; + ++var5; + } + } + } + + if (var6 == null) { + return null; + } else { + var7 = var3[0] / var5; + int var13 = var3[1] / var5; + var9 = var3[2] / var5; + var10 = (float) var4 / (float) var5; + var11 = (float) Math.max(var7, Math.max(var13, var9)); + var7 = (int) ((float) var7 * var10 / var11); + var13 = (int) ((float) var13 * var10 / var11); + var9 = (int) ((float) var9 * var10 / var11); + var17 = (var7 << 8) + var13; + var17 = (var17 << 8) + var9; + var6.func_82813_b(var2, var17); + return var2; + } + } + + /** + * Returns the size of the recipe area + */ + public int getRecipeSize() { + return 10; + } + + public ItemStack getRecipeOutput() { + return null; + } +} diff --git a/src/main/java/net/minecraft/src/RecipesCrafting.java b/src/main/java/net/minecraft/src/RecipesCrafting.java new file mode 100644 index 0000000..e8f1a55 --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesCrafting.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +public class RecipesCrafting { + /** + * Adds the crafting recipes to the CraftingManager. + */ + public void addRecipes(CraftingManager par1CraftingManager) { + par1CraftingManager.addRecipe(new ItemStack(Block.chest), new Object[] { "###", "# #", "###", '#', Block.planks }); + par1CraftingManager.addRecipe(new ItemStack(Block.chestTrapped), new Object[] { "#-", '#', Block.chest, '-', Block.tripWireSource }); + par1CraftingManager.addRecipe(new ItemStack(Block.enderChest), new Object[] { "###", "#E#", "###", '#', Block.obsidian, 'E', Item.eyeOfEnder }); + par1CraftingManager.addRecipe(new ItemStack(Block.furnaceIdle), new Object[] { "###", "# #", "###", '#', Block.cobblestone }); + par1CraftingManager.addRecipe(new ItemStack(Block.workbench), new Object[] { "##", "##", '#', Block.planks }); + par1CraftingManager.addRecipe(new ItemStack(Block.sandStone), new Object[] { "##", "##", '#', Block.sand }); + par1CraftingManager.addRecipe(new ItemStack(Block.sandStone, 4, 2), new Object[] { "##", "##", '#', Block.sandStone }); + par1CraftingManager.addRecipe(new ItemStack(Block.sandStone, 1, 1), new Object[] { "#", "#", '#', new ItemStack(Block.stoneSingleSlab, 1, 1) }); + par1CraftingManager.addRecipe(new ItemStack(Block.blockNetherQuartz, 1, 1), new Object[] { "#", "#", '#', new ItemStack(Block.stoneSingleSlab, 1, 7) }); + par1CraftingManager.addRecipe(new ItemStack(Block.blockNetherQuartz, 2, 2), new Object[] { "#", "#", '#', new ItemStack(Block.blockNetherQuartz, 1, 0) }); + par1CraftingManager.addRecipe(new ItemStack(Block.stoneBrick, 4), new Object[] { "##", "##", '#', Block.stone }); + par1CraftingManager.addRecipe(new ItemStack(Block.fenceIron, 16), new Object[] { "###", "###", '#', Item.ingotIron }); + par1CraftingManager.addRecipe(new ItemStack(Block.thinGlass, 16), new Object[] { "###", "###", '#', Block.glass }); + par1CraftingManager.addRecipe(new ItemStack(Block.redstoneLampIdle, 1), new Object[] { " R ", "RGR", " R ", 'R', Item.redstone, 'G', Block.glowStone }); + par1CraftingManager.addRecipe(new ItemStack(Block.beacon, 1), new Object[] { "GGG", "GSG", "OOO", 'G', Block.glass, 'S', Item.netherStar, 'O', Block.obsidian }); + par1CraftingManager.addRecipe(new ItemStack(Block.netherBrick, 1), new Object[] { "NN", "NN", 'N', Item.netherrackBrick }); + } +} diff --git a/src/main/java/net/minecraft/src/RecipesDyes.java b/src/main/java/net/minecraft/src/RecipesDyes.java new file mode 100644 index 0000000..230f026 --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesDyes.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +public class RecipesDyes { + /** + * Adds the dye recipes to the CraftingManager. + */ + public void addRecipes(CraftingManager par1CraftingManager) { + for (int var2 = 0; var2 < 16; ++var2) { + par1CraftingManager.addShapelessRecipe(new ItemStack(Block.cloth, 1, BlockCloth.getDyeFromBlock(var2)), new Object[] { new ItemStack(Item.dyePowder, 1, var2), new ItemStack(Item.itemsList[Block.cloth.blockID], 1, 0) }); + } + + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 11), new Object[] { Block.plantYellow }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 1), new Object[] { Block.plantRed }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 3, 15), new Object[] { Item.bone }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 9), new Object[] { new ItemStack(Item.dyePowder, 1, 1), new ItemStack(Item.dyePowder, 1, 15) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 14), new Object[] { new ItemStack(Item.dyePowder, 1, 1), new ItemStack(Item.dyePowder, 1, 11) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 10), new Object[] { new ItemStack(Item.dyePowder, 1, 2), new ItemStack(Item.dyePowder, 1, 15) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 8), new Object[] { new ItemStack(Item.dyePowder, 1, 0), new ItemStack(Item.dyePowder, 1, 15) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 7), new Object[] { new ItemStack(Item.dyePowder, 1, 8), new ItemStack(Item.dyePowder, 1, 15) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 3, 7), new Object[] { new ItemStack(Item.dyePowder, 1, 0), new ItemStack(Item.dyePowder, 1, 15), new ItemStack(Item.dyePowder, 1, 15) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 12), new Object[] { new ItemStack(Item.dyePowder, 1, 4), new ItemStack(Item.dyePowder, 1, 15) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 6), new Object[] { new ItemStack(Item.dyePowder, 1, 4), new ItemStack(Item.dyePowder, 1, 2) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 5), new Object[] { new ItemStack(Item.dyePowder, 1, 4), new ItemStack(Item.dyePowder, 1, 1) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 13), new Object[] { new ItemStack(Item.dyePowder, 1, 5), new ItemStack(Item.dyePowder, 1, 9) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 3, 13), new Object[] { new ItemStack(Item.dyePowder, 1, 4), new ItemStack(Item.dyePowder, 1, 1), new ItemStack(Item.dyePowder, 1, 9) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 4, 13), + new Object[] { new ItemStack(Item.dyePowder, 1, 4), new ItemStack(Item.dyePowder, 1, 1), new ItemStack(Item.dyePowder, 1, 1), new ItemStack(Item.dyePowder, 1, 15) }); + } +} diff --git a/src/main/java/net/minecraft/src/RecipesFood.java b/src/main/java/net/minecraft/src/RecipesFood.java new file mode 100644 index 0000000..2df9912 --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesFood.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +public class RecipesFood { + /** + * Adds the food recipes to the CraftingManager. + */ + public void addRecipes(CraftingManager par1CraftingManager) { + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.bowlSoup), new Object[] { Block.mushroomBrown, Block.mushroomRed, Item.bowlEmpty }); + par1CraftingManager.addRecipe(new ItemStack(Item.cookie, 8), new Object[] { "#X#", 'X', new ItemStack(Item.dyePowder, 1, 3), '#', Item.wheat }); + par1CraftingManager.addRecipe(new ItemStack(Block.melon), new Object[] { "MMM", "MMM", "MMM", 'M', Item.melon }); + par1CraftingManager.addRecipe(new ItemStack(Item.melonSeeds), new Object[] { "M", 'M', Item.melon }); + par1CraftingManager.addRecipe(new ItemStack(Item.pumpkinSeeds, 4), new Object[] { "M", 'M', Block.pumpkin }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.pumpkinPie), new Object[] { Block.pumpkin, Item.sugar, Item.egg }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.fermentedSpiderEye), new Object[] { Item.spiderEye, Block.mushroomBrown, Item.sugar }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.speckledMelon), new Object[] { Item.melon, Item.goldNugget }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.blazePowder, 2), new Object[] { Item.blazeRod }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.magmaCream), new Object[] { Item.blazePowder, Item.slimeBall }); + } +} diff --git a/src/main/java/net/minecraft/src/RecipesIngots.java b/src/main/java/net/minecraft/src/RecipesIngots.java new file mode 100644 index 0000000..d31673c --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesIngots.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +public class RecipesIngots { + private Object[][] recipeItems; + + public RecipesIngots() { + this.recipeItems = new Object[][] { { Block.blockGold, new ItemStack(Item.ingotGold, 9) }, { Block.blockIron, new ItemStack(Item.ingotIron, 9) }, { Block.blockDiamond, new ItemStack(Item.diamond, 9) }, + { Block.blockEmerald, new ItemStack(Item.emerald, 9) }, { Block.blockLapis, new ItemStack(Item.dyePowder, 9, 4) }, { Block.blockRedstone, new ItemStack(Item.redstone, 9) } }; + } + + /** + * Adds the ingot recipes to the CraftingManager. + */ + public void addRecipes(CraftingManager par1CraftingManager) { + for (int var2 = 0; var2 < this.recipeItems.length; ++var2) { + Block var3 = (Block) this.recipeItems[var2][0]; + ItemStack var4 = (ItemStack) this.recipeItems[var2][1]; + par1CraftingManager.addRecipe(new ItemStack(var3), new Object[] { "###", "###", "###", '#', var4 }); + par1CraftingManager.addRecipe(var4, new Object[] { "#", '#', var3 }); + } + + par1CraftingManager.addRecipe(new ItemStack(Item.ingotGold), new Object[] { "###", "###", "###", '#', Item.goldNugget }); + par1CraftingManager.addRecipe(new ItemStack(Item.goldNugget, 9), new Object[] { "#", '#', Item.ingotGold }); + } +} diff --git a/src/main/java/net/minecraft/src/RecipesMapCloning.java b/src/main/java/net/minecraft/src/RecipesMapCloning.java new file mode 100644 index 0000000..390e36d --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesMapCloning.java @@ -0,0 +1,84 @@ +package net.minecraft.src; + +public class RecipesMapCloning implements IRecipe { + /** + * Used to check if a recipe matches current crafting inventory + */ + public boolean matches(InventoryCrafting par1InventoryCrafting, World par2World) { + int var3 = 0; + ItemStack var4 = null; + + for (int var5 = 0; var5 < par1InventoryCrafting.getSizeInventory(); ++var5) { + ItemStack var6 = par1InventoryCrafting.getStackInSlot(var5); + + if (var6 != null) { + if (var6.itemID == Item.map.itemID) { + if (var4 != null) { + return false; + } + + var4 = var6; + } else { + if (var6.itemID != Item.emptyMap.itemID) { + return false; + } + + ++var3; + } + } + } + + return var4 != null && var3 > 0; + } + + /** + * Returns an Item that is the result of this recipe + */ + public ItemStack getCraftingResult(InventoryCrafting par1InventoryCrafting) { + int var2 = 0; + ItemStack var3 = null; + + for (int var4 = 0; var4 < par1InventoryCrafting.getSizeInventory(); ++var4) { + ItemStack var5 = par1InventoryCrafting.getStackInSlot(var4); + + if (var5 != null) { + if (var5.itemID == Item.map.itemID) { + if (var3 != null) { + return null; + } + + var3 = var5; + } else { + if (var5.itemID != Item.emptyMap.itemID) { + return null; + } + + ++var2; + } + } + } + + if (var3 != null && var2 >= 1) { + ItemStack var6 = new ItemStack(Item.map, var2 + 1, var3.getItemDamage()); + + if (var3.hasDisplayName()) { + var6.setItemName(var3.getDisplayName()); + } + + return var6; + } else { + return null; + } + } + + /** + * Returns the size of the recipe area + */ + public int getRecipeSize() { + return 9; + } + + public ItemStack getRecipeOutput() { + return null; + } +} diff --git a/src/main/java/net/minecraft/src/RecipesMapExtending.java b/src/main/java/net/minecraft/src/RecipesMapExtending.java new file mode 100644 index 0000000..3699c8c --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesMapExtending.java @@ -0,0 +1,59 @@ +package net.minecraft.src; + +public class RecipesMapExtending extends ShapedRecipes { + public RecipesMapExtending() { + super(3, 3, new ItemStack[] { new ItemStack(Item.paper), new ItemStack(Item.paper), new ItemStack(Item.paper), new ItemStack(Item.paper), new ItemStack(Item.map, 0, 32767), new ItemStack(Item.paper), new ItemStack(Item.paper), + new ItemStack(Item.paper), new ItemStack(Item.paper) }, new ItemStack(Item.emptyMap, 0, 0)); + } + + /** + * Used to check if a recipe matches current crafting inventory + */ + public boolean matches(InventoryCrafting par1InventoryCrafting, World par2World) { + if (!super.matches(par1InventoryCrafting, par2World)) { + return false; + } else { + ItemStack var3 = null; + + for (int var4 = 0; var4 < par1InventoryCrafting.getSizeInventory() && var3 == null; ++var4) { + ItemStack var5 = par1InventoryCrafting.getStackInSlot(var4); + + if (var5 != null && var5.itemID == Item.map.itemID) { + var3 = var5; + } + } + + if (var3 == null) { + return false; + } else { + MapData var6 = Item.map.getMapData(var3, par2World); + return var6 == null ? false : var6.scale < 4; + } + } + } + + /** + * Returns an Item that is the result of this recipe + */ + public ItemStack getCraftingResult(InventoryCrafting par1InventoryCrafting) { + ItemStack var2 = null; + + for (int var3 = 0; var3 < par1InventoryCrafting.getSizeInventory() && var2 == null; ++var3) { + ItemStack var4 = par1InventoryCrafting.getStackInSlot(var3); + + if (var4 != null && var4.itemID == Item.map.itemID) { + var2 = var4; + } + } + + var2 = var2.copy(); + var2.stackSize = 1; + + if (var2.getTagCompound() == null) { + var2.setTagCompound(new NBTTagCompound()); + } + + var2.getTagCompound().setBoolean("map_is_scaling", true); + return var2; + } +} diff --git a/src/main/java/net/minecraft/src/RecipesTools.java b/src/main/java/net/minecraft/src/RecipesTools.java new file mode 100644 index 0000000..ba3b898 --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesTools.java @@ -0,0 +1,28 @@ +package net.minecraft.src; + +public class RecipesTools { + private String[][] recipePatterns = new String[][] { { "XXX", " # ", " # " }, { "X", "#", "#" }, { "XX", "X#", " #" }, { "XX", " #", " #" } }; + private Object[][] recipeItems; + + public RecipesTools() { + this.recipeItems = new Object[][] { { Block.planks, Block.cobblestone, Item.ingotIron, Item.diamond, Item.ingotGold }, { Item.pickaxeWood, Item.pickaxeStone, Item.pickaxeIron, Item.pickaxeDiamond, Item.pickaxeGold }, + { Item.shovelWood, Item.shovelStone, Item.shovelIron, Item.shovelDiamond, Item.shovelGold }, { Item.axeWood, Item.axeStone, Item.axeIron, Item.axeDiamond, Item.axeGold }, + { Item.hoeWood, Item.hoeStone, Item.hoeIron, Item.hoeDiamond, Item.hoeGold } }; + } + + /** + * Adds the tool recipes to the CraftingManager. + */ + public void addRecipes(CraftingManager par1CraftingManager) { + for (int var2 = 0; var2 < this.recipeItems[0].length; ++var2) { + Object var3 = this.recipeItems[0][var2]; + + for (int var4 = 0; var4 < this.recipeItems.length - 1; ++var4) { + Item var5 = (Item) this.recipeItems[var4 + 1][var2]; + par1CraftingManager.addRecipe(new ItemStack(var5), new Object[] { this.recipePatterns[var4], '#', Item.stick, 'X', var3 }); + } + } + + par1CraftingManager.addRecipe(new ItemStack(Item.shears), new Object[] { " #", "# ", '#', Item.ingotIron }); + } +} diff --git a/src/main/java/net/minecraft/src/RecipesWeapons.java b/src/main/java/net/minecraft/src/RecipesWeapons.java new file mode 100644 index 0000000..f46c5f1 --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesWeapons.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class RecipesWeapons { + private String[][] recipePatterns = new String[][] { { "X", "X", "#" } }; + private Object[][] recipeItems; + + public RecipesWeapons() { + this.recipeItems = new Object[][] { { Block.planks, Block.cobblestone, Item.ingotIron, Item.diamond, Item.ingotGold }, { Item.swordWood, Item.swordStone, Item.swordIron, Item.swordDiamond, Item.swordGold } }; + } + + /** + * Adds the weapon recipes to the CraftingManager. + */ + public void addRecipes(CraftingManager par1CraftingManager) { + for (int var2 = 0; var2 < this.recipeItems[0].length; ++var2) { + Object var3 = this.recipeItems[0][var2]; + + for (int var4 = 0; var4 < this.recipeItems.length - 1; ++var4) { + Item var5 = (Item) this.recipeItems[var4 + 1][var2]; + par1CraftingManager.addRecipe(new ItemStack(var5), new Object[] { this.recipePatterns[var4], '#', Item.stick, 'X', var3 }); + } + } + + par1CraftingManager.addRecipe(new ItemStack(Item.bow, 1), new Object[] { " #X", "# X", " #X", 'X', Item.silk, '#', Item.stick }); + par1CraftingManager.addRecipe(new ItemStack(Item.arrow, 4), new Object[] { "X", "#", "Y", 'Y', Item.feather, 'X', Item.flint, '#', Item.stick }); + } +} diff --git a/src/main/java/net/minecraft/src/Rect2i.java b/src/main/java/net/minecraft/src/Rect2i.java new file mode 100644 index 0000000..b8598c0 --- /dev/null +++ b/src/main/java/net/minecraft/src/Rect2i.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + + + +public class Rect2i { + private int rectX; + private int rectY; + private int rectWidth; + private int rectHeight; + + public Rect2i(int par1, int par2, int par3, int par4) { + this.rectX = par1; + this.rectY = par2; + this.rectWidth = par3; + this.rectHeight = par4; + } + + public Rect2i intersection(Rect2i par1Rect2i) { + int var2 = this.rectX; + int var3 = this.rectY; + int var4 = this.rectX + this.rectWidth; + int var5 = this.rectY + this.rectHeight; + int var6 = par1Rect2i.getRectX(); + int var7 = par1Rect2i.getRectY(); + int var8 = var6 + par1Rect2i.getRectWidth(); + int var9 = var7 + par1Rect2i.getRectHeight(); + this.rectX = Math.max(var2, var6); + this.rectY = Math.max(var3, var7); + this.rectWidth = Math.max(0, Math.min(var4, var8) - this.rectX); + this.rectHeight = Math.max(0, Math.min(var5, var9) - this.rectY); + return this; + } + + public int getRectX() { + return this.rectX; + } + + public int getRectY() { + return this.rectY; + } + + public int getRectWidth() { + return this.rectWidth; + } + + public int getRectHeight() { + return this.rectHeight; + } +} diff --git a/src/main/java/net/minecraft/src/RedstoneUpdateInfo.java b/src/main/java/net/minecraft/src/RedstoneUpdateInfo.java new file mode 100644 index 0000000..4b96b68 --- /dev/null +++ b/src/main/java/net/minecraft/src/RedstoneUpdateInfo.java @@ -0,0 +1,15 @@ +package net.minecraft.src; + +class RedstoneUpdateInfo { + int x; + int y; + int z; + long updateTime; + + public RedstoneUpdateInfo(int par1, int par2, int par3, long par4) { + this.x = par1; + this.y = par2; + this.z = par3; + this.updateTime = par4; + } +} diff --git a/src/main/java/net/minecraft/src/RegistryDefaulted.java b/src/main/java/net/minecraft/src/RegistryDefaulted.java new file mode 100644 index 0000000..2dc3a5f --- /dev/null +++ b/src/main/java/net/minecraft/src/RegistryDefaulted.java @@ -0,0 +1,17 @@ +package net.minecraft.src; + +public class RegistryDefaulted extends RegistrySimple { + /** + * Default object for this registry, returned when an object is not found. + */ + private final Object defaultObject; + + public RegistryDefaulted(Object par1Obj) { + this.defaultObject = par1Obj; + } + + public Object func_82594_a(Object par1Obj) { + Object var2 = super.func_82594_a(par1Obj); + return var2 == null ? this.defaultObject : var2; + } +} diff --git a/src/main/java/net/minecraft/src/RegistrySimple.java b/src/main/java/net/minecraft/src/RegistrySimple.java new file mode 100644 index 0000000..3b8c974 --- /dev/null +++ b/src/main/java/net/minecraft/src/RegistrySimple.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.Map; + +public class RegistrySimple implements IRegistry { + /** Objects registered on this registry. */ + protected final Map registryObjects = new HashMap(); + + public Object func_82594_a(Object par1Obj) { + return this.registryObjects.get(par1Obj); + } + + /** + * Register an object on this registry. + */ + public void putObject(Object par1Obj, Object par2Obj) { + this.registryObjects.put(par1Obj, par2Obj); + } +} diff --git a/src/main/java/net/minecraft/src/Render.java b/src/main/java/net/minecraft/src/Render.java new file mode 100644 index 0000000..906f5b9 --- /dev/null +++ b/src/main/java/net/minecraft/src/Render.java @@ -0,0 +1,309 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public abstract class Render { + protected RenderManager renderManager; + private ModelBase modelBase = new ModelBiped(); + protected RenderBlocks renderBlocks = new RenderBlocks(); + protected float shadowSize = 0.0F; + + /** + * Determines the darkness of the object's shadow. Higher value makes a darker + * shadow. + */ + protected float shadowOpaque = 1.0F; + + /** + * Actually renders the given argument. This is a synthetic bridge method, + * always casting down its argument and then handing it off to a worker function + * which does the actual work. In all probabilty, the class Render is generic + * (Render 0.0F) { + Icon var19; + + if (var18 % 2 == 0) { + var19 = var9; + } else { + var19 = var10; + } + + float var20 = var19.getMinU(); + float var21 = var19.getMinV(); + float var22 = var19.getMaxU(); + float var23 = var19.getMaxV(); + + if (var18 / 2 % 2 == 0) { + float var24 = var22; + var22 = var20; + var20 = var24; + } + + var12.addVertexWithUV((double) (var13 - var14), (double) (0.0F - var16), (double) var17, (double) var22, (double) var23); + var12.addVertexWithUV((double) (-var13 - var14), (double) (0.0F - var16), (double) var17, (double) var20, (double) var23); + var12.addVertexWithUV((double) (-var13 - var14), (double) (1.4F - var16), (double) var17, (double) var20, (double) var21); + var12.addVertexWithUV((double) (var13 - var14), (double) (1.4F - var16), (double) var17, (double) var22, (double) var21); + var15 -= 0.45F; + var16 -= 0.45F; + var13 *= 0.9F; + var17 += 0.03F; + ++var18; + } + + var12.draw(); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + } + + private static final TextureLocation shadow = new TextureLocation("%clamp%/misc/shadow.png"); + + /** + * Renders the entity shadows at the position, shadow alpha and partialTickTime. + * Args: entity, x, y, z, shadowAlpha, partialTickTime + */ + private void renderShadow(Entity par1Entity, double par2, double par4, double par6, float par8, float par9) { + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + shadow.bindTexture(); + World var10 = this.getWorldFromRenderManager(); + EaglerAdapter.glDepthMask(false); + float var11 = this.shadowSize; + + if (par1Entity instanceof EntityLiving) { + EntityLiving var12 = (EntityLiving) par1Entity; + var11 *= var12.getRenderSizeModifier(); + + if (var12.isChild()) { + var11 *= 0.5F; + } + } + + double var35 = par1Entity.lastTickPosX + (par1Entity.posX - par1Entity.lastTickPosX) * (double) par9; + double var14 = par1Entity.lastTickPosY + (par1Entity.posY - par1Entity.lastTickPosY) * (double) par9 + (double) par1Entity.getShadowSize(); + double var16 = par1Entity.lastTickPosZ + (par1Entity.posZ - par1Entity.lastTickPosZ) * (double) par9; + int var18 = MathHelper.floor_double(var35 - (double) var11); + int var19 = MathHelper.floor_double(var35 + (double) var11); + int var20 = MathHelper.floor_double(var14 - (double) var11); + int var21 = MathHelper.floor_double(var14); + int var22 = MathHelper.floor_double(var16 - (double) var11); + int var23 = MathHelper.floor_double(var16 + (double) var11); + double var24 = par2 - var35; + double var26 = par4 - var14; + double var28 = par6 - var16; + Tessellator var30 = Tessellator.instance; + var30.startDrawingQuads(); + + for (int var31 = var18; var31 <= var19; ++var31) { + for (int var32 = var20; var32 <= var21; ++var32) { + for (int var33 = var22; var33 <= var23; ++var33) { + int var34 = var10.getBlockId(var31, var32 - 1, var33); + + if (var34 > 0 && var10.getBlockLightValue(var31, var32, var33) > 3) { + this.renderShadowOnBlock(Block.blocksList[var34], par2, par4 + (double) par1Entity.getShadowSize(), par6, var31, var32, var33, par8, var11, var24, var26 + (double) par1Entity.getShadowSize(), var28); + } + } + } + } + + var30.draw(); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glDepthMask(true); + } + + /** + * Returns the render manager's world object + */ + private World getWorldFromRenderManager() { + return this.renderManager.worldObj; + } + + /** + * Renders a shadow projected down onto the specified block. Brightness of the + * block plus how far away on the Y axis determines the alpha of the shadow. + * Args: block, centerX, centerY, centerZ, blockX, blockY, blockZ, baseAlpha, + * shadowSize, xOffset, yOffset, zOffset + */ + private void renderShadowOnBlock(Block par1Block, double par2, double par4, double par6, int par8, int par9, int par10, float par11, float par12, double par13, double par15, double par17) { + Tessellator var19 = Tessellator.instance; + + if (par1Block.renderAsNormalBlock()) { + double var20 = ((double) par11 - (par4 - ((double) par9 + par15)) / 2.0D) * 0.5D * (double) this.getWorldFromRenderManager().getLightBrightness(par8, par9, par10); + + if (var20 >= 0.0D) { + if (var20 > 1.0D) { + var20 = 1.0D; + } + + var19.setColorRGBA_F(1.0F, 1.0F, 1.0F, (float) var20); + double var22 = (double) par8 + par1Block.getBlockBoundsMinX() + par13; + double var24 = (double) par8 + par1Block.getBlockBoundsMaxX() + par13; + double var26 = (double) par9 + par1Block.getBlockBoundsMinY() + par15 + 0.015625D; + double var28 = (double) par10 + par1Block.getBlockBoundsMinZ() + par17; + double var30 = (double) par10 + par1Block.getBlockBoundsMaxZ() + par17; + float var32 = (float) ((par2 - var22) / 2.0D / (double) par12 + 0.5D); + float var33 = (float) ((par2 - var24) / 2.0D / (double) par12 + 0.5D); + float var34 = (float) ((par6 - var28) / 2.0D / (double) par12 + 0.5D); + float var35 = (float) ((par6 - var30) / 2.0D / (double) par12 + 0.5D); + var19.addVertexWithUV(var22, var26, var28, (double) var32, (double) var34); + var19.addVertexWithUV(var22, var26, var30, (double) var32, (double) var35); + var19.addVertexWithUV(var24, var26, var30, (double) var33, (double) var35); + var19.addVertexWithUV(var24, var26, var28, (double) var33, (double) var34); + } + } + } + + /** + * Renders a white box with the bounds of the AABB translated by the offset. + * Args: aabb, x, y, z + */ + public static void renderOffsetAABB(AxisAlignedBB par0AxisAlignedBB, double par1, double par3, double par5) { + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + Tessellator var7 = Tessellator.instance; + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + var7.startDrawingQuads(); + var7.setTranslation(par1, par3, par5); + var7.setNormal(0.0F, 0.0F, -1.0F); + var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); + var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); + var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); + var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); + var7.setNormal(0.0F, 0.0F, 1.0F); + var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); + var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); + var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); + var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); + var7.setNormal(0.0F, -1.0F, 0.0F); + var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); + var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); + var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); + var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); + var7.setNormal(0.0F, 1.0F, 0.0F); + var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); + var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); + var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); + var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); + var7.setNormal(-1.0F, 0.0F, 0.0F); + var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); + var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); + var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); + var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); + var7.setNormal(1.0F, 0.0F, 0.0F); + var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); + var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); + var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); + var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); + var7.setTranslation(0.0D, 0.0D, 0.0D); + var7.draw(); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + } + + /** + * Adds to the tesselator a box using the aabb for the bounds. Args: aabb + */ + public static void renderAABB(AxisAlignedBB par0AxisAlignedBB) { + Tessellator var1 = Tessellator.instance; + var1.startDrawingQuads(); + var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); + var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); + var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); + var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); + var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); + var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); + var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); + var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); + var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); + var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); + var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); + var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); + var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); + var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); + var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); + var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); + var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); + var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); + var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); + var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); + var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); + var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); + var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); + var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); + var1.draw(); + } + + /** + * Sets the RenderManager. + */ + public void setRenderManager(RenderManager par1RenderManager) { + this.renderManager = par1RenderManager; + } + + /** + * Renders the entity's shadow and fire (if its on fire). Args: entity, x, y, z, + * yaw, partialTickTime + */ + public void doRenderShadowAndFire(Entity par1Entity, double par2, double par4, double par6, float par8, float par9) { + if (this.renderManager.options.fancyGraphics && this.shadowSize > 0.0F && !par1Entity.isInvisible()) { + double var10 = this.renderManager.getDistanceToCamera(par1Entity.posX, par1Entity.posY, par1Entity.posZ); + float var12 = (float) ((1.0D - var10 / 256.0D) * (double) this.shadowOpaque); + + if (var12 > 0.0F) { + this.renderShadow(par1Entity, par2, par4, par6, var12, par9); + } + } + + if (par1Entity.canRenderOnFire()) { + this.renderEntityOnFire(par1Entity, par2, par4, par6, par9); + } + } + + /** + * Returns the font renderer from the set render manager + */ + public FontRenderer getFontRendererFromRenderManager() { + return this.renderManager.getFontRenderer(); + } + + public void updateIcons(IconRegister par1IconRegister) { + } +} diff --git a/src/main/java/net/minecraft/src/RenderArrow.java b/src/main/java/net/minecraft/src/RenderArrow.java new file mode 100644 index 0000000..071e47e --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderArrow.java @@ -0,0 +1,80 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class RenderArrow extends Render { + + private static final TextureLocation tex = new TextureLocation("/item/arrows.png"); + + public void renderArrow(EntityArrow par1EntityArrow, double par2, double par4, double par6, float par8, float par9) { + tex.bindTexture(); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef((float) par2, (float) par4, (float) par6); + EaglerAdapter.glRotatef(par1EntityArrow.prevRotationYaw + (par1EntityArrow.rotationYaw - par1EntityArrow.prevRotationYaw) * par9 - 90.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(par1EntityArrow.prevRotationPitch + (par1EntityArrow.rotationPitch - par1EntityArrow.prevRotationPitch) * par9, 0.0F, 0.0F, 1.0F); + Tessellator var10 = Tessellator.instance; + byte var11 = 0; + float var12 = 0.0F; + float var13 = 0.5F; + float var14 = (float) (0 + var11 * 10) / 32.0F; + float var15 = (float) (5 + var11 * 10) / 32.0F; + float var16 = 0.0F; + float var17 = 0.15625F; + float var18 = (float) (5 + var11 * 10) / 32.0F; + float var19 = (float) (10 + var11 * 10) / 32.0F; + float var20 = 0.05625F; + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + float var21 = (float) par1EntityArrow.arrowShake - par9; + + if (var21 > 0.0F) { + float var22 = -MathHelper.sin(var21 * 3.0F) * var21; + EaglerAdapter.glRotatef(var22, 0.0F, 0.0F, 1.0F); + } + + EaglerAdapter.glRotatef(45.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glScalef(var20, var20, var20); + EaglerAdapter.glTranslatef(-4.0F, 0.0F, 0.0F); + EaglerAdapter.glNormal3f(var20, 0.0F, 0.0F); + var10.startDrawingQuads(); + var10.addVertexWithUV(-7.0D, -2.0D, -2.0D, (double) var16, (double) var18); + var10.addVertexWithUV(-7.0D, -2.0D, 2.0D, (double) var17, (double) var18); + var10.addVertexWithUV(-7.0D, 2.0D, 2.0D, (double) var17, (double) var19); + var10.addVertexWithUV(-7.0D, 2.0D, -2.0D, (double) var16, (double) var19); + var10.draw(); + EaglerAdapter.glNormal3f(-var20, 0.0F, 0.0F); + var10.startDrawingQuads(); + var10.addVertexWithUV(-7.0D, 2.0D, -2.0D, (double) var16, (double) var18); + var10.addVertexWithUV(-7.0D, 2.0D, 2.0D, (double) var17, (double) var18); + var10.addVertexWithUV(-7.0D, -2.0D, 2.0D, (double) var17, (double) var19); + var10.addVertexWithUV(-7.0D, -2.0D, -2.0D, (double) var16, (double) var19); + var10.draw(); + + for (int var23 = 0; var23 < 4; ++var23) { + EaglerAdapter.glRotatef(90.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glNormal3f(0.0F, 0.0F, var20); + var10.startDrawingQuads(); + var10.addVertexWithUV(-8.0D, -2.0D, 0.0D, (double) var12, (double) var14); + var10.addVertexWithUV(8.0D, -2.0D, 0.0D, (double) var13, (double) var14); + var10.addVertexWithUV(8.0D, 2.0D, 0.0D, (double) var13, (double) var15); + var10.addVertexWithUV(-8.0D, 2.0D, 0.0D, (double) var12, (double) var15); + var10.draw(); + } + + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + EaglerAdapter.glPopMatrix(); + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, + * always casting down its argument and then handing it off to a worker function + * which does the actual work. In all probabilty, the class Render is generic + * (Render> 16 & 255) / 255.0F; + float var11 = (float) (var9 >> 8 & 255) / 255.0F; + float var12 = (float) (var9 & 255) / 255.0F; + EaglerAdapter.glColor3f(var8 * var10, var8 * var11, var8 * var12); + + if (var4.isItemEnchanted()) { + return 31; + } + + return 16; + } + + EaglerAdapter.glColor3f(var8, var8, var8); + + if (var4.isItemEnchanted()) { + return 15; + } + + return 1; + } + } + + return -1; + } + + protected void func_82408_c(EntityLiving par1EntityLiving, int par2, float par3) { + ItemStack var4 = par1EntityLiving.getCurrentArmor(3 - par2); + + if (var4 != null) { + Item var5 = var4.getItem(); + + if (var5 instanceof ItemArmor) { + ItemArmor var6 = (ItemArmor) var5; + this.loadTexture("/armor/" + bipedArmorFilenamePrefix[var6.renderIndex] + "_" + (par2 == 2 ? 2 : 1) + "_b.png"); + float var7 = 1.0F; + EaglerAdapter.glColor3f(var7, var7, var7); + } + } + } + + public void doRenderLiving(EntityLiving par1EntityLiving, double par2, double par4, double par6, float par8, float par9) { + float var10 = 1.0F; + EaglerAdapter.glColor3f(var10, var10, var10); + ItemStack var11 = par1EntityLiving.getHeldItem(); + this.func_82420_a(par1EntityLiving, var11); + double var12 = par4 - (double) par1EntityLiving.yOffset; + + if (par1EntityLiving.isSneaking() && !(par1EntityLiving instanceof EntityPlayerSP)) { + var12 -= 0.125D; + } + + super.doRenderLiving(par1EntityLiving, par2, var12, par6, par8, par9); + this.field_82423_g.aimedBow = this.field_82425_h.aimedBow = this.modelBipedMain.aimedBow = false; + this.field_82423_g.isSneak = this.field_82425_h.isSneak = this.modelBipedMain.isSneak = false; + this.field_82423_g.heldItemRight = this.field_82425_h.heldItemRight = this.modelBipedMain.heldItemRight = 0; + } + + protected void func_82420_a(EntityLiving par1EntityLiving, ItemStack par2ItemStack) { + this.field_82423_g.heldItemRight = this.field_82425_h.heldItemRight = this.modelBipedMain.heldItemRight = par2ItemStack != null ? 1 : 0; + this.field_82423_g.isSneak = this.field_82425_h.isSneak = this.modelBipedMain.isSneak = par1EntityLiving.isSneaking(); + } + + protected void renderEquippedItems(EntityLiving par1EntityLiving, float par2) { + float var3 = 1.0F; + EaglerAdapter.glColor3f(var3, var3, var3); + super.renderEquippedItems(par1EntityLiving, par2); + ItemStack var4 = par1EntityLiving.getHeldItem(); + ItemStack var5 = par1EntityLiving.getCurrentArmor(3); + float var6; + + if (var5 != null) { + EaglerAdapter.glPushMatrix(); + this.modelBipedMain.bipedHead.postRender(0.0625F); + + if (var5.getItem().itemID < 256) { + if (RenderBlocks.renderItemIn3d(Block.blocksList[var5.itemID].getRenderType())) { + var6 = 0.625F; + EaglerAdapter.glTranslatef(0.0F, -0.25F, 0.0F); + EaglerAdapter.glRotatef(90.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glScalef(var6, -var6, -var6); + } + + this.renderManager.itemRenderer.renderItem(par1EntityLiving, var5, 0); + } else if (var5.getItem().itemID == Item.skull.itemID) { + var6 = 1.0625F; + EaglerAdapter.glScalef(var6, -var6, -var6); + String var7 = ""; + + if (var5.hasTagCompound() && var5.getTagCompound().hasKey("SkullOwner")) { + var7 = var5.getTagCompound().getString("SkullOwner"); + } + + TileEntitySkullRenderer.skullRenderer.func_82393_a(-0.5F, 0.0F, -0.5F, 1, 180.0F, var5.getItemDamage(), var7); + } + + EaglerAdapter.glPopMatrix(); + } + + if (var4 != null) { + EaglerAdapter.glPushMatrix(); + + if (this.mainModel.isChild) { + var6 = 0.5F; + EaglerAdapter.glTranslatef(0.0F, 0.625F, 0.0F); + EaglerAdapter.glRotatef(-20.0F, -1.0F, 0.0F, 0.0F); + EaglerAdapter.glScalef(var6, var6, var6); + } + + this.modelBipedMain.bipedRightArm.postRender(0.0625F); + EaglerAdapter.glTranslatef(-0.0625F, 0.4375F, 0.0625F); + + if (var4.itemID < 256 && RenderBlocks.renderItemIn3d(Block.blocksList[var4.itemID].getRenderType())) { + var6 = 0.5F; + EaglerAdapter.glTranslatef(0.0F, 0.1875F, -0.3125F); + var6 *= 0.75F; + EaglerAdapter.glRotatef(20.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glScalef(-var6, -var6, var6); + } else if (var4.itemID == Item.bow.itemID) { + var6 = 0.625F; + EaglerAdapter.glTranslatef(0.0F, 0.125F, 0.3125F); + EaglerAdapter.glRotatef(-20.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glScalef(var6, -var6, var6); + EaglerAdapter.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + } else if (Item.itemsList[var4.itemID].isFull3D()) { + var6 = 0.625F; + + if (Item.itemsList[var4.itemID].shouldRotateAroundWhenRendering()) { + EaglerAdapter.glRotatef(180.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glTranslatef(0.0F, -0.125F, 0.0F); + } + + this.func_82422_c(); + EaglerAdapter.glScalef(var6, -var6, var6); + EaglerAdapter.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + } else { + var6 = 0.375F; + EaglerAdapter.glTranslatef(0.25F, 0.1875F, -0.1875F); + EaglerAdapter.glScalef(var6, var6, var6); + EaglerAdapter.glRotatef(60.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glRotatef(-90.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(20.0F, 0.0F, 0.0F, 1.0F); + } + + this.renderManager.itemRenderer.renderItem(par1EntityLiving, var4, 0); + + if (var4.getItem().requiresMultipleRenderPasses()) { + this.renderManager.itemRenderer.renderItem(par1EntityLiving, var4, 1); + } + + EaglerAdapter.glPopMatrix(); + } + } + + protected void func_82422_c() { + EaglerAdapter.glTranslatef(0.0F, 0.1875F, 0.0F); + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, + * always casting down its argument and then handing it off to a worker function + * which does the actual work. In all probabilty, the class Render is generic + * (Render=0, all block faces will be rendered using this texture index + */ + private Icon overrideBlockTexture = null; + + /** + * Set to true if the texture should be flipped horizontally during render*Face + */ + private boolean flipTexture = false; + + /** + * If true, renders all faces on all blocks rather than using the logic in + * Block.shouldSideBeRendered. Unused. + */ + private boolean renderAllFaces = false; + + /** Fancy grass side matching biome */ + public static boolean fancyGrass = true; + public boolean useInventoryTint = true; + + /** The minimum X value for rendering (default 0.0). */ + private double renderMinX; + + /** The maximum X value for rendering (default 1.0). */ + private double renderMaxX; + + /** The minimum Y value for rendering (default 0.0). */ + private double renderMinY; + + /** The maximum Y value for rendering (default 1.0). */ + private double renderMaxY; + + /** The minimum Z value for rendering (default 0.0). */ + private double renderMinZ; + + /** The maximum Z value for rendering (default 1.0). */ + private double renderMaxZ; + + /** + * Set by overrideBlockBounds, to keep this class from changing the visual + * bounding box. + */ + private boolean lockBlockBounds = false; + private boolean partialRenderBounds = false; + private final Minecraft minecraftRB; + private int uvRotateEast = 0; + private int uvRotateWest = 0; + private int uvRotateSouth = 0; + private int uvRotateNorth = 0; + private int uvRotateTop = 0; + private int uvRotateBottom = 0; + + /** Whether ambient occlusion is enabled or not */ + private boolean enableAO; + + /** + * Used as a scratch variable for ambient occlusion on the north/bottom/east + * corner. + */ + private float aoLightValueScratchXYZNNN; + + /** + * Used as a scratch variable for ambient occlusion between the bottom face and + * the north face. + */ + private float aoLightValueScratchXYNN; + + /** + * Used as a scratch variable for ambient occlusion on the north/bottom/west + * corner. + */ + private float aoLightValueScratchXYZNNP; + + /** + * Used as a scratch variable for ambient occlusion between the bottom face and + * the east face. + */ + private float aoLightValueScratchYZNN; + + /** + * Used as a scratch variable for ambient occlusion between the bottom face and + * the west face. + */ + private float aoLightValueScratchYZNP; + + /** + * Used as a scratch variable for ambient occlusion on the south/bottom/east + * corner. + */ + private float aoLightValueScratchXYZPNN; + + /** + * Used as a scratch variable for ambient occlusion between the bottom face and + * the south face. + */ + private float aoLightValueScratchXYPN; + + /** + * Used as a scratch variable for ambient occlusion on the south/bottom/west + * corner. + */ + private float aoLightValueScratchXYZPNP; + + /** + * Used as a scratch variable for ambient occlusion on the north/top/east + * corner. + */ + private float aoLightValueScratchXYZNPN; + + /** + * Used as a scratch variable for ambient occlusion between the top face and the + * north face. + */ + private float aoLightValueScratchXYNP; + + /** + * Used as a scratch variable for ambient occlusion on the north/top/west + * corner. + */ + private float aoLightValueScratchXYZNPP; + + /** + * Used as a scratch variable for ambient occlusion between the top face and the + * east face. + */ + private float aoLightValueScratchYZPN; + + /** + * Used as a scratch variable for ambient occlusion on the south/top/east + * corner. + */ + private float aoLightValueScratchXYZPPN; + + /** + * Used as a scratch variable for ambient occlusion between the top face and the + * south face. + */ + private float aoLightValueScratchXYPP; + + /** + * Used as a scratch variable for ambient occlusion between the top face and the + * west face. + */ + private float aoLightValueScratchYZPP; + + /** + * Used as a scratch variable for ambient occlusion on the south/top/west + * corner. + */ + private float aoLightValueScratchXYZPPP; + + /** + * Used as a scratch variable for ambient occlusion between the north face and + * the east face. + */ + private float aoLightValueScratchXZNN; + + /** + * Used as a scratch variable for ambient occlusion between the south face and + * the east face. + */ + private float aoLightValueScratchXZPN; + + /** + * Used as a scratch variable for ambient occlusion between the north face and + * the west face. + */ + private float aoLightValueScratchXZNP; + + /** + * Used as a scratch variable for ambient occlusion between the south face and + * the west face. + */ + private float aoLightValueScratchXZPP; + + /** Ambient occlusion brightness XYZNNN */ + private int aoBrightnessXYZNNN; + + /** Ambient occlusion brightness XYNN */ + private int aoBrightnessXYNN; + + /** Ambient occlusion brightness XYZNNP */ + private int aoBrightnessXYZNNP; + + /** Ambient occlusion brightness YZNN */ + private int aoBrightnessYZNN; + + /** Ambient occlusion brightness YZNP */ + private int aoBrightnessYZNP; + + /** Ambient occlusion brightness XYZPNN */ + private int aoBrightnessXYZPNN; + + /** Ambient occlusion brightness XYPN */ + private int aoBrightnessXYPN; + + /** Ambient occlusion brightness XYZPNP */ + private int aoBrightnessXYZPNP; + + /** Ambient occlusion brightness XYZNPN */ + private int aoBrightnessXYZNPN; + + /** Ambient occlusion brightness XYNP */ + private int aoBrightnessXYNP; + + /** Ambient occlusion brightness XYZNPP */ + private int aoBrightnessXYZNPP; + + /** Ambient occlusion brightness YZPN */ + private int aoBrightnessYZPN; + + /** Ambient occlusion brightness XYZPPN */ + private int aoBrightnessXYZPPN; + + /** Ambient occlusion brightness XYPP */ + private int aoBrightnessXYPP; + + /** Ambient occlusion brightness YZPP */ + private int aoBrightnessYZPP; + + /** Ambient occlusion brightness XYZPPP */ + private int aoBrightnessXYZPPP; + + /** Ambient occlusion brightness XZNN */ + private int aoBrightnessXZNN; + + /** Ambient occlusion brightness XZPN */ + private int aoBrightnessXZPN; + + /** Ambient occlusion brightness XZNP */ + private int aoBrightnessXZNP; + + /** Ambient occlusion brightness XZPP */ + private int aoBrightnessXZPP; + + /** Brightness top left */ + private int brightnessTopLeft; + + /** Brightness bottom left */ + private int brightnessBottomLeft; + + /** Brightness bottom right */ + private int brightnessBottomRight; + + /** Brightness top right */ + private int brightnessTopRight; + + /** Red color value for the top left corner */ + private float colorRedTopLeft; + + /** Red color value for the bottom left corner */ + private float colorRedBottomLeft; + + /** Red color value for the bottom right corner */ + private float colorRedBottomRight; + + /** Red color value for the top right corner */ + private float colorRedTopRight; + + /** Green color value for the top left corner */ + private float colorGreenTopLeft; + + /** Green color value for the bottom left corner */ + private float colorGreenBottomLeft; + + /** Green color value for the bottom right corner */ + private float colorGreenBottomRight; + + /** Green color value for the top right corner */ + private float colorGreenTopRight; + + /** Blue color value for the top left corner */ + private float colorBlueTopLeft; + + /** Blue color value for the bottom left corner */ + private float colorBlueBottomLeft; + + /** Blue color value for the bottom right corner */ + private float colorBlueBottomRight; + + /** Blue color value for the top right corner */ + private float colorBlueTopRight; + + public RenderBlocks(IBlockAccess par1IBlockAccess) { + this.blockAccess = par1IBlockAccess; + this.minecraftRB = Minecraft.getMinecraft(); + } + + public RenderBlocks() { + this.minecraftRB = Minecraft.getMinecraft(); + } + + /** + * Sets overrideBlockTexture + */ + public void setOverrideBlockTexture(Icon par1Icon) { + this.overrideBlockTexture = par1Icon; + } + + /** + * Clear override block texture + */ + public void clearOverrideBlockTexture() { + this.overrideBlockTexture = null; + } + + public boolean hasOverrideBlockTexture() { + return this.overrideBlockTexture != null; + } + + /** + * Sets the bounding box for the block to draw in, e.g. 0.25-0.75 on all axes + * for a half-size, centered block. + */ + public void setRenderBounds(double par1, double par3, double par5, double par7, double par9, double par11) { + if (!this.lockBlockBounds) { + this.renderMinX = par1; + this.renderMaxX = par7; + this.renderMinY = par3; + this.renderMaxY = par9; + this.renderMinZ = par5; + this.renderMaxZ = par11; + this.partialRenderBounds = this.minecraftRB.gameSettings.ambientOcclusion >= 2 + && (this.renderMinX > 0.0D || this.renderMaxX < 1.0D || this.renderMinY > 0.0D || this.renderMaxY < 1.0D || this.renderMinZ > 0.0D || this.renderMaxZ < 1.0D); + } + } + + /** + * Like setRenderBounds, but automatically pulling the bounds from the given + * Block. + */ + public void setRenderBoundsFromBlock(Block par1Block) { + if (!this.lockBlockBounds) { + this.renderMinX = par1Block.getBlockBoundsMinX(); + this.renderMaxX = par1Block.getBlockBoundsMaxX(); + this.renderMinY = par1Block.getBlockBoundsMinY(); + this.renderMaxY = par1Block.getBlockBoundsMaxY(); + this.renderMinZ = par1Block.getBlockBoundsMinZ(); + this.renderMaxZ = par1Block.getBlockBoundsMaxZ(); + this.partialRenderBounds = this.minecraftRB.gameSettings.ambientOcclusion >= 2 + && (this.renderMinX > 0.0D || this.renderMaxX < 1.0D || this.renderMinY > 0.0D || this.renderMaxY < 1.0D || this.renderMinZ > 0.0D || this.renderMaxZ < 1.0D); + } + } + + /** + * Like setRenderBounds, but locks the values so that RenderBlocks won't change + * them. If you use this, you must call unlockBlockBounds after you finish + * rendering! + */ + public void overrideBlockBounds(double par1, double par3, double par5, double par7, double par9, double par11) { + this.renderMinX = par1; + this.renderMaxX = par7; + this.renderMinY = par3; + this.renderMaxY = par9; + this.renderMinZ = par5; + this.renderMaxZ = par11; + this.lockBlockBounds = true; + this.partialRenderBounds = this.minecraftRB.gameSettings.ambientOcclusion >= 2 + && (this.renderMinX > 0.0D || this.renderMaxX < 1.0D || this.renderMinY > 0.0D || this.renderMaxY < 1.0D || this.renderMinZ > 0.0D || this.renderMaxZ < 1.0D); + } + + /** + * Unlocks the visual bounding box so that RenderBlocks can change it again. + */ + public void unlockBlockBounds() { + this.lockBlockBounds = false; + } + + /** + * Renders a block using the given texture instead of the block's own default + * texture + */ + public void renderBlockUsingTexture(Block par1Block, int par2, int par3, int par4, Icon par5Icon) { + this.setOverrideBlockTexture(par5Icon); + this.renderBlockByRenderType(par1Block, par2, par3, par4); + this.clearOverrideBlockTexture(); + } + + /** + * Render all faces of a block + */ + public void renderBlockAllFaces(Block par1Block, int par2, int par3, int par4) { + this.renderAllFaces = true; + this.renderBlockByRenderType(par1Block, par2, par3, par4); + this.renderAllFaces = false; + } + + /** + * Renders the block at the given coordinates using the block's rendering type + */ + public boolean renderBlockByRenderType(Block par1Block, int par2, int par3, int par4) { + int var5 = par1Block.getRenderType(); + + if (var5 == -1) { + return false; + } else { + par1Block.setBlockBoundsBasedOnState(this.blockAccess, par2, par3, par4); + this.setRenderBoundsFromBlock(par1Block); + return var5 == 0 ? this.renderStandardBlock(par1Block, par2, par3, par4) + : (var5 == 4 ? this.renderBlockFluids(par1Block, par2, par3, par4) + : (var5 == 31 ? this.renderBlockLog(par1Block, par2, par3, par4) + : (var5 == 1 ? this.renderCrossedSquares(par1Block, par2, par3, par4) + : (var5 == 2 ? this.renderBlockTorch(par1Block, par2, par3, par4) + : (var5 == 20 ? this.renderBlockVine(par1Block, par2, par3, par4) + : (var5 == 11 ? this.renderBlockFence((BlockFence) par1Block, par2, par3, par4) + : (var5 == 39 ? this.renderBlockQuartz(par1Block, par2, par3, par4) + : (var5 == 5 ? this.renderBlockRedstoneWire(par1Block, par2, par3, par4) + : (var5 == 13 ? this.renderBlockCactus(par1Block, par2, par3, par4) + : (var5 == 9 ? this.renderBlockMinecartTrack((BlockRailBase) par1Block, par2, par3, par4) + : (var5 == 19 ? this.renderBlockStem(par1Block, par2, par3, par4) + : (var5 == 23 ? this.renderBlockLilyPad(par1Block, par2, par3, par4) + : (var5 == 6 ? this.renderBlockCrops(par1Block, par2, par3, par4) + : (var5 == 3 ? this.renderBlockFire((BlockFire) par1Block, par2, par3, par4) + : (var5 == 8 ? this.renderBlockLadder(par1Block, par2, par3, par4) + : (var5 == 7 ? this.renderBlockDoor(par1Block, par2, par3, par4) + : (var5 == 10 ? this.renderBlockStairs((BlockStairs) par1Block, par2, par3, par4) + : (var5 == 27 ? this.renderBlockDragonEgg((BlockDragonEgg) par1Block, par2, par3, + par4) + : (var5 == 32 ? this.renderBlockWall((BlockWall) par1Block, par2, par3, + par4) + : (var5 == 12 ? this.renderBlockLever(par1Block, par2, par3, par4) + : (var5 == 29 + ? this.renderBlockTripWireSource(par1Block, par2, + par3, par4) + : (var5 == 30 + ? this.renderBlockTripWire(par1Block, par2, + par3, par4) + : (var5 == 14 + ? this.renderBlockBed(par1Block, + par2, par3, par4) + : (var5 == 15 + ? this.renderBlockRepeater( + (BlockRedstoneRepeater) par1Block, + par2, par3, par4) + : (var5 == 36 ? this + .renderBlockRedstoneLogic( + (BlockRedstoneLogic) par1Block, + par2, par3, + par4) + : (var5 == 37 ? this + .renderBlockComparator( + (BlockComparator) par1Block, + par2, + par3, + par4) + : (var5 == 16 + ? this.renderPistonBase( + par1Block, + par2, + par3, + par4, + false) + : (var5 == 17 + ? this.renderPistonExtension( + par1Block, + par2, + par3, + par4, + true) + : (var5 == 18 + ? this.renderBlockPane( + (BlockPane) par1Block, + par2, + par3, + par4) + : (var5 == 21 + ? this.renderBlockFenceGate( + (BlockFenceGate) par1Block, + par2, + par3, + par4) + : (var5 == 24 + ? this.renderBlockCauldron( + (BlockCauldron) par1Block, + par2, + par3, + par4) + : (var5 == 33 + ? this.renderBlockFlowerpot( + (BlockFlowerPot) par1Block, + par2, + par3, + par4) + : (var5 == 35 + ? this.renderBlockAnvil( + (BlockAnvil) par1Block, + par2, + par3, + par4) + : (var5 == 25 + ? this.renderBlockBrewingStand( + (BlockBrewingStand) par1Block, + par2, + par3, + par4) + : (var5 == 26 + ? this.renderBlockEndPortalFrame( + (BlockEndPortalFrame) par1Block, + par2, + par3, + par4) + : (var5 == 28 + ? this.renderBlockCocoa( + (BlockCocoa) par1Block, + par2, + par3, + par4) + : (var5 == 34 + ? this.renderBlockBeacon( + (BlockBeacon) par1Block, + par2, + par3, + par4) + : (var5 == 38 + ? this.renderBlockHopper( + (BlockHopper) par1Block, + par2, + par3, + par4) + : false)))))))))))))))))))))))))))))))))))))); + } + } + + /** + * Render BlockEndPortalFrame + */ + private boolean renderBlockEndPortalFrame(BlockEndPortalFrame par1BlockEndPortalFrame, int par2, int par3, int par4) { + int var5 = this.blockAccess.getBlockMetadata(par2, par3, par4); + int var6 = var5 & 3; + + if (var6 == 0) { + this.uvRotateTop = 3; + } else if (var6 == 3) { + this.uvRotateTop = 1; + } else if (var6 == 1) { + this.uvRotateTop = 2; + } + + if (!BlockEndPortalFrame.isEnderEyeInserted(var5)) { + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 0.8125D, 1.0D); + this.renderStandardBlock(par1BlockEndPortalFrame, par2, par3, par4); + this.uvRotateTop = 0; + return true; + } else { + this.renderAllFaces = true; + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 0.8125D, 1.0D); + this.renderStandardBlock(par1BlockEndPortalFrame, par2, par3, par4); + this.setOverrideBlockTexture(par1BlockEndPortalFrame.func_94398_p()); + this.setRenderBounds(0.25D, 0.8125D, 0.25D, 0.75D, 1.0D, 0.75D); + this.renderStandardBlock(par1BlockEndPortalFrame, par2, par3, par4); + this.renderAllFaces = false; + this.clearOverrideBlockTexture(); + this.uvRotateTop = 0; + return true; + } + } + + /** + * render a bed at the given coordinates + */ + private boolean renderBlockBed(Block par1Block, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + int var6 = this.blockAccess.getBlockMetadata(par2, par3, par4); + int var7 = BlockBed.getDirection(var6); + boolean var8 = BlockBed.isBlockHeadOfBed(var6); + float var9 = 0.5F; + float var10 = 1.0F; + float var11 = 0.8F; + float var12 = 0.6F; + int var25 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4); + var5.setBrightness(var25); + var5.setColorOpaque_F(var9, var9, var9); + Icon var27 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 0); + double var28 = (double) var27.getMinU(); + double var30 = (double) var27.getMaxU(); + double var32 = (double) var27.getMinV(); + double var34 = (double) var27.getMaxV(); + double var36 = (double) par2 + this.renderMinX; + double var38 = (double) par2 + this.renderMaxX; + double var40 = (double) par3 + this.renderMinY + 0.1875D; + double var42 = (double) par4 + this.renderMinZ; + double var44 = (double) par4 + this.renderMaxZ; + var5.addVertexWithUV(var36, var40, var44, var28, var34); + var5.addVertexWithUV(var36, var40, var42, var28, var32); + var5.addVertexWithUV(var38, var40, var42, var30, var32); + var5.addVertexWithUV(var38, var40, var44, var30, var34); + var5.setBrightness(par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4)); + var5.setColorOpaque_F(var10, var10, var10); + var27 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 1); + var28 = (double) var27.getMinU(); + var30 = (double) var27.getMaxU(); + var32 = (double) var27.getMinV(); + var34 = (double) var27.getMaxV(); + var36 = var28; + var38 = var30; + var40 = var32; + var42 = var32; + var44 = var28; + double var46 = var30; + double var48 = var34; + double var50 = var34; + + if (var7 == 0) { + var38 = var28; + var40 = var34; + var44 = var30; + var50 = var32; + } else if (var7 == 2) { + var36 = var30; + var42 = var34; + var46 = var28; + var48 = var32; + } else if (var7 == 3) { + var36 = var30; + var42 = var34; + var46 = var28; + var48 = var32; + var38 = var28; + var40 = var34; + var44 = var30; + var50 = var32; + } + + double var52 = (double) par2 + this.renderMinX; + double var54 = (double) par2 + this.renderMaxX; + double var56 = (double) par3 + this.renderMaxY; + double var58 = (double) par4 + this.renderMinZ; + double var60 = (double) par4 + this.renderMaxZ; + var5.addVertexWithUV(var54, var56, var60, var44, var48); + var5.addVertexWithUV(var54, var56, var58, var36, var40); + var5.addVertexWithUV(var52, var56, var58, var38, var42); + var5.addVertexWithUV(var52, var56, var60, var46, var50); + int var62 = Direction.directionToFacing[var7]; + + if (var8) { + var62 = Direction.directionToFacing[Direction.rotateOpposite[var7]]; + } + + byte var63 = 4; + + switch (var7) { + case 0: + var63 = 5; + break; + + case 1: + var63 = 3; + + case 2: + default: + break; + + case 3: + var63 = 2; + } + + if (var62 != 2 && (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3, par4 - 1, 2))) { + var5.setBrightness(this.renderMinZ > 0.0D ? var25 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 - 1)); + var5.setColorOpaque_F(var11, var11, var11); + this.flipTexture = var63 == 2; + this.renderFaceZNeg(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 2)); + } + + if (var62 != 3 && (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3, par4 + 1, 3))) { + var5.setBrightness(this.renderMaxZ < 1.0D ? var25 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 + 1)); + var5.setColorOpaque_F(var11, var11, var11); + this.flipTexture = var63 == 3; + this.renderFaceZPos(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 3)); + } + + if (var62 != 4 && (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2 - 1, par3, par4, 4))) { + var5.setBrightness(this.renderMinZ > 0.0D ? var25 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4)); + var5.setColorOpaque_F(var12, var12, var12); + this.flipTexture = var63 == 4; + this.renderFaceXNeg(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 4)); + } + + if (var62 != 5 && (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2 + 1, par3, par4, 5))) { + var5.setBrightness(this.renderMaxZ < 1.0D ? var25 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4)); + var5.setColorOpaque_F(var12, var12, var12); + this.flipTexture = var63 == 5; + this.renderFaceXPos(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 5)); + } + + this.flipTexture = false; + return true; + } + + /** + * Render BlockBrewingStand + */ + private boolean renderBlockBrewingStand(BlockBrewingStand par1BlockBrewingStand, int par2, int par3, int par4) { + this.setRenderBounds(0.4375D, 0.0D, 0.4375D, 0.5625D, 0.875D, 0.5625D); + this.renderStandardBlock(par1BlockBrewingStand, par2, par3, par4); + this.setOverrideBlockTexture(par1BlockBrewingStand.getBrewingStandIcon()); + this.setRenderBounds(0.5625D, 0.0D, 0.3125D, 0.9375D, 0.125D, 0.6875D); + this.renderStandardBlock(par1BlockBrewingStand, par2, par3, par4); + this.setRenderBounds(0.125D, 0.0D, 0.0625D, 0.5D, 0.125D, 0.4375D); + this.renderStandardBlock(par1BlockBrewingStand, par2, par3, par4); + this.setRenderBounds(0.125D, 0.0D, 0.5625D, 0.5D, 0.125D, 0.9375D); + this.renderStandardBlock(par1BlockBrewingStand, par2, par3, par4); + this.clearOverrideBlockTexture(); + Tessellator var5 = Tessellator.instance; + var5.setBrightness(par1BlockBrewingStand.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + float var6 = 1.0F; + int var7 = par1BlockBrewingStand.colorMultiplier(this.blockAccess, par2, par3, par4); + float var8 = (float) (var7 >> 16 & 255) / 255.0F; + float var9 = (float) (var7 >> 8 & 255) / 255.0F; + float var10 = (float) (var7 & 255) / 255.0F; + + if (EntityRenderer.anaglyphEnable) { + float var11 = (var8 * 30.0F + var9 * 59.0F + var10 * 11.0F) / 100.0F; + float var12 = (var8 * 30.0F + var9 * 70.0F) / 100.0F; + float var13 = (var8 * 30.0F + var10 * 70.0F) / 100.0F; + var8 = var11; + var9 = var12; + var10 = var13; + } + + var5.setColorOpaque_F(var6 * var8, var6 * var9, var6 * var10); + Icon var32 = this.getBlockIconFromSideAndMetadata(par1BlockBrewingStand, 0, 0); + + if (this.hasOverrideBlockTexture()) { + var32 = this.overrideBlockTexture; + } + + double var33 = (double) var32.getMinV(); + double var14 = (double) var32.getMaxV(); + int var16 = this.blockAccess.getBlockMetadata(par2, par3, par4); + + for (int var17 = 0; var17 < 3; ++var17) { + double var18 = (double) var17 * Math.PI * 2.0D / 3.0D + (Math.PI / 2D); + double var20 = (double) var32.getInterpolatedU(8.0D); + double var22 = (double) var32.getMaxU(); + + if ((var16 & 1 << var17) != 0) { + var22 = (double) var32.getMinU(); + } + + double var24 = (double) par2 + 0.5D; + double var26 = (double) par2 + 0.5D + Math.sin(var18) * 8.0D / 16.0D; + double var28 = (double) par4 + 0.5D; + double var30 = (double) par4 + 0.5D + Math.cos(var18) * 8.0D / 16.0D; + var5.addVertexWithUV(var24, (double) (par3 + 1), var28, var20, var33); + var5.addVertexWithUV(var24, (double) (par3 + 0), var28, var20, var14); + var5.addVertexWithUV(var26, (double) (par3 + 0), var30, var22, var14); + var5.addVertexWithUV(var26, (double) (par3 + 1), var30, var22, var33); + var5.addVertexWithUV(var26, (double) (par3 + 1), var30, var22, var33); + var5.addVertexWithUV(var26, (double) (par3 + 0), var30, var22, var14); + var5.addVertexWithUV(var24, (double) (par3 + 0), var28, var20, var14); + var5.addVertexWithUV(var24, (double) (par3 + 1), var28, var20, var33); + } + + par1BlockBrewingStand.setBlockBoundsForItemRender(); + return true; + } + + /** + * Render block cauldron + */ + private boolean renderBlockCauldron(BlockCauldron par1BlockCauldron, int par2, int par3, int par4) { + this.renderStandardBlock(par1BlockCauldron, par2, par3, par4); + Tessellator var5 = Tessellator.instance; + var5.setBrightness(par1BlockCauldron.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + float var6 = 1.0F; + int var7 = par1BlockCauldron.colorMultiplier(this.blockAccess, par2, par3, par4); + float var8 = (float) (var7 >> 16 & 255) / 255.0F; + float var9 = (float) (var7 >> 8 & 255) / 255.0F; + float var10 = (float) (var7 & 255) / 255.0F; + float var12; + + if (EntityRenderer.anaglyphEnable) { + float var11 = (var8 * 30.0F + var9 * 59.0F + var10 * 11.0F) / 100.0F; + var12 = (var8 * 30.0F + var9 * 70.0F) / 100.0F; + float var13 = (var8 * 30.0F + var10 * 70.0F) / 100.0F; + var8 = var11; + var9 = var12; + var10 = var13; + } + + var5.setColorOpaque_F(var6 * var8, var6 * var9, var6 * var10); + Icon var16 = par1BlockCauldron.getBlockTextureFromSide(2); + var12 = 0.125F; + this.renderFaceXPos(par1BlockCauldron, (double) ((float) par2 - 1.0F + var12), (double) par3, (double) par4, var16); + this.renderFaceXNeg(par1BlockCauldron, (double) ((float) par2 + 1.0F - var12), (double) par3, (double) par4, var16); + this.renderFaceZPos(par1BlockCauldron, (double) par2, (double) par3, (double) ((float) par4 - 1.0F + var12), var16); + this.renderFaceZNeg(par1BlockCauldron, (double) par2, (double) par3, (double) ((float) par4 + 1.0F - var12), var16); + Icon var17 = BlockCauldron.func_94375_b("cauldron_inner"); + this.renderFaceYPos(par1BlockCauldron, (double) par2, (double) ((float) par3 - 1.0F + 0.25F), (double) par4, var17); + this.renderFaceYNeg(par1BlockCauldron, (double) par2, (double) ((float) par3 + 1.0F - 0.75F), (double) par4, var17); + int var14 = this.blockAccess.getBlockMetadata(par2, par3, par4); + + if (var14 > 0) { + Icon var15 = BlockFluid.func_94424_b("water"); + + if (var14 > 3) { + var14 = 3; + } + + this.renderFaceYPos(par1BlockCauldron, (double) par2, (double) ((float) par3 - 1.0F + (6.0F + (float) var14 * 3.0F) / 16.0F), (double) par4, var15); + } + + return true; + } + + /** + * Renders flower pot + */ + private boolean renderBlockFlowerpot(BlockFlowerPot par1BlockFlowerPot, int par2, int par3, int par4) { + this.renderStandardBlock(par1BlockFlowerPot, par2, par3, par4); + Tessellator var5 = Tessellator.instance; + var5.setBrightness(par1BlockFlowerPot.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + float var6 = 1.0F; + int var7 = par1BlockFlowerPot.colorMultiplier(this.blockAccess, par2, par3, par4); + Icon var8 = this.getBlockIconFromSide(par1BlockFlowerPot, 0); + float var9 = (float) (var7 >> 16 & 255) / 255.0F; + float var10 = (float) (var7 >> 8 & 255) / 255.0F; + float var11 = (float) (var7 & 255) / 255.0F; + float var12; + float var14; + + if (EntityRenderer.anaglyphEnable) { + var12 = (var9 * 30.0F + var10 * 59.0F + var11 * 11.0F) / 100.0F; + float var13 = (var9 * 30.0F + var10 * 70.0F) / 100.0F; + var14 = (var9 * 30.0F + var11 * 70.0F) / 100.0F; + var9 = var12; + var10 = var13; + var11 = var14; + } + + var5.setColorOpaque_F(var6 * var9, var6 * var10, var6 * var11); + var12 = 0.1865F; + this.renderFaceXPos(par1BlockFlowerPot, (double) ((float) par2 - 0.5F + var12), (double) par3, (double) par4, var8); + this.renderFaceXNeg(par1BlockFlowerPot, (double) ((float) par2 + 0.5F - var12), (double) par3, (double) par4, var8); + this.renderFaceZPos(par1BlockFlowerPot, (double) par2, (double) par3, (double) ((float) par4 - 0.5F + var12), var8); + this.renderFaceZNeg(par1BlockFlowerPot, (double) par2, (double) par3, (double) ((float) par4 + 0.5F - var12), var8); + this.renderFaceYPos(par1BlockFlowerPot, (double) par2, (double) ((float) par3 - 0.5F + var12 + 0.1875F), (double) par4, this.getBlockIcon(Block.dirt)); + int var19 = this.blockAccess.getBlockMetadata(par2, par3, par4); + + if (var19 != 0) { + var14 = 0.0F; + float var15 = 4.0F; + float var16 = 0.0F; + BlockFlower var17 = null; + + switch (var19) { + case 1: + var17 = Block.plantRed; + break; + + case 2: + var17 = Block.plantYellow; + + case 3: + case 4: + case 5: + case 6: + default: + break; + + case 7: + var17 = Block.mushroomRed; + break; + + case 8: + var17 = Block.mushroomBrown; + } + + var5.addTranslation(var14 / 16.0F, var15 / 16.0F, var16 / 16.0F); + + if (var17 != null) { + this.renderBlockByRenderType(var17, par2, par3, par4); + } else if (var19 == 9) { + this.renderAllFaces = true; + float var18 = 0.125F; + this.setRenderBounds((double) (0.5F - var18), 0.0D, (double) (0.5F - var18), (double) (0.5F + var18), 0.25D, (double) (0.5F + var18)); + this.renderStandardBlock(Block.cactus, par2, par3, par4); + this.setRenderBounds((double) (0.5F - var18), 0.25D, (double) (0.5F - var18), (double) (0.5F + var18), 0.5D, (double) (0.5F + var18)); + this.renderStandardBlock(Block.cactus, par2, par3, par4); + this.setRenderBounds((double) (0.5F - var18), 0.5D, (double) (0.5F - var18), (double) (0.5F + var18), 0.75D, (double) (0.5F + var18)); + this.renderStandardBlock(Block.cactus, par2, par3, par4); + this.renderAllFaces = false; + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + } else if (var19 == 3) { + this.drawCrossedSquares(Block.sapling, 0, (double) par2, (double) par3, (double) par4, 0.75F); + } else if (var19 == 5) { + this.drawCrossedSquares(Block.sapling, 2, (double) par2, (double) par3, (double) par4, 0.75F); + } else if (var19 == 4) { + this.drawCrossedSquares(Block.sapling, 1, (double) par2, (double) par3, (double) par4, 0.75F); + } else if (var19 == 6) { + this.drawCrossedSquares(Block.sapling, 3, (double) par2, (double) par3, (double) par4, 0.75F); + } else if (var19 == 11) { + var7 = Block.tallGrass.colorMultiplier(this.blockAccess, par2, par3, par4); + var9 = (float) (var7 >> 16 & 255) / 255.0F; + var10 = (float) (var7 >> 8 & 255) / 255.0F; + var11 = (float) (var7 & 255) / 255.0F; + var5.setColorOpaque_F(var6 * var9, var6 * var10, var6 * var11); + this.drawCrossedSquares(Block.tallGrass, 2, (double) par2, (double) par3, (double) par4, 0.75F); + } else if (var19 == 10) { + this.drawCrossedSquares(Block.deadBush, 2, (double) par2, (double) par3, (double) par4, 0.75F); + } + + var5.addTranslation(-var14 / 16.0F, -var15 / 16.0F, -var16 / 16.0F); + } + + return true; + } + + /** + * Renders anvil + */ + private boolean renderBlockAnvil(BlockAnvil par1BlockAnvil, int par2, int par3, int par4) { + return this.renderBlockAnvilMetadata(par1BlockAnvil, par2, par3, par4, this.blockAccess.getBlockMetadata(par2, par3, par4)); + } + + /** + * Renders anvil block with metadata + */ + public boolean renderBlockAnvilMetadata(BlockAnvil par1BlockAnvil, int par2, int par3, int par4, int par5) { + Tessellator var6 = Tessellator.instance; + var6.setBrightness(par1BlockAnvil.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + float var7 = 1.0F; + int var8 = par1BlockAnvil.colorMultiplier(this.blockAccess, par2, par3, par4); + float var9 = (float) (var8 >> 16 & 255) / 255.0F; + float var10 = (float) (var8 >> 8 & 255) / 255.0F; + float var11 = (float) (var8 & 255) / 255.0F; + + if (EntityRenderer.anaglyphEnable) { + float var12 = (var9 * 30.0F + var10 * 59.0F + var11 * 11.0F) / 100.0F; + float var13 = (var9 * 30.0F + var10 * 70.0F) / 100.0F; + float var14 = (var9 * 30.0F + var11 * 70.0F) / 100.0F; + var9 = var12; + var10 = var13; + var11 = var14; + } + + var6.setColorOpaque_F(var7 * var9, var7 * var10, var7 * var11); + return this.renderBlockAnvilOrient(par1BlockAnvil, par2, par3, par4, par5, false); + } + + /** + * Renders anvil block with orientation + */ + private boolean renderBlockAnvilOrient(BlockAnvil par1BlockAnvil, int par2, int par3, int par4, int par5, boolean par6) { + int var7 = par6 ? 0 : par5 & 3; + boolean var8 = false; + float var9 = 0.0F; + + switch (var7) { + case 0: + this.uvRotateSouth = 2; + this.uvRotateNorth = 1; + this.uvRotateTop = 3; + this.uvRotateBottom = 3; + break; + + case 1: + this.uvRotateEast = 1; + this.uvRotateWest = 2; + this.uvRotateTop = 2; + this.uvRotateBottom = 1; + var8 = true; + break; + + case 2: + this.uvRotateSouth = 1; + this.uvRotateNorth = 2; + break; + + case 3: + this.uvRotateEast = 2; + this.uvRotateWest = 1; + this.uvRotateTop = 1; + this.uvRotateBottom = 2; + var8 = true; + } + + var9 = this.renderBlockAnvilRotate(par1BlockAnvil, par2, par3, par4, 0, var9, 0.75F, 0.25F, 0.75F, var8, par6, par5); + var9 = this.renderBlockAnvilRotate(par1BlockAnvil, par2, par3, par4, 1, var9, 0.5F, 0.0625F, 0.625F, var8, par6, par5); + var9 = this.renderBlockAnvilRotate(par1BlockAnvil, par2, par3, par4, 2, var9, 0.25F, 0.3125F, 0.5F, var8, par6, par5); + this.renderBlockAnvilRotate(par1BlockAnvil, par2, par3, par4, 3, var9, 0.625F, 0.375F, 1.0F, var8, par6, par5); + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + this.uvRotateEast = 0; + this.uvRotateWest = 0; + this.uvRotateSouth = 0; + this.uvRotateNorth = 0; + this.uvRotateTop = 0; + this.uvRotateBottom = 0; + return true; + } + + /** + * Renders anvil block with rotation + */ + private float renderBlockAnvilRotate(BlockAnvil par1BlockAnvil, int par2, int par3, int par4, int par5, float par6, float par7, float par8, float par9, boolean par10, boolean par11, int par12) { + if (par10) { + float var13 = par7; + par7 = par9; + par9 = var13; + } + + par7 /= 2.0F; + par9 /= 2.0F; + par1BlockAnvil.field_82521_b = par5; + this.setRenderBounds((double) (0.5F - par7), (double) par6, (double) (0.5F - par9), (double) (0.5F + par7), (double) (par6 + par8), (double) (0.5F + par9)); + + if (par11) { + Tessellator var14 = Tessellator.instance; + var14.startDrawingQuads(); + var14.setNormal(0.0F, -1.0F, 0.0F); + this.renderFaceYNeg(par1BlockAnvil, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1BlockAnvil, 0, par12)); + var14.draw(); + var14.startDrawingQuads(); + var14.setNormal(0.0F, 1.0F, 0.0F); + this.renderFaceYPos(par1BlockAnvil, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1BlockAnvil, 1, par12)); + var14.draw(); + var14.startDrawingQuads(); + var14.setNormal(0.0F, 0.0F, -1.0F); + this.renderFaceZNeg(par1BlockAnvil, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1BlockAnvil, 2, par12)); + var14.draw(); + var14.startDrawingQuads(); + var14.setNormal(0.0F, 0.0F, 1.0F); + this.renderFaceZPos(par1BlockAnvil, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1BlockAnvil, 3, par12)); + var14.draw(); + var14.startDrawingQuads(); + var14.setNormal(-1.0F, 0.0F, 0.0F); + this.renderFaceXNeg(par1BlockAnvil, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1BlockAnvil, 4, par12)); + var14.draw(); + var14.startDrawingQuads(); + var14.setNormal(1.0F, 0.0F, 0.0F); + this.renderFaceXPos(par1BlockAnvil, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1BlockAnvil, 5, par12)); + var14.draw(); + } else { + this.renderStandardBlock(par1BlockAnvil, par2, par3, par4); + } + + return par6 + par8; + } + + /** + * Renders a torch block at the given coordinates + */ + public boolean renderBlockTorch(Block par1Block, int par2, int par3, int par4) { + int var5 = this.blockAccess.getBlockMetadata(par2, par3, par4); + Tessellator var6 = Tessellator.instance; + var6.setBrightness(par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + var6.setColorOpaque_F(1.0F, 1.0F, 1.0F); + double var7 = 0.4000000059604645D; + double var9 = 0.5D - var7; + double var11 = 0.20000000298023224D; + + if (var5 == 1) { + this.renderTorchAtAngle(par1Block, (double) par2 - var9, (double) par3 + var11, (double) par4, -var7, 0.0D, 0); + } else if (var5 == 2) { + this.renderTorchAtAngle(par1Block, (double) par2 + var9, (double) par3 + var11, (double) par4, var7, 0.0D, 0); + } else if (var5 == 3) { + this.renderTorchAtAngle(par1Block, (double) par2, (double) par3 + var11, (double) par4 - var9, 0.0D, -var7, 0); + } else if (var5 == 4) { + this.renderTorchAtAngle(par1Block, (double) par2, (double) par3 + var11, (double) par4 + var9, 0.0D, var7, 0); + } else { + this.renderTorchAtAngle(par1Block, (double) par2, (double) par3, (double) par4, 0.0D, 0.0D, 0); + } + + return true; + } + + /** + * render a redstone repeater at the given coordinates + */ + private boolean renderBlockRepeater(BlockRedstoneRepeater par1BlockRedstoneRepeater, int par2, int par3, int par4) { + int var5 = this.blockAccess.getBlockMetadata(par2, par3, par4); + int var6 = var5 & 3; + int var7 = (var5 & 12) >> 2; + Tessellator var8 = Tessellator.instance; + var8.setBrightness(par1BlockRedstoneRepeater.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + var8.setColorOpaque_F(1.0F, 1.0F, 1.0F); + double var9 = -0.1875D; + boolean var11 = par1BlockRedstoneRepeater.func_94476_e(this.blockAccess, par2, par3, par4, var5); + double var12 = 0.0D; + double var14 = 0.0D; + double var16 = 0.0D; + double var18 = 0.0D; + + switch (var6) { + case 0: + var18 = -0.3125D; + var14 = BlockRedstoneRepeater.repeaterTorchOffset[var7]; + break; + + case 1: + var16 = 0.3125D; + var12 = -BlockRedstoneRepeater.repeaterTorchOffset[var7]; + break; + + case 2: + var18 = 0.3125D; + var14 = -BlockRedstoneRepeater.repeaterTorchOffset[var7]; + break; + + case 3: + var16 = -0.3125D; + var12 = BlockRedstoneRepeater.repeaterTorchOffset[var7]; + } + + if (!var11) { + this.renderTorchAtAngle(par1BlockRedstoneRepeater, (double) par2 + var12, (double) par3 + var9, (double) par4 + var14, 0.0D, 0.0D, 0); + } else { + Icon var20 = this.getBlockIcon(Block.bedrock); + this.setOverrideBlockTexture(var20); + float var21 = 2.0F; + float var22 = 14.0F; + float var23 = 7.0F; + float var24 = 9.0F; + + switch (var6) { + case 1: + case 3: + var21 = 7.0F; + var22 = 9.0F; + var23 = 2.0F; + var24 = 14.0F; + + case 0: + case 2: + default: + this.setRenderBounds((double) (var21 / 16.0F + (float) var12), 0.125D, (double) (var23 / 16.0F + (float) var14), (double) (var22 / 16.0F + (float) var12), 0.25D, (double) (var24 / 16.0F + (float) var14)); + double var25 = (double) var20.getInterpolatedU((double) var21); + double var27 = (double) var20.getInterpolatedV((double) var23); + double var29 = (double) var20.getInterpolatedU((double) var22); + double var31 = (double) var20.getInterpolatedV((double) var24); + var8.addVertexWithUV((double) ((float) par2 + var21 / 16.0F) + var12, (double) ((float) par3 + 0.25F), (double) ((float) par4 + var23 / 16.0F) + var14, var25, var27); + var8.addVertexWithUV((double) ((float) par2 + var21 / 16.0F) + var12, (double) ((float) par3 + 0.25F), (double) ((float) par4 + var24 / 16.0F) + var14, var25, var31); + var8.addVertexWithUV((double) ((float) par2 + var22 / 16.0F) + var12, (double) ((float) par3 + 0.25F), (double) ((float) par4 + var24 / 16.0F) + var14, var29, var31); + var8.addVertexWithUV((double) ((float) par2 + var22 / 16.0F) + var12, (double) ((float) par3 + 0.25F), (double) ((float) par4 + var23 / 16.0F) + var14, var29, var27); + this.renderStandardBlock(par1BlockRedstoneRepeater, par2, par3, par4); + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 0.125D, 1.0D); + this.clearOverrideBlockTexture(); + } + } + + var8.setBrightness(par1BlockRedstoneRepeater.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + var8.setColorOpaque_F(1.0F, 1.0F, 1.0F); + this.renderTorchAtAngle(par1BlockRedstoneRepeater, (double) par2 + var16, (double) par3 + var9, (double) par4 + var18, 0.0D, 0.0D, 0); + this.renderBlockRedstoneLogic(par1BlockRedstoneRepeater, par2, par3, par4); + return true; + } + + private boolean renderBlockComparator(BlockComparator par1BlockComparator, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + var5.setBrightness(par1BlockComparator.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + var5.setColorOpaque_F(1.0F, 1.0F, 1.0F); + int var6 = this.blockAccess.getBlockMetadata(par2, par3, par4); + int var7 = var6 & 3; + double var8 = 0.0D; + double var10 = -0.1875D; + double var12 = 0.0D; + double var14 = 0.0D; + double var16 = 0.0D; + Icon var18; + + if (par1BlockComparator.func_94490_c(var6)) { + var18 = Block.torchRedstoneActive.getBlockTextureFromSide(0); + } else { + var10 -= 0.1875D; + var18 = Block.torchRedstoneIdle.getBlockTextureFromSide(0); + } + + switch (var7) { + case 0: + var12 = -0.3125D; + var16 = 1.0D; + break; + + case 1: + var8 = 0.3125D; + var14 = -1.0D; + break; + + case 2: + var12 = 0.3125D; + var16 = -1.0D; + break; + + case 3: + var8 = -0.3125D; + var14 = 1.0D; + } + + this.renderTorchAtAngle(par1BlockComparator, (double) par2 + 0.25D * var14 + 0.1875D * var16, (double) ((float) par3 - 0.1875F), (double) par4 + 0.25D * var16 + 0.1875D * var14, 0.0D, 0.0D, var6); + this.renderTorchAtAngle(par1BlockComparator, (double) par2 + 0.25D * var14 + -0.1875D * var16, (double) ((float) par3 - 0.1875F), (double) par4 + 0.25D * var16 + -0.1875D * var14, 0.0D, 0.0D, var6); + this.setOverrideBlockTexture(var18); + this.renderTorchAtAngle(par1BlockComparator, (double) par2 + var8, (double) par3 + var10, (double) par4 + var12, 0.0D, 0.0D, var6); + this.clearOverrideBlockTexture(); + this.renderBlockRedstoneLogicMetadata(par1BlockComparator, par2, par3, par4, var7); + return true; + } + + private boolean renderBlockRedstoneLogic(BlockRedstoneLogic par1BlockRedstoneLogic, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + this.renderBlockRedstoneLogicMetadata(par1BlockRedstoneLogic, par2, par3, par4, this.blockAccess.getBlockMetadata(par2, par3, par4) & 3); + return true; + } + + private void renderBlockRedstoneLogicMetadata(BlockRedstoneLogic par1BlockRedstoneLogic, int par2, int par3, int par4, int par5) { + this.renderStandardBlock(par1BlockRedstoneLogic, par2, par3, par4); + Tessellator var6 = Tessellator.instance; + var6.setBrightness(par1BlockRedstoneLogic.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + var6.setColorOpaque_F(1.0F, 1.0F, 1.0F); + int var7 = this.blockAccess.getBlockMetadata(par2, par3, par4); + Icon var8 = this.getBlockIconFromSideAndMetadata(par1BlockRedstoneLogic, 1, var7); + double var9 = (double) var8.getMinU(); + double var11 = (double) var8.getMaxU(); + double var13 = (double) var8.getMinV(); + double var15 = (double) var8.getMaxV(); + double var17 = 0.125D; + double var19 = (double) (par2 + 1); + double var21 = (double) (par2 + 1); + double var23 = (double) (par2 + 0); + double var25 = (double) (par2 + 0); + double var27 = (double) (par4 + 0); + double var29 = (double) (par4 + 1); + double var31 = (double) (par4 + 1); + double var33 = (double) (par4 + 0); + double var35 = (double) par3 + var17; + + if (par5 == 2) { + var19 = var21 = (double) (par2 + 0); + var23 = var25 = (double) (par2 + 1); + var27 = var33 = (double) (par4 + 1); + var29 = var31 = (double) (par4 + 0); + } else if (par5 == 3) { + var19 = var25 = (double) (par2 + 0); + var21 = var23 = (double) (par2 + 1); + var27 = var29 = (double) (par4 + 0); + var31 = var33 = (double) (par4 + 1); + } else if (par5 == 1) { + var19 = var25 = (double) (par2 + 1); + var21 = var23 = (double) (par2 + 0); + var27 = var29 = (double) (par4 + 1); + var31 = var33 = (double) (par4 + 0); + } + + var6.addVertexWithUV(var25, var35, var33, var9, var13); + var6.addVertexWithUV(var23, var35, var31, var9, var15); + var6.addVertexWithUV(var21, var35, var29, var11, var15); + var6.addVertexWithUV(var19, var35, var27, var11, var13); + } + + /** + * Render all faces of the piston base + */ + public void renderPistonBaseAllFaces(Block par1Block, int par2, int par3, int par4) { + this.renderAllFaces = true; + this.renderPistonBase(par1Block, par2, par3, par4, true); + this.renderAllFaces = false; + } + + /** + * renders a block as a piston base + */ + private boolean renderPistonBase(Block par1Block, int par2, int par3, int par4, boolean par5) { + int var6 = this.blockAccess.getBlockMetadata(par2, par3, par4); + boolean var7 = par5 || (var6 & 8) != 0; + int var8 = BlockPistonBase.getOrientation(var6); + + if (var7) { + switch (var8) { + case 0: + this.uvRotateEast = 3; + this.uvRotateWest = 3; + this.uvRotateSouth = 3; + this.uvRotateNorth = 3; + this.setRenderBounds(0.0D, 0.25D, 0.0D, 1.0D, 1.0D, 1.0D); + break; + + case 1: + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 0.75D, 1.0D); + break; + + case 2: + this.uvRotateSouth = 1; + this.uvRotateNorth = 2; + this.setRenderBounds(0.0D, 0.0D, 0.25D, 1.0D, 1.0D, 1.0D); + break; + + case 3: + this.uvRotateSouth = 2; + this.uvRotateNorth = 1; + this.uvRotateTop = 3; + this.uvRotateBottom = 3; + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.75D); + break; + + case 4: + this.uvRotateEast = 1; + this.uvRotateWest = 2; + this.uvRotateTop = 2; + this.uvRotateBottom = 1; + this.setRenderBounds(0.25D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + break; + + case 5: + this.uvRotateEast = 2; + this.uvRotateWest = 1; + this.uvRotateTop = 1; + this.uvRotateBottom = 2; + this.setRenderBounds(0.0D, 0.0D, 0.0D, 0.75D, 1.0D, 1.0D); + } + + ((BlockPistonBase) par1Block).func_96479_b((float) this.renderMinX, (float) this.renderMinY, (float) this.renderMinZ, (float) this.renderMaxX, (float) this.renderMaxY, (float) this.renderMaxZ); + this.renderStandardBlock(par1Block, par2, par3, par4); + this.uvRotateEast = 0; + this.uvRotateWest = 0; + this.uvRotateSouth = 0; + this.uvRotateNorth = 0; + this.uvRotateTop = 0; + this.uvRotateBottom = 0; + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + ((BlockPistonBase) par1Block).func_96479_b((float) this.renderMinX, (float) this.renderMinY, (float) this.renderMinZ, (float) this.renderMaxX, (float) this.renderMaxY, (float) this.renderMaxZ); + } else { + switch (var8) { + case 0: + this.uvRotateEast = 3; + this.uvRotateWest = 3; + this.uvRotateSouth = 3; + this.uvRotateNorth = 3; + + case 1: + default: + break; + + case 2: + this.uvRotateSouth = 1; + this.uvRotateNorth = 2; + break; + + case 3: + this.uvRotateSouth = 2; + this.uvRotateNorth = 1; + this.uvRotateTop = 3; + this.uvRotateBottom = 3; + break; + + case 4: + this.uvRotateEast = 1; + this.uvRotateWest = 2; + this.uvRotateTop = 2; + this.uvRotateBottom = 1; + break; + + case 5: + this.uvRotateEast = 2; + this.uvRotateWest = 1; + this.uvRotateTop = 1; + this.uvRotateBottom = 2; + } + + this.renderStandardBlock(par1Block, par2, par3, par4); + this.uvRotateEast = 0; + this.uvRotateWest = 0; + this.uvRotateSouth = 0; + this.uvRotateNorth = 0; + this.uvRotateTop = 0; + this.uvRotateBottom = 0; + } + + return true; + } + + /** + * Render piston rod up/down + */ + private void renderPistonRodUD(double par1, double par3, double par5, double par7, double par9, double par11, float par13, double par14) { + Icon var16 = BlockPistonBase.func_94496_b("piston_side"); + + if (this.hasOverrideBlockTexture()) { + var16 = this.overrideBlockTexture; + } + + Tessellator var17 = Tessellator.instance; + double var18 = (double) var16.getMinU(); + double var20 = (double) var16.getMinV(); + double var22 = (double) var16.getInterpolatedU(par14); + double var24 = (double) var16.getInterpolatedV(4.0D); + var17.setColorOpaque_F(par13, par13, par13); + var17.addVertexWithUV(par1, par7, par9, var22, var20); + var17.addVertexWithUV(par1, par5, par9, var18, var20); + var17.addVertexWithUV(par3, par5, par11, var18, var24); + var17.addVertexWithUV(par3, par7, par11, var22, var24); + } + + /** + * Render piston rod south/north + */ + private void renderPistonRodSN(double par1, double par3, double par5, double par7, double par9, double par11, float par13, double par14) { + Icon var16 = BlockPistonBase.func_94496_b("piston_side"); + + if (this.hasOverrideBlockTexture()) { + var16 = this.overrideBlockTexture; + } + + Tessellator var17 = Tessellator.instance; + double var18 = (double) var16.getMinU(); + double var20 = (double) var16.getMinV(); + double var22 = (double) var16.getInterpolatedU(par14); + double var24 = (double) var16.getInterpolatedV(4.0D); + var17.setColorOpaque_F(par13, par13, par13); + var17.addVertexWithUV(par1, par5, par11, var22, var20); + var17.addVertexWithUV(par1, par5, par9, var18, var20); + var17.addVertexWithUV(par3, par7, par9, var18, var24); + var17.addVertexWithUV(par3, par7, par11, var22, var24); + } + + /** + * Render piston rod east/west + */ + private void renderPistonRodEW(double par1, double par3, double par5, double par7, double par9, double par11, float par13, double par14) { + Icon var16 = BlockPistonBase.func_94496_b("piston_side"); + + if (this.hasOverrideBlockTexture()) { + var16 = this.overrideBlockTexture; + } + + Tessellator var17 = Tessellator.instance; + double var18 = (double) var16.getMinU(); + double var20 = (double) var16.getMinV(); + double var22 = (double) var16.getInterpolatedU(par14); + double var24 = (double) var16.getInterpolatedV(4.0D); + var17.setColorOpaque_F(par13, par13, par13); + var17.addVertexWithUV(par3, par5, par9, var22, var20); + var17.addVertexWithUV(par1, par5, par9, var18, var20); + var17.addVertexWithUV(par1, par7, par11, var18, var24); + var17.addVertexWithUV(par3, par7, par11, var22, var24); + } + + /** + * Render all faces of the piston extension + */ + public void renderPistonExtensionAllFaces(Block par1Block, int par2, int par3, int par4, boolean par5) { + this.renderAllFaces = true; + this.renderPistonExtension(par1Block, par2, par3, par4, par5); + this.renderAllFaces = false; + } + + /** + * renders the pushing part of a piston + */ + private boolean renderPistonExtension(Block par1Block, int par2, int par3, int par4, boolean par5) { + int var6 = this.blockAccess.getBlockMetadata(par2, par3, par4); + int var7 = BlockPistonExtension.getDirectionMeta(var6); + float var11 = par1Block.getBlockBrightness(this.blockAccess, par2, par3, par4); + float var12 = par5 ? 1.0F : 0.5F; + double var13 = par5 ? 16.0D : 8.0D; + + switch (var7) { + case 0: + this.uvRotateEast = 3; + this.uvRotateWest = 3; + this.uvRotateSouth = 3; + this.uvRotateNorth = 3; + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 0.25D, 1.0D); + this.renderStandardBlock(par1Block, par2, par3, par4); + this.renderPistonRodUD((double) ((float) par2 + 0.375F), (double) ((float) par2 + 0.625F), (double) ((float) par3 + 0.25F), (double) ((float) par3 + 0.25F + var12), (double) ((float) par4 + 0.625F), + (double) ((float) par4 + 0.625F), var11 * 0.8F, var13); + this.renderPistonRodUD((double) ((float) par2 + 0.625F), (double) ((float) par2 + 0.375F), (double) ((float) par3 + 0.25F), (double) ((float) par3 + 0.25F + var12), (double) ((float) par4 + 0.375F), + (double) ((float) par4 + 0.375F), var11 * 0.8F, var13); + this.renderPistonRodUD((double) ((float) par2 + 0.375F), (double) ((float) par2 + 0.375F), (double) ((float) par3 + 0.25F), (double) ((float) par3 + 0.25F + var12), (double) ((float) par4 + 0.375F), + (double) ((float) par4 + 0.625F), var11 * 0.6F, var13); + this.renderPistonRodUD((double) ((float) par2 + 0.625F), (double) ((float) par2 + 0.625F), (double) ((float) par3 + 0.25F), (double) ((float) par3 + 0.25F + var12), (double) ((float) par4 + 0.625F), + (double) ((float) par4 + 0.375F), var11 * 0.6F, var13); + break; + + case 1: + this.setRenderBounds(0.0D, 0.75D, 0.0D, 1.0D, 1.0D, 1.0D); + this.renderStandardBlock(par1Block, par2, par3, par4); + this.renderPistonRodUD((double) ((float) par2 + 0.375F), (double) ((float) par2 + 0.625F), (double) ((float) par3 - 0.25F + 1.0F - var12), (double) ((float) par3 - 0.25F + 1.0F), (double) ((float) par4 + 0.625F), + (double) ((float) par4 + 0.625F), var11 * 0.8F, var13); + this.renderPistonRodUD((double) ((float) par2 + 0.625F), (double) ((float) par2 + 0.375F), (double) ((float) par3 - 0.25F + 1.0F - var12), (double) ((float) par3 - 0.25F + 1.0F), (double) ((float) par4 + 0.375F), + (double) ((float) par4 + 0.375F), var11 * 0.8F, var13); + this.renderPistonRodUD((double) ((float) par2 + 0.375F), (double) ((float) par2 + 0.375F), (double) ((float) par3 - 0.25F + 1.0F - var12), (double) ((float) par3 - 0.25F + 1.0F), (double) ((float) par4 + 0.375F), + (double) ((float) par4 + 0.625F), var11 * 0.6F, var13); + this.renderPistonRodUD((double) ((float) par2 + 0.625F), (double) ((float) par2 + 0.625F), (double) ((float) par3 - 0.25F + 1.0F - var12), (double) ((float) par3 - 0.25F + 1.0F), (double) ((float) par4 + 0.625F), + (double) ((float) par4 + 0.375F), var11 * 0.6F, var13); + break; + + case 2: + this.uvRotateSouth = 1; + this.uvRotateNorth = 2; + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.25D); + this.renderStandardBlock(par1Block, par2, par3, par4); + this.renderPistonRodSN((double) ((float) par2 + 0.375F), (double) ((float) par2 + 0.375F), (double) ((float) par3 + 0.625F), (double) ((float) par3 + 0.375F), (double) ((float) par4 + 0.25F), + (double) ((float) par4 + 0.25F + var12), var11 * 0.6F, var13); + this.renderPistonRodSN((double) ((float) par2 + 0.625F), (double) ((float) par2 + 0.625F), (double) ((float) par3 + 0.375F), (double) ((float) par3 + 0.625F), (double) ((float) par4 + 0.25F), + (double) ((float) par4 + 0.25F + var12), var11 * 0.6F, var13); + this.renderPistonRodSN((double) ((float) par2 + 0.375F), (double) ((float) par2 + 0.625F), (double) ((float) par3 + 0.375F), (double) ((float) par3 + 0.375F), (double) ((float) par4 + 0.25F), + (double) ((float) par4 + 0.25F + var12), var11 * 0.5F, var13); + this.renderPistonRodSN((double) ((float) par2 + 0.625F), (double) ((float) par2 + 0.375F), (double) ((float) par3 + 0.625F), (double) ((float) par3 + 0.625F), (double) ((float) par4 + 0.25F), + (double) ((float) par4 + 0.25F + var12), var11, var13); + break; + + case 3: + this.uvRotateSouth = 2; + this.uvRotateNorth = 1; + this.uvRotateTop = 3; + this.uvRotateBottom = 3; + this.setRenderBounds(0.0D, 0.0D, 0.75D, 1.0D, 1.0D, 1.0D); + this.renderStandardBlock(par1Block, par2, par3, par4); + this.renderPistonRodSN((double) ((float) par2 + 0.375F), (double) ((float) par2 + 0.375F), (double) ((float) par3 + 0.625F), (double) ((float) par3 + 0.375F), (double) ((float) par4 - 0.25F + 1.0F - var12), + (double) ((float) par4 - 0.25F + 1.0F), var11 * 0.6F, var13); + this.renderPistonRodSN((double) ((float) par2 + 0.625F), (double) ((float) par2 + 0.625F), (double) ((float) par3 + 0.375F), (double) ((float) par3 + 0.625F), (double) ((float) par4 - 0.25F + 1.0F - var12), + (double) ((float) par4 - 0.25F + 1.0F), var11 * 0.6F, var13); + this.renderPistonRodSN((double) ((float) par2 + 0.375F), (double) ((float) par2 + 0.625F), (double) ((float) par3 + 0.375F), (double) ((float) par3 + 0.375F), (double) ((float) par4 - 0.25F + 1.0F - var12), + (double) ((float) par4 - 0.25F + 1.0F), var11 * 0.5F, var13); + this.renderPistonRodSN((double) ((float) par2 + 0.625F), (double) ((float) par2 + 0.375F), (double) ((float) par3 + 0.625F), (double) ((float) par3 + 0.625F), (double) ((float) par4 - 0.25F + 1.0F - var12), + (double) ((float) par4 - 0.25F + 1.0F), var11, var13); + break; + + case 4: + this.uvRotateEast = 1; + this.uvRotateWest = 2; + this.uvRotateTop = 2; + this.uvRotateBottom = 1; + this.setRenderBounds(0.0D, 0.0D, 0.0D, 0.25D, 1.0D, 1.0D); + this.renderStandardBlock(par1Block, par2, par3, par4); + this.renderPistonRodEW((double) ((float) par2 + 0.25F), (double) ((float) par2 + 0.25F + var12), (double) ((float) par3 + 0.375F), (double) ((float) par3 + 0.375F), (double) ((float) par4 + 0.625F), + (double) ((float) par4 + 0.375F), var11 * 0.5F, var13); + this.renderPistonRodEW((double) ((float) par2 + 0.25F), (double) ((float) par2 + 0.25F + var12), (double) ((float) par3 + 0.625F), (double) ((float) par3 + 0.625F), (double) ((float) par4 + 0.375F), + (double) ((float) par4 + 0.625F), var11, var13); + this.renderPistonRodEW((double) ((float) par2 + 0.25F), (double) ((float) par2 + 0.25F + var12), (double) ((float) par3 + 0.375F), (double) ((float) par3 + 0.625F), (double) ((float) par4 + 0.375F), + (double) ((float) par4 + 0.375F), var11 * 0.6F, var13); + this.renderPistonRodEW((double) ((float) par2 + 0.25F), (double) ((float) par2 + 0.25F + var12), (double) ((float) par3 + 0.625F), (double) ((float) par3 + 0.375F), (double) ((float) par4 + 0.625F), + (double) ((float) par4 + 0.625F), var11 * 0.6F, var13); + break; + + case 5: + this.uvRotateEast = 2; + this.uvRotateWest = 1; + this.uvRotateTop = 1; + this.uvRotateBottom = 2; + this.setRenderBounds(0.75D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + this.renderStandardBlock(par1Block, par2, par3, par4); + this.renderPistonRodEW((double) ((float) par2 - 0.25F + 1.0F - var12), (double) ((float) par2 - 0.25F + 1.0F), (double) ((float) par3 + 0.375F), (double) ((float) par3 + 0.375F), (double) ((float) par4 + 0.625F), + (double) ((float) par4 + 0.375F), var11 * 0.5F, var13); + this.renderPistonRodEW((double) ((float) par2 - 0.25F + 1.0F - var12), (double) ((float) par2 - 0.25F + 1.0F), (double) ((float) par3 + 0.625F), (double) ((float) par3 + 0.625F), (double) ((float) par4 + 0.375F), + (double) ((float) par4 + 0.625F), var11, var13); + this.renderPistonRodEW((double) ((float) par2 - 0.25F + 1.0F - var12), (double) ((float) par2 - 0.25F + 1.0F), (double) ((float) par3 + 0.375F), (double) ((float) par3 + 0.625F), (double) ((float) par4 + 0.375F), + (double) ((float) par4 + 0.375F), var11 * 0.6F, var13); + this.renderPistonRodEW((double) ((float) par2 - 0.25F + 1.0F - var12), (double) ((float) par2 - 0.25F + 1.0F), (double) ((float) par3 + 0.625F), (double) ((float) par3 + 0.375F), (double) ((float) par4 + 0.625F), + (double) ((float) par4 + 0.625F), var11 * 0.6F, var13); + } + + this.uvRotateEast = 0; + this.uvRotateWest = 0; + this.uvRotateSouth = 0; + this.uvRotateNorth = 0; + this.uvRotateTop = 0; + this.uvRotateBottom = 0; + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + return true; + } + + /** + * Renders a lever block at the given coordinates + */ + public boolean renderBlockLever(Block par1Block, int par2, int par3, int par4) { + int var5 = this.blockAccess.getBlockMetadata(par2, par3, par4); + int var6 = var5 & 7; + boolean var7 = (var5 & 8) > 0; + Tessellator var8 = Tessellator.instance; + boolean var9 = this.hasOverrideBlockTexture(); + + if (!var9) { + this.setOverrideBlockTexture(this.getBlockIcon(Block.cobblestone)); + } + + float var10 = 0.25F; + float var11 = 0.1875F; + float var12 = 0.1875F; + + if (var6 == 5) { + this.setRenderBounds((double) (0.5F - var11), 0.0D, (double) (0.5F - var10), (double) (0.5F + var11), (double) var12, (double) (0.5F + var10)); + } else if (var6 == 6) { + this.setRenderBounds((double) (0.5F - var10), 0.0D, (double) (0.5F - var11), (double) (0.5F + var10), (double) var12, (double) (0.5F + var11)); + } else if (var6 == 4) { + this.setRenderBounds((double) (0.5F - var11), (double) (0.5F - var10), (double) (1.0F - var12), (double) (0.5F + var11), (double) (0.5F + var10), 1.0D); + } else if (var6 == 3) { + this.setRenderBounds((double) (0.5F - var11), (double) (0.5F - var10), 0.0D, (double) (0.5F + var11), (double) (0.5F + var10), (double) var12); + } else if (var6 == 2) { + this.setRenderBounds((double) (1.0F - var12), (double) (0.5F - var10), (double) (0.5F - var11), 1.0D, (double) (0.5F + var10), (double) (0.5F + var11)); + } else if (var6 == 1) { + this.setRenderBounds(0.0D, (double) (0.5F - var10), (double) (0.5F - var11), (double) var12, (double) (0.5F + var10), (double) (0.5F + var11)); + } else if (var6 == 0) { + this.setRenderBounds((double) (0.5F - var10), (double) (1.0F - var12), (double) (0.5F - var11), (double) (0.5F + var10), 1.0D, (double) (0.5F + var11)); + } else if (var6 == 7) { + this.setRenderBounds((double) (0.5F - var11), (double) (1.0F - var12), (double) (0.5F - var10), (double) (0.5F + var11), 1.0D, (double) (0.5F + var10)); + } + + this.renderStandardBlock(par1Block, par2, par3, par4); + + if (!var9) { + this.clearOverrideBlockTexture(); + } + + var8.setBrightness(par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + float var13 = 1.0F; + + if (Block.lightValue[par1Block.blockID] > 0) { + var13 = 1.0F; + } + + var8.setColorOpaque_F(var13, var13, var13); + Icon var14 = this.getBlockIconFromSide(par1Block, 0); + + if (this.hasOverrideBlockTexture()) { + var14 = this.overrideBlockTexture; + } + + double var15 = (double) var14.getMinU(); + double var17 = (double) var14.getMinV(); + double var19 = (double) var14.getMaxU(); + double var21 = (double) var14.getMaxV(); + Vec3[] var23 = new Vec3[8]; + float var24 = 0.0625F; + float var25 = 0.0625F; + float var26 = 0.625F; + var23[0] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) (-var24), 0.0D, (double) (-var25)); + var23[1] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) var24, 0.0D, (double) (-var25)); + var23[2] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) var24, 0.0D, (double) var25); + var23[3] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) (-var24), 0.0D, (double) var25); + var23[4] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) (-var24), (double) var26, (double) (-var25)); + var23[5] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) var24, (double) var26, (double) (-var25)); + var23[6] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) var24, (double) var26, (double) var25); + var23[7] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) (-var24), (double) var26, (double) var25); + + for (int var27 = 0; var27 < 8; ++var27) { + if (var7) { + var23[var27].zCoord -= 0.0625D; + var23[var27].rotateAroundX(((float) Math.PI * 2F / 9F)); + } else { + var23[var27].zCoord += 0.0625D; + var23[var27].rotateAroundX(-((float) Math.PI * 2F / 9F)); + } + + if (var6 == 0 || var6 == 7) { + var23[var27].rotateAroundZ((float) Math.PI); + } + + if (var6 == 6 || var6 == 0) { + var23[var27].rotateAroundY(((float) Math.PI / 2F)); + } + + if (var6 > 0 && var6 < 5) { + var23[var27].yCoord -= 0.375D; + var23[var27].rotateAroundX(((float) Math.PI / 2F)); + + if (var6 == 4) { + var23[var27].rotateAroundY(0.0F); + } + + if (var6 == 3) { + var23[var27].rotateAroundY((float) Math.PI); + } + + if (var6 == 2) { + var23[var27].rotateAroundY(((float) Math.PI / 2F)); + } + + if (var6 == 1) { + var23[var27].rotateAroundY(-((float) Math.PI / 2F)); + } + + var23[var27].xCoord += (double) par2 + 0.5D; + var23[var27].yCoord += (double) ((float) par3 + 0.5F); + var23[var27].zCoord += (double) par4 + 0.5D; + } else if (var6 != 0 && var6 != 7) { + var23[var27].xCoord += (double) par2 + 0.5D; + var23[var27].yCoord += (double) ((float) par3 + 0.125F); + var23[var27].zCoord += (double) par4 + 0.5D; + } else { + var23[var27].xCoord += (double) par2 + 0.5D; + var23[var27].yCoord += (double) ((float) par3 + 0.875F); + var23[var27].zCoord += (double) par4 + 0.5D; + } + } + + Vec3 var32 = null; + Vec3 var28 = null; + Vec3 var29 = null; + Vec3 var30 = null; + + for (int var31 = 0; var31 < 6; ++var31) { + if (var31 == 0) { + var15 = (double) var14.getInterpolatedU(7.0D); + var17 = (double) var14.getInterpolatedV(6.0D); + var19 = (double) var14.getInterpolatedU(9.0D); + var21 = (double) var14.getInterpolatedV(8.0D); + } else if (var31 == 2) { + var15 = (double) var14.getInterpolatedU(7.0D); + var17 = (double) var14.getInterpolatedV(6.0D); + var19 = (double) var14.getInterpolatedU(9.0D); + var21 = (double) var14.getMaxV(); + } + + if (var31 == 0) { + var32 = var23[0]; + var28 = var23[1]; + var29 = var23[2]; + var30 = var23[3]; + } else if (var31 == 1) { + var32 = var23[7]; + var28 = var23[6]; + var29 = var23[5]; + var30 = var23[4]; + } else if (var31 == 2) { + var32 = var23[1]; + var28 = var23[0]; + var29 = var23[4]; + var30 = var23[5]; + } else if (var31 == 3) { + var32 = var23[2]; + var28 = var23[1]; + var29 = var23[5]; + var30 = var23[6]; + } else if (var31 == 4) { + var32 = var23[3]; + var28 = var23[2]; + var29 = var23[6]; + var30 = var23[7]; + } else if (var31 == 5) { + var32 = var23[0]; + var28 = var23[3]; + var29 = var23[7]; + var30 = var23[4]; + } + + var8.addVertexWithUV(var32.xCoord, var32.yCoord, var32.zCoord, var15, var21); + var8.addVertexWithUV(var28.xCoord, var28.yCoord, var28.zCoord, var19, var21); + var8.addVertexWithUV(var29.xCoord, var29.yCoord, var29.zCoord, var19, var17); + var8.addVertexWithUV(var30.xCoord, var30.yCoord, var30.zCoord, var15, var17); + } + + return true; + } + + /** + * Renders a trip wire source block at the given coordinates + */ + public boolean renderBlockTripWireSource(Block par1Block, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + int var6 = this.blockAccess.getBlockMetadata(par2, par3, par4); + int var7 = var6 & 3; + boolean var8 = (var6 & 4) == 4; + boolean var9 = (var6 & 8) == 8; + boolean var10 = !this.blockAccess.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4); + boolean var11 = this.hasOverrideBlockTexture(); + + if (!var11) { + this.setOverrideBlockTexture(this.getBlockIcon(Block.planks)); + } + + float var12 = 0.25F; + float var13 = 0.125F; + float var14 = 0.125F; + float var15 = 0.3F - var12; + float var16 = 0.3F + var12; + + if (var7 == 2) { + this.setRenderBounds((double) (0.5F - var13), (double) var15, (double) (1.0F - var14), (double) (0.5F + var13), (double) var16, 1.0D); + } else if (var7 == 0) { + this.setRenderBounds((double) (0.5F - var13), (double) var15, 0.0D, (double) (0.5F + var13), (double) var16, (double) var14); + } else if (var7 == 1) { + this.setRenderBounds((double) (1.0F - var14), (double) var15, (double) (0.5F - var13), 1.0D, (double) var16, (double) (0.5F + var13)); + } else if (var7 == 3) { + this.setRenderBounds(0.0D, (double) var15, (double) (0.5F - var13), (double) var14, (double) var16, (double) (0.5F + var13)); + } + + this.renderStandardBlock(par1Block, par2, par3, par4); + + if (!var11) { + this.clearOverrideBlockTexture(); + } + + var5.setBrightness(par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + float var17 = 1.0F; + + if (Block.lightValue[par1Block.blockID] > 0) { + var17 = 1.0F; + } + + var5.setColorOpaque_F(var17, var17, var17); + Icon var18 = this.getBlockIconFromSide(par1Block, 0); + + if (this.hasOverrideBlockTexture()) { + var18 = this.overrideBlockTexture; + } + + double var19 = (double) var18.getMinU(); + double var21 = (double) var18.getMinV(); + double var23 = (double) var18.getMaxU(); + double var25 = (double) var18.getMaxV(); + Vec3[] var27 = new Vec3[8]; + float var28 = 0.046875F; + float var29 = 0.046875F; + float var30 = 0.3125F; + var27[0] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) (-var28), 0.0D, (double) (-var29)); + var27[1] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) var28, 0.0D, (double) (-var29)); + var27[2] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) var28, 0.0D, (double) var29); + var27[3] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) (-var28), 0.0D, (double) var29); + var27[4] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) (-var28), (double) var30, (double) (-var29)); + var27[5] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) var28, (double) var30, (double) (-var29)); + var27[6] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) var28, (double) var30, (double) var29); + var27[7] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) (-var28), (double) var30, (double) var29); + + for (int var31 = 0; var31 < 8; ++var31) { + var27[var31].zCoord += 0.0625D; + + if (var9) { + var27[var31].rotateAroundX(0.5235988F); + var27[var31].yCoord -= 0.4375D; + } else if (var8) { + var27[var31].rotateAroundX(0.08726647F); + var27[var31].yCoord -= 0.4375D; + } else { + var27[var31].rotateAroundX(-((float) Math.PI * 2F / 9F)); + var27[var31].yCoord -= 0.375D; + } + + var27[var31].rotateAroundX(((float) Math.PI / 2F)); + + if (var7 == 2) { + var27[var31].rotateAroundY(0.0F); + } + + if (var7 == 0) { + var27[var31].rotateAroundY((float) Math.PI); + } + + if (var7 == 1) { + var27[var31].rotateAroundY(((float) Math.PI / 2F)); + } + + if (var7 == 3) { + var27[var31].rotateAroundY(-((float) Math.PI / 2F)); + } + + var27[var31].xCoord += (double) par2 + 0.5D; + var27[var31].yCoord += (double) ((float) par3 + 0.3125F); + var27[var31].zCoord += (double) par4 + 0.5D; + } + + Vec3 var62 = null; + Vec3 var32 = null; + Vec3 var33 = null; + Vec3 var34 = null; + byte var35 = 7; + byte var36 = 9; + byte var37 = 9; + byte var38 = 16; + + for (int var39 = 0; var39 < 6; ++var39) { + if (var39 == 0) { + var62 = var27[0]; + var32 = var27[1]; + var33 = var27[2]; + var34 = var27[3]; + var19 = (double) var18.getInterpolatedU((double) var35); + var21 = (double) var18.getInterpolatedV((double) var37); + var23 = (double) var18.getInterpolatedU((double) var36); + var25 = (double) var18.getInterpolatedV((double) (var37 + 2)); + } else if (var39 == 1) { + var62 = var27[7]; + var32 = var27[6]; + var33 = var27[5]; + var34 = var27[4]; + } else if (var39 == 2) { + var62 = var27[1]; + var32 = var27[0]; + var33 = var27[4]; + var34 = var27[5]; + var19 = (double) var18.getInterpolatedU((double) var35); + var21 = (double) var18.getInterpolatedV((double) var37); + var23 = (double) var18.getInterpolatedU((double) var36); + var25 = (double) var18.getInterpolatedV((double) var38); + } else if (var39 == 3) { + var62 = var27[2]; + var32 = var27[1]; + var33 = var27[5]; + var34 = var27[6]; + } else if (var39 == 4) { + var62 = var27[3]; + var32 = var27[2]; + var33 = var27[6]; + var34 = var27[7]; + } else if (var39 == 5) { + var62 = var27[0]; + var32 = var27[3]; + var33 = var27[7]; + var34 = var27[4]; + } + + var5.addVertexWithUV(var62.xCoord, var62.yCoord, var62.zCoord, var19, var25); + var5.addVertexWithUV(var32.xCoord, var32.yCoord, var32.zCoord, var23, var25); + var5.addVertexWithUV(var33.xCoord, var33.yCoord, var33.zCoord, var23, var21); + var5.addVertexWithUV(var34.xCoord, var34.yCoord, var34.zCoord, var19, var21); + } + + float var63 = 0.09375F; + float var40 = 0.09375F; + float var41 = 0.03125F; + var27[0] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) (-var63), 0.0D, (double) (-var40)); + var27[1] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) var63, 0.0D, (double) (-var40)); + var27[2] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) var63, 0.0D, (double) var40); + var27[3] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) (-var63), 0.0D, (double) var40); + var27[4] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) (-var63), (double) var41, (double) (-var40)); + var27[5] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) var63, (double) var41, (double) (-var40)); + var27[6] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) var63, (double) var41, (double) var40); + var27[7] = this.blockAccess.getWorldVec3Pool().getVecFromPool((double) (-var63), (double) var41, (double) var40); + + for (int var42 = 0; var42 < 8; ++var42) { + var27[var42].zCoord += 0.21875D; + + if (var9) { + var27[var42].yCoord -= 0.09375D; + var27[var42].zCoord -= 0.1625D; + var27[var42].rotateAroundX(0.0F); + } else if (var8) { + var27[var42].yCoord += 0.015625D; + var27[var42].zCoord -= 0.171875D; + var27[var42].rotateAroundX(0.17453294F); + } else { + var27[var42].rotateAroundX(0.87266463F); + } + + if (var7 == 2) { + var27[var42].rotateAroundY(0.0F); + } + + if (var7 == 0) { + var27[var42].rotateAroundY((float) Math.PI); + } + + if (var7 == 1) { + var27[var42].rotateAroundY(((float) Math.PI / 2F)); + } + + if (var7 == 3) { + var27[var42].rotateAroundY(-((float) Math.PI / 2F)); + } + + var27[var42].xCoord += (double) par2 + 0.5D; + var27[var42].yCoord += (double) ((float) par3 + 0.3125F); + var27[var42].zCoord += (double) par4 + 0.5D; + } + + byte var64 = 5; + byte var43 = 11; + byte var44 = 3; + byte var45 = 9; + + for (int var46 = 0; var46 < 6; ++var46) { + if (var46 == 0) { + var62 = var27[0]; + var32 = var27[1]; + var33 = var27[2]; + var34 = var27[3]; + var19 = (double) var18.getInterpolatedU((double) var64); + var21 = (double) var18.getInterpolatedV((double) var44); + var23 = (double) var18.getInterpolatedU((double) var43); + var25 = (double) var18.getInterpolatedV((double) var45); + } else if (var46 == 1) { + var62 = var27[7]; + var32 = var27[6]; + var33 = var27[5]; + var34 = var27[4]; + } else if (var46 == 2) { + var62 = var27[1]; + var32 = var27[0]; + var33 = var27[4]; + var34 = var27[5]; + var19 = (double) var18.getInterpolatedU((double) var64); + var21 = (double) var18.getInterpolatedV((double) var44); + var23 = (double) var18.getInterpolatedU((double) var43); + var25 = (double) var18.getInterpolatedV((double) (var44 + 2)); + } else if (var46 == 3) { + var62 = var27[2]; + var32 = var27[1]; + var33 = var27[5]; + var34 = var27[6]; + } else if (var46 == 4) { + var62 = var27[3]; + var32 = var27[2]; + var33 = var27[6]; + var34 = var27[7]; + } else if (var46 == 5) { + var62 = var27[0]; + var32 = var27[3]; + var33 = var27[7]; + var34 = var27[4]; + } + + var5.addVertexWithUV(var62.xCoord, var62.yCoord, var62.zCoord, var19, var25); + var5.addVertexWithUV(var32.xCoord, var32.yCoord, var32.zCoord, var23, var25); + var5.addVertexWithUV(var33.xCoord, var33.yCoord, var33.zCoord, var23, var21); + var5.addVertexWithUV(var34.xCoord, var34.yCoord, var34.zCoord, var19, var21); + } + + if (var8) { + double var65 = var27[0].yCoord; + float var48 = 0.03125F; + float var49 = 0.5F - var48 / 2.0F; + float var50 = var49 + var48; + Icon var51 = this.getBlockIcon(Block.tripWire); + double var52 = (double) var18.getMinU(); + double var54 = (double) var18.getInterpolatedV(var8 ? 2.0D : 0.0D); + double var56 = (double) var18.getMaxU(); + double var58 = (double) var18.getInterpolatedV(var8 ? 4.0D : 2.0D); + double var60 = (double) (var10 ? 3.5F : 1.5F) / 16.0D; + var17 = par1Block.getBlockBrightness(this.blockAccess, par2, par3, par4) * 0.75F; + var5.setColorOpaque_F(var17, var17, var17); + + if (var7 == 2) { + var5.addVertexWithUV((double) ((float) par2 + var49), (double) par3 + var60, (double) par4 + 0.25D, var52, var54); + var5.addVertexWithUV((double) ((float) par2 + var50), (double) par3 + var60, (double) par4 + 0.25D, var52, var58); + var5.addVertexWithUV((double) ((float) par2 + var50), (double) par3 + var60, (double) par4, var56, var58); + var5.addVertexWithUV((double) ((float) par2 + var49), (double) par3 + var60, (double) par4, var56, var54); + var5.addVertexWithUV((double) ((float) par2 + var49), var65, (double) par4 + 0.5D, var52, var54); + var5.addVertexWithUV((double) ((float) par2 + var50), var65, (double) par4 + 0.5D, var52, var58); + var5.addVertexWithUV((double) ((float) par2 + var50), (double) par3 + var60, (double) par4 + 0.25D, var56, var58); + var5.addVertexWithUV((double) ((float) par2 + var49), (double) par3 + var60, (double) par4 + 0.25D, var56, var54); + } else if (var7 == 0) { + var5.addVertexWithUV((double) ((float) par2 + var49), (double) par3 + var60, (double) par4 + 0.75D, var52, var54); + var5.addVertexWithUV((double) ((float) par2 + var50), (double) par3 + var60, (double) par4 + 0.75D, var52, var58); + var5.addVertexWithUV((double) ((float) par2 + var50), var65, (double) par4 + 0.5D, var56, var58); + var5.addVertexWithUV((double) ((float) par2 + var49), var65, (double) par4 + 0.5D, var56, var54); + var5.addVertexWithUV((double) ((float) par2 + var49), (double) par3 + var60, (double) (par4 + 1), var52, var54); + var5.addVertexWithUV((double) ((float) par2 + var50), (double) par3 + var60, (double) (par4 + 1), var52, var58); + var5.addVertexWithUV((double) ((float) par2 + var50), (double) par3 + var60, (double) par4 + 0.75D, var56, var58); + var5.addVertexWithUV((double) ((float) par2 + var49), (double) par3 + var60, (double) par4 + 0.75D, var56, var54); + } else if (var7 == 1) { + var5.addVertexWithUV((double) par2, (double) par3 + var60, (double) ((float) par4 + var50), var52, var58); + var5.addVertexWithUV((double) par2 + 0.25D, (double) par3 + var60, (double) ((float) par4 + var50), var56, var58); + var5.addVertexWithUV((double) par2 + 0.25D, (double) par3 + var60, (double) ((float) par4 + var49), var56, var54); + var5.addVertexWithUV((double) par2, (double) par3 + var60, (double) ((float) par4 + var49), var52, var54); + var5.addVertexWithUV((double) par2 + 0.25D, (double) par3 + var60, (double) ((float) par4 + var50), var52, var58); + var5.addVertexWithUV((double) par2 + 0.5D, var65, (double) ((float) par4 + var50), var56, var58); + var5.addVertexWithUV((double) par2 + 0.5D, var65, (double) ((float) par4 + var49), var56, var54); + var5.addVertexWithUV((double) par2 + 0.25D, (double) par3 + var60, (double) ((float) par4 + var49), var52, var54); + } else { + var5.addVertexWithUV((double) par2 + 0.5D, var65, (double) ((float) par4 + var50), var52, var58); + var5.addVertexWithUV((double) par2 + 0.75D, (double) par3 + var60, (double) ((float) par4 + var50), var56, var58); + var5.addVertexWithUV((double) par2 + 0.75D, (double) par3 + var60, (double) ((float) par4 + var49), var56, var54); + var5.addVertexWithUV((double) par2 + 0.5D, var65, (double) ((float) par4 + var49), var52, var54); + var5.addVertexWithUV((double) par2 + 0.75D, (double) par3 + var60, (double) ((float) par4 + var50), var52, var58); + var5.addVertexWithUV((double) (par2 + 1), (double) par3 + var60, (double) ((float) par4 + var50), var56, var58); + var5.addVertexWithUV((double) (par2 + 1), (double) par3 + var60, (double) ((float) par4 + var49), var56, var54); + var5.addVertexWithUV((double) par2 + 0.75D, (double) par3 + var60, (double) ((float) par4 + var49), var52, var54); + } + } + + return true; + } + + /** + * Renders a trip wire block at the given coordinates + */ + public boolean renderBlockTripWire(Block par1Block, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + Icon var6 = this.getBlockIconFromSide(par1Block, 0); + int var7 = this.blockAccess.getBlockMetadata(par2, par3, par4); + boolean var8 = (var7 & 4) == 4; + boolean var9 = (var7 & 2) == 2; + + if (this.hasOverrideBlockTexture()) { + var6 = this.overrideBlockTexture; + } + + var5.setBrightness(par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + float var10 = par1Block.getBlockBrightness(this.blockAccess, par2, par3, par4) * 0.75F; + var5.setColorOpaque_F(var10, var10, var10); + double var11 = (double) var6.getMinU(); + double var13 = (double) var6.getInterpolatedV(var8 ? 2.0D : 0.0D); + double var15 = (double) var6.getMaxU(); + double var17 = (double) var6.getInterpolatedV(var8 ? 4.0D : 2.0D); + double var19 = (double) (var9 ? 3.5F : 1.5F) / 16.0D; + boolean var21 = BlockTripWire.func_72148_a(this.blockAccess, par2, par3, par4, var7, 1); + boolean var22 = BlockTripWire.func_72148_a(this.blockAccess, par2, par3, par4, var7, 3); + boolean var23 = BlockTripWire.func_72148_a(this.blockAccess, par2, par3, par4, var7, 2); + boolean var24 = BlockTripWire.func_72148_a(this.blockAccess, par2, par3, par4, var7, 0); + float var25 = 0.03125F; + float var26 = 0.5F - var25 / 2.0F; + float var27 = var26 + var25; + + if (!var23 && !var22 && !var24 && !var21) { + var23 = true; + var24 = true; + } + + if (var23) { + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) par4 + 0.25D, var11, var13); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) par4 + 0.25D, var11, var17); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) par4, var15, var17); + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) par4, var15, var13); + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) par4, var15, var13); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) par4, var15, var17); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) par4 + 0.25D, var11, var17); + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) par4 + 0.25D, var11, var13); + } + + if (var23 || var24 && !var22 && !var21) { + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) par4 + 0.5D, var11, var13); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) par4 + 0.5D, var11, var17); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) par4 + 0.25D, var15, var17); + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) par4 + 0.25D, var15, var13); + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) par4 + 0.25D, var15, var13); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) par4 + 0.25D, var15, var17); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) par4 + 0.5D, var11, var17); + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) par4 + 0.5D, var11, var13); + } + + if (var24 || var23 && !var22 && !var21) { + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) par4 + 0.75D, var11, var13); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) par4 + 0.75D, var11, var17); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) par4 + 0.5D, var15, var17); + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) par4 + 0.5D, var15, var13); + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) par4 + 0.5D, var15, var13); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) par4 + 0.5D, var15, var17); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) par4 + 0.75D, var11, var17); + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) par4 + 0.75D, var11, var13); + } + + if (var24) { + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) (par4 + 1), var11, var13); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) (par4 + 1), var11, var17); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) par4 + 0.75D, var15, var17); + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) par4 + 0.75D, var15, var13); + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) par4 + 0.75D, var15, var13); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) par4 + 0.75D, var15, var17); + var5.addVertexWithUV((double) ((float) par2 + var27), (double) par3 + var19, (double) (par4 + 1), var11, var17); + var5.addVertexWithUV((double) ((float) par2 + var26), (double) par3 + var19, (double) (par4 + 1), var11, var13); + } + + if (var21) { + var5.addVertexWithUV((double) par2, (double) par3 + var19, (double) ((float) par4 + var27), var11, var17); + var5.addVertexWithUV((double) par2 + 0.25D, (double) par3 + var19, (double) ((float) par4 + var27), var15, var17); + var5.addVertexWithUV((double) par2 + 0.25D, (double) par3 + var19, (double) ((float) par4 + var26), var15, var13); + var5.addVertexWithUV((double) par2, (double) par3 + var19, (double) ((float) par4 + var26), var11, var13); + var5.addVertexWithUV((double) par2, (double) par3 + var19, (double) ((float) par4 + var26), var11, var13); + var5.addVertexWithUV((double) par2 + 0.25D, (double) par3 + var19, (double) ((float) par4 + var26), var15, var13); + var5.addVertexWithUV((double) par2 + 0.25D, (double) par3 + var19, (double) ((float) par4 + var27), var15, var17); + var5.addVertexWithUV((double) par2, (double) par3 + var19, (double) ((float) par4 + var27), var11, var17); + } + + if (var21 || var22 && !var23 && !var24) { + var5.addVertexWithUV((double) par2 + 0.25D, (double) par3 + var19, (double) ((float) par4 + var27), var11, var17); + var5.addVertexWithUV((double) par2 + 0.5D, (double) par3 + var19, (double) ((float) par4 + var27), var15, var17); + var5.addVertexWithUV((double) par2 + 0.5D, (double) par3 + var19, (double) ((float) par4 + var26), var15, var13); + var5.addVertexWithUV((double) par2 + 0.25D, (double) par3 + var19, (double) ((float) par4 + var26), var11, var13); + var5.addVertexWithUV((double) par2 + 0.25D, (double) par3 + var19, (double) ((float) par4 + var26), var11, var13); + var5.addVertexWithUV((double) par2 + 0.5D, (double) par3 + var19, (double) ((float) par4 + var26), var15, var13); + var5.addVertexWithUV((double) par2 + 0.5D, (double) par3 + var19, (double) ((float) par4 + var27), var15, var17); + var5.addVertexWithUV((double) par2 + 0.25D, (double) par3 + var19, (double) ((float) par4 + var27), var11, var17); + } + + if (var22 || var21 && !var23 && !var24) { + var5.addVertexWithUV((double) par2 + 0.5D, (double) par3 + var19, (double) ((float) par4 + var27), var11, var17); + var5.addVertexWithUV((double) par2 + 0.75D, (double) par3 + var19, (double) ((float) par4 + var27), var15, var17); + var5.addVertexWithUV((double) par2 + 0.75D, (double) par3 + var19, (double) ((float) par4 + var26), var15, var13); + var5.addVertexWithUV((double) par2 + 0.5D, (double) par3 + var19, (double) ((float) par4 + var26), var11, var13); + var5.addVertexWithUV((double) par2 + 0.5D, (double) par3 + var19, (double) ((float) par4 + var26), var11, var13); + var5.addVertexWithUV((double) par2 + 0.75D, (double) par3 + var19, (double) ((float) par4 + var26), var15, var13); + var5.addVertexWithUV((double) par2 + 0.75D, (double) par3 + var19, (double) ((float) par4 + var27), var15, var17); + var5.addVertexWithUV((double) par2 + 0.5D, (double) par3 + var19, (double) ((float) par4 + var27), var11, var17); + } + + if (var22) { + var5.addVertexWithUV((double) par2 + 0.75D, (double) par3 + var19, (double) ((float) par4 + var27), var11, var17); + var5.addVertexWithUV((double) (par2 + 1), (double) par3 + var19, (double) ((float) par4 + var27), var15, var17); + var5.addVertexWithUV((double) (par2 + 1), (double) par3 + var19, (double) ((float) par4 + var26), var15, var13); + var5.addVertexWithUV((double) par2 + 0.75D, (double) par3 + var19, (double) ((float) par4 + var26), var11, var13); + var5.addVertexWithUV((double) par2 + 0.75D, (double) par3 + var19, (double) ((float) par4 + var26), var11, var13); + var5.addVertexWithUV((double) (par2 + 1), (double) par3 + var19, (double) ((float) par4 + var26), var15, var13); + var5.addVertexWithUV((double) (par2 + 1), (double) par3 + var19, (double) ((float) par4 + var27), var15, var17); + var5.addVertexWithUV((double) par2 + 0.75D, (double) par3 + var19, (double) ((float) par4 + var27), var11, var17); + } + + return true; + } + + /** + * Renders a fire block at the given coordinates + */ + public boolean renderBlockFire(BlockFire par1BlockFire, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + Icon var6 = par1BlockFire.func_94438_c(0); + Icon var7 = par1BlockFire.func_94438_c(1); + Icon var8 = var6; + + if (this.hasOverrideBlockTexture()) { + var8 = this.overrideBlockTexture; + } + + var5.setColorOpaque_F(1.0F, 1.0F, 1.0F); + var5.setBrightness(par1BlockFire.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + double var9 = (double) var8.getMinU(); + double var11 = (double) var8.getMinV(); + double var13 = (double) var8.getMaxU(); + double var15 = (double) var8.getMaxV(); + float var17 = 1.4F; + double var20; + double var22; + double var24; + double var26; + double var28; + double var30; + double var32; + + if (!this.blockAccess.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) && !Block.fire.canBlockCatchFire(this.blockAccess, par2, par3 - 1, par4)) { + float var36 = 0.2F; + float var19 = 0.0625F; + + if ((par2 + par3 + par4 & 1) == 1) { + var9 = (double) var7.getMinU(); + var11 = (double) var7.getMinV(); + var13 = (double) var7.getMaxU(); + var15 = (double) var7.getMaxV(); + } + + if ((par2 / 2 + par3 / 2 + par4 / 2 & 1) == 1) { + var20 = var13; + var13 = var9; + var9 = var20; + } + + if (Block.fire.canBlockCatchFire(this.blockAccess, par2 - 1, par3, par4)) { + var5.addVertexWithUV((double) ((float) par2 + var36), (double) ((float) par3 + var17 + var19), (double) (par4 + 1), var13, var11); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) (par3 + 0) + var19), (double) (par4 + 1), var13, var15); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) (par3 + 0) + var19), (double) (par4 + 0), var9, var15); + var5.addVertexWithUV((double) ((float) par2 + var36), (double) ((float) par3 + var17 + var19), (double) (par4 + 0), var9, var11); + var5.addVertexWithUV((double) ((float) par2 + var36), (double) ((float) par3 + var17 + var19), (double) (par4 + 0), var9, var11); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) (par3 + 0) + var19), (double) (par4 + 0), var9, var15); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) (par3 + 0) + var19), (double) (par4 + 1), var13, var15); + var5.addVertexWithUV((double) ((float) par2 + var36), (double) ((float) par3 + var17 + var19), (double) (par4 + 1), var13, var11); + } + + if (Block.fire.canBlockCatchFire(this.blockAccess, par2 + 1, par3, par4)) { + var5.addVertexWithUV((double) ((float) (par2 + 1) - var36), (double) ((float) par3 + var17 + var19), (double) (par4 + 0), var9, var11); + var5.addVertexWithUV((double) (par2 + 1 - 0), (double) ((float) (par3 + 0) + var19), (double) (par4 + 0), var9, var15); + var5.addVertexWithUV((double) (par2 + 1 - 0), (double) ((float) (par3 + 0) + var19), (double) (par4 + 1), var13, var15); + var5.addVertexWithUV((double) ((float) (par2 + 1) - var36), (double) ((float) par3 + var17 + var19), (double) (par4 + 1), var13, var11); + var5.addVertexWithUV((double) ((float) (par2 + 1) - var36), (double) ((float) par3 + var17 + var19), (double) (par4 + 1), var13, var11); + var5.addVertexWithUV((double) (par2 + 1 - 0), (double) ((float) (par3 + 0) + var19), (double) (par4 + 1), var13, var15); + var5.addVertexWithUV((double) (par2 + 1 - 0), (double) ((float) (par3 + 0) + var19), (double) (par4 + 0), var9, var15); + var5.addVertexWithUV((double) ((float) (par2 + 1) - var36), (double) ((float) par3 + var17 + var19), (double) (par4 + 0), var9, var11); + } + + if (Block.fire.canBlockCatchFire(this.blockAccess, par2, par3, par4 - 1)) { + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) par3 + var17 + var19), (double) ((float) par4 + var36), var13, var11); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) (par3 + 0) + var19), (double) (par4 + 0), var13, var15); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) (par3 + 0) + var19), (double) (par4 + 0), var9, var15); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) par3 + var17 + var19), (double) ((float) par4 + var36), var9, var11); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) par3 + var17 + var19), (double) ((float) par4 + var36), var9, var11); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) (par3 + 0) + var19), (double) (par4 + 0), var9, var15); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) (par3 + 0) + var19), (double) (par4 + 0), var13, var15); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) par3 + var17 + var19), (double) ((float) par4 + var36), var13, var11); + } + + if (Block.fire.canBlockCatchFire(this.blockAccess, par2, par3, par4 + 1)) { + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) par3 + var17 + var19), (double) ((float) (par4 + 1) - var36), var9, var11); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) (par3 + 0) + var19), (double) (par4 + 1 - 0), var9, var15); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) (par3 + 0) + var19), (double) (par4 + 1 - 0), var13, var15); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) par3 + var17 + var19), (double) ((float) (par4 + 1) - var36), var13, var11); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) par3 + var17 + var19), (double) ((float) (par4 + 1) - var36), var13, var11); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) (par3 + 0) + var19), (double) (par4 + 1 - 0), var13, var15); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) (par3 + 0) + var19), (double) (par4 + 1 - 0), var9, var15); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) par3 + var17 + var19), (double) ((float) (par4 + 1) - var36), var9, var11); + } + + if (Block.fire.canBlockCatchFire(this.blockAccess, par2, par3 + 1, par4)) { + var20 = (double) par2 + 0.5D + 0.5D; + var22 = (double) par2 + 0.5D - 0.5D; + var24 = (double) par4 + 0.5D + 0.5D; + var26 = (double) par4 + 0.5D - 0.5D; + var28 = (double) par2 + 0.5D - 0.5D; + var30 = (double) par2 + 0.5D + 0.5D; + var32 = (double) par4 + 0.5D - 0.5D; + double var34 = (double) par4 + 0.5D + 0.5D; + var9 = (double) var6.getMinU(); + var11 = (double) var6.getMinV(); + var13 = (double) var6.getMaxU(); + var15 = (double) var6.getMaxV(); + ++par3; + var17 = -0.2F; + + if ((par2 + par3 + par4 & 1) == 0) { + var5.addVertexWithUV(var28, (double) ((float) par3 + var17), (double) (par4 + 0), var13, var11); + var5.addVertexWithUV(var20, (double) (par3 + 0), (double) (par4 + 0), var13, var15); + var5.addVertexWithUV(var20, (double) (par3 + 0), (double) (par4 + 1), var9, var15); + var5.addVertexWithUV(var28, (double) ((float) par3 + var17), (double) (par4 + 1), var9, var11); + var9 = (double) var7.getMinU(); + var11 = (double) var7.getMinV(); + var13 = (double) var7.getMaxU(); + var15 = (double) var7.getMaxV(); + var5.addVertexWithUV(var30, (double) ((float) par3 + var17), (double) (par4 + 1), var13, var11); + var5.addVertexWithUV(var22, (double) (par3 + 0), (double) (par4 + 1), var13, var15); + var5.addVertexWithUV(var22, (double) (par3 + 0), (double) (par4 + 0), var9, var15); + var5.addVertexWithUV(var30, (double) ((float) par3 + var17), (double) (par4 + 0), var9, var11); + } else { + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) par3 + var17), var34, var13, var11); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 0), var26, var13, var15); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 0), var26, var9, var15); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) par3 + var17), var34, var9, var11); + var9 = (double) var7.getMinU(); + var11 = (double) var7.getMinV(); + var13 = (double) var7.getMaxU(); + var15 = (double) var7.getMaxV(); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) par3 + var17), var32, var13, var11); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 0), var24, var13, var15); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 0), var24, var9, var15); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) par3 + var17), var32, var9, var11); + } + } + } else { + double var18 = (double) par2 + 0.5D + 0.2D; + var20 = (double) par2 + 0.5D - 0.2D; + var22 = (double) par4 + 0.5D + 0.2D; + var24 = (double) par4 + 0.5D - 0.2D; + var26 = (double) par2 + 0.5D - 0.3D; + var28 = (double) par2 + 0.5D + 0.3D; + var30 = (double) par4 + 0.5D - 0.3D; + var32 = (double) par4 + 0.5D + 0.3D; + var5.addVertexWithUV(var26, (double) ((float) par3 + var17), (double) (par4 + 1), var13, var11); + var5.addVertexWithUV(var18, (double) (par3 + 0), (double) (par4 + 1), var13, var15); + var5.addVertexWithUV(var18, (double) (par3 + 0), (double) (par4 + 0), var9, var15); + var5.addVertexWithUV(var26, (double) ((float) par3 + var17), (double) (par4 + 0), var9, var11); + var5.addVertexWithUV(var28, (double) ((float) par3 + var17), (double) (par4 + 0), var13, var11); + var5.addVertexWithUV(var20, (double) (par3 + 0), (double) (par4 + 0), var13, var15); + var5.addVertexWithUV(var20, (double) (par3 + 0), (double) (par4 + 1), var9, var15); + var5.addVertexWithUV(var28, (double) ((float) par3 + var17), (double) (par4 + 1), var9, var11); + var9 = (double) var7.getMinU(); + var11 = (double) var7.getMinV(); + var13 = (double) var7.getMaxU(); + var15 = (double) var7.getMaxV(); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) par3 + var17), var32, var13, var11); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 0), var24, var13, var15); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 0), var24, var9, var15); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) par3 + var17), var32, var9, var11); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) par3 + var17), var30, var13, var11); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 0), var22, var13, var15); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 0), var22, var9, var15); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) par3 + var17), var30, var9, var11); + var18 = (double) par2 + 0.5D - 0.5D; + var20 = (double) par2 + 0.5D + 0.5D; + var22 = (double) par4 + 0.5D - 0.5D; + var24 = (double) par4 + 0.5D + 0.5D; + var26 = (double) par2 + 0.5D - 0.4D; + var28 = (double) par2 + 0.5D + 0.4D; + var30 = (double) par4 + 0.5D - 0.4D; + var32 = (double) par4 + 0.5D + 0.4D; + var5.addVertexWithUV(var26, (double) ((float) par3 + var17), (double) (par4 + 0), var9, var11); + var5.addVertexWithUV(var18, (double) (par3 + 0), (double) (par4 + 0), var9, var15); + var5.addVertexWithUV(var18, (double) (par3 + 0), (double) (par4 + 1), var13, var15); + var5.addVertexWithUV(var26, (double) ((float) par3 + var17), (double) (par4 + 1), var13, var11); + var5.addVertexWithUV(var28, (double) ((float) par3 + var17), (double) (par4 + 1), var9, var11); + var5.addVertexWithUV(var20, (double) (par3 + 0), (double) (par4 + 1), var9, var15); + var5.addVertexWithUV(var20, (double) (par3 + 0), (double) (par4 + 0), var13, var15); + var5.addVertexWithUV(var28, (double) ((float) par3 + var17), (double) (par4 + 0), var13, var11); + var9 = (double) var6.getMinU(); + var11 = (double) var6.getMinV(); + var13 = (double) var6.getMaxU(); + var15 = (double) var6.getMaxV(); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) par3 + var17), var32, var9, var11); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 0), var24, var9, var15); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 0), var24, var13, var15); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) par3 + var17), var32, var13, var11); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) par3 + var17), var30, var9, var11); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 0), var22, var9, var15); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 0), var22, var13, var15); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) par3 + var17), var30, var13, var11); + } + + return true; + } + + /** + * Renders a redstone wire block at the given coordinates + */ + public boolean renderBlockRedstoneWire(Block par1Block, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + int var6 = this.blockAccess.getBlockMetadata(par2, par3, par4); + Icon var7 = BlockRedstoneWire.func_94409_b("redstoneDust_cross"); + Icon var8 = BlockRedstoneWire.func_94409_b("redstoneDust_line"); + Icon var9 = BlockRedstoneWire.func_94409_b("redstoneDust_cross_overlay"); + Icon var10 = BlockRedstoneWire.func_94409_b("redstoneDust_line_overlay"); + var5.setBrightness(par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + float var11 = 1.0F; + float var12 = (float) var6 / 15.0F; + float var13 = var12 * 0.6F + 0.4F; + + if (var6 == 0) { + var13 = 0.3F; + } + + float var14 = var12 * var12 * 0.7F - 0.5F; + float var15 = var12 * var12 * 0.6F - 0.7F; + + if (var14 < 0.0F) { + var14 = 0.0F; + } + + if (var15 < 0.0F) { + var15 = 0.0F; + } + + var5.setColorOpaque_F(var13, var14, var15); + boolean var20 = BlockRedstoneWire.isPowerProviderOrWire(this.blockAccess, par2 - 1, par3, par4, 1) + || !this.blockAccess.isBlockNormalCube(par2 - 1, par3, par4) && BlockRedstoneWire.isPowerProviderOrWire(this.blockAccess, par2 - 1, par3 - 1, par4, -1); + boolean var21 = BlockRedstoneWire.isPowerProviderOrWire(this.blockAccess, par2 + 1, par3, par4, 3) + || !this.blockAccess.isBlockNormalCube(par2 + 1, par3, par4) && BlockRedstoneWire.isPowerProviderOrWire(this.blockAccess, par2 + 1, par3 - 1, par4, -1); + boolean var22 = BlockRedstoneWire.isPowerProviderOrWire(this.blockAccess, par2, par3, par4 - 1, 2) + || !this.blockAccess.isBlockNormalCube(par2, par3, par4 - 1) && BlockRedstoneWire.isPowerProviderOrWire(this.blockAccess, par2, par3 - 1, par4 - 1, -1); + boolean var23 = BlockRedstoneWire.isPowerProviderOrWire(this.blockAccess, par2, par3, par4 + 1, 0) + || !this.blockAccess.isBlockNormalCube(par2, par3, par4 + 1) && BlockRedstoneWire.isPowerProviderOrWire(this.blockAccess, par2, par3 - 1, par4 + 1, -1); + + if (!this.blockAccess.isBlockNormalCube(par2, par3 + 1, par4)) { + if (this.blockAccess.isBlockNormalCube(par2 - 1, par3, par4) && BlockRedstoneWire.isPowerProviderOrWire(this.blockAccess, par2 - 1, par3 + 1, par4, -1)) { + var20 = true; + } + + if (this.blockAccess.isBlockNormalCube(par2 + 1, par3, par4) && BlockRedstoneWire.isPowerProviderOrWire(this.blockAccess, par2 + 1, par3 + 1, par4, -1)) { + var21 = true; + } + + if (this.blockAccess.isBlockNormalCube(par2, par3, par4 - 1) && BlockRedstoneWire.isPowerProviderOrWire(this.blockAccess, par2, par3 + 1, par4 - 1, -1)) { + var22 = true; + } + + if (this.blockAccess.isBlockNormalCube(par2, par3, par4 + 1) && BlockRedstoneWire.isPowerProviderOrWire(this.blockAccess, par2, par3 + 1, par4 + 1, -1)) { + var23 = true; + } + } + + float var24 = (float) (par2 + 0); + float var25 = (float) (par2 + 1); + float var26 = (float) (par4 + 0); + float var27 = (float) (par4 + 1); + int var28 = 0; + + if ((var20 || var21) && !var22 && !var23) { + var28 = 1; + } + + if ((var22 || var23) && !var21 && !var20) { + var28 = 2; + } + + if (var28 == 0) { + int var29 = 0; + int var30 = 0; + int var31 = 16; + int var32 = 16; + + if (!var20) { + var24 += 0.3125F; + } + + if (!var20) { + var29 += 5; + } + + if (!var21) { + var25 -= 0.3125F; + } + + if (!var21) { + var31 -= 5; + } + + if (!var22) { + var26 += 0.3125F; + } + + if (!var22) { + var30 += 5; + } + + if (!var23) { + var27 -= 0.3125F; + } + + if (!var23) { + var32 -= 5; + } + + var5.addVertexWithUV((double) var25, (double) par3 + 0.015625D, (double) var27, (double) var7.getInterpolatedU((double) var31), (double) var7.getInterpolatedV((double) var32)); + var5.addVertexWithUV((double) var25, (double) par3 + 0.015625D, (double) var26, (double) var7.getInterpolatedU((double) var31), (double) var7.getInterpolatedV((double) var30)); + var5.addVertexWithUV((double) var24, (double) par3 + 0.015625D, (double) var26, (double) var7.getInterpolatedU((double) var29), (double) var7.getInterpolatedV((double) var30)); + var5.addVertexWithUV((double) var24, (double) par3 + 0.015625D, (double) var27, (double) var7.getInterpolatedU((double) var29), (double) var7.getInterpolatedV((double) var32)); + var5.setColorOpaque_F(var11, var11, var11); + var5.addVertexWithUV((double) var25, (double) par3 + 0.015625D, (double) var27, (double) var9.getInterpolatedU((double) var31), (double) var9.getInterpolatedV((double) var32)); + var5.addVertexWithUV((double) var25, (double) par3 + 0.015625D, (double) var26, (double) var9.getInterpolatedU((double) var31), (double) var9.getInterpolatedV((double) var30)); + var5.addVertexWithUV((double) var24, (double) par3 + 0.015625D, (double) var26, (double) var9.getInterpolatedU((double) var29), (double) var9.getInterpolatedV((double) var30)); + var5.addVertexWithUV((double) var24, (double) par3 + 0.015625D, (double) var27, (double) var9.getInterpolatedU((double) var29), (double) var9.getInterpolatedV((double) var32)); + } else if (var28 == 1) { + var5.addVertexWithUV((double) var25, (double) par3 + 0.015625D, (double) var27, (double) var8.getMaxU(), (double) var8.getMaxV()); + var5.addVertexWithUV((double) var25, (double) par3 + 0.015625D, (double) var26, (double) var8.getMaxU(), (double) var8.getMinV()); + var5.addVertexWithUV((double) var24, (double) par3 + 0.015625D, (double) var26, (double) var8.getMinU(), (double) var8.getMinV()); + var5.addVertexWithUV((double) var24, (double) par3 + 0.015625D, (double) var27, (double) var8.getMinU(), (double) var8.getMaxV()); + var5.setColorOpaque_F(var11, var11, var11); + var5.addVertexWithUV((double) var25, (double) par3 + 0.015625D, (double) var27, (double) var10.getMaxU(), (double) var10.getMaxV()); + var5.addVertexWithUV((double) var25, (double) par3 + 0.015625D, (double) var26, (double) var10.getMaxU(), (double) var10.getMinV()); + var5.addVertexWithUV((double) var24, (double) par3 + 0.015625D, (double) var26, (double) var10.getMinU(), (double) var10.getMinV()); + var5.addVertexWithUV((double) var24, (double) par3 + 0.015625D, (double) var27, (double) var10.getMinU(), (double) var10.getMaxV()); + } else { + var5.addVertexWithUV((double) var25, (double) par3 + 0.015625D, (double) var27, (double) var8.getMaxU(), (double) var8.getMaxV()); + var5.addVertexWithUV((double) var25, (double) par3 + 0.015625D, (double) var26, (double) var8.getMinU(), (double) var8.getMaxV()); + var5.addVertexWithUV((double) var24, (double) par3 + 0.015625D, (double) var26, (double) var8.getMinU(), (double) var8.getMinV()); + var5.addVertexWithUV((double) var24, (double) par3 + 0.015625D, (double) var27, (double) var8.getMaxU(), (double) var8.getMinV()); + var5.setColorOpaque_F(var11, var11, var11); + var5.addVertexWithUV((double) var25, (double) par3 + 0.015625D, (double) var27, (double) var10.getMaxU(), (double) var10.getMaxV()); + var5.addVertexWithUV((double) var25, (double) par3 + 0.015625D, (double) var26, (double) var10.getMinU(), (double) var10.getMaxV()); + var5.addVertexWithUV((double) var24, (double) par3 + 0.015625D, (double) var26, (double) var10.getMinU(), (double) var10.getMinV()); + var5.addVertexWithUV((double) var24, (double) par3 + 0.015625D, (double) var27, (double) var10.getMaxU(), (double) var10.getMinV()); + } + + if (!this.blockAccess.isBlockNormalCube(par2, par3 + 1, par4)) { + if (this.blockAccess.isBlockNormalCube(par2 - 1, par3, par4) && this.blockAccess.getBlockId(par2 - 1, par3 + 1, par4) == Block.redstoneWire.blockID) { + var5.setColorOpaque_F(var11 * var13, var11 * var14, var11 * var15); + var5.addVertexWithUV((double) par2 + 0.015625D, (double) ((float) (par3 + 1) + 0.021875F), (double) (par4 + 1), (double) var8.getMaxU(), (double) var8.getMinV()); + var5.addVertexWithUV((double) par2 + 0.015625D, (double) (par3 + 0), (double) (par4 + 1), (double) var8.getMinU(), (double) var8.getMinV()); + var5.addVertexWithUV((double) par2 + 0.015625D, (double) (par3 + 0), (double) (par4 + 0), (double) var8.getMinU(), (double) var8.getMaxV()); + var5.addVertexWithUV((double) par2 + 0.015625D, (double) ((float) (par3 + 1) + 0.021875F), (double) (par4 + 0), (double) var8.getMaxU(), (double) var8.getMaxV()); + var5.setColorOpaque_F(var11, var11, var11); + var5.addVertexWithUV((double) par2 + 0.015625D, (double) ((float) (par3 + 1) + 0.021875F), (double) (par4 + 1), (double) var10.getMaxU(), (double) var10.getMinV()); + var5.addVertexWithUV((double) par2 + 0.015625D, (double) (par3 + 0), (double) (par4 + 1), (double) var10.getMinU(), (double) var10.getMinV()); + var5.addVertexWithUV((double) par2 + 0.015625D, (double) (par3 + 0), (double) (par4 + 0), (double) var10.getMinU(), (double) var10.getMaxV()); + var5.addVertexWithUV((double) par2 + 0.015625D, (double) ((float) (par3 + 1) + 0.021875F), (double) (par4 + 0), (double) var10.getMaxU(), (double) var10.getMaxV()); + } + + if (this.blockAccess.isBlockNormalCube(par2 + 1, par3, par4) && this.blockAccess.getBlockId(par2 + 1, par3 + 1, par4) == Block.redstoneWire.blockID) { + var5.setColorOpaque_F(var11 * var13, var11 * var14, var11 * var15); + var5.addVertexWithUV((double) (par2 + 1) - 0.015625D, (double) (par3 + 0), (double) (par4 + 1), (double) var8.getMinU(), (double) var8.getMaxV()); + var5.addVertexWithUV((double) (par2 + 1) - 0.015625D, (double) ((float) (par3 + 1) + 0.021875F), (double) (par4 + 1), (double) var8.getMaxU(), (double) var8.getMaxV()); + var5.addVertexWithUV((double) (par2 + 1) - 0.015625D, (double) ((float) (par3 + 1) + 0.021875F), (double) (par4 + 0), (double) var8.getMaxU(), (double) var8.getMinV()); + var5.addVertexWithUV((double) (par2 + 1) - 0.015625D, (double) (par3 + 0), (double) (par4 + 0), (double) var8.getMinU(), (double) var8.getMinV()); + var5.setColorOpaque_F(var11, var11, var11); + var5.addVertexWithUV((double) (par2 + 1) - 0.015625D, (double) (par3 + 0), (double) (par4 + 1), (double) var10.getMinU(), (double) var10.getMaxV()); + var5.addVertexWithUV((double) (par2 + 1) - 0.015625D, (double) ((float) (par3 + 1) + 0.021875F), (double) (par4 + 1), (double) var10.getMaxU(), (double) var10.getMaxV()); + var5.addVertexWithUV((double) (par2 + 1) - 0.015625D, (double) ((float) (par3 + 1) + 0.021875F), (double) (par4 + 0), (double) var10.getMaxU(), (double) var10.getMinV()); + var5.addVertexWithUV((double) (par2 + 1) - 0.015625D, (double) (par3 + 0), (double) (par4 + 0), (double) var10.getMinU(), (double) var10.getMinV()); + } + + if (this.blockAccess.isBlockNormalCube(par2, par3, par4 - 1) && this.blockAccess.getBlockId(par2, par3 + 1, par4 - 1) == Block.redstoneWire.blockID) { + var5.setColorOpaque_F(var11 * var13, var11 * var14, var11 * var15); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 0), (double) par4 + 0.015625D, (double) var8.getMinU(), (double) var8.getMaxV()); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) (par3 + 1) + 0.021875F), (double) par4 + 0.015625D, (double) var8.getMaxU(), (double) var8.getMaxV()); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) (par3 + 1) + 0.021875F), (double) par4 + 0.015625D, (double) var8.getMaxU(), (double) var8.getMinV()); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 0), (double) par4 + 0.015625D, (double) var8.getMinU(), (double) var8.getMinV()); + var5.setColorOpaque_F(var11, var11, var11); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 0), (double) par4 + 0.015625D, (double) var10.getMinU(), (double) var10.getMaxV()); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) (par3 + 1) + 0.021875F), (double) par4 + 0.015625D, (double) var10.getMaxU(), (double) var10.getMaxV()); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) (par3 + 1) + 0.021875F), (double) par4 + 0.015625D, (double) var10.getMaxU(), (double) var10.getMinV()); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 0), (double) par4 + 0.015625D, (double) var10.getMinU(), (double) var10.getMinV()); + } + + if (this.blockAccess.isBlockNormalCube(par2, par3, par4 + 1) && this.blockAccess.getBlockId(par2, par3 + 1, par4 + 1) == Block.redstoneWire.blockID) { + var5.setColorOpaque_F(var11 * var13, var11 * var14, var11 * var15); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) (par3 + 1) + 0.021875F), (double) (par4 + 1) - 0.015625D, (double) var8.getMaxU(), (double) var8.getMinV()); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 0), (double) (par4 + 1) - 0.015625D, (double) var8.getMinU(), (double) var8.getMinV()); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 0), (double) (par4 + 1) - 0.015625D, (double) var8.getMinU(), (double) var8.getMaxV()); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) (par3 + 1) + 0.021875F), (double) (par4 + 1) - 0.015625D, (double) var8.getMaxU(), (double) var8.getMaxV()); + var5.setColorOpaque_F(var11, var11, var11); + var5.addVertexWithUV((double) (par2 + 1), (double) ((float) (par3 + 1) + 0.021875F), (double) (par4 + 1) - 0.015625D, (double) var10.getMaxU(), (double) var10.getMinV()); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 0), (double) (par4 + 1) - 0.015625D, (double) var10.getMinU(), (double) var10.getMinV()); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 0), (double) (par4 + 1) - 0.015625D, (double) var10.getMinU(), (double) var10.getMaxV()); + var5.addVertexWithUV((double) (par2 + 0), (double) ((float) (par3 + 1) + 0.021875F), (double) (par4 + 1) - 0.015625D, (double) var10.getMaxU(), (double) var10.getMaxV()); + } + } + + return true; + } + + /** + * Renders a minecart track block at the given coordinates + */ + public boolean renderBlockMinecartTrack(BlockRailBase par1BlockRailBase, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + int var6 = this.blockAccess.getBlockMetadata(par2, par3, par4); + Icon var7 = this.getBlockIconFromSideAndMetadata(par1BlockRailBase, 0, var6); + + if (this.hasOverrideBlockTexture()) { + var7 = this.overrideBlockTexture; + } + + if (par1BlockRailBase.isPowered()) { + var6 &= 7; + } + + var5.setBrightness(par1BlockRailBase.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + var5.setColorOpaque_F(1.0F, 1.0F, 1.0F); + double var8 = (double) var7.getMinU(); + double var10 = (double) var7.getMinV(); + double var12 = (double) var7.getMaxU(); + double var14 = (double) var7.getMaxV(); + double var16 = 0.0625D; + double var18 = (double) (par2 + 1); + double var20 = (double) (par2 + 1); + double var22 = (double) (par2 + 0); + double var24 = (double) (par2 + 0); + double var26 = (double) (par4 + 0); + double var28 = (double) (par4 + 1); + double var30 = (double) (par4 + 1); + double var32 = (double) (par4 + 0); + double var34 = (double) par3 + var16; + double var36 = (double) par3 + var16; + double var38 = (double) par3 + var16; + double var40 = (double) par3 + var16; + + if (var6 != 1 && var6 != 2 && var6 != 3 && var6 != 7) { + if (var6 == 8) { + var18 = var20 = (double) (par2 + 0); + var22 = var24 = (double) (par2 + 1); + var26 = var32 = (double) (par4 + 1); + var28 = var30 = (double) (par4 + 0); + } else if (var6 == 9) { + var18 = var24 = (double) (par2 + 0); + var20 = var22 = (double) (par2 + 1); + var26 = var28 = (double) (par4 + 0); + var30 = var32 = (double) (par4 + 1); + } + } else { + var18 = var24 = (double) (par2 + 1); + var20 = var22 = (double) (par2 + 0); + var26 = var28 = (double) (par4 + 1); + var30 = var32 = (double) (par4 + 0); + } + + if (var6 != 2 && var6 != 4) { + if (var6 == 3 || var6 == 5) { + ++var36; + ++var38; + } + } else { + ++var34; + ++var40; + } + + var5.addVertexWithUV(var18, var34, var26, var12, var10); + var5.addVertexWithUV(var20, var36, var28, var12, var14); + var5.addVertexWithUV(var22, var38, var30, var8, var14); + var5.addVertexWithUV(var24, var40, var32, var8, var10); + var5.addVertexWithUV(var24, var40, var32, var8, var10); + var5.addVertexWithUV(var22, var38, var30, var8, var14); + var5.addVertexWithUV(var20, var36, var28, var12, var14); + var5.addVertexWithUV(var18, var34, var26, var12, var10); + return true; + } + + /** + * Renders a ladder block at the given coordinates + */ + public boolean renderBlockLadder(Block par1Block, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + Icon var6 = this.getBlockIconFromSide(par1Block, 0); + + if (this.hasOverrideBlockTexture()) { + var6 = this.overrideBlockTexture; + } + + var5.setBrightness(par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + float var7 = 1.0F; + var5.setColorOpaque_F(var7, var7, var7); + double var20 = (double) var6.getMinU(); + double var9 = (double) var6.getMinV(); + double var11 = (double) var6.getMaxU(); + double var13 = (double) var6.getMaxV(); + int var15 = this.blockAccess.getBlockMetadata(par2, par3, par4); + double var16 = 0.0D; + double var18 = 0.05000000074505806D; + + if (var15 == 5) { + var5.addVertexWithUV((double) par2 + var18, (double) (par3 + 1) + var16, (double) (par4 + 1) + var16, var20, var9); + var5.addVertexWithUV((double) par2 + var18, (double) (par3 + 0) - var16, (double) (par4 + 1) + var16, var20, var13); + var5.addVertexWithUV((double) par2 + var18, (double) (par3 + 0) - var16, (double) (par4 + 0) - var16, var11, var13); + var5.addVertexWithUV((double) par2 + var18, (double) (par3 + 1) + var16, (double) (par4 + 0) - var16, var11, var9); + } + + if (var15 == 4) { + var5.addVertexWithUV((double) (par2 + 1) - var18, (double) (par3 + 0) - var16, (double) (par4 + 1) + var16, var11, var13); + var5.addVertexWithUV((double) (par2 + 1) - var18, (double) (par3 + 1) + var16, (double) (par4 + 1) + var16, var11, var9); + var5.addVertexWithUV((double) (par2 + 1) - var18, (double) (par3 + 1) + var16, (double) (par4 + 0) - var16, var20, var9); + var5.addVertexWithUV((double) (par2 + 1) - var18, (double) (par3 + 0) - var16, (double) (par4 + 0) - var16, var20, var13); + } + + if (var15 == 3) { + var5.addVertexWithUV((double) (par2 + 1) + var16, (double) (par3 + 0) - var16, (double) par4 + var18, var11, var13); + var5.addVertexWithUV((double) (par2 + 1) + var16, (double) (par3 + 1) + var16, (double) par4 + var18, var11, var9); + var5.addVertexWithUV((double) (par2 + 0) - var16, (double) (par3 + 1) + var16, (double) par4 + var18, var20, var9); + var5.addVertexWithUV((double) (par2 + 0) - var16, (double) (par3 + 0) - var16, (double) par4 + var18, var20, var13); + } + + if (var15 == 2) { + var5.addVertexWithUV((double) (par2 + 1) + var16, (double) (par3 + 1) + var16, (double) (par4 + 1) - var18, var20, var9); + var5.addVertexWithUV((double) (par2 + 1) + var16, (double) (par3 + 0) - var16, (double) (par4 + 1) - var18, var20, var13); + var5.addVertexWithUV((double) (par2 + 0) - var16, (double) (par3 + 0) - var16, (double) (par4 + 1) - var18, var11, var13); + var5.addVertexWithUV((double) (par2 + 0) - var16, (double) (par3 + 1) + var16, (double) (par4 + 1) - var18, var11, var9); + } + + return true; + } + + /** + * Render block vine + */ + public boolean renderBlockVine(Block par1Block, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + Icon var6 = this.getBlockIconFromSide(par1Block, 0); + + if (this.hasOverrideBlockTexture()) { + var6 = this.overrideBlockTexture; + } + + float var7 = 1.0F; + var5.setBrightness(par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + int var8 = par1Block.colorMultiplier(this.blockAccess, par2, par3, par4); + float var9 = (float) (var8 >> 16 & 255) / 255.0F; + float var10 = (float) (var8 >> 8 & 255) / 255.0F; + float var11 = (float) (var8 & 255) / 255.0F; + var5.setColorOpaque_F(var7 * var9, var7 * var10, var7 * var11); + double var19 = (double) var6.getMinU(); + double var20 = (double) var6.getMinV(); + double var12 = (double) var6.getMaxU(); + double var14 = (double) var6.getMaxV(); + double var16 = 0.05000000074505806D; + int var18 = this.blockAccess.getBlockMetadata(par2, par3, par4); + + if ((var18 & 2) != 0) { + var5.addVertexWithUV((double) par2 + var16, (double) (par3 + 1), (double) (par4 + 1), var19, var20); + var5.addVertexWithUV((double) par2 + var16, (double) (par3 + 0), (double) (par4 + 1), var19, var14); + var5.addVertexWithUV((double) par2 + var16, (double) (par3 + 0), (double) (par4 + 0), var12, var14); + var5.addVertexWithUV((double) par2 + var16, (double) (par3 + 1), (double) (par4 + 0), var12, var20); + var5.addVertexWithUV((double) par2 + var16, (double) (par3 + 1), (double) (par4 + 0), var12, var20); + var5.addVertexWithUV((double) par2 + var16, (double) (par3 + 0), (double) (par4 + 0), var12, var14); + var5.addVertexWithUV((double) par2 + var16, (double) (par3 + 0), (double) (par4 + 1), var19, var14); + var5.addVertexWithUV((double) par2 + var16, (double) (par3 + 1), (double) (par4 + 1), var19, var20); + } + + if ((var18 & 8) != 0) { + var5.addVertexWithUV((double) (par2 + 1) - var16, (double) (par3 + 0), (double) (par4 + 1), var12, var14); + var5.addVertexWithUV((double) (par2 + 1) - var16, (double) (par3 + 1), (double) (par4 + 1), var12, var20); + var5.addVertexWithUV((double) (par2 + 1) - var16, (double) (par3 + 1), (double) (par4 + 0), var19, var20); + var5.addVertexWithUV((double) (par2 + 1) - var16, (double) (par3 + 0), (double) (par4 + 0), var19, var14); + var5.addVertexWithUV((double) (par2 + 1) - var16, (double) (par3 + 0), (double) (par4 + 0), var19, var14); + var5.addVertexWithUV((double) (par2 + 1) - var16, (double) (par3 + 1), (double) (par4 + 0), var19, var20); + var5.addVertexWithUV((double) (par2 + 1) - var16, (double) (par3 + 1), (double) (par4 + 1), var12, var20); + var5.addVertexWithUV((double) (par2 + 1) - var16, (double) (par3 + 0), (double) (par4 + 1), var12, var14); + } + + if ((var18 & 4) != 0) { + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 0), (double) par4 + var16, var12, var14); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 1), (double) par4 + var16, var12, var20); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 1), (double) par4 + var16, var19, var20); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 0), (double) par4 + var16, var19, var14); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 0), (double) par4 + var16, var19, var14); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 1), (double) par4 + var16, var19, var20); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 1), (double) par4 + var16, var12, var20); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 0), (double) par4 + var16, var12, var14); + } + + if ((var18 & 1) != 0) { + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 1), (double) (par4 + 1) - var16, var19, var20); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 0), (double) (par4 + 1) - var16, var19, var14); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 0), (double) (par4 + 1) - var16, var12, var14); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 1), (double) (par4 + 1) - var16, var12, var20); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 1), (double) (par4 + 1) - var16, var12, var20); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 0), (double) (par4 + 1) - var16, var12, var14); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 0), (double) (par4 + 1) - var16, var19, var14); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 1), (double) (par4 + 1) - var16, var19, var20); + } + + if (this.blockAccess.isBlockNormalCube(par2, par3 + 1, par4)) { + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 1) - var16, (double) (par4 + 0), var19, var20); + var5.addVertexWithUV((double) (par2 + 1), (double) (par3 + 1) - var16, (double) (par4 + 1), var19, var14); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 1) - var16, (double) (par4 + 1), var12, var14); + var5.addVertexWithUV((double) (par2 + 0), (double) (par3 + 1) - var16, (double) (par4 + 0), var12, var20); + } + + return true; + } + + public boolean renderBlockPane(BlockPane par1BlockPane, int par2, int par3, int par4) { + int var5 = this.blockAccess.getHeight(); + Tessellator var6 = Tessellator.instance; + var6.setBrightness(par1BlockPane.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + float var7 = 1.0F; + int var8 = par1BlockPane.colorMultiplier(this.blockAccess, par2, par3, par4); + float var9 = (float) (var8 >> 16 & 255) / 255.0F; + float var10 = (float) (var8 >> 8 & 255) / 255.0F; + float var11 = (float) (var8 & 255) / 255.0F; + + if (EntityRenderer.anaglyphEnable) { + float var12 = (var9 * 30.0F + var10 * 59.0F + var11 * 11.0F) / 100.0F; + float var13 = (var9 * 30.0F + var10 * 70.0F) / 100.0F; + float var14 = (var9 * 30.0F + var11 * 70.0F) / 100.0F; + var9 = var12; + var10 = var13; + var11 = var14; + } + + var6.setColorOpaque_F(var7 * var9, var7 * var10, var7 * var11); + Icon var64; + Icon var65; + int var66; + + if (this.hasOverrideBlockTexture()) { + var64 = this.overrideBlockTexture; + var65 = this.overrideBlockTexture; + } else { + var66 = this.blockAccess.getBlockMetadata(par2, par3, par4); + var64 = this.getBlockIconFromSideAndMetadata(par1BlockPane, 0, var66); + var65 = par1BlockPane.getSideTextureIndex(); + } + + var66 = var64.getOriginX(); + int var15 = var64.getOriginY(); + double var16 = (double) var64.getMinU(); + double var18 = (double) var64.getInterpolatedU(8.0D); + double var20 = (double) var64.getMaxU(); + double var22 = (double) var64.getMinV(); + double var24 = (double) var64.getMaxV(); + int var26 = var65.getOriginX(); + int var27 = var65.getOriginY(); + double var28 = (double) var65.getInterpolatedU(7.0D); + double var30 = (double) var65.getInterpolatedU(9.0D); + double var32 = (double) var65.getMinV(); + double var34 = (double) var65.getInterpolatedV(8.0D); + double var36 = (double) var65.getMaxV(); + double var38 = (double) par2; + double var40 = (double) par2 + 0.5D; + double var42 = (double) (par2 + 1); + double var44 = (double) par4; + double var46 = (double) par4 + 0.5D; + double var48 = (double) (par4 + 1); + double var50 = (double) par2 + 0.5D - 0.0625D; + double var52 = (double) par2 + 0.5D + 0.0625D; + double var54 = (double) par4 + 0.5D - 0.0625D; + double var56 = (double) par4 + 0.5D + 0.0625D; + boolean var58 = par1BlockPane.canThisPaneConnectToThisBlockID(this.blockAccess.getBlockId(par2, par3, par4 - 1)); + boolean var59 = par1BlockPane.canThisPaneConnectToThisBlockID(this.blockAccess.getBlockId(par2, par3, par4 + 1)); + boolean var60 = par1BlockPane.canThisPaneConnectToThisBlockID(this.blockAccess.getBlockId(par2 - 1, par3, par4)); + boolean var61 = par1BlockPane.canThisPaneConnectToThisBlockID(this.blockAccess.getBlockId(par2 + 1, par3, par4)); + boolean var62 = par1BlockPane.shouldSideBeRendered(this.blockAccess, par2, par3 + 1, par4, 1); + boolean var63 = par1BlockPane.shouldSideBeRendered(this.blockAccess, par2, par3 - 1, par4, 0); + + if ((!var60 || !var61) && (var60 || var61 || var58 || var59)) { + if (var60 && !var61) { + var6.addVertexWithUV(var38, (double) (par3 + 1), var46, var16, var22); + var6.addVertexWithUV(var38, (double) (par3 + 0), var46, var16, var24); + var6.addVertexWithUV(var40, (double) (par3 + 0), var46, var18, var24); + var6.addVertexWithUV(var40, (double) (par3 + 1), var46, var18, var22); + var6.addVertexWithUV(var40, (double) (par3 + 1), var46, var16, var22); + var6.addVertexWithUV(var40, (double) (par3 + 0), var46, var16, var24); + var6.addVertexWithUV(var38, (double) (par3 + 0), var46, var18, var24); + var6.addVertexWithUV(var38, (double) (par3 + 1), var46, var18, var22); + + if (!var59 && !var58) { + var6.addVertexWithUV(var40, (double) (par3 + 1), var56, var28, var32); + var6.addVertexWithUV(var40, (double) (par3 + 0), var56, var28, var36); + var6.addVertexWithUV(var40, (double) (par3 + 0), var54, var30, var36); + var6.addVertexWithUV(var40, (double) (par3 + 1), var54, var30, var32); + var6.addVertexWithUV(var40, (double) (par3 + 1), var54, var28, var32); + var6.addVertexWithUV(var40, (double) (par3 + 0), var54, var28, var36); + var6.addVertexWithUV(var40, (double) (par3 + 0), var56, var30, var36); + var6.addVertexWithUV(var40, (double) (par3 + 1), var56, var30, var32); + } + + if (var62 || par3 < var5 - 1 && this.blockAccess.isAirBlock(par2 - 1, par3 + 1, par4)) { + var6.addVertexWithUV(var38, (double) (par3 + 1) + 0.01D, var56, var30, var34); + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var56, var30, var36); + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var54, var28, var36); + var6.addVertexWithUV(var38, (double) (par3 + 1) + 0.01D, var54, var28, var34); + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var56, var30, var34); + var6.addVertexWithUV(var38, (double) (par3 + 1) + 0.01D, var56, var30, var36); + var6.addVertexWithUV(var38, (double) (par3 + 1) + 0.01D, var54, var28, var36); + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var54, var28, var34); + } + + if (var63 || par3 > 1 && this.blockAccess.isAirBlock(par2 - 1, par3 - 1, par4)) { + var6.addVertexWithUV(var38, (double) par3 - 0.01D, var56, var30, var34); + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var56, var30, var36); + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var54, var28, var36); + var6.addVertexWithUV(var38, (double) par3 - 0.01D, var54, var28, var34); + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var56, var30, var34); + var6.addVertexWithUV(var38, (double) par3 - 0.01D, var56, var30, var36); + var6.addVertexWithUV(var38, (double) par3 - 0.01D, var54, var28, var36); + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var54, var28, var34); + } + } else if (!var60 && var61) { + var6.addVertexWithUV(var40, (double) (par3 + 1), var46, var18, var22); + var6.addVertexWithUV(var40, (double) (par3 + 0), var46, var18, var24); + var6.addVertexWithUV(var42, (double) (par3 + 0), var46, var20, var24); + var6.addVertexWithUV(var42, (double) (par3 + 1), var46, var20, var22); + var6.addVertexWithUV(var42, (double) (par3 + 1), var46, var18, var22); + var6.addVertexWithUV(var42, (double) (par3 + 0), var46, var18, var24); + var6.addVertexWithUV(var40, (double) (par3 + 0), var46, var20, var24); + var6.addVertexWithUV(var40, (double) (par3 + 1), var46, var20, var22); + + if (!var59 && !var58) { + var6.addVertexWithUV(var40, (double) (par3 + 1), var54, var28, var32); + var6.addVertexWithUV(var40, (double) (par3 + 0), var54, var28, var36); + var6.addVertexWithUV(var40, (double) (par3 + 0), var56, var30, var36); + var6.addVertexWithUV(var40, (double) (par3 + 1), var56, var30, var32); + var6.addVertexWithUV(var40, (double) (par3 + 1), var56, var28, var32); + var6.addVertexWithUV(var40, (double) (par3 + 0), var56, var28, var36); + var6.addVertexWithUV(var40, (double) (par3 + 0), var54, var30, var36); + var6.addVertexWithUV(var40, (double) (par3 + 1), var54, var30, var32); + } + + if (var62 || par3 < var5 - 1 && this.blockAccess.isAirBlock(par2 + 1, par3 + 1, par4)) { + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var56, var30, var32); + var6.addVertexWithUV(var42, (double) (par3 + 1) + 0.01D, var56, var30, var34); + var6.addVertexWithUV(var42, (double) (par3 + 1) + 0.01D, var54, var28, var34); + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var54, var28, var32); + var6.addVertexWithUV(var42, (double) (par3 + 1) + 0.01D, var56, var30, var32); + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var56, var30, var34); + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var54, var28, var34); + var6.addVertexWithUV(var42, (double) (par3 + 1) + 0.01D, var54, var28, var32); + } + + if (var63 || par3 > 1 && this.blockAccess.isAirBlock(par2 + 1, par3 - 1, par4)) { + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var56, var30, var32); + var6.addVertexWithUV(var42, (double) par3 - 0.01D, var56, var30, var34); + var6.addVertexWithUV(var42, (double) par3 - 0.01D, var54, var28, var34); + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var54, var28, var32); + var6.addVertexWithUV(var42, (double) par3 - 0.01D, var56, var30, var32); + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var56, var30, var34); + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var54, var28, var34); + var6.addVertexWithUV(var42, (double) par3 - 0.01D, var54, var28, var32); + } + } + } else { + var6.addVertexWithUV(var38, (double) (par3 + 1), var46, var16, var22); + var6.addVertexWithUV(var38, (double) (par3 + 0), var46, var16, var24); + var6.addVertexWithUV(var42, (double) (par3 + 0), var46, var20, var24); + var6.addVertexWithUV(var42, (double) (par3 + 1), var46, var20, var22); + var6.addVertexWithUV(var42, (double) (par3 + 1), var46, var16, var22); + var6.addVertexWithUV(var42, (double) (par3 + 0), var46, var16, var24); + var6.addVertexWithUV(var38, (double) (par3 + 0), var46, var20, var24); + var6.addVertexWithUV(var38, (double) (par3 + 1), var46, var20, var22); + + if (var62) { + var6.addVertexWithUV(var38, (double) (par3 + 1) + 0.01D, var56, var30, var36); + var6.addVertexWithUV(var42, (double) (par3 + 1) + 0.01D, var56, var30, var32); + var6.addVertexWithUV(var42, (double) (par3 + 1) + 0.01D, var54, var28, var32); + var6.addVertexWithUV(var38, (double) (par3 + 1) + 0.01D, var54, var28, var36); + var6.addVertexWithUV(var42, (double) (par3 + 1) + 0.01D, var56, var30, var36); + var6.addVertexWithUV(var38, (double) (par3 + 1) + 0.01D, var56, var30, var32); + var6.addVertexWithUV(var38, (double) (par3 + 1) + 0.01D, var54, var28, var32); + var6.addVertexWithUV(var42, (double) (par3 + 1) + 0.01D, var54, var28, var36); + } else { + if (par3 < var5 - 1 && this.blockAccess.isAirBlock(par2 - 1, par3 + 1, par4)) { + var6.addVertexWithUV(var38, (double) (par3 + 1) + 0.01D, var56, var30, var34); + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var56, var30, var36); + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var54, var28, var36); + var6.addVertexWithUV(var38, (double) (par3 + 1) + 0.01D, var54, var28, var34); + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var56, var30, var34); + var6.addVertexWithUV(var38, (double) (par3 + 1) + 0.01D, var56, var30, var36); + var6.addVertexWithUV(var38, (double) (par3 + 1) + 0.01D, var54, var28, var36); + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var54, var28, var34); + } + + if (par3 < var5 - 1 && this.blockAccess.isAirBlock(par2 + 1, par3 + 1, par4)) { + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var56, var30, var32); + var6.addVertexWithUV(var42, (double) (par3 + 1) + 0.01D, var56, var30, var34); + var6.addVertexWithUV(var42, (double) (par3 + 1) + 0.01D, var54, var28, var34); + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var54, var28, var32); + var6.addVertexWithUV(var42, (double) (par3 + 1) + 0.01D, var56, var30, var32); + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var56, var30, var34); + var6.addVertexWithUV(var40, (double) (par3 + 1) + 0.01D, var54, var28, var34); + var6.addVertexWithUV(var42, (double) (par3 + 1) + 0.01D, var54, var28, var32); + } + } + + if (var63) { + var6.addVertexWithUV(var38, (double) par3 - 0.01D, var56, var30, var36); + var6.addVertexWithUV(var42, (double) par3 - 0.01D, var56, var30, var32); + var6.addVertexWithUV(var42, (double) par3 - 0.01D, var54, var28, var32); + var6.addVertexWithUV(var38, (double) par3 - 0.01D, var54, var28, var36); + var6.addVertexWithUV(var42, (double) par3 - 0.01D, var56, var30, var36); + var6.addVertexWithUV(var38, (double) par3 - 0.01D, var56, var30, var32); + var6.addVertexWithUV(var38, (double) par3 - 0.01D, var54, var28, var32); + var6.addVertexWithUV(var42, (double) par3 - 0.01D, var54, var28, var36); + } else { + if (par3 > 1 && this.blockAccess.isAirBlock(par2 - 1, par3 - 1, par4)) { + var6.addVertexWithUV(var38, (double) par3 - 0.01D, var56, var30, var34); + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var56, var30, var36); + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var54, var28, var36); + var6.addVertexWithUV(var38, (double) par3 - 0.01D, var54, var28, var34); + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var56, var30, var34); + var6.addVertexWithUV(var38, (double) par3 - 0.01D, var56, var30, var36); + var6.addVertexWithUV(var38, (double) par3 - 0.01D, var54, var28, var36); + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var54, var28, var34); + } + + if (par3 > 1 && this.blockAccess.isAirBlock(par2 + 1, par3 - 1, par4)) { + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var56, var30, var32); + var6.addVertexWithUV(var42, (double) par3 - 0.01D, var56, var30, var34); + var6.addVertexWithUV(var42, (double) par3 - 0.01D, var54, var28, var34); + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var54, var28, var32); + var6.addVertexWithUV(var42, (double) par3 - 0.01D, var56, var30, var32); + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var56, var30, var34); + var6.addVertexWithUV(var40, (double) par3 - 0.01D, var54, var28, var34); + var6.addVertexWithUV(var42, (double) par3 - 0.01D, var54, var28, var32); + } + } + } + + if ((!var58 || !var59) && (var60 || var61 || var58 || var59)) { + if (var58 && !var59) { + var6.addVertexWithUV(var40, (double) (par3 + 1), var44, var16, var22); + var6.addVertexWithUV(var40, (double) (par3 + 0), var44, var16, var24); + var6.addVertexWithUV(var40, (double) (par3 + 0), var46, var18, var24); + var6.addVertexWithUV(var40, (double) (par3 + 1), var46, var18, var22); + var6.addVertexWithUV(var40, (double) (par3 + 1), var46, var16, var22); + var6.addVertexWithUV(var40, (double) (par3 + 0), var46, var16, var24); + var6.addVertexWithUV(var40, (double) (par3 + 0), var44, var18, var24); + var6.addVertexWithUV(var40, (double) (par3 + 1), var44, var18, var22); + + if (!var61 && !var60) { + var6.addVertexWithUV(var50, (double) (par3 + 1), var46, var28, var32); + var6.addVertexWithUV(var50, (double) (par3 + 0), var46, var28, var36); + var6.addVertexWithUV(var52, (double) (par3 + 0), var46, var30, var36); + var6.addVertexWithUV(var52, (double) (par3 + 1), var46, var30, var32); + var6.addVertexWithUV(var52, (double) (par3 + 1), var46, var28, var32); + var6.addVertexWithUV(var52, (double) (par3 + 0), var46, var28, var36); + var6.addVertexWithUV(var50, (double) (par3 + 0), var46, var30, var36); + var6.addVertexWithUV(var50, (double) (par3 + 1), var46, var30, var32); + } + + if (var62 || par3 < var5 - 1 && this.blockAccess.isAirBlock(par2, par3 + 1, par4 - 1)) { + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var44, var30, var32); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var46, var30, var34); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var46, var28, var34); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var44, var28, var32); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var46, var30, var32); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var44, var30, var34); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var44, var28, var34); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var46, var28, var32); + } + + if (var63 || par3 > 1 && this.blockAccess.isAirBlock(par2, par3 - 1, par4 - 1)) { + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var44, var30, var32); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var46, var30, var34); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var46, var28, var34); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var44, var28, var32); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var46, var30, var32); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var44, var30, var34); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var44, var28, var34); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var46, var28, var32); + } + } else if (!var58 && var59) { + var6.addVertexWithUV(var40, (double) (par3 + 1), var46, var18, var22); + var6.addVertexWithUV(var40, (double) (par3 + 0), var46, var18, var24); + var6.addVertexWithUV(var40, (double) (par3 + 0), var48, var20, var24); + var6.addVertexWithUV(var40, (double) (par3 + 1), var48, var20, var22); + var6.addVertexWithUV(var40, (double) (par3 + 1), var48, var18, var22); + var6.addVertexWithUV(var40, (double) (par3 + 0), var48, var18, var24); + var6.addVertexWithUV(var40, (double) (par3 + 0), var46, var20, var24); + var6.addVertexWithUV(var40, (double) (par3 + 1), var46, var20, var22); + + if (!var61 && !var60) { + var6.addVertexWithUV(var52, (double) (par3 + 1), var46, var28, var32); + var6.addVertexWithUV(var52, (double) (par3 + 0), var46, var28, var36); + var6.addVertexWithUV(var50, (double) (par3 + 0), var46, var30, var36); + var6.addVertexWithUV(var50, (double) (par3 + 1), var46, var30, var32); + var6.addVertexWithUV(var50, (double) (par3 + 1), var46, var28, var32); + var6.addVertexWithUV(var50, (double) (par3 + 0), var46, var28, var36); + var6.addVertexWithUV(var52, (double) (par3 + 0), var46, var30, var36); + var6.addVertexWithUV(var52, (double) (par3 + 1), var46, var30, var32); + } + + if (var62 || par3 < var5 - 1 && this.blockAccess.isAirBlock(par2, par3 + 1, par4 + 1)) { + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var46, var28, var34); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var48, var28, var36); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var48, var30, var36); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var46, var30, var34); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var48, var28, var34); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var46, var28, var36); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var46, var30, var36); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var48, var30, var34); + } + + if (var63 || par3 > 1 && this.blockAccess.isAirBlock(par2, par3 - 1, par4 + 1)) { + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var46, var28, var34); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var48, var28, var36); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var48, var30, var36); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var46, var30, var34); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var48, var28, var34); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var46, var28, var36); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var46, var30, var36); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var48, var30, var34); + } + } + } else { + var6.addVertexWithUV(var40, (double) (par3 + 1), var48, var16, var22); + var6.addVertexWithUV(var40, (double) (par3 + 0), var48, var16, var24); + var6.addVertexWithUV(var40, (double) (par3 + 0), var44, var20, var24); + var6.addVertexWithUV(var40, (double) (par3 + 1), var44, var20, var22); + var6.addVertexWithUV(var40, (double) (par3 + 1), var44, var16, var22); + var6.addVertexWithUV(var40, (double) (par3 + 0), var44, var16, var24); + var6.addVertexWithUV(var40, (double) (par3 + 0), var48, var20, var24); + var6.addVertexWithUV(var40, (double) (par3 + 1), var48, var20, var22); + + if (var62) { + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var48, var30, var36); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var44, var30, var32); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var44, var28, var32); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var48, var28, var36); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var44, var30, var36); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var48, var30, var32); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var48, var28, var32); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var44, var28, var36); + } else { + if (par3 < var5 - 1 && this.blockAccess.isAirBlock(par2, par3 + 1, par4 - 1)) { + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var44, var30, var32); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var46, var30, var34); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var46, var28, var34); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var44, var28, var32); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var46, var30, var32); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var44, var30, var34); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var44, var28, var34); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var46, var28, var32); + } + + if (par3 < var5 - 1 && this.blockAccess.isAirBlock(par2, par3 + 1, par4 + 1)) { + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var46, var28, var34); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var48, var28, var36); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var48, var30, var36); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var46, var30, var34); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var48, var28, var34); + var6.addVertexWithUV(var50, (double) (par3 + 1) + 0.005D, var46, var28, var36); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var46, var30, var36); + var6.addVertexWithUV(var52, (double) (par3 + 1) + 0.005D, var48, var30, var34); + } + } + + if (var63) { + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var48, var30, var36); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var44, var30, var32); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var44, var28, var32); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var48, var28, var36); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var44, var30, var36); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var48, var30, var32); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var48, var28, var32); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var44, var28, var36); + } else { + if (par3 > 1 && this.blockAccess.isAirBlock(par2, par3 - 1, par4 - 1)) { + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var44, var30, var32); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var46, var30, var34); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var46, var28, var34); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var44, var28, var32); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var46, var30, var32); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var44, var30, var34); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var44, var28, var34); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var46, var28, var32); + } + + if (par3 > 1 && this.blockAccess.isAirBlock(par2, par3 - 1, par4 + 1)) { + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var46, var28, var34); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var48, var28, var36); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var48, var30, var36); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var46, var30, var34); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var48, var28, var34); + var6.addVertexWithUV(var50, (double) par3 - 0.005D, var46, var28, var36); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var46, var30, var36); + var6.addVertexWithUV(var52, (double) par3 - 0.005D, var48, var30, var34); + } + } + } + + return true; + } + + /** + * Renders any block requiring croseed squares such as reeds, flowers, and + * mushrooms + */ + public boolean renderCrossedSquares(Block par1Block, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + var5.setBrightness(par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + float var6 = 1.0F; + int var7 = par1Block.colorMultiplier(this.blockAccess, par2, par3, par4); + float var8 = (float) (var7 >> 16 & 255) / 255.0F; + float var9 = (float) (var7 >> 8 & 255) / 255.0F; + float var10 = (float) (var7 & 255) / 255.0F; + + if (EntityRenderer.anaglyphEnable) { + float var11 = (var8 * 30.0F + var9 * 59.0F + var10 * 11.0F) / 100.0F; + float var12 = (var8 * 30.0F + var9 * 70.0F) / 100.0F; + float var13 = (var8 * 30.0F + var10 * 70.0F) / 100.0F; + var8 = var11; + var9 = var12; + var10 = var13; + } + + var5.setColorOpaque_F(var6 * var8, var6 * var9, var6 * var10); + double var19 = (double) par2; + double var20 = (double) par3; + double var15 = (double) par4; + + if (par1Block == Block.tallGrass) { + long var17 = (long) (par2 * 3129871) ^ (long) par4 * 116129781L ^ (long) par3; + var17 = var17 * var17 * 42317861L + var17 * 11L; + var19 += ((double) ((float) (var17 >> 16 & 15L) / 15.0F) - 0.5D) * 0.5D; + var20 += ((double) ((float) (var17 >> 20 & 15L) / 15.0F) - 1.0D) * 0.2D; + var15 += ((double) ((float) (var17 >> 24 & 15L) / 15.0F) - 0.5D) * 0.5D; + } + + this.drawCrossedSquares(par1Block, this.blockAccess.getBlockMetadata(par2, par3, par4), var19, var20, var15, 1.0F); + return true; + } + + /** + * Render block stem + */ + public boolean renderBlockStem(Block par1Block, int par2, int par3, int par4) { + BlockStem var5 = (BlockStem) par1Block; + Tessellator var6 = Tessellator.instance; + var6.setBrightness(var5.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + float var7 = 1.0F; + int var8 = var5.colorMultiplier(this.blockAccess, par2, par3, par4); + float var9 = (float) (var8 >> 16 & 255) / 255.0F; + float var10 = (float) (var8 >> 8 & 255) / 255.0F; + float var11 = (float) (var8 & 255) / 255.0F; + + if (EntityRenderer.anaglyphEnable) { + float var12 = (var9 * 30.0F + var10 * 59.0F + var11 * 11.0F) / 100.0F; + float var13 = (var9 * 30.0F + var10 * 70.0F) / 100.0F; + float var14 = (var9 * 30.0F + var11 * 70.0F) / 100.0F; + var9 = var12; + var10 = var13; + var11 = var14; + } + + var6.setColorOpaque_F(var7 * var9, var7 * var10, var7 * var11); + var5.setBlockBoundsBasedOnState(this.blockAccess, par2, par3, par4); + int var15 = var5.getState(this.blockAccess, par2, par3, par4); + + if (var15 < 0) { + this.renderBlockStemSmall(var5, this.blockAccess.getBlockMetadata(par2, par3, par4), this.renderMaxY, (double) par2, (double) ((float) par3 - 0.0625F), (double) par4); + } else { + this.renderBlockStemSmall(var5, this.blockAccess.getBlockMetadata(par2, par3, par4), 0.5D, (double) par2, (double) ((float) par3 - 0.0625F), (double) par4); + this.renderBlockStemBig(var5, this.blockAccess.getBlockMetadata(par2, par3, par4), var15, this.renderMaxY, (double) par2, (double) ((float) par3 - 0.0625F), (double) par4); + } + + return true; + } + + /** + * Render block crops + */ + public boolean renderBlockCrops(Block par1Block, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + var5.setBrightness(par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + var5.setColorOpaque_F(1.0F, 1.0F, 1.0F); + this.renderBlockCropsImpl(par1Block, this.blockAccess.getBlockMetadata(par2, par3, par4), (double) par2, (double) ((float) par3 - 0.0625F), (double) par4); + return true; + } + + /** + * Renders a torch at the given coordinates, with the base slanting at the given + * delta + */ + public void renderTorchAtAngle(Block par1Block, double par2, double par4, double par6, double par8, double par10, int par12) { + Tessellator var13 = Tessellator.instance; + Icon var14 = this.getBlockIconFromSideAndMetadata(par1Block, 0, par12); + + if (this.hasOverrideBlockTexture()) { + var14 = this.overrideBlockTexture; + } + + double var15 = (double) var14.getMinU(); + double var17 = (double) var14.getMinV(); + double var19 = (double) var14.getMaxU(); + double var21 = (double) var14.getMaxV(); + double var23 = (double) var14.getInterpolatedU(7.0D); + double var25 = (double) var14.getInterpolatedV(6.0D); + double var27 = (double) var14.getInterpolatedU(9.0D); + double var29 = (double) var14.getInterpolatedV(8.0D); + double var31 = (double) var14.getInterpolatedU(7.0D); + double var33 = (double) var14.getInterpolatedV(13.0D); + double var35 = (double) var14.getInterpolatedU(9.0D); + double var37 = (double) var14.getInterpolatedV(15.0D); + par2 += 0.5D; + par6 += 0.5D; + double var39 = par2 - 0.5D; + double var41 = par2 + 0.5D; + double var43 = par6 - 0.5D; + double var45 = par6 + 0.5D; + double var47 = 0.0625D; + double var49 = 0.625D; + var13.addVertexWithUV(par2 + par8 * (1.0D - var49) - var47, par4 + var49, par6 + par10 * (1.0D - var49) - var47, var23, var25); + var13.addVertexWithUV(par2 + par8 * (1.0D - var49) - var47, par4 + var49, par6 + par10 * (1.0D - var49) + var47, var23, var29); + var13.addVertexWithUV(par2 + par8 * (1.0D - var49) + var47, par4 + var49, par6 + par10 * (1.0D - var49) + var47, var27, var29); + var13.addVertexWithUV(par2 + par8 * (1.0D - var49) + var47, par4 + var49, par6 + par10 * (1.0D - var49) - var47, var27, var25); + var13.addVertexWithUV(par2 + var47 + par8, par4, par6 - var47 + par10, var35, var33); + var13.addVertexWithUV(par2 + var47 + par8, par4, par6 + var47 + par10, var35, var37); + var13.addVertexWithUV(par2 - var47 + par8, par4, par6 + var47 + par10, var31, var37); + var13.addVertexWithUV(par2 - var47 + par8, par4, par6 - var47 + par10, var31, var33); + var13.addVertexWithUV(par2 - var47, par4 + 1.0D, var43, var15, var17); + var13.addVertexWithUV(par2 - var47 + par8, par4 + 0.0D, var43 + par10, var15, var21); + var13.addVertexWithUV(par2 - var47 + par8, par4 + 0.0D, var45 + par10, var19, var21); + var13.addVertexWithUV(par2 - var47, par4 + 1.0D, var45, var19, var17); + var13.addVertexWithUV(par2 + var47, par4 + 1.0D, var45, var15, var17); + var13.addVertexWithUV(par2 + par8 + var47, par4 + 0.0D, var45 + par10, var15, var21); + var13.addVertexWithUV(par2 + par8 + var47, par4 + 0.0D, var43 + par10, var19, var21); + var13.addVertexWithUV(par2 + var47, par4 + 1.0D, var43, var19, var17); + var13.addVertexWithUV(var39, par4 + 1.0D, par6 + var47, var15, var17); + var13.addVertexWithUV(var39 + par8, par4 + 0.0D, par6 + var47 + par10, var15, var21); + var13.addVertexWithUV(var41 + par8, par4 + 0.0D, par6 + var47 + par10, var19, var21); + var13.addVertexWithUV(var41, par4 + 1.0D, par6 + var47, var19, var17); + var13.addVertexWithUV(var41, par4 + 1.0D, par6 - var47, var15, var17); + var13.addVertexWithUV(var41 + par8, par4 + 0.0D, par6 - var47 + par10, var15, var21); + var13.addVertexWithUV(var39 + par8, par4 + 0.0D, par6 - var47 + par10, var19, var21); + var13.addVertexWithUV(var39, par4 + 1.0D, par6 - var47, var19, var17); + } + + /** + * Utility function to draw crossed swuares + */ + public void drawCrossedSquares(Block par1Block, int par2, double par3, double par5, double par7, float par9) { + Tessellator var10 = Tessellator.instance; + Icon var11 = this.getBlockIconFromSideAndMetadata(par1Block, 0, par2); + + if (this.hasOverrideBlockTexture()) { + var11 = this.overrideBlockTexture; + } + + double var12 = (double) var11.getMinU(); + double var14 = (double) var11.getMinV(); + double var16 = (double) var11.getMaxU(); + double var18 = (double) var11.getMaxV(); + double var20 = 0.45D * (double) par9; + double var22 = par3 + 0.5D - var20; + double var24 = par3 + 0.5D + var20; + double var26 = par7 + 0.5D - var20; + double var28 = par7 + 0.5D + var20; + var10.addVertexWithUV(var22, par5 + (double) par9, var26, var12, var14); + var10.addVertexWithUV(var22, par5 + 0.0D, var26, var12, var18); + var10.addVertexWithUV(var24, par5 + 0.0D, var28, var16, var18); + var10.addVertexWithUV(var24, par5 + (double) par9, var28, var16, var14); + var10.addVertexWithUV(var24, par5 + (double) par9, var28, var12, var14); + var10.addVertexWithUV(var24, par5 + 0.0D, var28, var12, var18); + var10.addVertexWithUV(var22, par5 + 0.0D, var26, var16, var18); + var10.addVertexWithUV(var22, par5 + (double) par9, var26, var16, var14); + var10.addVertexWithUV(var22, par5 + (double) par9, var28, var12, var14); + var10.addVertexWithUV(var22, par5 + 0.0D, var28, var12, var18); + var10.addVertexWithUV(var24, par5 + 0.0D, var26, var16, var18); + var10.addVertexWithUV(var24, par5 + (double) par9, var26, var16, var14); + var10.addVertexWithUV(var24, par5 + (double) par9, var26, var12, var14); + var10.addVertexWithUV(var24, par5 + 0.0D, var26, var12, var18); + var10.addVertexWithUV(var22, par5 + 0.0D, var28, var16, var18); + var10.addVertexWithUV(var22, par5 + (double) par9, var28, var16, var14); + } + + /** + * Render block stem small + */ + public void renderBlockStemSmall(Block par1Block, int par2, double par3, double par5, double par7, double par9) { + Tessellator var11 = Tessellator.instance; + Icon var12 = this.getBlockIconFromSideAndMetadata(par1Block, 0, par2); + + if (this.hasOverrideBlockTexture()) { + var12 = this.overrideBlockTexture; + } + + double var13 = (double) var12.getMinU(); + double var15 = (double) var12.getMinV(); + double var17 = (double) var12.getMaxU(); + double var19 = (double) var12.getInterpolatedV(par3 * 16.0D); + double var21 = par5 + 0.5D - 0.44999998807907104D; + double var23 = par5 + 0.5D + 0.44999998807907104D; + double var25 = par9 + 0.5D - 0.44999998807907104D; + double var27 = par9 + 0.5D + 0.44999998807907104D; + var11.addVertexWithUV(var21, par7 + par3, var25, var13, var15); + var11.addVertexWithUV(var21, par7 + 0.0D, var25, var13, var19); + var11.addVertexWithUV(var23, par7 + 0.0D, var27, var17, var19); + var11.addVertexWithUV(var23, par7 + par3, var27, var17, var15); + var11.addVertexWithUV(var23, par7 + par3, var27, var13, var15); + var11.addVertexWithUV(var23, par7 + 0.0D, var27, var13, var19); + var11.addVertexWithUV(var21, par7 + 0.0D, var25, var17, var19); + var11.addVertexWithUV(var21, par7 + par3, var25, var17, var15); + var11.addVertexWithUV(var21, par7 + par3, var27, var13, var15); + var11.addVertexWithUV(var21, par7 + 0.0D, var27, var13, var19); + var11.addVertexWithUV(var23, par7 + 0.0D, var25, var17, var19); + var11.addVertexWithUV(var23, par7 + par3, var25, var17, var15); + var11.addVertexWithUV(var23, par7 + par3, var25, var13, var15); + var11.addVertexWithUV(var23, par7 + 0.0D, var25, var13, var19); + var11.addVertexWithUV(var21, par7 + 0.0D, var27, var17, var19); + var11.addVertexWithUV(var21, par7 + par3, var27, var17, var15); + } + + /** + * Render BlockLilyPad + */ + public boolean renderBlockLilyPad(Block par1Block, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + Icon var6 = this.getBlockIconFromSide(par1Block, 1); + + if (this.hasOverrideBlockTexture()) { + var6 = this.overrideBlockTexture; + } + + float var7 = 0.015625F; + double var8 = (double) var6.getMinU(); + double var10 = (double) var6.getMinV(); + double var12 = (double) var6.getMaxU(); + double var14 = (double) var6.getMaxV(); + long var16 = (long) (par2 * 3129871) ^ (long) par4 * 116129781L ^ (long) par3; + var16 = var16 * var16 * 42317861L + var16 * 11L; + int var18 = (int) (var16 >> 16 & 3L); + var5.setBrightness(par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + float var19 = (float) par2 + 0.5F; + float var20 = (float) par4 + 0.5F; + float var21 = (float) (var18 & 1) * 0.5F * (float) (1 - var18 / 2 % 2 * 2); + float var22 = (float) (var18 + 1 & 1) * 0.5F * (float) (1 - (var18 + 1) / 2 % 2 * 2); + var5.setColorOpaque_I(par1Block.getBlockColor()); + var5.addVertexWithUV((double) (var19 + var21 - var22), (double) ((float) par3 + var7), (double) (var20 + var21 + var22), var8, var10); + var5.addVertexWithUV((double) (var19 + var21 + var22), (double) ((float) par3 + var7), (double) (var20 - var21 + var22), var12, var10); + var5.addVertexWithUV((double) (var19 - var21 + var22), (double) ((float) par3 + var7), (double) (var20 - var21 - var22), var12, var14); + var5.addVertexWithUV((double) (var19 - var21 - var22), (double) ((float) par3 + var7), (double) (var20 + var21 - var22), var8, var14); + var5.setColorOpaque_I((par1Block.getBlockColor() & 16711422) >> 1); + var5.addVertexWithUV((double) (var19 - var21 - var22), (double) ((float) par3 + var7), (double) (var20 + var21 - var22), var8, var14); + var5.addVertexWithUV((double) (var19 - var21 + var22), (double) ((float) par3 + var7), (double) (var20 - var21 - var22), var12, var14); + var5.addVertexWithUV((double) (var19 + var21 + var22), (double) ((float) par3 + var7), (double) (var20 - var21 + var22), var12, var10); + var5.addVertexWithUV((double) (var19 + var21 - var22), (double) ((float) par3 + var7), (double) (var20 + var21 + var22), var8, var10); + return true; + } + + /** + * Render block stem big + */ + public void renderBlockStemBig(BlockStem par1BlockStem, int par2, int par3, double par4, double par6, double par8, double par10) { + Tessellator var12 = Tessellator.instance; + Icon var13 = par1BlockStem.func_94368_p(); + + if (this.hasOverrideBlockTexture()) { + var13 = this.overrideBlockTexture; + } + + double var14 = (double) var13.getMinU(); + double var16 = (double) var13.getMinV(); + double var18 = (double) var13.getMaxU(); + double var20 = (double) var13.getMaxV(); + double var22 = par6 + 0.5D - 0.5D; + double var24 = par6 + 0.5D + 0.5D; + double var26 = par10 + 0.5D - 0.5D; + double var28 = par10 + 0.5D + 0.5D; + double var30 = par6 + 0.5D; + double var32 = par10 + 0.5D; + + if ((par3 + 1) / 2 % 2 == 1) { + double var34 = var18; + var18 = var14; + var14 = var34; + } + + if (par3 < 2) { + var12.addVertexWithUV(var22, par8 + par4, var32, var14, var16); + var12.addVertexWithUV(var22, par8 + 0.0D, var32, var14, var20); + var12.addVertexWithUV(var24, par8 + 0.0D, var32, var18, var20); + var12.addVertexWithUV(var24, par8 + par4, var32, var18, var16); + var12.addVertexWithUV(var24, par8 + par4, var32, var18, var16); + var12.addVertexWithUV(var24, par8 + 0.0D, var32, var18, var20); + var12.addVertexWithUV(var22, par8 + 0.0D, var32, var14, var20); + var12.addVertexWithUV(var22, par8 + par4, var32, var14, var16); + } else { + var12.addVertexWithUV(var30, par8 + par4, var28, var14, var16); + var12.addVertexWithUV(var30, par8 + 0.0D, var28, var14, var20); + var12.addVertexWithUV(var30, par8 + 0.0D, var26, var18, var20); + var12.addVertexWithUV(var30, par8 + par4, var26, var18, var16); + var12.addVertexWithUV(var30, par8 + par4, var26, var18, var16); + var12.addVertexWithUV(var30, par8 + 0.0D, var26, var18, var20); + var12.addVertexWithUV(var30, par8 + 0.0D, var28, var14, var20); + var12.addVertexWithUV(var30, par8 + par4, var28, var14, var16); + } + } + + /** + * Render block crops implementation + */ + public void renderBlockCropsImpl(Block par1Block, int par2, double par3, double par5, double par7) { + Tessellator var9 = Tessellator.instance; + Icon var10 = this.getBlockIconFromSideAndMetadata(par1Block, 0, par2); + + if (this.hasOverrideBlockTexture()) { + var10 = this.overrideBlockTexture; + } + + double var11 = (double) var10.getMinU(); + double var13 = (double) var10.getMinV(); + double var15 = (double) var10.getMaxU(); + double var17 = (double) var10.getMaxV(); + double var19 = par3 + 0.5D - 0.25D; + double var21 = par3 + 0.5D + 0.25D; + double var23 = par7 + 0.5D - 0.5D; + double var25 = par7 + 0.5D + 0.5D; + var9.addVertexWithUV(var19, par5 + 1.0D, var23, var11, var13); + var9.addVertexWithUV(var19, par5 + 0.0D, var23, var11, var17); + var9.addVertexWithUV(var19, par5 + 0.0D, var25, var15, var17); + var9.addVertexWithUV(var19, par5 + 1.0D, var25, var15, var13); + var9.addVertexWithUV(var19, par5 + 1.0D, var25, var11, var13); + var9.addVertexWithUV(var19, par5 + 0.0D, var25, var11, var17); + var9.addVertexWithUV(var19, par5 + 0.0D, var23, var15, var17); + var9.addVertexWithUV(var19, par5 + 1.0D, var23, var15, var13); + var9.addVertexWithUV(var21, par5 + 1.0D, var25, var11, var13); + var9.addVertexWithUV(var21, par5 + 0.0D, var25, var11, var17); + var9.addVertexWithUV(var21, par5 + 0.0D, var23, var15, var17); + var9.addVertexWithUV(var21, par5 + 1.0D, var23, var15, var13); + var9.addVertexWithUV(var21, par5 + 1.0D, var23, var11, var13); + var9.addVertexWithUV(var21, par5 + 0.0D, var23, var11, var17); + var9.addVertexWithUV(var21, par5 + 0.0D, var25, var15, var17); + var9.addVertexWithUV(var21, par5 + 1.0D, var25, var15, var13); + var19 = par3 + 0.5D - 0.5D; + var21 = par3 + 0.5D + 0.5D; + var23 = par7 + 0.5D - 0.25D; + var25 = par7 + 0.5D + 0.25D; + var9.addVertexWithUV(var19, par5 + 1.0D, var23, var11, var13); + var9.addVertexWithUV(var19, par5 + 0.0D, var23, var11, var17); + var9.addVertexWithUV(var21, par5 + 0.0D, var23, var15, var17); + var9.addVertexWithUV(var21, par5 + 1.0D, var23, var15, var13); + var9.addVertexWithUV(var21, par5 + 1.0D, var23, var11, var13); + var9.addVertexWithUV(var21, par5 + 0.0D, var23, var11, var17); + var9.addVertexWithUV(var19, par5 + 0.0D, var23, var15, var17); + var9.addVertexWithUV(var19, par5 + 1.0D, var23, var15, var13); + var9.addVertexWithUV(var21, par5 + 1.0D, var25, var11, var13); + var9.addVertexWithUV(var21, par5 + 0.0D, var25, var11, var17); + var9.addVertexWithUV(var19, par5 + 0.0D, var25, var15, var17); + var9.addVertexWithUV(var19, par5 + 1.0D, var25, var15, var13); + var9.addVertexWithUV(var19, par5 + 1.0D, var25, var11, var13); + var9.addVertexWithUV(var19, par5 + 0.0D, var25, var11, var17); + var9.addVertexWithUV(var21, par5 + 0.0D, var25, var15, var17); + var9.addVertexWithUV(var21, par5 + 1.0D, var25, var15, var13); + } + + /** + * Renders a block based on the BlockFluids class at the given coordinates + */ + public boolean renderBlockFluids(Block par1Block, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + int var6 = par1Block.colorMultiplier(this.blockAccess, par2, par3, par4); + float var7 = (float) (var6 >> 16 & 255) / 255.0F; + float var8 = (float) (var6 >> 8 & 255) / 255.0F; + float var9 = (float) (var6 & 255) / 255.0F; + boolean var10 = par1Block.shouldSideBeRendered(this.blockAccess, par2, par3 + 1, par4, 1); + boolean var11 = par1Block.shouldSideBeRendered(this.blockAccess, par2, par3 - 1, par4, 0); + boolean[] var12 = new boolean[] { par1Block.shouldSideBeRendered(this.blockAccess, par2, par3, par4 - 1, 2), par1Block.shouldSideBeRendered(this.blockAccess, par2, par3, par4 + 1, 3), + par1Block.shouldSideBeRendered(this.blockAccess, par2 - 1, par3, par4, 4), par1Block.shouldSideBeRendered(this.blockAccess, par2 + 1, par3, par4, 5) }; + + if (!var10 && !var11 && !var12[0] && !var12[1] && !var12[2] && !var12[3]) { + return false; + } else { + boolean var13 = false; + float var14 = 0.5F; + float var15 = 1.0F; + float var16 = 0.8F; + float var17 = 0.6F; + double var18 = 0.0D; + double var20 = 1.0D; + Material var22 = par1Block.blockMaterial; + int var23 = this.blockAccess.getBlockMetadata(par2, par3, par4); + double var24 = (double) this.getFluidHeight(par2, par3, par4, var22); + double var26 = (double) this.getFluidHeight(par2, par3, par4 + 1, var22); + double var28 = (double) this.getFluidHeight(par2 + 1, par3, par4 + 1, var22); + double var30 = (double) this.getFluidHeight(par2 + 1, par3, par4, var22); + double var32 = 0.0010000000474974513D; + float var52; + float var53; + + if (this.renderAllFaces || var10) { + var13 = true; + Icon var34 = this.getBlockIconFromSideAndMetadata(par1Block, 1, var23); + float var35 = (float) BlockFluid.getFlowDirection(this.blockAccess, par2, par3, par4, var22); + + if (var35 > -999.0F) { + var34 = this.getBlockIconFromSideAndMetadata(par1Block, 2, var23); + } + + var24 -= var32; + var26 -= var32; + var28 -= var32; + var30 -= var32; + double var36; + double var38; + double var40; + double var42; + double var44; + double var46; + double var48; + double var50; + + if (var35 < -999.0F) { + var36 = (double) var34.getInterpolatedU(0.0D); + var44 = (double) var34.getInterpolatedV(0.0D); + var38 = var36; + var46 = (double) var34.getInterpolatedV(16.0D); + var40 = (double) var34.getInterpolatedU(16.0D); + var48 = var46; + var42 = var40; + var50 = var44; + } else { + var52 = MathHelper.sin(var35) * 0.25F; + var53 = MathHelper.cos(var35) * 0.25F; + var36 = (double) var34.getInterpolatedU((double) (8.0F + (-var53 - var52) * 16.0F)); + var44 = (double) var34.getInterpolatedV((double) (8.0F + (-var53 + var52) * 16.0F)); + var38 = (double) var34.getInterpolatedU((double) (8.0F + (-var53 + var52) * 16.0F)); + var46 = (double) var34.getInterpolatedV((double) (8.0F + (var53 + var52) * 16.0F)); + var40 = (double) var34.getInterpolatedU((double) (8.0F + (var53 + var52) * 16.0F)); + var48 = (double) var34.getInterpolatedV((double) (8.0F + (var53 - var52) * 16.0F)); + var42 = (double) var34.getInterpolatedU((double) (8.0F + (var53 - var52) * 16.0F)); + var50 = (double) var34.getInterpolatedV((double) (8.0F + (-var53 - var52) * 16.0F)); + } + + var5.setBrightness(par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + var52 = 1.0F; + var5.setColorOpaque_F(var15 * var52 * var7, var15 * var52 * var8, var15 * var52 * var9); + var5.addVertexWithUV((double) (par2 + 0), (double) par3 + var24, (double) (par4 + 0), var36, var44); + var5.addVertexWithUV((double) (par2 + 0), (double) par3 + var26, (double) (par4 + 1), var38, var46); + var5.addVertexWithUV((double) (par2 + 1), (double) par3 + var28, (double) (par4 + 1), var40, var48); + var5.addVertexWithUV((double) (par2 + 1), (double) par3 + var30, (double) (par4 + 0), var42, var50); + } + + if (this.renderAllFaces || var11) { + var5.setBrightness(par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4)); + float var57 = 1.0F; + var5.setColorOpaque_F(var14 * var57, var14 * var57, var14 * var57); + this.renderFaceYNeg(par1Block, (double) par2, (double) par3 + var32, (double) par4, this.getBlockIconFromSide(par1Block, 0)); + var13 = true; + } + + for (int var59 = 0; var59 < 4; ++var59) { + int var58 = par2; + int var37 = par4; + + if (var59 == 0) { + var37 = par4 - 1; + } + + if (var59 == 1) { + ++var37; + } + + if (var59 == 2) { + var58 = par2 - 1; + } + + if (var59 == 3) { + ++var58; + } + + Icon var60 = this.getBlockIconFromSideAndMetadata(par1Block, var59 + 2, var23); + + if (this.renderAllFaces || var12[var59]) { + double var39; + double var41; + double var43; + double var45; + double var47; + double var49; + + if (var59 == 0) { + var39 = var24; + var41 = var30; + var43 = (double) par2; + var47 = (double) (par2 + 1); + var45 = (double) par4 + var32; + var49 = (double) par4 + var32; + } else if (var59 == 1) { + var39 = var28; + var41 = var26; + var43 = (double) (par2 + 1); + var47 = (double) par2; + var45 = (double) (par4 + 1) - var32; + var49 = (double) (par4 + 1) - var32; + } else if (var59 == 2) { + var39 = var26; + var41 = var24; + var43 = (double) par2 + var32; + var47 = (double) par2 + var32; + var45 = (double) (par4 + 1); + var49 = (double) par4; + } else { + var39 = var30; + var41 = var28; + var43 = (double) (par2 + 1) - var32; + var47 = (double) (par2 + 1) - var32; + var45 = (double) par4; + var49 = (double) (par4 + 1); + } + + var13 = true; + float var51 = var60.getInterpolatedU(0.0D); + var52 = var60.getInterpolatedU(8.0D); + var53 = var60.getInterpolatedV((1.0D - var39) * 16.0D * 0.5D); + float var54 = var60.getInterpolatedV((1.0D - var41) * 16.0D * 0.5D); + float var55 = var60.getInterpolatedV(8.0D); + var5.setBrightness(par1Block.getMixedBrightnessForBlock(this.blockAccess, var58, par3, var37)); + float var56 = 1.0F; + + if (var59 < 2) { + var56 *= var16; + } else { + var56 *= var17; + } + + var5.setColorOpaque_F(var15 * var56 * var7, var15 * var56 * var8, var15 * var56 * var9); + var5.addVertexWithUV(var43, (double) par3 + var39, var45, (double) var51, (double) var53); + var5.addVertexWithUV(var47, (double) par3 + var41, var49, (double) var52, (double) var54); + var5.addVertexWithUV(var47, (double) (par3 + 0), var49, (double) var52, (double) var55); + var5.addVertexWithUV(var43, (double) (par3 + 0), var45, (double) var51, (double) var55); + } + } + + this.renderMinY = var18; + this.renderMaxY = var20; + return var13; + } + } + + /** + * Get fluid height + */ + private float getFluidHeight(int par1, int par2, int par3, Material par4Material) { + int var5 = 0; + float var6 = 0.0F; + + for (int var7 = 0; var7 < 4; ++var7) { + int var8 = par1 - (var7 & 1); + int var10 = par3 - (var7 >> 1 & 1); + + if (this.blockAccess.getBlockMaterial(var8, par2 + 1, var10) == par4Material) { + return 1.0F; + } + + Material var11 = this.blockAccess.getBlockMaterial(var8, par2, var10); + + if (var11 == par4Material) { + int var12 = this.blockAccess.getBlockMetadata(var8, par2, var10); + + if (var12 >= 8 || var12 == 0) { + var6 += BlockFluid.getFluidHeightPercent(var12) * 10.0F; + var5 += 10; + } + + var6 += BlockFluid.getFluidHeightPercent(var12); + ++var5; + } else if (!var11.isSolid()) { + ++var6; + ++var5; + } + } + + return 1.0F - var6 / (float) var5; + } + + /** + * Renders a falling sand block + */ + public void renderBlockSandFalling(Block par1Block, World par2World, int par3, int par4, int par5, int par6) { + float var7 = 0.5F; + float var8 = 1.0F; + float var9 = 0.8F; + float var10 = 0.6F; + Tessellator var11 = Tessellator.instance; + var11.startDrawingQuads(); + var11.setBrightness(par1Block.getMixedBrightnessForBlock(par2World, par3, par4, par5)); + float var12 = 1.0F; + float var13 = 1.0F; + + if (var13 < var12) { + var13 = var12; + } + + var11.setColorOpaque_F(var7 * var13, var7 * var13, var7 * var13); + this.renderFaceYNeg(par1Block, -0.5D, -0.5D, -0.5D, this.getBlockIconFromSideAndMetadata(par1Block, 0, par6)); + var13 = 1.0F; + + if (var13 < var12) { + var13 = var12; + } + + var11.setColorOpaque_F(var8 * var13, var8 * var13, var8 * var13); + this.renderFaceYPos(par1Block, -0.5D, -0.5D, -0.5D, this.getBlockIconFromSideAndMetadata(par1Block, 1, par6)); + var13 = 1.0F; + + if (var13 < var12) { + var13 = var12; + } + + var11.setColorOpaque_F(var9 * var13, var9 * var13, var9 * var13); + this.renderFaceZNeg(par1Block, -0.5D, -0.5D, -0.5D, this.getBlockIconFromSideAndMetadata(par1Block, 2, par6)); + var13 = 1.0F; + + if (var13 < var12) { + var13 = var12; + } + + var11.setColorOpaque_F(var9 * var13, var9 * var13, var9 * var13); + this.renderFaceZPos(par1Block, -0.5D, -0.5D, -0.5D, this.getBlockIconFromSideAndMetadata(par1Block, 3, par6)); + var13 = 1.0F; + + if (var13 < var12) { + var13 = var12; + } + + var11.setColorOpaque_F(var10 * var13, var10 * var13, var10 * var13); + this.renderFaceXNeg(par1Block, -0.5D, -0.5D, -0.5D, this.getBlockIconFromSideAndMetadata(par1Block, 4, par6)); + var13 = 1.0F; + + if (var13 < var12) { + var13 = var12; + } + + var11.setColorOpaque_F(var10 * var13, var10 * var13, var10 * var13); + this.renderFaceXPos(par1Block, -0.5D, -0.5D, -0.5D, this.getBlockIconFromSideAndMetadata(par1Block, 5, par6)); + var11.draw(); + } + + /** + * Renders a standard cube block at the given coordinates + */ + public boolean renderStandardBlock(Block par1Block, int par2, int par3, int par4) { + int var5 = par1Block.colorMultiplier(this.blockAccess, par2, par3, par4); + float var6 = (float) (var5 >> 16 & 255) / 255.0F; + float var7 = (float) (var5 >> 8 & 255) / 255.0F; + float var8 = (float) (var5 & 255) / 255.0F; + + if (EntityRenderer.anaglyphEnable) { + float var9 = (var6 * 30.0F + var7 * 59.0F + var8 * 11.0F) / 100.0F; + float var10 = (var6 * 30.0F + var7 * 70.0F) / 100.0F; + float var11 = (var6 * 30.0F + var8 * 70.0F) / 100.0F; + var6 = var9; + var7 = var10; + var8 = var11; + } + + return Minecraft.isAmbientOcclusionEnabled() && Block.lightValue[par1Block.blockID] == 0 + ? (this.partialRenderBounds ? this.func_102027_b(par1Block, par2, par3, par4, var6, var7, var8) : this.renderStandardBlockWithAmbientOcclusion(par1Block, par2, par3, par4, var6, var7, var8)) + : this.renderStandardBlockWithColorMultiplier(par1Block, par2, par3, par4, var6, var7, var8); + } + + /** + * Renders a log block at the given coordinates + */ + public boolean renderBlockLog(Block par1Block, int par2, int par3, int par4) { + int var5 = this.blockAccess.getBlockMetadata(par2, par3, par4); + int var6 = var5 & 12; + + if (var6 == 4) { + this.uvRotateEast = 1; + this.uvRotateWest = 1; + this.uvRotateTop = 1; + this.uvRotateBottom = 1; + } else if (var6 == 8) { + this.uvRotateSouth = 1; + this.uvRotateNorth = 1; + } + + boolean var7 = this.renderStandardBlock(par1Block, par2, par3, par4); + this.uvRotateSouth = 0; + this.uvRotateEast = 0; + this.uvRotateWest = 0; + this.uvRotateNorth = 0; + this.uvRotateTop = 0; + this.uvRotateBottom = 0; + return var7; + } + + public boolean renderBlockQuartz(Block par1Block, int par2, int par3, int par4) { + int var5 = this.blockAccess.getBlockMetadata(par2, par3, par4); + + if (var5 == 3) { + this.uvRotateEast = 1; + this.uvRotateWest = 1; + this.uvRotateTop = 1; + this.uvRotateBottom = 1; + } else if (var5 == 4) { + this.uvRotateSouth = 1; + this.uvRotateNorth = 1; + } + + boolean var6 = this.renderStandardBlock(par1Block, par2, par3, par4); + this.uvRotateSouth = 0; + this.uvRotateEast = 0; + this.uvRotateWest = 0; + this.uvRotateNorth = 0; + this.uvRotateTop = 0; + this.uvRotateBottom = 0; + return var6; + } + + public boolean renderStandardBlockWithAmbientOcclusion(Block par1Block, int par2, int par3, int par4, float par5, float par6, float par7) { + this.enableAO = true; + boolean var8 = false; + float var9 = 0.0F; + float var10 = 0.0F; + float var11 = 0.0F; + float var12 = 0.0F; + boolean var13 = true; + int var14 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4); + Tessellator var15 = Tessellator.instance; + var15.setBrightness(983055); + + if (this.getBlockIcon(par1Block).getIconName().equals("grass_top")) { + var13 = false; + } else if (this.hasOverrideBlockTexture()) { + var13 = false; + } + + boolean var16; + boolean var17; + boolean var18; + boolean var19; + int var20; + float var21; + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3 - 1, par4, 0)) { + if (this.renderMinY <= 0.0D) { + --par3; + } + + this.aoBrightnessXYNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4); + this.aoBrightnessYZNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 - 1); + this.aoBrightnessYZNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 + 1); + this.aoBrightnessXYPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4); + this.aoLightValueScratchXYNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4); + this.aoLightValueScratchYZNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 - 1); + this.aoLightValueScratchYZNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 + 1); + this.aoLightValueScratchXYPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4); + var16 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3 - 1, par4)]; + var17 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3 - 1, par4)]; + var18 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 - 1, par4 + 1)]; + var19 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 - 1, par4 - 1)]; + + if (!var19 && !var17) { + this.aoLightValueScratchXYZNNN = this.aoLightValueScratchXYNN; + this.aoBrightnessXYZNNN = this.aoBrightnessXYNN; + } else { + this.aoLightValueScratchXYZNNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4 - 1); + this.aoBrightnessXYZNNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4 - 1); + } + + if (!var18 && !var17) { + this.aoLightValueScratchXYZNNP = this.aoLightValueScratchXYNN; + this.aoBrightnessXYZNNP = this.aoBrightnessXYNN; + } else { + this.aoLightValueScratchXYZNNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4 + 1); + this.aoBrightnessXYZNNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4 + 1); + } + + if (!var19 && !var16) { + this.aoLightValueScratchXYZPNN = this.aoLightValueScratchXYPN; + this.aoBrightnessXYZPNN = this.aoBrightnessXYPN; + } else { + this.aoLightValueScratchXYZPNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4 - 1); + this.aoBrightnessXYZPNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4 - 1); + } + + if (!var18 && !var16) { + this.aoLightValueScratchXYZPNP = this.aoLightValueScratchXYPN; + this.aoBrightnessXYZPNP = this.aoBrightnessXYPN; + } else { + this.aoLightValueScratchXYZPNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4 + 1); + this.aoBrightnessXYZPNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4 + 1); + } + + if (this.renderMinY <= 0.0D) { + ++par3; + } + + var20 = var14; + + if (this.renderMinY <= 0.0D || !this.blockAccess.isBlockOpaqueCube(par2, par3 - 1, par4)) { + var20 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4); + } + + var21 = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4); + var9 = (this.aoLightValueScratchXYZNNP + this.aoLightValueScratchXYNN + this.aoLightValueScratchYZNP + var21) / 4.0F; + var12 = (this.aoLightValueScratchYZNP + var21 + this.aoLightValueScratchXYZPNP + this.aoLightValueScratchXYPN) / 4.0F; + var11 = (var21 + this.aoLightValueScratchYZNN + this.aoLightValueScratchXYPN + this.aoLightValueScratchXYZPNN) / 4.0F; + var10 = (this.aoLightValueScratchXYNN + this.aoLightValueScratchXYZNNN + var21 + this.aoLightValueScratchYZNN) / 4.0F; + this.brightnessTopLeft = this.getAoBrightness(this.aoBrightnessXYZNNP, this.aoBrightnessXYNN, this.aoBrightnessYZNP, var20); + this.brightnessTopRight = this.getAoBrightness(this.aoBrightnessYZNP, this.aoBrightnessXYZPNP, this.aoBrightnessXYPN, var20); + this.brightnessBottomRight = this.getAoBrightness(this.aoBrightnessYZNN, this.aoBrightnessXYPN, this.aoBrightnessXYZPNN, var20); + this.brightnessBottomLeft = this.getAoBrightness(this.aoBrightnessXYNN, this.aoBrightnessXYZNNN, this.aoBrightnessYZNN, var20); + + if (var13) { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = par5 * 0.5F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = par6 * 0.5F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = par7 * 0.5F; + } else { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = 0.5F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = 0.5F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = 0.5F; + } + + this.colorRedTopLeft *= var9; + this.colorGreenTopLeft *= var9; + this.colorBlueTopLeft *= var9; + this.colorRedBottomLeft *= var10; + this.colorGreenBottomLeft *= var10; + this.colorBlueBottomLeft *= var10; + this.colorRedBottomRight *= var11; + this.colorGreenBottomRight *= var11; + this.colorBlueBottomRight *= var11; + this.colorRedTopRight *= var12; + this.colorGreenTopRight *= var12; + this.colorBlueTopRight *= var12; + this.renderFaceYNeg(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 0)); + var8 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3 + 1, par4, 1)) { + if (this.renderMaxY >= 1.0D) { + ++par3; + } + + this.aoBrightnessXYNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4); + this.aoBrightnessXYPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4); + this.aoBrightnessYZPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 - 1); + this.aoBrightnessYZPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 + 1); + this.aoLightValueScratchXYNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4); + this.aoLightValueScratchXYPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4); + this.aoLightValueScratchYZPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 - 1); + this.aoLightValueScratchYZPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 + 1); + var16 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3 + 1, par4)]; + var17 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3 + 1, par4)]; + var18 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 + 1, par4 + 1)]; + var19 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 + 1, par4 - 1)]; + + if (!var19 && !var17) { + this.aoLightValueScratchXYZNPN = this.aoLightValueScratchXYNP; + this.aoBrightnessXYZNPN = this.aoBrightnessXYNP; + } else { + this.aoLightValueScratchXYZNPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4 - 1); + this.aoBrightnessXYZNPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4 - 1); + } + + if (!var19 && !var16) { + this.aoLightValueScratchXYZPPN = this.aoLightValueScratchXYPP; + this.aoBrightnessXYZPPN = this.aoBrightnessXYPP; + } else { + this.aoLightValueScratchXYZPPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4 - 1); + this.aoBrightnessXYZPPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4 - 1); + } + + if (!var18 && !var17) { + this.aoLightValueScratchXYZNPP = this.aoLightValueScratchXYNP; + this.aoBrightnessXYZNPP = this.aoBrightnessXYNP; + } else { + this.aoLightValueScratchXYZNPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4 + 1); + this.aoBrightnessXYZNPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4 + 1); + } + + if (!var18 && !var16) { + this.aoLightValueScratchXYZPPP = this.aoLightValueScratchXYPP; + this.aoBrightnessXYZPPP = this.aoBrightnessXYPP; + } else { + this.aoLightValueScratchXYZPPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4 + 1); + this.aoBrightnessXYZPPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4 + 1); + } + + if (this.renderMaxY >= 1.0D) { + --par3; + } + + var20 = var14; + + if (this.renderMaxY >= 1.0D || !this.blockAccess.isBlockOpaqueCube(par2, par3 + 1, par4)) { + var20 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4); + } + + var21 = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4); + var12 = (this.aoLightValueScratchXYZNPP + this.aoLightValueScratchXYNP + this.aoLightValueScratchYZPP + var21) / 4.0F; + var9 = (this.aoLightValueScratchYZPP + var21 + this.aoLightValueScratchXYZPPP + this.aoLightValueScratchXYPP) / 4.0F; + var10 = (var21 + this.aoLightValueScratchYZPN + this.aoLightValueScratchXYPP + this.aoLightValueScratchXYZPPN) / 4.0F; + var11 = (this.aoLightValueScratchXYNP + this.aoLightValueScratchXYZNPN + var21 + this.aoLightValueScratchYZPN) / 4.0F; + this.brightnessTopRight = this.getAoBrightness(this.aoBrightnessXYZNPP, this.aoBrightnessXYNP, this.aoBrightnessYZPP, var20); + this.brightnessTopLeft = this.getAoBrightness(this.aoBrightnessYZPP, this.aoBrightnessXYZPPP, this.aoBrightnessXYPP, var20); + this.brightnessBottomLeft = this.getAoBrightness(this.aoBrightnessYZPN, this.aoBrightnessXYPP, this.aoBrightnessXYZPPN, var20); + this.brightnessBottomRight = this.getAoBrightness(this.aoBrightnessXYNP, this.aoBrightnessXYZNPN, this.aoBrightnessYZPN, var20); + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = par5; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = par6; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = par7; + this.colorRedTopLeft *= var9; + this.colorGreenTopLeft *= var9; + this.colorBlueTopLeft *= var9; + this.colorRedBottomLeft *= var10; + this.colorGreenBottomLeft *= var10; + this.colorBlueBottomLeft *= var10; + this.colorRedBottomRight *= var11; + this.colorGreenBottomRight *= var11; + this.colorBlueBottomRight *= var11; + this.colorRedTopRight *= var12; + this.colorGreenTopRight *= var12; + this.colorBlueTopRight *= var12; + this.renderFaceYPos(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 1)); + var8 = true; + } + + Icon var22; + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3, par4 - 1, 2)) { + if (this.renderMinZ <= 0.0D) { + --par4; + } + + this.aoLightValueScratchXZNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4); + this.aoLightValueScratchYZNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4); + this.aoLightValueScratchYZPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4); + this.aoLightValueScratchXZPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4); + this.aoBrightnessXZNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4); + this.aoBrightnessYZNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4); + this.aoBrightnessYZPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4); + this.aoBrightnessXZPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4); + var16 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3, par4 - 1)]; + var17 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3, par4 - 1)]; + var18 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 + 1, par4 - 1)]; + var19 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 - 1, par4 - 1)]; + + if (!var17 && !var19) { + this.aoLightValueScratchXYZNNN = this.aoLightValueScratchXZNN; + this.aoBrightnessXYZNNN = this.aoBrightnessXZNN; + } else { + this.aoLightValueScratchXYZNNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3 - 1, par4); + this.aoBrightnessXYZNNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3 - 1, par4); + } + + if (!var17 && !var18) { + this.aoLightValueScratchXYZNPN = this.aoLightValueScratchXZNN; + this.aoBrightnessXYZNPN = this.aoBrightnessXZNN; + } else { + this.aoLightValueScratchXYZNPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3 + 1, par4); + this.aoBrightnessXYZNPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3 + 1, par4); + } + + if (!var16 && !var19) { + this.aoLightValueScratchXYZPNN = this.aoLightValueScratchXZPN; + this.aoBrightnessXYZPNN = this.aoBrightnessXZPN; + } else { + this.aoLightValueScratchXYZPNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3 - 1, par4); + this.aoBrightnessXYZPNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3 - 1, par4); + } + + if (!var16 && !var18) { + this.aoLightValueScratchXYZPPN = this.aoLightValueScratchXZPN; + this.aoBrightnessXYZPPN = this.aoBrightnessXZPN; + } else { + this.aoLightValueScratchXYZPPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3 + 1, par4); + this.aoBrightnessXYZPPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3 + 1, par4); + } + + if (this.renderMinZ <= 0.0D) { + ++par4; + } + + var20 = var14; + + if (this.renderMinZ <= 0.0D || !this.blockAccess.isBlockOpaqueCube(par2, par3, par4 - 1)) { + var20 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 - 1); + } + + var21 = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 - 1); + var9 = (this.aoLightValueScratchXZNN + this.aoLightValueScratchXYZNPN + var21 + this.aoLightValueScratchYZPN) / 4.0F; + var10 = (var21 + this.aoLightValueScratchYZPN + this.aoLightValueScratchXZPN + this.aoLightValueScratchXYZPPN) / 4.0F; + var11 = (this.aoLightValueScratchYZNN + var21 + this.aoLightValueScratchXYZPNN + this.aoLightValueScratchXZPN) / 4.0F; + var12 = (this.aoLightValueScratchXYZNNN + this.aoLightValueScratchXZNN + this.aoLightValueScratchYZNN + var21) / 4.0F; + this.brightnessTopLeft = this.getAoBrightness(this.aoBrightnessXZNN, this.aoBrightnessXYZNPN, this.aoBrightnessYZPN, var20); + this.brightnessBottomLeft = this.getAoBrightness(this.aoBrightnessYZPN, this.aoBrightnessXZPN, this.aoBrightnessXYZPPN, var20); + this.brightnessBottomRight = this.getAoBrightness(this.aoBrightnessYZNN, this.aoBrightnessXYZPNN, this.aoBrightnessXZPN, var20); + this.brightnessTopRight = this.getAoBrightness(this.aoBrightnessXYZNNN, this.aoBrightnessXZNN, this.aoBrightnessYZNN, var20); + + if (var13) { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = par5 * 0.8F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = par6 * 0.8F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = par7 * 0.8F; + } else { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = 0.8F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = 0.8F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = 0.8F; + } + + this.colorRedTopLeft *= var9; + this.colorGreenTopLeft *= var9; + this.colorBlueTopLeft *= var9; + this.colorRedBottomLeft *= var10; + this.colorGreenBottomLeft *= var10; + this.colorBlueBottomLeft *= var10; + this.colorRedBottomRight *= var11; + this.colorGreenBottomRight *= var11; + this.colorBlueBottomRight *= var11; + this.colorRedTopRight *= var12; + this.colorGreenTopRight *= var12; + this.colorBlueTopRight *= var12; + var22 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 2); + this.renderFaceZNeg(par1Block, (double) par2, (double) par3, (double) par4, var22); + + if (fancyGrass && var22.getIconName().equals("grass_side") && !this.hasOverrideBlockTexture()) { + this.colorRedTopLeft *= par5; + this.colorRedBottomLeft *= par5; + this.colorRedBottomRight *= par5; + this.colorRedTopRight *= par5; + this.colorGreenTopLeft *= par6; + this.colorGreenBottomLeft *= par6; + this.colorGreenBottomRight *= par6; + this.colorGreenTopRight *= par6; + this.colorBlueTopLeft *= par7; + this.colorBlueBottomLeft *= par7; + this.colorBlueBottomRight *= par7; + this.colorBlueTopRight *= par7; + this.renderFaceZNeg(par1Block, (double) par2, (double) par3, (double) par4, BlockGrass.getIconSideOverlay()); + } + + var8 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3, par4 + 1, 3)) { + if (this.renderMaxZ >= 1.0D) { + ++par4; + } + + this.aoLightValueScratchXZNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4); + this.aoLightValueScratchXZPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4); + this.aoLightValueScratchYZNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4); + this.aoLightValueScratchYZPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4); + this.aoBrightnessXZNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4); + this.aoBrightnessXZPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4); + this.aoBrightnessYZNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4); + this.aoBrightnessYZPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4); + var16 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3, par4 + 1)]; + var17 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3, par4 + 1)]; + var18 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 + 1, par4 + 1)]; + var19 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 - 1, par4 + 1)]; + + if (!var17 && !var19) { + this.aoLightValueScratchXYZNNP = this.aoLightValueScratchXZNP; + this.aoBrightnessXYZNNP = this.aoBrightnessXZNP; + } else { + this.aoLightValueScratchXYZNNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3 - 1, par4); + this.aoBrightnessXYZNNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3 - 1, par4); + } + + if (!var17 && !var18) { + this.aoLightValueScratchXYZNPP = this.aoLightValueScratchXZNP; + this.aoBrightnessXYZNPP = this.aoBrightnessXZNP; + } else { + this.aoLightValueScratchXYZNPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3 + 1, par4); + this.aoBrightnessXYZNPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3 + 1, par4); + } + + if (!var16 && !var19) { + this.aoLightValueScratchXYZPNP = this.aoLightValueScratchXZPP; + this.aoBrightnessXYZPNP = this.aoBrightnessXZPP; + } else { + this.aoLightValueScratchXYZPNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3 - 1, par4); + this.aoBrightnessXYZPNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3 - 1, par4); + } + + if (!var16 && !var18) { + this.aoLightValueScratchXYZPPP = this.aoLightValueScratchXZPP; + this.aoBrightnessXYZPPP = this.aoBrightnessXZPP; + } else { + this.aoLightValueScratchXYZPPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3 + 1, par4); + this.aoBrightnessXYZPPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3 + 1, par4); + } + + if (this.renderMaxZ >= 1.0D) { + --par4; + } + + var20 = var14; + + if (this.renderMaxZ >= 1.0D || !this.blockAccess.isBlockOpaqueCube(par2, par3, par4 + 1)) { + var20 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 + 1); + } + + var21 = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 + 1); + var9 = (this.aoLightValueScratchXZNP + this.aoLightValueScratchXYZNPP + var21 + this.aoLightValueScratchYZPP) / 4.0F; + var12 = (var21 + this.aoLightValueScratchYZPP + this.aoLightValueScratchXZPP + this.aoLightValueScratchXYZPPP) / 4.0F; + var11 = (this.aoLightValueScratchYZNP + var21 + this.aoLightValueScratchXYZPNP + this.aoLightValueScratchXZPP) / 4.0F; + var10 = (this.aoLightValueScratchXYZNNP + this.aoLightValueScratchXZNP + this.aoLightValueScratchYZNP + var21) / 4.0F; + this.brightnessTopLeft = this.getAoBrightness(this.aoBrightnessXZNP, this.aoBrightnessXYZNPP, this.aoBrightnessYZPP, var20); + this.brightnessTopRight = this.getAoBrightness(this.aoBrightnessYZPP, this.aoBrightnessXZPP, this.aoBrightnessXYZPPP, var20); + this.brightnessBottomRight = this.getAoBrightness(this.aoBrightnessYZNP, this.aoBrightnessXYZPNP, this.aoBrightnessXZPP, var20); + this.brightnessBottomLeft = this.getAoBrightness(this.aoBrightnessXYZNNP, this.aoBrightnessXZNP, this.aoBrightnessYZNP, var20); + + if (var13) { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = par5 * 0.8F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = par6 * 0.8F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = par7 * 0.8F; + } else { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = 0.8F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = 0.8F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = 0.8F; + } + + this.colorRedTopLeft *= var9; + this.colorGreenTopLeft *= var9; + this.colorBlueTopLeft *= var9; + this.colorRedBottomLeft *= var10; + this.colorGreenBottomLeft *= var10; + this.colorBlueBottomLeft *= var10; + this.colorRedBottomRight *= var11; + this.colorGreenBottomRight *= var11; + this.colorBlueBottomRight *= var11; + this.colorRedTopRight *= var12; + this.colorGreenTopRight *= var12; + this.colorBlueTopRight *= var12; + var22 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 3); + this.renderFaceZPos(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 3)); + + if (fancyGrass && var22.getIconName().equals("grass_side") && !this.hasOverrideBlockTexture()) { + this.colorRedTopLeft *= par5; + this.colorRedBottomLeft *= par5; + this.colorRedBottomRight *= par5; + this.colorRedTopRight *= par5; + this.colorGreenTopLeft *= par6; + this.colorGreenBottomLeft *= par6; + this.colorGreenBottomRight *= par6; + this.colorGreenTopRight *= par6; + this.colorBlueTopLeft *= par7; + this.colorBlueBottomLeft *= par7; + this.colorBlueBottomRight *= par7; + this.colorBlueTopRight *= par7; + this.renderFaceZPos(par1Block, (double) par2, (double) par3, (double) par4, BlockGrass.getIconSideOverlay()); + } + + var8 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2 - 1, par3, par4, 4)) { + if (this.renderMinX <= 0.0D) { + --par2; + } + + this.aoLightValueScratchXYNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4); + this.aoLightValueScratchXZNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 - 1); + this.aoLightValueScratchXZNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 + 1); + this.aoLightValueScratchXYNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4); + this.aoBrightnessXYNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4); + this.aoBrightnessXZNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 - 1); + this.aoBrightnessXZNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 + 1); + this.aoBrightnessXYNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4); + var16 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3 + 1, par4)]; + var17 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3 - 1, par4)]; + var18 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3, par4 - 1)]; + var19 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3, par4 + 1)]; + + if (!var18 && !var17) { + this.aoLightValueScratchXYZNNN = this.aoLightValueScratchXZNN; + this.aoBrightnessXYZNNN = this.aoBrightnessXZNN; + } else { + this.aoLightValueScratchXYZNNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4 - 1); + this.aoBrightnessXYZNNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4 - 1); + } + + if (!var19 && !var17) { + this.aoLightValueScratchXYZNNP = this.aoLightValueScratchXZNP; + this.aoBrightnessXYZNNP = this.aoBrightnessXZNP; + } else { + this.aoLightValueScratchXYZNNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4 + 1); + this.aoBrightnessXYZNNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4 + 1); + } + + if (!var18 && !var16) { + this.aoLightValueScratchXYZNPN = this.aoLightValueScratchXZNN; + this.aoBrightnessXYZNPN = this.aoBrightnessXZNN; + } else { + this.aoLightValueScratchXYZNPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4 - 1); + this.aoBrightnessXYZNPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4 - 1); + } + + if (!var19 && !var16) { + this.aoLightValueScratchXYZNPP = this.aoLightValueScratchXZNP; + this.aoBrightnessXYZNPP = this.aoBrightnessXZNP; + } else { + this.aoLightValueScratchXYZNPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4 + 1); + this.aoBrightnessXYZNPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4 + 1); + } + + if (this.renderMinX <= 0.0D) { + ++par2; + } + + var20 = var14; + + if (this.renderMinX <= 0.0D || !this.blockAccess.isBlockOpaqueCube(par2 - 1, par3, par4)) { + var20 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4); + } + + var21 = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4); + var12 = (this.aoLightValueScratchXYNN + this.aoLightValueScratchXYZNNP + var21 + this.aoLightValueScratchXZNP) / 4.0F; + var9 = (var21 + this.aoLightValueScratchXZNP + this.aoLightValueScratchXYNP + this.aoLightValueScratchXYZNPP) / 4.0F; + var10 = (this.aoLightValueScratchXZNN + var21 + this.aoLightValueScratchXYZNPN + this.aoLightValueScratchXYNP) / 4.0F; + var11 = (this.aoLightValueScratchXYZNNN + this.aoLightValueScratchXYNN + this.aoLightValueScratchXZNN + var21) / 4.0F; + this.brightnessTopRight = this.getAoBrightness(this.aoBrightnessXYNN, this.aoBrightnessXYZNNP, this.aoBrightnessXZNP, var20); + this.brightnessTopLeft = this.getAoBrightness(this.aoBrightnessXZNP, this.aoBrightnessXYNP, this.aoBrightnessXYZNPP, var20); + this.brightnessBottomLeft = this.getAoBrightness(this.aoBrightnessXZNN, this.aoBrightnessXYZNPN, this.aoBrightnessXYNP, var20); + this.brightnessBottomRight = this.getAoBrightness(this.aoBrightnessXYZNNN, this.aoBrightnessXYNN, this.aoBrightnessXZNN, var20); + + if (var13) { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = par5 * 0.6F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = par6 * 0.6F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = par7 * 0.6F; + } else { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = 0.6F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = 0.6F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = 0.6F; + } + + this.colorRedTopLeft *= var9; + this.colorGreenTopLeft *= var9; + this.colorBlueTopLeft *= var9; + this.colorRedBottomLeft *= var10; + this.colorGreenBottomLeft *= var10; + this.colorBlueBottomLeft *= var10; + this.colorRedBottomRight *= var11; + this.colorGreenBottomRight *= var11; + this.colorBlueBottomRight *= var11; + this.colorRedTopRight *= var12; + this.colorGreenTopRight *= var12; + this.colorBlueTopRight *= var12; + var22 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 4); + this.renderFaceXNeg(par1Block, (double) par2, (double) par3, (double) par4, var22); + + if (fancyGrass && var22.getIconName().equals("grass_side") && !this.hasOverrideBlockTexture()) { + this.colorRedTopLeft *= par5; + this.colorRedBottomLeft *= par5; + this.colorRedBottomRight *= par5; + this.colorRedTopRight *= par5; + this.colorGreenTopLeft *= par6; + this.colorGreenBottomLeft *= par6; + this.colorGreenBottomRight *= par6; + this.colorGreenTopRight *= par6; + this.colorBlueTopLeft *= par7; + this.colorBlueBottomLeft *= par7; + this.colorBlueBottomRight *= par7; + this.colorBlueTopRight *= par7; + this.renderFaceXNeg(par1Block, (double) par2, (double) par3, (double) par4, BlockGrass.getIconSideOverlay()); + } + + var8 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2 + 1, par3, par4, 5)) { + if (this.renderMaxX >= 1.0D) { + ++par2; + } + + this.aoLightValueScratchXYPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4); + this.aoLightValueScratchXZPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 - 1); + this.aoLightValueScratchXZPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 + 1); + this.aoLightValueScratchXYPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4); + this.aoBrightnessXYPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4); + this.aoBrightnessXZPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 - 1); + this.aoBrightnessXZPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 + 1); + this.aoBrightnessXYPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4); + var16 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3 + 1, par4)]; + var17 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3 - 1, par4)]; + var18 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3, par4 + 1)]; + var19 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3, par4 - 1)]; + + if (!var17 && !var19) { + this.aoLightValueScratchXYZPNN = this.aoLightValueScratchXZPN; + this.aoBrightnessXYZPNN = this.aoBrightnessXZPN; + } else { + this.aoLightValueScratchXYZPNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4 - 1); + this.aoBrightnessXYZPNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4 - 1); + } + + if (!var17 && !var18) { + this.aoLightValueScratchXYZPNP = this.aoLightValueScratchXZPP; + this.aoBrightnessXYZPNP = this.aoBrightnessXZPP; + } else { + this.aoLightValueScratchXYZPNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4 + 1); + this.aoBrightnessXYZPNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4 + 1); + } + + if (!var16 && !var19) { + this.aoLightValueScratchXYZPPN = this.aoLightValueScratchXZPN; + this.aoBrightnessXYZPPN = this.aoBrightnessXZPN; + } else { + this.aoLightValueScratchXYZPPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4 - 1); + this.aoBrightnessXYZPPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4 - 1); + } + + if (!var16 && !var18) { + this.aoLightValueScratchXYZPPP = this.aoLightValueScratchXZPP; + this.aoBrightnessXYZPPP = this.aoBrightnessXZPP; + } else { + this.aoLightValueScratchXYZPPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4 + 1); + this.aoBrightnessXYZPPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4 + 1); + } + + if (this.renderMaxX >= 1.0D) { + --par2; + } + + var20 = var14; + + if (this.renderMaxX >= 1.0D || !this.blockAccess.isBlockOpaqueCube(par2 + 1, par3, par4)) { + var20 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4); + } + + var21 = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4); + var9 = (this.aoLightValueScratchXYPN + this.aoLightValueScratchXYZPNP + var21 + this.aoLightValueScratchXZPP) / 4.0F; + var10 = (this.aoLightValueScratchXYZPNN + this.aoLightValueScratchXYPN + this.aoLightValueScratchXZPN + var21) / 4.0F; + var11 = (this.aoLightValueScratchXZPN + var21 + this.aoLightValueScratchXYZPPN + this.aoLightValueScratchXYPP) / 4.0F; + var12 = (var21 + this.aoLightValueScratchXZPP + this.aoLightValueScratchXYPP + this.aoLightValueScratchXYZPPP) / 4.0F; + this.brightnessTopLeft = this.getAoBrightness(this.aoBrightnessXYPN, this.aoBrightnessXYZPNP, this.aoBrightnessXZPP, var20); + this.brightnessTopRight = this.getAoBrightness(this.aoBrightnessXZPP, this.aoBrightnessXYPP, this.aoBrightnessXYZPPP, var20); + this.brightnessBottomRight = this.getAoBrightness(this.aoBrightnessXZPN, this.aoBrightnessXYZPPN, this.aoBrightnessXYPP, var20); + this.brightnessBottomLeft = this.getAoBrightness(this.aoBrightnessXYZPNN, this.aoBrightnessXYPN, this.aoBrightnessXZPN, var20); + + if (var13) { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = par5 * 0.6F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = par6 * 0.6F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = par7 * 0.6F; + } else { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = 0.6F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = 0.6F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = 0.6F; + } + + this.colorRedTopLeft *= var9; + this.colorGreenTopLeft *= var9; + this.colorBlueTopLeft *= var9; + this.colorRedBottomLeft *= var10; + this.colorGreenBottomLeft *= var10; + this.colorBlueBottomLeft *= var10; + this.colorRedBottomRight *= var11; + this.colorGreenBottomRight *= var11; + this.colorBlueBottomRight *= var11; + this.colorRedTopRight *= var12; + this.colorGreenTopRight *= var12; + this.colorBlueTopRight *= var12; + var22 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 5); + this.renderFaceXPos(par1Block, (double) par2, (double) par3, (double) par4, var22); + + if (fancyGrass && var22.getIconName().equals("grass_side") && !this.hasOverrideBlockTexture()) { + this.colorRedTopLeft *= par5; + this.colorRedBottomLeft *= par5; + this.colorRedBottomRight *= par5; + this.colorRedTopRight *= par5; + this.colorGreenTopLeft *= par6; + this.colorGreenBottomLeft *= par6; + this.colorGreenBottomRight *= par6; + this.colorGreenTopRight *= par6; + this.colorBlueTopLeft *= par7; + this.colorBlueBottomLeft *= par7; + this.colorBlueBottomRight *= par7; + this.colorBlueTopRight *= par7; + this.renderFaceXPos(par1Block, (double) par2, (double) par3, (double) par4, BlockGrass.getIconSideOverlay()); + } + + var8 = true; + } + + this.enableAO = false; + return var8; + } + + public boolean func_102027_b(Block par1Block, int par2, int par3, int par4, float par5, float par6, float par7) { + this.enableAO = true; + boolean var8 = false; + float var9 = 0.0F; + float var10 = 0.0F; + float var11 = 0.0F; + float var12 = 0.0F; + boolean var13 = true; + int var14 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4); + Tessellator var15 = Tessellator.instance; + var15.setBrightness(983055); + + if (this.getBlockIcon(par1Block).getIconName().equals("grass_top")) { + var13 = false; + } else if (this.hasOverrideBlockTexture()) { + var13 = false; + } + + boolean var16; + boolean var17; + boolean var18; + boolean var19; + int var20; + float var21; + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3 - 1, par4, 0)) { + if (this.renderMinY <= 0.0D) { + --par3; + } + + this.aoBrightnessXYNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4); + this.aoBrightnessYZNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 - 1); + this.aoBrightnessYZNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 + 1); + this.aoBrightnessXYPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4); + this.aoLightValueScratchXYNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4); + this.aoLightValueScratchYZNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 - 1); + this.aoLightValueScratchYZNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 + 1); + this.aoLightValueScratchXYPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4); + var16 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3 - 1, par4)]; + var17 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3 - 1, par4)]; + var18 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 - 1, par4 + 1)]; + var19 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 - 1, par4 - 1)]; + + if (!var19 && !var17) { + this.aoLightValueScratchXYZNNN = this.aoLightValueScratchXYNN; + this.aoBrightnessXYZNNN = this.aoBrightnessXYNN; + } else { + this.aoLightValueScratchXYZNNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4 - 1); + this.aoBrightnessXYZNNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4 - 1); + } + + if (!var18 && !var17) { + this.aoLightValueScratchXYZNNP = this.aoLightValueScratchXYNN; + this.aoBrightnessXYZNNP = this.aoBrightnessXYNN; + } else { + this.aoLightValueScratchXYZNNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4 + 1); + this.aoBrightnessXYZNNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4 + 1); + } + + if (!var19 && !var16) { + this.aoLightValueScratchXYZPNN = this.aoLightValueScratchXYPN; + this.aoBrightnessXYZPNN = this.aoBrightnessXYPN; + } else { + this.aoLightValueScratchXYZPNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4 - 1); + this.aoBrightnessXYZPNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4 - 1); + } + + if (!var18 && !var16) { + this.aoLightValueScratchXYZPNP = this.aoLightValueScratchXYPN; + this.aoBrightnessXYZPNP = this.aoBrightnessXYPN; + } else { + this.aoLightValueScratchXYZPNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4 + 1); + this.aoBrightnessXYZPNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4 + 1); + } + + if (this.renderMinY <= 0.0D) { + ++par3; + } + + var20 = var14; + + if (this.renderMinY <= 0.0D || !this.blockAccess.isBlockOpaqueCube(par2, par3 - 1, par4)) { + var20 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4); + } + + var21 = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4); + var9 = (this.aoLightValueScratchXYZNNP + this.aoLightValueScratchXYNN + this.aoLightValueScratchYZNP + var21) / 4.0F; + var12 = (this.aoLightValueScratchYZNP + var21 + this.aoLightValueScratchXYZPNP + this.aoLightValueScratchXYPN) / 4.0F; + var11 = (var21 + this.aoLightValueScratchYZNN + this.aoLightValueScratchXYPN + this.aoLightValueScratchXYZPNN) / 4.0F; + var10 = (this.aoLightValueScratchXYNN + this.aoLightValueScratchXYZNNN + var21 + this.aoLightValueScratchYZNN) / 4.0F; + this.brightnessTopLeft = this.getAoBrightness(this.aoBrightnessXYZNNP, this.aoBrightnessXYNN, this.aoBrightnessYZNP, var20); + this.brightnessTopRight = this.getAoBrightness(this.aoBrightnessYZNP, this.aoBrightnessXYZPNP, this.aoBrightnessXYPN, var20); + this.brightnessBottomRight = this.getAoBrightness(this.aoBrightnessYZNN, this.aoBrightnessXYPN, this.aoBrightnessXYZPNN, var20); + this.brightnessBottomLeft = this.getAoBrightness(this.aoBrightnessXYNN, this.aoBrightnessXYZNNN, this.aoBrightnessYZNN, var20); + + if (var13) { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = par5 * 0.5F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = par6 * 0.5F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = par7 * 0.5F; + } else { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = 0.5F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = 0.5F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = 0.5F; + } + + this.colorRedTopLeft *= var9; + this.colorGreenTopLeft *= var9; + this.colorBlueTopLeft *= var9; + this.colorRedBottomLeft *= var10; + this.colorGreenBottomLeft *= var10; + this.colorBlueBottomLeft *= var10; + this.colorRedBottomRight *= var11; + this.colorGreenBottomRight *= var11; + this.colorBlueBottomRight *= var11; + this.colorRedTopRight *= var12; + this.colorGreenTopRight *= var12; + this.colorBlueTopRight *= var12; + this.renderFaceYNeg(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 0)); + var8 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3 + 1, par4, 1)) { + if (this.renderMaxY >= 1.0D) { + ++par3; + } + + this.aoBrightnessXYNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4); + this.aoBrightnessXYPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4); + this.aoBrightnessYZPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 - 1); + this.aoBrightnessYZPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 + 1); + this.aoLightValueScratchXYNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4); + this.aoLightValueScratchXYPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4); + this.aoLightValueScratchYZPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 - 1); + this.aoLightValueScratchYZPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 + 1); + var16 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3 + 1, par4)]; + var17 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3 + 1, par4)]; + var18 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 + 1, par4 + 1)]; + var19 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 + 1, par4 - 1)]; + + if (!var19 && !var17) { + this.aoLightValueScratchXYZNPN = this.aoLightValueScratchXYNP; + this.aoBrightnessXYZNPN = this.aoBrightnessXYNP; + } else { + this.aoLightValueScratchXYZNPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4 - 1); + this.aoBrightnessXYZNPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4 - 1); + } + + if (!var19 && !var16) { + this.aoLightValueScratchXYZPPN = this.aoLightValueScratchXYPP; + this.aoBrightnessXYZPPN = this.aoBrightnessXYPP; + } else { + this.aoLightValueScratchXYZPPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4 - 1); + this.aoBrightnessXYZPPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4 - 1); + } + + if (!var18 && !var17) { + this.aoLightValueScratchXYZNPP = this.aoLightValueScratchXYNP; + this.aoBrightnessXYZNPP = this.aoBrightnessXYNP; + } else { + this.aoLightValueScratchXYZNPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4 + 1); + this.aoBrightnessXYZNPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4 + 1); + } + + if (!var18 && !var16) { + this.aoLightValueScratchXYZPPP = this.aoLightValueScratchXYPP; + this.aoBrightnessXYZPPP = this.aoBrightnessXYPP; + } else { + this.aoLightValueScratchXYZPPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4 + 1); + this.aoBrightnessXYZPPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4 + 1); + } + + if (this.renderMaxY >= 1.0D) { + --par3; + } + + var20 = var14; + + if (this.renderMaxY >= 1.0D || !this.blockAccess.isBlockOpaqueCube(par2, par3 + 1, par4)) { + var20 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4); + } + + var21 = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4); + var12 = (this.aoLightValueScratchXYZNPP + this.aoLightValueScratchXYNP + this.aoLightValueScratchYZPP + var21) / 4.0F; + var9 = (this.aoLightValueScratchYZPP + var21 + this.aoLightValueScratchXYZPPP + this.aoLightValueScratchXYPP) / 4.0F; + var10 = (var21 + this.aoLightValueScratchYZPN + this.aoLightValueScratchXYPP + this.aoLightValueScratchXYZPPN) / 4.0F; + var11 = (this.aoLightValueScratchXYNP + this.aoLightValueScratchXYZNPN + var21 + this.aoLightValueScratchYZPN) / 4.0F; + this.brightnessTopRight = this.getAoBrightness(this.aoBrightnessXYZNPP, this.aoBrightnessXYNP, this.aoBrightnessYZPP, var20); + this.brightnessTopLeft = this.getAoBrightness(this.aoBrightnessYZPP, this.aoBrightnessXYZPPP, this.aoBrightnessXYPP, var20); + this.brightnessBottomLeft = this.getAoBrightness(this.aoBrightnessYZPN, this.aoBrightnessXYPP, this.aoBrightnessXYZPPN, var20); + this.brightnessBottomRight = this.getAoBrightness(this.aoBrightnessXYNP, this.aoBrightnessXYZNPN, this.aoBrightnessYZPN, var20); + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = par5; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = par6; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = par7; + this.colorRedTopLeft *= var9; + this.colorGreenTopLeft *= var9; + this.colorBlueTopLeft *= var9; + this.colorRedBottomLeft *= var10; + this.colorGreenBottomLeft *= var10; + this.colorBlueBottomLeft *= var10; + this.colorRedBottomRight *= var11; + this.colorGreenBottomRight *= var11; + this.colorBlueBottomRight *= var11; + this.colorRedTopRight *= var12; + this.colorGreenTopRight *= var12; + this.colorBlueTopRight *= var12; + this.renderFaceYPos(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 1)); + var8 = true; + } + + float var22; + float var23; + float var24; + float var25; + int var26; + int var27; + int var28; + int var29; + Icon var30; + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3, par4 - 1, 2)) { + if (this.renderMinZ <= 0.0D) { + --par4; + } + + this.aoLightValueScratchXZNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4); + this.aoLightValueScratchYZNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4); + this.aoLightValueScratchYZPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4); + this.aoLightValueScratchXZPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4); + this.aoBrightnessXZNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4); + this.aoBrightnessYZNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4); + this.aoBrightnessYZPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4); + this.aoBrightnessXZPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4); + var16 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3, par4 - 1)]; + var17 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3, par4 - 1)]; + var18 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 + 1, par4 - 1)]; + var19 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 - 1, par4 - 1)]; + + if (!var17 && !var19) { + this.aoLightValueScratchXYZNNN = this.aoLightValueScratchXZNN; + this.aoBrightnessXYZNNN = this.aoBrightnessXZNN; + } else { + this.aoLightValueScratchXYZNNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3 - 1, par4); + this.aoBrightnessXYZNNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3 - 1, par4); + } + + if (!var17 && !var18) { + this.aoLightValueScratchXYZNPN = this.aoLightValueScratchXZNN; + this.aoBrightnessXYZNPN = this.aoBrightnessXZNN; + } else { + this.aoLightValueScratchXYZNPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3 + 1, par4); + this.aoBrightnessXYZNPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3 + 1, par4); + } + + if (!var16 && !var19) { + this.aoLightValueScratchXYZPNN = this.aoLightValueScratchXZPN; + this.aoBrightnessXYZPNN = this.aoBrightnessXZPN; + } else { + this.aoLightValueScratchXYZPNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3 - 1, par4); + this.aoBrightnessXYZPNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3 - 1, par4); + } + + if (!var16 && !var18) { + this.aoLightValueScratchXYZPPN = this.aoLightValueScratchXZPN; + this.aoBrightnessXYZPPN = this.aoBrightnessXZPN; + } else { + this.aoLightValueScratchXYZPPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3 + 1, par4); + this.aoBrightnessXYZPPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3 + 1, par4); + } + + if (this.renderMinZ <= 0.0D) { + ++par4; + } + + var20 = var14; + + if (this.renderMinZ <= 0.0D || !this.blockAccess.isBlockOpaqueCube(par2, par3, par4 - 1)) { + var20 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 - 1); + } + + var21 = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 - 1); + var22 = (this.aoLightValueScratchXZNN + this.aoLightValueScratchXYZNPN + var21 + this.aoLightValueScratchYZPN) / 4.0F; + var23 = (var21 + this.aoLightValueScratchYZPN + this.aoLightValueScratchXZPN + this.aoLightValueScratchXYZPPN) / 4.0F; + var24 = (this.aoLightValueScratchYZNN + var21 + this.aoLightValueScratchXYZPNN + this.aoLightValueScratchXZPN) / 4.0F; + var25 = (this.aoLightValueScratchXYZNNN + this.aoLightValueScratchXZNN + this.aoLightValueScratchYZNN + var21) / 4.0F; + var9 = (float) ((double) var22 * this.renderMaxY * (1.0D - this.renderMinX) + (double) var23 * this.renderMinY * this.renderMinX + (double) var24 * (1.0D - this.renderMaxY) * this.renderMinX + + (double) var25 * (1.0D - this.renderMaxY) * (1.0D - this.renderMinX)); + var10 = (float) ((double) var22 * this.renderMaxY * (1.0D - this.renderMaxX) + (double) var23 * this.renderMaxY * this.renderMaxX + (double) var24 * (1.0D - this.renderMaxY) * this.renderMaxX + + (double) var25 * (1.0D - this.renderMaxY) * (1.0D - this.renderMaxX)); + var11 = (float) ((double) var22 * this.renderMinY * (1.0D - this.renderMaxX) + (double) var23 * this.renderMinY * this.renderMaxX + (double) var24 * (1.0D - this.renderMinY) * this.renderMaxX + + (double) var25 * (1.0D - this.renderMinY) * (1.0D - this.renderMaxX)); + var12 = (float) ((double) var22 * this.renderMinY * (1.0D - this.renderMinX) + (double) var23 * this.renderMinY * this.renderMinX + (double) var24 * (1.0D - this.renderMinY) * this.renderMinX + + (double) var25 * (1.0D - this.renderMinY) * (1.0D - this.renderMinX)); + var26 = this.getAoBrightness(this.aoBrightnessXZNN, this.aoBrightnessXYZNPN, this.aoBrightnessYZPN, var20); + var27 = this.getAoBrightness(this.aoBrightnessYZPN, this.aoBrightnessXZPN, this.aoBrightnessXYZPPN, var20); + var28 = this.getAoBrightness(this.aoBrightnessYZNN, this.aoBrightnessXYZPNN, this.aoBrightnessXZPN, var20); + var29 = this.getAoBrightness(this.aoBrightnessXYZNNN, this.aoBrightnessXZNN, this.aoBrightnessYZNN, var20); + this.brightnessTopLeft = this.mixAoBrightness(var26, var27, var28, var29, this.renderMaxY * (1.0D - this.renderMinX), this.renderMaxY * this.renderMinX, (1.0D - this.renderMaxY) * this.renderMinX, + (1.0D - this.renderMaxY) * (1.0D - this.renderMinX)); + this.brightnessBottomLeft = this.mixAoBrightness(var26, var27, var28, var29, this.renderMaxY * (1.0D - this.renderMaxX), this.renderMaxY * this.renderMaxX, (1.0D - this.renderMaxY) * this.renderMaxX, + (1.0D - this.renderMaxY) * (1.0D - this.renderMaxX)); + this.brightnessBottomRight = this.mixAoBrightness(var26, var27, var28, var29, this.renderMinY * (1.0D - this.renderMaxX), this.renderMinY * this.renderMaxX, (1.0D - this.renderMinY) * this.renderMaxX, + (1.0D - this.renderMinY) * (1.0D - this.renderMaxX)); + this.brightnessTopRight = this.mixAoBrightness(var26, var27, var28, var29, this.renderMinY * (1.0D - this.renderMinX), this.renderMinY * this.renderMinX, (1.0D - this.renderMinY) * this.renderMinX, + (1.0D - this.renderMinY) * (1.0D - this.renderMinX)); + + if (var13) { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = par5 * 0.8F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = par6 * 0.8F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = par7 * 0.8F; + } else { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = 0.8F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = 0.8F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = 0.8F; + } + + this.colorRedTopLeft *= var9; + this.colorGreenTopLeft *= var9; + this.colorBlueTopLeft *= var9; + this.colorRedBottomLeft *= var10; + this.colorGreenBottomLeft *= var10; + this.colorBlueBottomLeft *= var10; + this.colorRedBottomRight *= var11; + this.colorGreenBottomRight *= var11; + this.colorBlueBottomRight *= var11; + this.colorRedTopRight *= var12; + this.colorGreenTopRight *= var12; + this.colorBlueTopRight *= var12; + var30 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 2); + this.renderFaceZNeg(par1Block, (double) par2, (double) par3, (double) par4, var30); + + if (fancyGrass && var30.getIconName().equals("grass_side") && !this.hasOverrideBlockTexture()) { + this.colorRedTopLeft *= par5; + this.colorRedBottomLeft *= par5; + this.colorRedBottomRight *= par5; + this.colorRedTopRight *= par5; + this.colorGreenTopLeft *= par6; + this.colorGreenBottomLeft *= par6; + this.colorGreenBottomRight *= par6; + this.colorGreenTopRight *= par6; + this.colorBlueTopLeft *= par7; + this.colorBlueBottomLeft *= par7; + this.colorBlueBottomRight *= par7; + this.colorBlueTopRight *= par7; + this.renderFaceZNeg(par1Block, (double) par2, (double) par3, (double) par4, BlockGrass.getIconSideOverlay()); + } + + var8 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3, par4 + 1, 3)) { + if (this.renderMaxZ >= 1.0D) { + ++par4; + } + + this.aoLightValueScratchXZNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4); + this.aoLightValueScratchXZPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4); + this.aoLightValueScratchYZNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4); + this.aoLightValueScratchYZPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4); + this.aoBrightnessXZNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4); + this.aoBrightnessXZPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4); + this.aoBrightnessYZNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4); + this.aoBrightnessYZPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4); + var16 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3, par4 + 1)]; + var17 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3, par4 + 1)]; + var18 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 + 1, par4 + 1)]; + var19 = Block.canBlockGrass[this.blockAccess.getBlockId(par2, par3 - 1, par4 + 1)]; + + if (!var17 && !var19) { + this.aoLightValueScratchXYZNNP = this.aoLightValueScratchXZNP; + this.aoBrightnessXYZNNP = this.aoBrightnessXZNP; + } else { + this.aoLightValueScratchXYZNNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3 - 1, par4); + this.aoBrightnessXYZNNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3 - 1, par4); + } + + if (!var17 && !var18) { + this.aoLightValueScratchXYZNPP = this.aoLightValueScratchXZNP; + this.aoBrightnessXYZNPP = this.aoBrightnessXZNP; + } else { + this.aoLightValueScratchXYZNPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3 + 1, par4); + this.aoBrightnessXYZNPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3 + 1, par4); + } + + if (!var16 && !var19) { + this.aoLightValueScratchXYZPNP = this.aoLightValueScratchXZPP; + this.aoBrightnessXYZPNP = this.aoBrightnessXZPP; + } else { + this.aoLightValueScratchXYZPNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3 - 1, par4); + this.aoBrightnessXYZPNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3 - 1, par4); + } + + if (!var16 && !var18) { + this.aoLightValueScratchXYZPPP = this.aoLightValueScratchXZPP; + this.aoBrightnessXYZPPP = this.aoBrightnessXZPP; + } else { + this.aoLightValueScratchXYZPPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3 + 1, par4); + this.aoBrightnessXYZPPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3 + 1, par4); + } + + if (this.renderMaxZ >= 1.0D) { + --par4; + } + + var20 = var14; + + if (this.renderMaxZ >= 1.0D || !this.blockAccess.isBlockOpaqueCube(par2, par3, par4 + 1)) { + var20 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 + 1); + } + + var21 = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 + 1); + var22 = (this.aoLightValueScratchXZNP + this.aoLightValueScratchXYZNPP + var21 + this.aoLightValueScratchYZPP) / 4.0F; + var23 = (var21 + this.aoLightValueScratchYZPP + this.aoLightValueScratchXZPP + this.aoLightValueScratchXYZPPP) / 4.0F; + var24 = (this.aoLightValueScratchYZNP + var21 + this.aoLightValueScratchXYZPNP + this.aoLightValueScratchXZPP) / 4.0F; + var25 = (this.aoLightValueScratchXYZNNP + this.aoLightValueScratchXZNP + this.aoLightValueScratchYZNP + var21) / 4.0F; + var9 = (float) ((double) var22 * this.renderMaxY * (1.0D - this.renderMinX) + (double) var23 * this.renderMaxY * this.renderMinX + (double) var24 * (1.0D - this.renderMaxY) * this.renderMinX + + (double) var25 * (1.0D - this.renderMaxY) * (1.0D - this.renderMinX)); + var10 = (float) ((double) var22 * this.renderMinY * (1.0D - this.renderMinX) + (double) var23 * this.renderMinY * this.renderMinX + (double) var24 * (1.0D - this.renderMinY) * this.renderMinX + + (double) var25 * (1.0D - this.renderMinY) * (1.0D - this.renderMinX)); + var11 = (float) ((double) var22 * this.renderMinY * (1.0D - this.renderMaxX) + (double) var23 * this.renderMinY * this.renderMaxX + (double) var24 * (1.0D - this.renderMinY) * this.renderMaxX + + (double) var25 * (1.0D - this.renderMinY) * (1.0D - this.renderMaxX)); + var12 = (float) ((double) var22 * this.renderMaxY * (1.0D - this.renderMaxX) + (double) var23 * this.renderMaxY * this.renderMaxX + (double) var24 * (1.0D - this.renderMaxY) * this.renderMaxX + + (double) var25 * (1.0D - this.renderMaxY) * (1.0D - this.renderMaxX)); + var26 = this.getAoBrightness(this.aoBrightnessXZNP, this.aoBrightnessXYZNPP, this.aoBrightnessYZPP, var20); + var27 = this.getAoBrightness(this.aoBrightnessYZPP, this.aoBrightnessXZPP, this.aoBrightnessXYZPPP, var20); + var28 = this.getAoBrightness(this.aoBrightnessYZNP, this.aoBrightnessXYZPNP, this.aoBrightnessXZPP, var20); + var29 = this.getAoBrightness(this.aoBrightnessXYZNNP, this.aoBrightnessXZNP, this.aoBrightnessYZNP, var20); + this.brightnessTopLeft = this.mixAoBrightness(var26, var29, var28, var27, this.renderMaxY * (1.0D - this.renderMinX), (1.0D - this.renderMaxY) * (1.0D - this.renderMinX), (1.0D - this.renderMaxY) * this.renderMinX, + this.renderMaxY * this.renderMinX); + this.brightnessBottomLeft = this.mixAoBrightness(var26, var29, var28, var27, this.renderMinY * (1.0D - this.renderMinX), (1.0D - this.renderMinY) * (1.0D - this.renderMinX), (1.0D - this.renderMinY) * this.renderMinX, + this.renderMinY * this.renderMinX); + this.brightnessBottomRight = this.mixAoBrightness(var26, var29, var28, var27, this.renderMinY * (1.0D - this.renderMaxX), (1.0D - this.renderMinY) * (1.0D - this.renderMaxX), (1.0D - this.renderMinY) * this.renderMaxX, + this.renderMinY * this.renderMaxX); + this.brightnessTopRight = this.mixAoBrightness(var26, var29, var28, var27, this.renderMaxY * (1.0D - this.renderMaxX), (1.0D - this.renderMaxY) * (1.0D - this.renderMaxX), (1.0D - this.renderMaxY) * this.renderMaxX, + this.renderMaxY * this.renderMaxX); + + if (var13) { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = par5 * 0.8F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = par6 * 0.8F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = par7 * 0.8F; + } else { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = 0.8F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = 0.8F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = 0.8F; + } + + this.colorRedTopLeft *= var9; + this.colorGreenTopLeft *= var9; + this.colorBlueTopLeft *= var9; + this.colorRedBottomLeft *= var10; + this.colorGreenBottomLeft *= var10; + this.colorBlueBottomLeft *= var10; + this.colorRedBottomRight *= var11; + this.colorGreenBottomRight *= var11; + this.colorBlueBottomRight *= var11; + this.colorRedTopRight *= var12; + this.colorGreenTopRight *= var12; + this.colorBlueTopRight *= var12; + var30 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 3); + this.renderFaceZPos(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 3)); + + if (fancyGrass && var30.getIconName().equals("grass_side") && !this.hasOverrideBlockTexture()) { + this.colorRedTopLeft *= par5; + this.colorRedBottomLeft *= par5; + this.colorRedBottomRight *= par5; + this.colorRedTopRight *= par5; + this.colorGreenTopLeft *= par6; + this.colorGreenBottomLeft *= par6; + this.colorGreenBottomRight *= par6; + this.colorGreenTopRight *= par6; + this.colorBlueTopLeft *= par7; + this.colorBlueBottomLeft *= par7; + this.colorBlueBottomRight *= par7; + this.colorBlueTopRight *= par7; + this.renderFaceZPos(par1Block, (double) par2, (double) par3, (double) par4, BlockGrass.getIconSideOverlay()); + } + + var8 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2 - 1, par3, par4, 4)) { + if (this.renderMinX <= 0.0D) { + --par2; + } + + this.aoLightValueScratchXYNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4); + this.aoLightValueScratchXZNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 - 1); + this.aoLightValueScratchXZNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 + 1); + this.aoLightValueScratchXYNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4); + this.aoBrightnessXYNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4); + this.aoBrightnessXZNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 - 1); + this.aoBrightnessXZNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 + 1); + this.aoBrightnessXYNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4); + var16 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3 + 1, par4)]; + var17 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3 - 1, par4)]; + var18 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3, par4 - 1)]; + var19 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 - 1, par3, par4 + 1)]; + + if (!var18 && !var17) { + this.aoLightValueScratchXYZNNN = this.aoLightValueScratchXZNN; + this.aoBrightnessXYZNNN = this.aoBrightnessXZNN; + } else { + this.aoLightValueScratchXYZNNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4 - 1); + this.aoBrightnessXYZNNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4 - 1); + } + + if (!var19 && !var17) { + this.aoLightValueScratchXYZNNP = this.aoLightValueScratchXZNP; + this.aoBrightnessXYZNNP = this.aoBrightnessXZNP; + } else { + this.aoLightValueScratchXYZNNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4 + 1); + this.aoBrightnessXYZNNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4 + 1); + } + + if (!var18 && !var16) { + this.aoLightValueScratchXYZNPN = this.aoLightValueScratchXZNN; + this.aoBrightnessXYZNPN = this.aoBrightnessXZNN; + } else { + this.aoLightValueScratchXYZNPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4 - 1); + this.aoBrightnessXYZNPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4 - 1); + } + + if (!var19 && !var16) { + this.aoLightValueScratchXYZNPP = this.aoLightValueScratchXZNP; + this.aoBrightnessXYZNPP = this.aoBrightnessXZNP; + } else { + this.aoLightValueScratchXYZNPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4 + 1); + this.aoBrightnessXYZNPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4 + 1); + } + + if (this.renderMinX <= 0.0D) { + ++par2; + } + + var20 = var14; + + if (this.renderMinX <= 0.0D || !this.blockAccess.isBlockOpaqueCube(par2 - 1, par3, par4)) { + var20 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4); + } + + var21 = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 - 1, par3, par4); + var22 = (this.aoLightValueScratchXYNN + this.aoLightValueScratchXYZNNP + var21 + this.aoLightValueScratchXZNP) / 4.0F; + var23 = (var21 + this.aoLightValueScratchXZNP + this.aoLightValueScratchXYNP + this.aoLightValueScratchXYZNPP) / 4.0F; + var24 = (this.aoLightValueScratchXZNN + var21 + this.aoLightValueScratchXYZNPN + this.aoLightValueScratchXYNP) / 4.0F; + var25 = (this.aoLightValueScratchXYZNNN + this.aoLightValueScratchXYNN + this.aoLightValueScratchXZNN + var21) / 4.0F; + var9 = (float) ((double) var23 * this.renderMaxY * this.renderMaxZ + (double) var24 * this.renderMaxY * (1.0D - this.renderMaxZ) + (double) var25 * (1.0D - this.renderMaxY) * (1.0D - this.renderMaxZ) + + (double) var22 * (1.0D - this.renderMaxY) * this.renderMaxZ); + var10 = (float) ((double) var23 * this.renderMaxY * this.renderMinZ + (double) var24 * this.renderMaxY * (1.0D - this.renderMinZ) + (double) var25 * (1.0D - this.renderMaxY) * (1.0D - this.renderMinZ) + + (double) var22 * (1.0D - this.renderMaxY) * this.renderMinZ); + var11 = (float) ((double) var23 * this.renderMinY * this.renderMinZ + (double) var24 * this.renderMinY * (1.0D - this.renderMinZ) + (double) var25 * (1.0D - this.renderMinY) * (1.0D - this.renderMinZ) + + (double) var22 * (1.0D - this.renderMinY) * this.renderMinZ); + var12 = (float) ((double) var23 * this.renderMinY * this.renderMaxZ + (double) var24 * this.renderMinY * (1.0D - this.renderMaxZ) + (double) var25 * (1.0D - this.renderMinY) * (1.0D - this.renderMaxZ) + + (double) var22 * (1.0D - this.renderMinY) * this.renderMaxZ); + var26 = this.getAoBrightness(this.aoBrightnessXYNN, this.aoBrightnessXYZNNP, this.aoBrightnessXZNP, var20); + var27 = this.getAoBrightness(this.aoBrightnessXZNP, this.aoBrightnessXYNP, this.aoBrightnessXYZNPP, var20); + var28 = this.getAoBrightness(this.aoBrightnessXZNN, this.aoBrightnessXYZNPN, this.aoBrightnessXYNP, var20); + var29 = this.getAoBrightness(this.aoBrightnessXYZNNN, this.aoBrightnessXYNN, this.aoBrightnessXZNN, var20); + this.brightnessTopLeft = this.mixAoBrightness(var27, var28, var29, var26, this.renderMaxY * this.renderMaxZ, this.renderMaxY * (1.0D - this.renderMaxZ), (1.0D - this.renderMaxY) * (1.0D - this.renderMaxZ), + (1.0D - this.renderMaxY) * this.renderMaxZ); + this.brightnessBottomLeft = this.mixAoBrightness(var27, var28, var29, var26, this.renderMaxY * this.renderMinZ, this.renderMaxY * (1.0D - this.renderMinZ), (1.0D - this.renderMaxY) * (1.0D - this.renderMinZ), + (1.0D - this.renderMaxY) * this.renderMinZ); + this.brightnessBottomRight = this.mixAoBrightness(var27, var28, var29, var26, this.renderMinY * this.renderMinZ, this.renderMinY * (1.0D - this.renderMinZ), (1.0D - this.renderMinY) * (1.0D - this.renderMinZ), + (1.0D - this.renderMinY) * this.renderMinZ); + this.brightnessTopRight = this.mixAoBrightness(var27, var28, var29, var26, this.renderMinY * this.renderMaxZ, this.renderMinY * (1.0D - this.renderMaxZ), (1.0D - this.renderMinY) * (1.0D - this.renderMaxZ), + (1.0D - this.renderMinY) * this.renderMaxZ); + + if (var13) { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = par5 * 0.6F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = par6 * 0.6F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = par7 * 0.6F; + } else { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = 0.6F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = 0.6F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = 0.6F; + } + + this.colorRedTopLeft *= var9; + this.colorGreenTopLeft *= var9; + this.colorBlueTopLeft *= var9; + this.colorRedBottomLeft *= var10; + this.colorGreenBottomLeft *= var10; + this.colorBlueBottomLeft *= var10; + this.colorRedBottomRight *= var11; + this.colorGreenBottomRight *= var11; + this.colorBlueBottomRight *= var11; + this.colorRedTopRight *= var12; + this.colorGreenTopRight *= var12; + this.colorBlueTopRight *= var12; + var30 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 4); + this.renderFaceXNeg(par1Block, (double) par2, (double) par3, (double) par4, var30); + + if (fancyGrass && var30.getIconName().equals("grass_side") && !this.hasOverrideBlockTexture()) { + this.colorRedTopLeft *= par5; + this.colorRedBottomLeft *= par5; + this.colorRedBottomRight *= par5; + this.colorRedTopRight *= par5; + this.colorGreenTopLeft *= par6; + this.colorGreenBottomLeft *= par6; + this.colorGreenBottomRight *= par6; + this.colorGreenTopRight *= par6; + this.colorBlueTopLeft *= par7; + this.colorBlueBottomLeft *= par7; + this.colorBlueBottomRight *= par7; + this.colorBlueTopRight *= par7; + this.renderFaceXNeg(par1Block, (double) par2, (double) par3, (double) par4, BlockGrass.getIconSideOverlay()); + } + + var8 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2 + 1, par3, par4, 5)) { + if (this.renderMaxX >= 1.0D) { + ++par2; + } + + this.aoLightValueScratchXYPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4); + this.aoLightValueScratchXZPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 - 1); + this.aoLightValueScratchXZPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3, par4 + 1); + this.aoLightValueScratchXYPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4); + this.aoBrightnessXYPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4); + this.aoBrightnessXZPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 - 1); + this.aoBrightnessXZPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 + 1); + this.aoBrightnessXYPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4); + var16 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3 + 1, par4)]; + var17 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3 - 1, par4)]; + var18 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3, par4 + 1)]; + var19 = Block.canBlockGrass[this.blockAccess.getBlockId(par2 + 1, par3, par4 - 1)]; + + if (!var17 && !var19) { + this.aoLightValueScratchXYZPNN = this.aoLightValueScratchXZPN; + this.aoBrightnessXYZPNN = this.aoBrightnessXZPN; + } else { + this.aoLightValueScratchXYZPNN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4 - 1); + this.aoBrightnessXYZPNN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4 - 1); + } + + if (!var17 && !var18) { + this.aoLightValueScratchXYZPNP = this.aoLightValueScratchXZPP; + this.aoBrightnessXYZPNP = this.aoBrightnessXZPP; + } else { + this.aoLightValueScratchXYZPNP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 - 1, par4 + 1); + this.aoBrightnessXYZPNP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4 + 1); + } + + if (!var16 && !var19) { + this.aoLightValueScratchXYZPPN = this.aoLightValueScratchXZPN; + this.aoBrightnessXYZPPN = this.aoBrightnessXZPN; + } else { + this.aoLightValueScratchXYZPPN = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4 - 1); + this.aoBrightnessXYZPPN = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4 - 1); + } + + if (!var16 && !var18) { + this.aoLightValueScratchXYZPPP = this.aoLightValueScratchXZPP; + this.aoBrightnessXYZPPP = this.aoBrightnessXZPP; + } else { + this.aoLightValueScratchXYZPPP = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2, par3 + 1, par4 + 1); + this.aoBrightnessXYZPPP = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4 + 1); + } + + if (this.renderMaxX >= 1.0D) { + --par2; + } + + var20 = var14; + + if (this.renderMaxX >= 1.0D || !this.blockAccess.isBlockOpaqueCube(par2 + 1, par3, par4)) { + var20 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4); + } + + var21 = par1Block.getAmbientOcclusionLightValue(this.blockAccess, par2 + 1, par3, par4); + var22 = (this.aoLightValueScratchXYPN + this.aoLightValueScratchXYZPNP + var21 + this.aoLightValueScratchXZPP) / 4.0F; + var23 = (this.aoLightValueScratchXYZPNN + this.aoLightValueScratchXYPN + this.aoLightValueScratchXZPN + var21) / 4.0F; + var24 = (this.aoLightValueScratchXZPN + var21 + this.aoLightValueScratchXYZPPN + this.aoLightValueScratchXYPP) / 4.0F; + var25 = (var21 + this.aoLightValueScratchXZPP + this.aoLightValueScratchXYPP + this.aoLightValueScratchXYZPPP) / 4.0F; + var9 = (float) ((double) var22 * (1.0D - this.renderMinY) * this.renderMaxZ + (double) var23 * (1.0D - this.renderMinY) * (1.0D - this.renderMaxZ) + (double) var24 * this.renderMinY * (1.0D - this.renderMaxZ) + + (double) var25 * this.renderMinY * this.renderMaxZ); + var10 = (float) ((double) var22 * (1.0D - this.renderMinY) * this.renderMinZ + (double) var23 * (1.0D - this.renderMinY) * (1.0D - this.renderMinZ) + (double) var24 * this.renderMinY * (1.0D - this.renderMinZ) + + (double) var25 * this.renderMinY * this.renderMinZ); + var11 = (float) ((double) var22 * (1.0D - this.renderMaxY) * this.renderMinZ + (double) var23 * (1.0D - this.renderMaxY) * (1.0D - this.renderMinZ) + (double) var24 * this.renderMaxY * (1.0D - this.renderMinZ) + + (double) var25 * this.renderMaxY * this.renderMinZ); + var12 = (float) ((double) var22 * (1.0D - this.renderMaxY) * this.renderMaxZ + (double) var23 * (1.0D - this.renderMaxY) * (1.0D - this.renderMaxZ) + (double) var24 * this.renderMaxY * (1.0D - this.renderMaxZ) + + (double) var25 * this.renderMaxY * this.renderMaxZ); + var26 = this.getAoBrightness(this.aoBrightnessXYPN, this.aoBrightnessXYZPNP, this.aoBrightnessXZPP, var20); + var27 = this.getAoBrightness(this.aoBrightnessXZPP, this.aoBrightnessXYPP, this.aoBrightnessXYZPPP, var20); + var28 = this.getAoBrightness(this.aoBrightnessXZPN, this.aoBrightnessXYZPPN, this.aoBrightnessXYPP, var20); + var29 = this.getAoBrightness(this.aoBrightnessXYZPNN, this.aoBrightnessXYPN, this.aoBrightnessXZPN, var20); + this.brightnessTopLeft = this.mixAoBrightness(var26, var29, var28, var27, (1.0D - this.renderMinY) * this.renderMaxZ, (1.0D - this.renderMinY) * (1.0D - this.renderMaxZ), this.renderMinY * (1.0D - this.renderMaxZ), + this.renderMinY * this.renderMaxZ); + this.brightnessBottomLeft = this.mixAoBrightness(var26, var29, var28, var27, (1.0D - this.renderMinY) * this.renderMinZ, (1.0D - this.renderMinY) * (1.0D - this.renderMinZ), this.renderMinY * (1.0D - this.renderMinZ), + this.renderMinY * this.renderMinZ); + this.brightnessBottomRight = this.mixAoBrightness(var26, var29, var28, var27, (1.0D - this.renderMaxY) * this.renderMinZ, (1.0D - this.renderMaxY) * (1.0D - this.renderMinZ), this.renderMaxY * (1.0D - this.renderMinZ), + this.renderMaxY * this.renderMinZ); + this.brightnessTopRight = this.mixAoBrightness(var26, var29, var28, var27, (1.0D - this.renderMaxY) * this.renderMaxZ, (1.0D - this.renderMaxY) * (1.0D - this.renderMaxZ), this.renderMaxY * (1.0D - this.renderMaxZ), + this.renderMaxY * this.renderMaxZ); + + if (var13) { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = par5 * 0.6F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = par6 * 0.6F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = par7 * 0.6F; + } else { + this.colorRedTopLeft = this.colorRedBottomLeft = this.colorRedBottomRight = this.colorRedTopRight = 0.6F; + this.colorGreenTopLeft = this.colorGreenBottomLeft = this.colorGreenBottomRight = this.colorGreenTopRight = 0.6F; + this.colorBlueTopLeft = this.colorBlueBottomLeft = this.colorBlueBottomRight = this.colorBlueTopRight = 0.6F; + } + + this.colorRedTopLeft *= var9; + this.colorGreenTopLeft *= var9; + this.colorBlueTopLeft *= var9; + this.colorRedBottomLeft *= var10; + this.colorGreenBottomLeft *= var10; + this.colorBlueBottomLeft *= var10; + this.colorRedBottomRight *= var11; + this.colorGreenBottomRight *= var11; + this.colorBlueBottomRight *= var11; + this.colorRedTopRight *= var12; + this.colorGreenTopRight *= var12; + this.colorBlueTopRight *= var12; + var30 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 5); + this.renderFaceXPos(par1Block, (double) par2, (double) par3, (double) par4, var30); + + if (fancyGrass && var30.getIconName().equals("grass_side") && !this.hasOverrideBlockTexture()) { + this.colorRedTopLeft *= par5; + this.colorRedBottomLeft *= par5; + this.colorRedBottomRight *= par5; + this.colorRedTopRight *= par5; + this.colorGreenTopLeft *= par6; + this.colorGreenBottomLeft *= par6; + this.colorGreenBottomRight *= par6; + this.colorGreenTopRight *= par6; + this.colorBlueTopLeft *= par7; + this.colorBlueBottomLeft *= par7; + this.colorBlueBottomRight *= par7; + this.colorBlueTopRight *= par7; + this.renderFaceXPos(par1Block, (double) par2, (double) par3, (double) par4, BlockGrass.getIconSideOverlay()); + } + + var8 = true; + } + + this.enableAO = false; + return var8; + } + + /** + * Get ambient occlusion brightness + */ + private int getAoBrightness(int par1, int par2, int par3, int par4) { + if (par1 == 0) { + par1 = par4; + } + + if (par2 == 0) { + par2 = par4; + } + + if (par3 == 0) { + par3 = par4; + } + + return par1 + par2 + par3 + par4 >> 2 & 16711935; + } + + private int mixAoBrightness(int par1, int par2, int par3, int par4, double par5, double par7, double par9, double par11) { + int var13 = (int) ((double) (par1 >> 16 & 255) * par5 + (double) (par2 >> 16 & 255) * par7 + (double) (par3 >> 16 & 255) * par9 + (double) (par4 >> 16 & 255) * par11) & 255; + int var14 = (int) ((double) (par1 & 255) * par5 + (double) (par2 & 255) * par7 + (double) (par3 & 255) * par9 + (double) (par4 & 255) * par11) & 255; + return var13 << 16 | var14; + } + + /** + * Renders a standard cube block at the given coordinates, with a given color + * ratio. Args: block, x, y, z, r, g, b + */ + public boolean renderStandardBlockWithColorMultiplier(Block par1Block, int par2, int par3, int par4, float par5, float par6, float par7) { + this.enableAO = false; + Tessellator var8 = Tessellator.instance; + boolean var9 = false; + float var10 = 0.5F; + float var11 = 1.0F; + float var12 = 0.8F; + float var13 = 0.6F; + float var14 = var11 * par5; + float var15 = var11 * par6; + float var16 = var11 * par7; + float var17 = var10; + float var18 = var12; + float var19 = var13; + float var20 = var10; + float var21 = var12; + float var22 = var13; + float var23 = var10; + float var24 = var12; + float var25 = var13; + + if (par1Block != Block.grass) { + var17 = var10 * par5; + var18 = var12 * par5; + var19 = var13 * par5; + var20 = var10 * par6; + var21 = var12 * par6; + var22 = var13 * par6; + var23 = var10 * par7; + var24 = var12 * par7; + var25 = var13 * par7; + } + + int var26 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4); + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3 - 1, par4, 0)) { + var8.setBrightness(this.renderMinY > 0.0D ? var26 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4)); + var8.setColorOpaque_F(var17, var20, var23); + this.renderFaceYNeg(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 0)); + var9 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3 + 1, par4, 1)) { + var8.setBrightness(this.renderMaxY < 1.0D ? var26 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4)); + var8.setColorOpaque_F(var14, var15, var16); + this.renderFaceYPos(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 1)); + var9 = true; + } + + Icon var28; + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3, par4 - 1, 2)) { + var8.setBrightness(this.renderMinZ > 0.0D ? var26 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 - 1)); + var8.setColorOpaque_F(var18, var21, var24); + var28 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 2); + this.renderFaceZNeg(par1Block, (double) par2, (double) par3, (double) par4, var28); + + if (fancyGrass && var28.getIconName().equals("grass_side") && !this.hasOverrideBlockTexture()) { + var8.setColorOpaque_F(var18 * par5, var21 * par6, var24 * par7); + this.renderFaceZNeg(par1Block, (double) par2, (double) par3, (double) par4, BlockGrass.getIconSideOverlay()); + } + + var9 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3, par4 + 1, 3)) { + var8.setBrightness(this.renderMaxZ < 1.0D ? var26 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 + 1)); + var8.setColorOpaque_F(var18, var21, var24); + var28 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 3); + this.renderFaceZPos(par1Block, (double) par2, (double) par3, (double) par4, var28); + + if (fancyGrass && var28.getIconName().equals("grass_side") && !this.hasOverrideBlockTexture()) { + var8.setColorOpaque_F(var18 * par5, var21 * par6, var24 * par7); + this.renderFaceZPos(par1Block, (double) par2, (double) par3, (double) par4, BlockGrass.getIconSideOverlay()); + } + + var9 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2 - 1, par3, par4, 4)) { + var8.setBrightness(this.renderMinX > 0.0D ? var26 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4)); + var8.setColorOpaque_F(var19, var22, var25); + var28 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 4); + this.renderFaceXNeg(par1Block, (double) par2, (double) par3, (double) par4, var28); + + if (fancyGrass && var28.getIconName().equals("grass_side") && !this.hasOverrideBlockTexture()) { + var8.setColorOpaque_F(var19 * par5, var22 * par6, var25 * par7); + this.renderFaceXNeg(par1Block, (double) par2, (double) par3, (double) par4, BlockGrass.getIconSideOverlay()); + } + + var9 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2 + 1, par3, par4, 5)) { + var8.setBrightness(this.renderMaxX < 1.0D ? var26 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4)); + var8.setColorOpaque_F(var19, var22, var25); + var28 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 5); + this.renderFaceXPos(par1Block, (double) par2, (double) par3, (double) par4, var28); + + if (fancyGrass && var28.getIconName().equals("grass_side") && !this.hasOverrideBlockTexture()) { + var8.setColorOpaque_F(var19 * par5, var22 * par6, var25 * par7); + this.renderFaceXPos(par1Block, (double) par2, (double) par3, (double) par4, BlockGrass.getIconSideOverlay()); + } + + var9 = true; + } + + return var9; + } + + /** + * Renders a Cocoa block at the given coordinates + */ + private boolean renderBlockCocoa(BlockCocoa par1BlockCocoa, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + var5.setBrightness(par1BlockCocoa.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + var5.setColorOpaque_F(1.0F, 1.0F, 1.0F); + int var6 = this.blockAccess.getBlockMetadata(par2, par3, par4); + int var7 = BlockDirectional.getDirection(var6); + int var8 = BlockCocoa.func_72219_c(var6); + Icon var9 = par1BlockCocoa.func_94468_i_(var8); + int var10 = 4 + var8 * 2; + int var11 = 5 + var8 * 2; + double var12 = 15.0D - (double) var10; + double var14 = 15.0D; + double var16 = 4.0D; + double var18 = 4.0D + (double) var11; + double var20 = (double) var9.getInterpolatedU(var12); + double var22 = (double) var9.getInterpolatedU(var14); + double var24 = (double) var9.getInterpolatedV(var16); + double var26 = (double) var9.getInterpolatedV(var18); + double var28 = 0.0D; + double var30 = 0.0D; + + switch (var7) { + case 0: + var28 = 8.0D - (double) (var10 / 2); + var30 = 15.0D - (double) var10; + break; + + case 1: + var28 = 1.0D; + var30 = 8.0D - (double) (var10 / 2); + break; + + case 2: + var28 = 8.0D - (double) (var10 / 2); + var30 = 1.0D; + break; + + case 3: + var28 = 15.0D - (double) var10; + var30 = 8.0D - (double) (var10 / 2); + } + + double var32 = (double) par2 + var28 / 16.0D; + double var34 = (double) par2 + (var28 + (double) var10) / 16.0D; + double var36 = (double) par3 + (12.0D - (double) var11) / 16.0D; + double var38 = (double) par3 + 0.75D; + double var40 = (double) par4 + var30 / 16.0D; + double var42 = (double) par4 + (var30 + (double) var10) / 16.0D; + var5.addVertexWithUV(var32, var36, var40, var20, var26); + var5.addVertexWithUV(var32, var36, var42, var22, var26); + var5.addVertexWithUV(var32, var38, var42, var22, var24); + var5.addVertexWithUV(var32, var38, var40, var20, var24); + var5.addVertexWithUV(var34, var36, var42, var20, var26); + var5.addVertexWithUV(var34, var36, var40, var22, var26); + var5.addVertexWithUV(var34, var38, var40, var22, var24); + var5.addVertexWithUV(var34, var38, var42, var20, var24); + var5.addVertexWithUV(var34, var36, var40, var20, var26); + var5.addVertexWithUV(var32, var36, var40, var22, var26); + var5.addVertexWithUV(var32, var38, var40, var22, var24); + var5.addVertexWithUV(var34, var38, var40, var20, var24); + var5.addVertexWithUV(var32, var36, var42, var20, var26); + var5.addVertexWithUV(var34, var36, var42, var22, var26); + var5.addVertexWithUV(var34, var38, var42, var22, var24); + var5.addVertexWithUV(var32, var38, var42, var20, var24); + int var44 = var10; + + if (var8 >= 2) { + var44 = var10 - 1; + } + + var20 = (double) var9.getMinU(); + var22 = (double) var9.getInterpolatedU((double) var44); + var24 = (double) var9.getMinV(); + var26 = (double) var9.getInterpolatedV((double) var44); + var5.addVertexWithUV(var32, var38, var42, var20, var26); + var5.addVertexWithUV(var34, var38, var42, var22, var26); + var5.addVertexWithUV(var34, var38, var40, var22, var24); + var5.addVertexWithUV(var32, var38, var40, var20, var24); + var5.addVertexWithUV(var32, var36, var40, var20, var24); + var5.addVertexWithUV(var34, var36, var40, var22, var24); + var5.addVertexWithUV(var34, var36, var42, var22, var26); + var5.addVertexWithUV(var32, var36, var42, var20, var26); + var20 = (double) var9.getInterpolatedU(12.0D); + var22 = (double) var9.getMaxU(); + var24 = (double) var9.getMinV(); + var26 = (double) var9.getInterpolatedV(4.0D); + var28 = 8.0D; + var30 = 0.0D; + double var45; + + switch (var7) { + case 0: + var28 = 8.0D; + var30 = 12.0D; + var45 = var20; + var20 = var22; + var22 = var45; + break; + + case 1: + var28 = 0.0D; + var30 = 8.0D; + break; + + case 2: + var28 = 8.0D; + var30 = 0.0D; + break; + + case 3: + var28 = 12.0D; + var30 = 8.0D; + var45 = var20; + var20 = var22; + var22 = var45; + } + + var32 = (double) par2 + var28 / 16.0D; + var34 = (double) par2 + (var28 + 4.0D) / 16.0D; + var36 = (double) par3 + 0.75D; + var38 = (double) par3 + 1.0D; + var40 = (double) par4 + var30 / 16.0D; + var42 = (double) par4 + (var30 + 4.0D) / 16.0D; + + if (var7 != 2 && var7 != 0) { + if (var7 == 1 || var7 == 3) { + var5.addVertexWithUV(var34, var36, var40, var20, var26); + var5.addVertexWithUV(var32, var36, var40, var22, var26); + var5.addVertexWithUV(var32, var38, var40, var22, var24); + var5.addVertexWithUV(var34, var38, var40, var20, var24); + var5.addVertexWithUV(var32, var36, var40, var22, var26); + var5.addVertexWithUV(var34, var36, var40, var20, var26); + var5.addVertexWithUV(var34, var38, var40, var20, var24); + var5.addVertexWithUV(var32, var38, var40, var22, var24); + } + } else { + var5.addVertexWithUV(var32, var36, var40, var22, var26); + var5.addVertexWithUV(var32, var36, var42, var20, var26); + var5.addVertexWithUV(var32, var38, var42, var20, var24); + var5.addVertexWithUV(var32, var38, var40, var22, var24); + var5.addVertexWithUV(var32, var36, var42, var20, var26); + var5.addVertexWithUV(var32, var36, var40, var22, var26); + var5.addVertexWithUV(var32, var38, var40, var22, var24); + var5.addVertexWithUV(var32, var38, var42, var20, var24); + } + + return true; + } + + /** + * Renders beacon block + */ + private boolean renderBlockBeacon(BlockBeacon par1BlockBeacon, int par2, int par3, int par4) { + float var5 = 0.1875F; + this.setOverrideBlockTexture(this.getBlockIcon(Block.obsidian)); + this.setRenderBounds(0.125D, 0.0062500000931322575D, 0.125D, 0.875D, (double) var5, 0.875D); + this.renderStandardBlock(par1BlockBeacon, par2, par3, par4); + this.setOverrideBlockTexture(this.getBlockIcon(Block.glass)); + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + this.renderStandardBlock(par1BlockBeacon, par2, par3, par4); + this.setOverrideBlockTexture(par1BlockBeacon.getBeaconIcon()); + this.setRenderBounds(0.1875D, (double) var5, 0.1875D, 0.8125D, 0.875D, 0.8125D); + this.renderStandardBlock(par1BlockBeacon, par2, par3, par4); + this.clearOverrideBlockTexture(); + return true; + } + + /** + * Renders a cactus block at the given coordinates + */ + public boolean renderBlockCactus(Block par1Block, int par2, int par3, int par4) { + int var5 = par1Block.colorMultiplier(this.blockAccess, par2, par3, par4); + float var6 = (float) (var5 >> 16 & 255) / 255.0F; + float var7 = (float) (var5 >> 8 & 255) / 255.0F; + float var8 = (float) (var5 & 255) / 255.0F; + + if (EntityRenderer.anaglyphEnable) { + float var9 = (var6 * 30.0F + var7 * 59.0F + var8 * 11.0F) / 100.0F; + float var10 = (var6 * 30.0F + var7 * 70.0F) / 100.0F; + float var11 = (var6 * 30.0F + var8 * 70.0F) / 100.0F; + var6 = var9; + var7 = var10; + var8 = var11; + } + + return this.renderBlockCactusImpl(par1Block, par2, par3, par4, var6, var7, var8); + } + + /** + * Render block cactus implementation + */ + public boolean renderBlockCactusImpl(Block par1Block, int par2, int par3, int par4, float par5, float par6, float par7) { + Tessellator var8 = Tessellator.instance; + boolean var9 = false; + float var10 = 0.5F; + float var11 = 1.0F; + float var12 = 0.8F; + float var13 = 0.6F; + float var14 = var10 * par5; + float var15 = var11 * par5; + float var16 = var12 * par5; + float var17 = var13 * par5; + float var18 = var10 * par6; + float var19 = var11 * par6; + float var20 = var12 * par6; + float var21 = var13 * par6; + float var22 = var10 * par7; + float var23 = var11 * par7; + float var24 = var12 * par7; + float var25 = var13 * par7; + float var26 = 0.0625F; + int var28 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4); + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3 - 1, par4, 0)) { + var8.setBrightness(this.renderMinY > 0.0D ? var28 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4)); + var8.setColorOpaque_F(var14, var18, var22); + this.renderFaceYNeg(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 0)); + var9 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3 + 1, par4, 1)) { + var8.setBrightness(this.renderMaxY < 1.0D ? var28 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4)); + var8.setColorOpaque_F(var15, var19, var23); + this.renderFaceYPos(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 1)); + var9 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3, par4 - 1, 2)) { + var8.setBrightness(this.renderMinZ > 0.0D ? var28 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 - 1)); + var8.setColorOpaque_F(var16, var20, var24); + var8.addTranslation(0.0F, 0.0F, var26); + this.renderFaceZNeg(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 2)); + var8.addTranslation(0.0F, 0.0F, -var26); + var9 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2, par3, par4 + 1, 3)) { + var8.setBrightness(this.renderMaxZ < 1.0D ? var28 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 + 1)); + var8.setColorOpaque_F(var16, var20, var24); + var8.addTranslation(0.0F, 0.0F, -var26); + this.renderFaceZPos(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 3)); + var8.addTranslation(0.0F, 0.0F, var26); + var9 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2 - 1, par3, par4, 4)) { + var8.setBrightness(this.renderMinX > 0.0D ? var28 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4)); + var8.setColorOpaque_F(var17, var21, var25); + var8.addTranslation(var26, 0.0F, 0.0F); + this.renderFaceXNeg(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 4)); + var8.addTranslation(-var26, 0.0F, 0.0F); + var9 = true; + } + + if (this.renderAllFaces || par1Block.shouldSideBeRendered(this.blockAccess, par2 + 1, par3, par4, 5)) { + var8.setBrightness(this.renderMaxX < 1.0D ? var28 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4)); + var8.setColorOpaque_F(var17, var21, var25); + var8.addTranslation(-var26, 0.0F, 0.0F); + this.renderFaceXPos(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 5)); + var8.addTranslation(var26, 0.0F, 0.0F); + var9 = true; + } + + return var9; + } + + public boolean renderBlockFence(BlockFence par1BlockFence, int par2, int par3, int par4) { + boolean var5 = false; + float var6 = 0.375F; + float var7 = 0.625F; + this.setRenderBounds((double) var6, 0.0D, (double) var6, (double) var7, 1.0D, (double) var7); + this.renderStandardBlock(par1BlockFence, par2, par3, par4); + var5 = true; + boolean var8 = false; + boolean var9 = false; + + if (par1BlockFence.canConnectFenceTo(this.blockAccess, par2 - 1, par3, par4) || par1BlockFence.canConnectFenceTo(this.blockAccess, par2 + 1, par3, par4)) { + var8 = true; + } + + if (par1BlockFence.canConnectFenceTo(this.blockAccess, par2, par3, par4 - 1) || par1BlockFence.canConnectFenceTo(this.blockAccess, par2, par3, par4 + 1)) { + var9 = true; + } + + boolean var10 = par1BlockFence.canConnectFenceTo(this.blockAccess, par2 - 1, par3, par4); + boolean var11 = par1BlockFence.canConnectFenceTo(this.blockAccess, par2 + 1, par3, par4); + boolean var12 = par1BlockFence.canConnectFenceTo(this.blockAccess, par2, par3, par4 - 1); + boolean var13 = par1BlockFence.canConnectFenceTo(this.blockAccess, par2, par3, par4 + 1); + + if (!var8 && !var9) { + var8 = true; + } + + var6 = 0.4375F; + var7 = 0.5625F; + float var14 = 0.75F; + float var15 = 0.9375F; + float var16 = var10 ? 0.0F : var6; + float var17 = var11 ? 1.0F : var7; + float var18 = var12 ? 0.0F : var6; + float var19 = var13 ? 1.0F : var7; + + if (var8) { + this.setRenderBounds((double) var16, (double) var14, (double) var6, (double) var17, (double) var15, (double) var7); + this.renderStandardBlock(par1BlockFence, par2, par3, par4); + var5 = true; + } + + if (var9) { + this.setRenderBounds((double) var6, (double) var14, (double) var18, (double) var7, (double) var15, (double) var19); + this.renderStandardBlock(par1BlockFence, par2, par3, par4); + var5 = true; + } + + var14 = 0.375F; + var15 = 0.5625F; + + if (var8) { + this.setRenderBounds((double) var16, (double) var14, (double) var6, (double) var17, (double) var15, (double) var7); + this.renderStandardBlock(par1BlockFence, par2, par3, par4); + var5 = true; + } + + if (var9) { + this.setRenderBounds((double) var6, (double) var14, (double) var18, (double) var7, (double) var15, (double) var19); + this.renderStandardBlock(par1BlockFence, par2, par3, par4); + var5 = true; + } + + par1BlockFence.setBlockBoundsBasedOnState(this.blockAccess, par2, par3, par4); + return var5; + } + + /** + * Renders wall block + */ + public boolean renderBlockWall(BlockWall par1BlockWall, int par2, int par3, int par4) { + boolean var5 = par1BlockWall.canConnectWallTo(this.blockAccess, par2 - 1, par3, par4); + boolean var6 = par1BlockWall.canConnectWallTo(this.blockAccess, par2 + 1, par3, par4); + boolean var7 = par1BlockWall.canConnectWallTo(this.blockAccess, par2, par3, par4 - 1); + boolean var8 = par1BlockWall.canConnectWallTo(this.blockAccess, par2, par3, par4 + 1); + boolean var9 = var7 && var8 && !var5 && !var6; + boolean var10 = !var7 && !var8 && var5 && var6; + boolean var11 = this.blockAccess.isAirBlock(par2, par3 + 1, par4); + + if ((var9 || var10) && var11) { + if (var9) { + this.setRenderBounds(0.3125D, 0.0D, 0.0D, 0.6875D, 0.8125D, 1.0D); + this.renderStandardBlock(par1BlockWall, par2, par3, par4); + } else { + this.setRenderBounds(0.0D, 0.0D, 0.3125D, 1.0D, 0.8125D, 0.6875D); + this.renderStandardBlock(par1BlockWall, par2, par3, par4); + } + } else { + this.setRenderBounds(0.25D, 0.0D, 0.25D, 0.75D, 1.0D, 0.75D); + this.renderStandardBlock(par1BlockWall, par2, par3, par4); + + if (var5) { + this.setRenderBounds(0.0D, 0.0D, 0.3125D, 0.25D, 0.8125D, 0.6875D); + this.renderStandardBlock(par1BlockWall, par2, par3, par4); + } + + if (var6) { + this.setRenderBounds(0.75D, 0.0D, 0.3125D, 1.0D, 0.8125D, 0.6875D); + this.renderStandardBlock(par1BlockWall, par2, par3, par4); + } + + if (var7) { + this.setRenderBounds(0.3125D, 0.0D, 0.0D, 0.6875D, 0.8125D, 0.25D); + this.renderStandardBlock(par1BlockWall, par2, par3, par4); + } + + if (var8) { + this.setRenderBounds(0.3125D, 0.0D, 0.75D, 0.6875D, 0.8125D, 1.0D); + this.renderStandardBlock(par1BlockWall, par2, par3, par4); + } + } + + par1BlockWall.setBlockBoundsBasedOnState(this.blockAccess, par2, par3, par4); + return true; + } + + public boolean renderBlockDragonEgg(BlockDragonEgg par1BlockDragonEgg, int par2, int par3, int par4) { + boolean var5 = false; + int var6 = 0; + + for (int var7 = 0; var7 < 8; ++var7) { + byte var8 = 0; + byte var9 = 1; + + if (var7 == 0) { + var8 = 2; + } + + if (var7 == 1) { + var8 = 3; + } + + if (var7 == 2) { + var8 = 4; + } + + if (var7 == 3) { + var8 = 5; + var9 = 2; + } + + if (var7 == 4) { + var8 = 6; + var9 = 3; + } + + if (var7 == 5) { + var8 = 7; + var9 = 5; + } + + if (var7 == 6) { + var8 = 6; + var9 = 2; + } + + if (var7 == 7) { + var8 = 3; + } + + float var10 = (float) var8 / 16.0F; + float var11 = 1.0F - (float) var6 / 16.0F; + float var12 = 1.0F - (float) (var6 + var9) / 16.0F; + var6 += var9; + this.setRenderBounds((double) (0.5F - var10), (double) var12, (double) (0.5F - var10), (double) (0.5F + var10), (double) var11, (double) (0.5F + var10)); + this.renderStandardBlock(par1BlockDragonEgg, par2, par3, par4); + } + + var5 = true; + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + return var5; + } + + /** + * Render block fence gate + */ + public boolean renderBlockFenceGate(BlockFenceGate par1BlockFenceGate, int par2, int par3, int par4) { + boolean var5 = true; + int var6 = this.blockAccess.getBlockMetadata(par2, par3, par4); + boolean var7 = BlockFenceGate.isFenceGateOpen(var6); + int var8 = BlockDirectional.getDirection(var6); + float var9 = 0.375F; + float var10 = 0.5625F; + float var11 = 0.75F; + float var12 = 0.9375F; + float var13 = 0.3125F; + float var14 = 1.0F; + + if ((var8 == 2 || var8 == 0) && this.blockAccess.getBlockId(par2 - 1, par3, par4) == Block.cobblestoneWall.blockID && this.blockAccess.getBlockId(par2 + 1, par3, par4) == Block.cobblestoneWall.blockID + || (var8 == 3 || var8 == 1) && this.blockAccess.getBlockId(par2, par3, par4 - 1) == Block.cobblestoneWall.blockID && this.blockAccess.getBlockId(par2, par3, par4 + 1) == Block.cobblestoneWall.blockID) { + var9 -= 0.1875F; + var10 -= 0.1875F; + var11 -= 0.1875F; + var12 -= 0.1875F; + var13 -= 0.1875F; + var14 -= 0.1875F; + } + + this.renderAllFaces = true; + float var15; + float var16; + float var17; + float var18; + + if (var8 != 3 && var8 != 1) { + var15 = 0.0F; + var16 = 0.125F; + var17 = 0.4375F; + var18 = 0.5625F; + this.setRenderBounds((double) var15, (double) var13, (double) var17, (double) var16, (double) var14, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + var15 = 0.875F; + var16 = 1.0F; + this.setRenderBounds((double) var15, (double) var13, (double) var17, (double) var16, (double) var14, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + } else { + this.uvRotateTop = 1; + var15 = 0.4375F; + var16 = 0.5625F; + var17 = 0.0F; + var18 = 0.125F; + this.setRenderBounds((double) var15, (double) var13, (double) var17, (double) var16, (double) var14, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + var17 = 0.875F; + var18 = 1.0F; + this.setRenderBounds((double) var15, (double) var13, (double) var17, (double) var16, (double) var14, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.uvRotateTop = 0; + } + + if (var7) { + if (var8 == 2 || var8 == 0) { + this.uvRotateTop = 1; + } + + if (var8 == 3) { + this.setRenderBounds(0.8125D, (double) var9, 0.0D, 0.9375D, (double) var12, 0.125D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.8125D, (double) var9, 0.875D, 0.9375D, (double) var12, 1.0D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.5625D, (double) var9, 0.0D, 0.8125D, (double) var10, 0.125D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.5625D, (double) var9, 0.875D, 0.8125D, (double) var10, 1.0D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.5625D, (double) var11, 0.0D, 0.8125D, (double) var12, 0.125D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.5625D, (double) var11, 0.875D, 0.8125D, (double) var12, 1.0D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + } else if (var8 == 1) { + this.setRenderBounds(0.0625D, (double) var9, 0.0D, 0.1875D, (double) var12, 0.125D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.0625D, (double) var9, 0.875D, 0.1875D, (double) var12, 1.0D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.1875D, (double) var9, 0.0D, 0.4375D, (double) var10, 0.125D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.1875D, (double) var9, 0.875D, 0.4375D, (double) var10, 1.0D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.1875D, (double) var11, 0.0D, 0.4375D, (double) var12, 0.125D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.1875D, (double) var11, 0.875D, 0.4375D, (double) var12, 1.0D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + } else if (var8 == 0) { + this.setRenderBounds(0.0D, (double) var9, 0.8125D, 0.125D, (double) var12, 0.9375D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.875D, (double) var9, 0.8125D, 1.0D, (double) var12, 0.9375D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.0D, (double) var9, 0.5625D, 0.125D, (double) var10, 0.8125D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.875D, (double) var9, 0.5625D, 1.0D, (double) var10, 0.8125D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.0D, (double) var11, 0.5625D, 0.125D, (double) var12, 0.8125D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.875D, (double) var11, 0.5625D, 1.0D, (double) var12, 0.8125D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + } else if (var8 == 2) { + this.setRenderBounds(0.0D, (double) var9, 0.0625D, 0.125D, (double) var12, 0.1875D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.875D, (double) var9, 0.0625D, 1.0D, (double) var12, 0.1875D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.0D, (double) var9, 0.1875D, 0.125D, (double) var10, 0.4375D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.875D, (double) var9, 0.1875D, 1.0D, (double) var10, 0.4375D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.0D, (double) var11, 0.1875D, 0.125D, (double) var12, 0.4375D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds(0.875D, (double) var11, 0.1875D, 1.0D, (double) var12, 0.4375D); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + } + } else if (var8 != 3 && var8 != 1) { + var15 = 0.375F; + var16 = 0.5F; + var17 = 0.4375F; + var18 = 0.5625F; + this.setRenderBounds((double) var15, (double) var9, (double) var17, (double) var16, (double) var12, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + var15 = 0.5F; + var16 = 0.625F; + this.setRenderBounds((double) var15, (double) var9, (double) var17, (double) var16, (double) var12, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + var15 = 0.625F; + var16 = 0.875F; + this.setRenderBounds((double) var15, (double) var9, (double) var17, (double) var16, (double) var10, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds((double) var15, (double) var11, (double) var17, (double) var16, (double) var12, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + var15 = 0.125F; + var16 = 0.375F; + this.setRenderBounds((double) var15, (double) var9, (double) var17, (double) var16, (double) var10, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds((double) var15, (double) var11, (double) var17, (double) var16, (double) var12, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + } else { + this.uvRotateTop = 1; + var15 = 0.4375F; + var16 = 0.5625F; + var17 = 0.375F; + var18 = 0.5F; + this.setRenderBounds((double) var15, (double) var9, (double) var17, (double) var16, (double) var12, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + var17 = 0.5F; + var18 = 0.625F; + this.setRenderBounds((double) var15, (double) var9, (double) var17, (double) var16, (double) var12, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + var17 = 0.625F; + var18 = 0.875F; + this.setRenderBounds((double) var15, (double) var9, (double) var17, (double) var16, (double) var10, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds((double) var15, (double) var11, (double) var17, (double) var16, (double) var12, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + var17 = 0.125F; + var18 = 0.375F; + this.setRenderBounds((double) var15, (double) var9, (double) var17, (double) var16, (double) var10, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + this.setRenderBounds((double) var15, (double) var11, (double) var17, (double) var16, (double) var12, (double) var18); + this.renderStandardBlock(par1BlockFenceGate, par2, par3, par4); + } + + this.renderAllFaces = false; + this.uvRotateTop = 0; + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + return var5; + } + + private boolean renderBlockHopper(BlockHopper par1BlockHopper, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + var5.setBrightness(par1BlockHopper.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + float var6 = 1.0F; + int var7 = par1BlockHopper.colorMultiplier(this.blockAccess, par2, par3, par4); + float var8 = (float) (var7 >> 16 & 255) / 255.0F; + float var9 = (float) (var7 >> 8 & 255) / 255.0F; + float var10 = (float) (var7 & 255) / 255.0F; + + if (EntityRenderer.anaglyphEnable) { + float var11 = (var8 * 30.0F + var9 * 59.0F + var10 * 11.0F) / 100.0F; + float var12 = (var8 * 30.0F + var9 * 70.0F) / 100.0F; + float var13 = (var8 * 30.0F + var10 * 70.0F) / 100.0F; + var8 = var11; + var9 = var12; + var10 = var13; + } + + var5.setColorOpaque_F(var6 * var8, var6 * var9, var6 * var10); + return this.renderBlockHopperMetadata(par1BlockHopper, par2, par3, par4, this.blockAccess.getBlockMetadata(par2, par3, par4), false); + } + + private boolean renderBlockHopperMetadata(BlockHopper par1BlockHopper, int par2, int par3, int par4, int par5, boolean par6) { + Tessellator var7 = Tessellator.instance; + int var8 = BlockHopper.getDirectionFromMetadata(par5); + double var9 = 0.625D; + this.setRenderBounds(0.0D, var9, 0.0D, 1.0D, 1.0D, 1.0D); + + if (par6) { + var7.startDrawingQuads(); + var7.setNormal(0.0F, -1.0F, 0.0F); + this.renderFaceYNeg(par1BlockHopper, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1BlockHopper, 0, par5)); + var7.draw(); + var7.startDrawingQuads(); + var7.setNormal(0.0F, 1.0F, 0.0F); + this.renderFaceYPos(par1BlockHopper, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1BlockHopper, 1, par5)); + var7.draw(); + var7.startDrawingQuads(); + var7.setNormal(0.0F, 0.0F, -1.0F); + this.renderFaceZNeg(par1BlockHopper, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1BlockHopper, 2, par5)); + var7.draw(); + var7.startDrawingQuads(); + var7.setNormal(0.0F, 0.0F, 1.0F); + this.renderFaceZPos(par1BlockHopper, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1BlockHopper, 3, par5)); + var7.draw(); + var7.startDrawingQuads(); + var7.setNormal(-1.0F, 0.0F, 0.0F); + this.renderFaceXNeg(par1BlockHopper, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1BlockHopper, 4, par5)); + var7.draw(); + var7.startDrawingQuads(); + var7.setNormal(1.0F, 0.0F, 0.0F); + this.renderFaceXPos(par1BlockHopper, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1BlockHopper, 5, par5)); + var7.draw(); + } else { + this.renderStandardBlock(par1BlockHopper, par2, par3, par4); + } + + float var13; + + if (!par6) { + var7.setBrightness(par1BlockHopper.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4)); + float var11 = 1.0F; + int var12 = par1BlockHopper.colorMultiplier(this.blockAccess, par2, par3, par4); + var13 = (float) (var12 >> 16 & 255) / 255.0F; + float var14 = (float) (var12 >> 8 & 255) / 255.0F; + float var15 = (float) (var12 & 255) / 255.0F; + + if (EntityRenderer.anaglyphEnable) { + float var16 = (var13 * 30.0F + var14 * 59.0F + var15 * 11.0F) / 100.0F; + float var17 = (var13 * 30.0F + var14 * 70.0F) / 100.0F; + float var18 = (var13 * 30.0F + var15 * 70.0F) / 100.0F; + var13 = var16; + var14 = var17; + var15 = var18; + } + + var7.setColorOpaque_F(var11 * var13, var11 * var14, var11 * var15); + } + + Icon var24 = BlockHopper.getHopperIcon("hopper"); + Icon var25 = BlockHopper.getHopperIcon("hopper_inside"); + var13 = 0.125F; + + if (par6) { + var7.startDrawingQuads(); + //var7.setNormal(1.0F, 0.0F, 0.0F); + this.renderFaceXPos(par1BlockHopper, (double) (-1.0F + var13), 0.0D, 0.0D, var24); + var7.draw(); + var7.startDrawingQuads(); + //var7.setNormal(-1.0F, 0.0F, 0.0F); + this.renderFaceXNeg(par1BlockHopper, (double) (1.0F - var13), 0.0D, 0.0D, var24); + var7.draw(); + var7.startDrawingQuads(); + //var7.setNormal(0.0F, 0.0F, 1.0F); + this.renderFaceZPos(par1BlockHopper, 0.0D, 0.0D, (double) (-1.0F + var13), var24); + var7.draw(); + var7.startDrawingQuads(); + //var7.setNormal(0.0F, 0.0F, -1.0F); + this.renderFaceZNeg(par1BlockHopper, 0.0D, 0.0D, (double) (1.0F - var13), var24); + var7.draw(); + var7.startDrawingQuads(); + //var7.setNormal(0.0F, 1.0F, 0.0F); + this.renderFaceYPos(par1BlockHopper, 0.0D, -1.0D + var9, 0.0D, var25); + var7.draw(); + } else { + this.renderFaceXPos(par1BlockHopper, (double) ((float) par2 - 1.0F + var13), (double) par3, (double) par4, var24); + this.renderFaceXNeg(par1BlockHopper, (double) ((float) par2 + 1.0F - var13), (double) par3, (double) par4, var24); + this.renderFaceZPos(par1BlockHopper, (double) par2, (double) par3, (double) ((float) par4 - 1.0F + var13), var24); + this.renderFaceZNeg(par1BlockHopper, (double) par2, (double) par3, (double) ((float) par4 + 1.0F - var13), var24); + this.renderFaceYPos(par1BlockHopper, (double) par2, (double) ((float) par3 - 1.0F) + var9, (double) par4, var25); + } + + this.setOverrideBlockTexture(var24); + double var26 = 0.25D; + double var27 = 0.25D; + this.setRenderBounds(var26, var27, var26, 1.0D - var26, var9 - 0.002D, 1.0D - var26); + + if (par6) { + var7.startDrawingQuads(); + //var7.setNormal(1.0F, 0.0F, 0.0F); + this.renderFaceXPos(par1BlockHopper, 0.0D, 0.0D, 0.0D, var24); + var7.draw(); + var7.startDrawingQuads(); + //var7.setNormal(-1.0F, 0.0F, 0.0F); + this.renderFaceXNeg(par1BlockHopper, 0.0D, 0.0D, 0.0D, var24); + var7.draw(); + var7.startDrawingQuads(); + //var7.setNormal(0.0F, 0.0F, 1.0F); + this.renderFaceZPos(par1BlockHopper, 0.0D, 0.0D, 0.0D, var24); + var7.draw(); + var7.startDrawingQuads(); + //var7.setNormal(0.0F, 0.0F, -1.0F); + this.renderFaceZNeg(par1BlockHopper, 0.0D, 0.0D, 0.0D, var24); + var7.draw(); + var7.startDrawingQuads(); + //var7.setNormal(0.0F, 1.0F, 0.0F); + this.renderFaceYPos(par1BlockHopper, 0.0D, 0.0D, 0.0D, var24); + var7.draw(); + var7.startDrawingQuads(); + //var7.setNormal(0.0F, -1.0F, 0.0F); + this.renderFaceYNeg(par1BlockHopper, 0.0D, 0.0D, 0.0D, var24); + var7.draw(); + } else { + this.renderStandardBlock(par1BlockHopper, par2, par3, par4); + } + + if (!par6) { + double var20 = 0.375D; + double var22 = 0.25D; + this.setOverrideBlockTexture(var24); + + if (var8 == 0) { + this.setRenderBounds(var20, 0.0D, var20, 1.0D - var20, 0.25D, 1.0D - var20); + this.renderStandardBlock(par1BlockHopper, par2, par3, par4); + } + + if (var8 == 2) { + this.setRenderBounds(var20, var27, 0.0D, 1.0D - var20, var27 + var22, var26); + this.renderStandardBlock(par1BlockHopper, par2, par3, par4); + } + + if (var8 == 3) { + this.setRenderBounds(var20, var27, 1.0D - var26, 1.0D - var20, var27 + var22, 1.0D); + this.renderStandardBlock(par1BlockHopper, par2, par3, par4); + } + + if (var8 == 4) { + this.setRenderBounds(0.0D, var27, var20, var26, var27 + var22, 1.0D - var20); + this.renderStandardBlock(par1BlockHopper, par2, par3, par4); + } + + if (var8 == 5) { + this.setRenderBounds(1.0D - var26, var27, var20, 1.0D, var27 + var22, 1.0D - var20); + this.renderStandardBlock(par1BlockHopper, par2, par3, par4); + } + } + + this.clearOverrideBlockTexture(); + return true; + } + + /** + * Renders a stair block at the given coordinates + */ + public boolean renderBlockStairs(BlockStairs par1BlockStairs, int par2, int par3, int par4) { + par1BlockStairs.func_82541_d(this.blockAccess, par2, par3, par4); + this.setRenderBoundsFromBlock(par1BlockStairs); + this.renderStandardBlock(par1BlockStairs, par2, par3, par4); + boolean var5 = par1BlockStairs.func_82542_g(this.blockAccess, par2, par3, par4); + this.setRenderBoundsFromBlock(par1BlockStairs); + this.renderStandardBlock(par1BlockStairs, par2, par3, par4); + + if (var5 && par1BlockStairs.func_82544_h(this.blockAccess, par2, par3, par4)) { + this.setRenderBoundsFromBlock(par1BlockStairs); + this.renderStandardBlock(par1BlockStairs, par2, par3, par4); + } + + return true; + } + + /** + * Renders a door block at the given coordinates + */ + public boolean renderBlockDoor(Block par1Block, int par2, int par3, int par4) { + Tessellator var5 = Tessellator.instance; + int var6 = this.blockAccess.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) != 0) { + if (this.blockAccess.getBlockId(par2, par3 - 1, par4) != par1Block.blockID) { + return false; + } + } else if (this.blockAccess.getBlockId(par2, par3 + 1, par4) != par1Block.blockID) { + return false; + } + + boolean var7 = false; + float var8 = 0.5F; + float var9 = 1.0F; + float var10 = 0.8F; + float var11 = 0.6F; + int var12 = par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4); + var5.setBrightness(this.renderMinY > 0.0D ? var12 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 - 1, par4)); + var5.setColorOpaque_F(var8, var8, var8); + this.renderFaceYNeg(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 0)); + var7 = true; + var5.setBrightness(this.renderMaxY < 1.0D ? var12 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3 + 1, par4)); + var5.setColorOpaque_F(var9, var9, var9); + this.renderFaceYPos(par1Block, (double) par2, (double) par3, (double) par4, this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 1)); + var7 = true; + var5.setBrightness(this.renderMinZ > 0.0D ? var12 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 - 1)); + var5.setColorOpaque_F(var10, var10, var10); + Icon var14 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 2); + this.renderFaceZNeg(par1Block, (double) par2, (double) par3, (double) par4, var14); + var7 = true; + this.flipTexture = false; + var5.setBrightness(this.renderMaxZ < 1.0D ? var12 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2, par3, par4 + 1)); + var5.setColorOpaque_F(var10, var10, var10); + var14 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 3); + this.renderFaceZPos(par1Block, (double) par2, (double) par3, (double) par4, var14); + var7 = true; + this.flipTexture = false; + var5.setBrightness(this.renderMinX > 0.0D ? var12 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 - 1, par3, par4)); + var5.setColorOpaque_F(var11, var11, var11); + var14 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 4); + this.renderFaceXNeg(par1Block, (double) par2, (double) par3, (double) par4, var14); + var7 = true; + this.flipTexture = false; + var5.setBrightness(this.renderMaxX < 1.0D ? var12 : par1Block.getMixedBrightnessForBlock(this.blockAccess, par2 + 1, par3, par4)); + var5.setColorOpaque_F(var11, var11, var11); + var14 = this.getBlockIcon(par1Block, this.blockAccess, par2, par3, par4, 5); + this.renderFaceXPos(par1Block, (double) par2, (double) par3, (double) par4, var14); + var7 = true; + this.flipTexture = false; + return var7; + } + + /** + * Renders the given texture to the bottom face of the block. Args: block, x, y, + * z, texture + */ + public void renderFaceYNeg(Block par1Block, double par2, double par4, double par6, Icon par8Icon) { + Tessellator var9 = Tessellator.instance; + + if (this.hasOverrideBlockTexture()) { + par8Icon = this.overrideBlockTexture; + } + + double var10 = (double) par8Icon.getInterpolatedU(this.renderMinX * 16.0D); + double var12 = (double) par8Icon.getInterpolatedU(this.renderMaxX * 16.0D); + double var14 = (double) par8Icon.getInterpolatedV(this.renderMinZ * 16.0D); + double var16 = (double) par8Icon.getInterpolatedV(this.renderMaxZ * 16.0D); + + if (this.renderMinX < 0.0D || this.renderMaxX > 1.0D) { + var10 = (double) par8Icon.getMinU(); + var12 = (double) par8Icon.getMaxU(); + } + + if (this.renderMinZ < 0.0D || this.renderMaxZ > 1.0D) { + var14 = (double) par8Icon.getMinV(); + var16 = (double) par8Icon.getMaxV(); + } + + double var18 = var12; + double var20 = var10; + double var22 = var14; + double var24 = var16; + + if (this.uvRotateBottom == 2) { + var10 = (double) par8Icon.getInterpolatedU(this.renderMinZ * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMaxX * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(this.renderMaxZ * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMinX * 16.0D); + var22 = var14; + var24 = var16; + var18 = var10; + var20 = var12; + var14 = var16; + var16 = var22; + } else if (this.uvRotateBottom == 1) { + var10 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMaxZ * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(this.renderMinX * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMinZ * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(this.renderMaxX * 16.0D); + var18 = var12; + var20 = var10; + var10 = var12; + var12 = var20; + var22 = var16; + var24 = var14; + } else if (this.uvRotateBottom == 3) { + var10 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMinX * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMaxX * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMinZ * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMaxZ * 16.0D); + var18 = var12; + var20 = var10; + var22 = var14; + var24 = var16; + } + + double var26 = par2 + this.renderMinX; + double var28 = par2 + this.renderMaxX; + double var30 = par4 + this.renderMinY; + double var32 = par6 + this.renderMinZ; + double var34 = par6 + this.renderMaxZ; + + if (this.enableAO) { + var9.setColorOpaque_F(this.colorRedTopLeft, this.colorGreenTopLeft, this.colorBlueTopLeft); + var9.setBrightness(this.brightnessTopLeft); + var9.addVertexWithUV(var26, var30, var34, var20, var24); + var9.setColorOpaque_F(this.colorRedBottomLeft, this.colorGreenBottomLeft, this.colorBlueBottomLeft); + var9.setBrightness(this.brightnessBottomLeft); + var9.addVertexWithUV(var26, var30, var32, var10, var14); + var9.setColorOpaque_F(this.colorRedBottomRight, this.colorGreenBottomRight, this.colorBlueBottomRight); + var9.setBrightness(this.brightnessBottomRight); + var9.addVertexWithUV(var28, var30, var32, var18, var22); + var9.setColorOpaque_F(this.colorRedTopRight, this.colorGreenTopRight, this.colorBlueTopRight); + var9.setBrightness(this.brightnessTopRight); + var9.addVertexWithUV(var28, var30, var34, var12, var16); + } else { + var9.addVertexWithUV(var26, var30, var34, var20, var24); + var9.addVertexWithUV(var26, var30, var32, var10, var14); + var9.addVertexWithUV(var28, var30, var32, var18, var22); + var9.addVertexWithUV(var28, var30, var34, var12, var16); + } + } + + /** + * Renders the given texture to the top face of the block. Args: block, x, y, z, + * texture + */ + public void renderFaceYPos(Block par1Block, double par2, double par4, double par6, Icon par8Icon) { + Tessellator var9 = Tessellator.instance; + + if (this.hasOverrideBlockTexture()) { + par8Icon = this.overrideBlockTexture; + } + + double var10 = (double) par8Icon.getInterpolatedU(this.renderMinX * 16.0D); + double var12 = (double) par8Icon.getInterpolatedU(this.renderMaxX * 16.0D); + double var14 = (double) par8Icon.getInterpolatedV(this.renderMinZ * 16.0D); + double var16 = (double) par8Icon.getInterpolatedV(this.renderMaxZ * 16.0D); + + if (this.renderMinX < 0.0D || this.renderMaxX > 1.0D) { + var10 = (double) par8Icon.getMinU(); + var12 = (double) par8Icon.getMaxU(); + } + + if (this.renderMinZ < 0.0D || this.renderMaxZ > 1.0D) { + var14 = (double) par8Icon.getMinV(); + var16 = (double) par8Icon.getMaxV(); + } + + double var18 = var12; + double var20 = var10; + double var22 = var14; + double var24 = var16; + + if (this.uvRotateTop == 1) { + var10 = (double) par8Icon.getInterpolatedU(this.renderMinZ * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMaxX * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(this.renderMaxZ * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMinX * 16.0D); + var22 = var14; + var24 = var16; + var18 = var10; + var20 = var12; + var14 = var16; + var16 = var22; + } else if (this.uvRotateTop == 2) { + var10 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMaxZ * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(this.renderMinX * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMinZ * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(this.renderMaxX * 16.0D); + var18 = var12; + var20 = var10; + var10 = var12; + var12 = var20; + var22 = var16; + var24 = var14; + } else if (this.uvRotateTop == 3) { + var10 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMinX * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMaxX * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMinZ * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMaxZ * 16.0D); + var18 = var12; + var20 = var10; + var22 = var14; + var24 = var16; + } + + double var26 = par2 + this.renderMinX; + double var28 = par2 + this.renderMaxX; + double var30 = par4 + this.renderMaxY; + double var32 = par6 + this.renderMinZ; + double var34 = par6 + this.renderMaxZ; + + if (this.enableAO) { + var9.setColorOpaque_F(this.colorRedTopLeft, this.colorGreenTopLeft, this.colorBlueTopLeft); + var9.setBrightness(this.brightnessTopLeft); + var9.addVertexWithUV(var28, var30, var34, var12, var16); + var9.setColorOpaque_F(this.colorRedBottomLeft, this.colorGreenBottomLeft, this.colorBlueBottomLeft); + var9.setBrightness(this.brightnessBottomLeft); + var9.addVertexWithUV(var28, var30, var32, var18, var22); + var9.setColorOpaque_F(this.colorRedBottomRight, this.colorGreenBottomRight, this.colorBlueBottomRight); + var9.setBrightness(this.brightnessBottomRight); + var9.addVertexWithUV(var26, var30, var32, var10, var14); + var9.setColorOpaque_F(this.colorRedTopRight, this.colorGreenTopRight, this.colorBlueTopRight); + var9.setBrightness(this.brightnessTopRight); + var9.addVertexWithUV(var26, var30, var34, var20, var24); + } else { + var9.addVertexWithUV(var28, var30, var34, var12, var16); + var9.addVertexWithUV(var28, var30, var32, var18, var22); + var9.addVertexWithUV(var26, var30, var32, var10, var14); + var9.addVertexWithUV(var26, var30, var34, var20, var24); + } + } + + /** + * Renders the given texture to the north (z-negative) face of the block. Args: + * block, x, y, z, texture + */ + public void renderFaceZNeg(Block par1Block, double par2, double par4, double par6, Icon par8Icon) { + Tessellator var9 = Tessellator.instance; + + if (this.hasOverrideBlockTexture()) { + par8Icon = this.overrideBlockTexture; + } + + double var10 = (double) par8Icon.getInterpolatedU(this.renderMinX * 16.0D); + double var12 = (double) par8Icon.getInterpolatedU(this.renderMaxX * 16.0D); + double var14 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMaxY * 16.0D); + double var16 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMinY * 16.0D); + double var18; + + if (this.flipTexture) { + var18 = var10; + var10 = var12; + var12 = var18; + } + + if (this.renderMinX < 0.0D || this.renderMaxX > 1.0D) { + var10 = (double) par8Icon.getMinU(); + var12 = (double) par8Icon.getMaxU(); + } + + if (this.renderMinY < 0.0D || this.renderMaxY > 1.0D) { + var14 = (double) par8Icon.getMinV(); + var16 = (double) par8Icon.getMaxV(); + } + + var18 = var12; + double var20 = var10; + double var22 = var14; + double var24 = var16; + + if (this.uvRotateEast == 2) { + var10 = (double) par8Icon.getInterpolatedU(this.renderMinY * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMinX * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(this.renderMaxY * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMaxX * 16.0D); + var22 = var14; + var24 = var16; + var18 = var10; + var20 = var12; + var14 = var16; + var16 = var22; + } else if (this.uvRotateEast == 1) { + var10 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMaxY * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(this.renderMaxX * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMinY * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(this.renderMinX * 16.0D); + var18 = var12; + var20 = var10; + var10 = var12; + var12 = var20; + var22 = var16; + var24 = var14; + } else if (this.uvRotateEast == 3) { + var10 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMinX * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMaxX * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(this.renderMaxY * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(this.renderMinY * 16.0D); + var18 = var12; + var20 = var10; + var22 = var14; + var24 = var16; + } + + double var26 = par2 + this.renderMinX; + double var28 = par2 + this.renderMaxX; + double var30 = par4 + this.renderMinY; + double var32 = par4 + this.renderMaxY; + double var34 = par6 + this.renderMinZ; + + if (this.enableAO) { + var9.setColorOpaque_F(this.colorRedTopLeft, this.colorGreenTopLeft, this.colorBlueTopLeft); + var9.setBrightness(this.brightnessTopLeft); + var9.addVertexWithUV(var26, var32, var34, var18, var22); + var9.setColorOpaque_F(this.colorRedBottomLeft, this.colorGreenBottomLeft, this.colorBlueBottomLeft); + var9.setBrightness(this.brightnessBottomLeft); + var9.addVertexWithUV(var28, var32, var34, var10, var14); + var9.setColorOpaque_F(this.colorRedBottomRight, this.colorGreenBottomRight, this.colorBlueBottomRight); + var9.setBrightness(this.brightnessBottomRight); + var9.addVertexWithUV(var28, var30, var34, var20, var24); + var9.setColorOpaque_F(this.colorRedTopRight, this.colorGreenTopRight, this.colorBlueTopRight); + var9.setBrightness(this.brightnessTopRight); + var9.addVertexWithUV(var26, var30, var34, var12, var16); + } else { + var9.addVertexWithUV(var26, var32, var34, var18, var22); + var9.addVertexWithUV(var28, var32, var34, var10, var14); + var9.addVertexWithUV(var28, var30, var34, var20, var24); + var9.addVertexWithUV(var26, var30, var34, var12, var16); + } + } + + /** + * Renders the given texture to the south (z-positive) face of the block. Args: + * block, x, y, z, texture + */ + public void renderFaceZPos(Block par1Block, double par2, double par4, double par6, Icon par8Icon) { + Tessellator var9 = Tessellator.instance; + + if (this.hasOverrideBlockTexture()) { + par8Icon = this.overrideBlockTexture; + } + + double var10 = (double) par8Icon.getInterpolatedU(this.renderMinX * 16.0D); + double var12 = (double) par8Icon.getInterpolatedU(this.renderMaxX * 16.0D); + double var14 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMaxY * 16.0D); + double var16 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMinY * 16.0D); + double var18; + + if (this.flipTexture) { + var18 = var10; + var10 = var12; + var12 = var18; + } + + if (this.renderMinX < 0.0D || this.renderMaxX > 1.0D) { + var10 = (double) par8Icon.getMinU(); + var12 = (double) par8Icon.getMaxU(); + } + + if (this.renderMinY < 0.0D || this.renderMaxY > 1.0D) { + var14 = (double) par8Icon.getMinV(); + var16 = (double) par8Icon.getMaxV(); + } + + var18 = var12; + double var20 = var10; + double var22 = var14; + double var24 = var16; + + if (this.uvRotateWest == 1) { + var10 = (double) par8Icon.getInterpolatedU(this.renderMinY * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMinX * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(this.renderMaxY * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMaxX * 16.0D); + var22 = var14; + var24 = var16; + var18 = var10; + var20 = var12; + var14 = var16; + var16 = var22; + } else if (this.uvRotateWest == 2) { + var10 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMaxY * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(this.renderMinX * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMinY * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(this.renderMaxX * 16.0D); + var18 = var12; + var20 = var10; + var10 = var12; + var12 = var20; + var22 = var16; + var24 = var14; + } else if (this.uvRotateWest == 3) { + var10 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMinX * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMaxX * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(this.renderMaxY * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(this.renderMinY * 16.0D); + var18 = var12; + var20 = var10; + var22 = var14; + var24 = var16; + } + + double var26 = par2 + this.renderMinX; + double var28 = par2 + this.renderMaxX; + double var30 = par4 + this.renderMinY; + double var32 = par4 + this.renderMaxY; + double var34 = par6 + this.renderMaxZ; + + if (this.enableAO) { + var9.setColorOpaque_F(this.colorRedTopLeft, this.colorGreenTopLeft, this.colorBlueTopLeft); + var9.setBrightness(this.brightnessTopLeft); + var9.addVertexWithUV(var26, var32, var34, var10, var14); + var9.setColorOpaque_F(this.colorRedBottomLeft, this.colorGreenBottomLeft, this.colorBlueBottomLeft); + var9.setBrightness(this.brightnessBottomLeft); + var9.addVertexWithUV(var26, var30, var34, var20, var24); + var9.setColorOpaque_F(this.colorRedBottomRight, this.colorGreenBottomRight, this.colorBlueBottomRight); + var9.setBrightness(this.brightnessBottomRight); + var9.addVertexWithUV(var28, var30, var34, var12, var16); + var9.setColorOpaque_F(this.colorRedTopRight, this.colorGreenTopRight, this.colorBlueTopRight); + var9.setBrightness(this.brightnessTopRight); + var9.addVertexWithUV(var28, var32, var34, var18, var22); + } else { + var9.addVertexWithUV(var26, var32, var34, var10, var14); + var9.addVertexWithUV(var26, var30, var34, var20, var24); + var9.addVertexWithUV(var28, var30, var34, var12, var16); + var9.addVertexWithUV(var28, var32, var34, var18, var22); + } + } + + /** + * Renders the given texture to the west (x-negative) face of the block. Args: + * block, x, y, z, texture + */ + public void renderFaceXNeg(Block par1Block, double par2, double par4, double par6, Icon par8Icon) { + Tessellator var9 = Tessellator.instance; + + if (this.hasOverrideBlockTexture()) { + par8Icon = this.overrideBlockTexture; + } + + double var10 = (double) par8Icon.getInterpolatedU(this.renderMinZ * 16.0D); + double var12 = (double) par8Icon.getInterpolatedU(this.renderMaxZ * 16.0D); + double var14 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMaxY * 16.0D); + double var16 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMinY * 16.0D); + double var18; + + if (this.flipTexture) { + var18 = var10; + var10 = var12; + var12 = var18; + } + + if (this.renderMinZ < 0.0D || this.renderMaxZ > 1.0D) { + var10 = (double) par8Icon.getMinU(); + var12 = (double) par8Icon.getMaxU(); + } + + if (this.renderMinY < 0.0D || this.renderMaxY > 1.0D) { + var14 = (double) par8Icon.getMinV(); + var16 = (double) par8Icon.getMaxV(); + } + + var18 = var12; + double var20 = var10; + double var22 = var14; + double var24 = var16; + + if (this.uvRotateNorth == 1) { + var10 = (double) par8Icon.getInterpolatedU(this.renderMinY * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMaxZ * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(this.renderMaxY * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMinZ * 16.0D); + var22 = var14; + var24 = var16; + var18 = var10; + var20 = var12; + var14 = var16; + var16 = var22; + } else if (this.uvRotateNorth == 2) { + var10 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMaxY * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(this.renderMinZ * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMinY * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(this.renderMaxZ * 16.0D); + var18 = var12; + var20 = var10; + var10 = var12; + var12 = var20; + var22 = var16; + var24 = var14; + } else if (this.uvRotateNorth == 3) { + var10 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMinZ * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMaxZ * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(this.renderMaxY * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(this.renderMinY * 16.0D); + var18 = var12; + var20 = var10; + var22 = var14; + var24 = var16; + } + + double var26 = par2 + this.renderMinX; + double var28 = par4 + this.renderMinY; + double var30 = par4 + this.renderMaxY; + double var32 = par6 + this.renderMinZ; + double var34 = par6 + this.renderMaxZ; + + if (this.enableAO) { + var9.setColorOpaque_F(this.colorRedTopLeft, this.colorGreenTopLeft, this.colorBlueTopLeft); + var9.setBrightness(this.brightnessTopLeft); + var9.addVertexWithUV(var26, var30, var34, var18, var22); + var9.setColorOpaque_F(this.colorRedBottomLeft, this.colorGreenBottomLeft, this.colorBlueBottomLeft); + var9.setBrightness(this.brightnessBottomLeft); + var9.addVertexWithUV(var26, var30, var32, var10, var14); + var9.setColorOpaque_F(this.colorRedBottomRight, this.colorGreenBottomRight, this.colorBlueBottomRight); + var9.setBrightness(this.brightnessBottomRight); + var9.addVertexWithUV(var26, var28, var32, var20, var24); + var9.setColorOpaque_F(this.colorRedTopRight, this.colorGreenTopRight, this.colorBlueTopRight); + var9.setBrightness(this.brightnessTopRight); + var9.addVertexWithUV(var26, var28, var34, var12, var16); + } else { + var9.addVertexWithUV(var26, var30, var34, var18, var22); + var9.addVertexWithUV(var26, var30, var32, var10, var14); + var9.addVertexWithUV(var26, var28, var32, var20, var24); + var9.addVertexWithUV(var26, var28, var34, var12, var16); + } + } + + /** + * Renders the given texture to the east (x-positive) face of the block. Args: + * block, x, y, z, texture + */ + public void renderFaceXPos(Block par1Block, double par2, double par4, double par6, Icon par8Icon) { + Tessellator var9 = Tessellator.instance; + + if (this.hasOverrideBlockTexture()) { + par8Icon = this.overrideBlockTexture; + } + + double var10 = (double) par8Icon.getInterpolatedU(this.renderMinZ * 16.0D); + double var12 = (double) par8Icon.getInterpolatedU(this.renderMaxZ * 16.0D); + double var14 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMaxY * 16.0D); + double var16 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMinY * 16.0D); + double var18; + + if (this.flipTexture) { + var18 = var10; + var10 = var12; + var12 = var18; + } + + if (this.renderMinZ < 0.0D || this.renderMaxZ > 1.0D) { + var10 = (double) par8Icon.getMinU(); + var12 = (double) par8Icon.getMaxU(); + } + + if (this.renderMinY < 0.0D || this.renderMaxY > 1.0D) { + var14 = (double) par8Icon.getMinV(); + var16 = (double) par8Icon.getMaxV(); + } + + var18 = var12; + double var20 = var10; + double var22 = var14; + double var24 = var16; + + if (this.uvRotateSouth == 2) { + var10 = (double) par8Icon.getInterpolatedU(this.renderMinY * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMinZ * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(this.renderMaxY * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(16.0D - this.renderMaxZ * 16.0D); + var22 = var14; + var24 = var16; + var18 = var10; + var20 = var12; + var14 = var16; + var16 = var22; + } else if (this.uvRotateSouth == 1) { + var10 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMaxY * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(this.renderMaxZ * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMinY * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(this.renderMinZ * 16.0D); + var18 = var12; + var20 = var10; + var10 = var12; + var12 = var20; + var22 = var16; + var24 = var14; + } else if (this.uvRotateSouth == 3) { + var10 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMinZ * 16.0D); + var12 = (double) par8Icon.getInterpolatedU(16.0D - this.renderMaxZ * 16.0D); + var14 = (double) par8Icon.getInterpolatedV(this.renderMaxY * 16.0D); + var16 = (double) par8Icon.getInterpolatedV(this.renderMinY * 16.0D); + var18 = var12; + var20 = var10; + var22 = var14; + var24 = var16; + } + + double var26 = par2 + this.renderMaxX; + double var28 = par4 + this.renderMinY; + double var30 = par4 + this.renderMaxY; + double var32 = par6 + this.renderMinZ; + double var34 = par6 + this.renderMaxZ; + + if (this.enableAO) { + var9.setColorOpaque_F(this.colorRedTopLeft, this.colorGreenTopLeft, this.colorBlueTopLeft); + var9.setBrightness(this.brightnessTopLeft); + var9.addVertexWithUV(var26, var28, var34, var20, var24); + var9.setColorOpaque_F(this.colorRedBottomLeft, this.colorGreenBottomLeft, this.colorBlueBottomLeft); + var9.setBrightness(this.brightnessBottomLeft); + var9.addVertexWithUV(var26, var28, var32, var12, var16); + var9.setColorOpaque_F(this.colorRedBottomRight, this.colorGreenBottomRight, this.colorBlueBottomRight); + var9.setBrightness(this.brightnessBottomRight); + var9.addVertexWithUV(var26, var30, var32, var18, var22); + var9.setColorOpaque_F(this.colorRedTopRight, this.colorGreenTopRight, this.colorBlueTopRight); + var9.setBrightness(this.brightnessTopRight); + var9.addVertexWithUV(var26, var30, var34, var10, var14); + } else { + var9.addVertexWithUV(var26, var28, var34, var20, var24); + var9.addVertexWithUV(var26, var28, var32, var12, var16); + var9.addVertexWithUV(var26, var30, var32, var18, var22); + var9.addVertexWithUV(var26, var30, var34, var10, var14); + } + } + + /** + * Is called to render the image of a block on an inventory, as a held item, or + * as a an item on the ground + */ + public void renderBlockAsItem(Block par1Block, int par2, float par3) { + Tessellator var4 = Tessellator.instance; + boolean var5 = par1Block.blockID == Block.grass.blockID; + + if (par1Block == Block.dispenser || par1Block == Block.dropper || par1Block == Block.furnaceIdle) { + par2 = 3; + } + + int var6; + float var7; + float var8; + float var9; + + if (this.useInventoryTint) { + var6 = par1Block.getRenderColor(par2); + + if (var5) { + var6 = 16777215; + } + + var7 = (float) (var6 >> 16 & 255) / 255.0F; + var8 = (float) (var6 >> 8 & 255) / 255.0F; + var9 = (float) (var6 & 255) / 255.0F; + EaglerAdapter.glColor4f(var7 * par3, var8 * par3, var9 * par3, 1.0F); + } + + var6 = par1Block.getRenderType(); + this.setRenderBoundsFromBlock(par1Block); + int var14; + + if (var6 != 0 && var6 != 31 && var6 != 39 && var6 != 16 && var6 != 26) { + if (var6 == 1) { + var4.startDrawingQuads(); + var4.setNormal(0.0F, -1.0F, 0.0F); + this.drawCrossedSquares(par1Block, par2, -0.5D, -0.5D, -0.5D, 1.0F); + var4.draw(); + } else if (var6 == 19) { + var4.startDrawingQuads(); + var4.setNormal(0.0F, -1.0F, 0.0F); + par1Block.setBlockBoundsForItemRender(); + this.renderBlockStemSmall(par1Block, par2, this.renderMaxY, -0.5D, -0.5D, -0.5D); + var4.draw(); + } else if (var6 == 23) { + var4.startDrawingQuads(); + var4.setNormal(0.0F, -1.0F, 0.0F); + par1Block.setBlockBoundsForItemRender(); + var4.draw(); + } else if (var6 == 13) { + par1Block.setBlockBoundsForItemRender(); + EaglerAdapter.glTranslatef(-0.5F, -0.5F, -0.5F); + var7 = 0.0625F; + var4.startDrawingQuads(); + var4.setNormal(0.0F, -1.0F, 0.0F); + this.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 0)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 1.0F, 0.0F); + this.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 1)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 0.0F, -1.0F); + var4.addTranslation(0.0F, 0.0F, var7); + this.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 2)); + var4.addTranslation(0.0F, 0.0F, -var7); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 0.0F, 1.0F); + var4.addTranslation(0.0F, 0.0F, -var7); + this.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 3)); + var4.addTranslation(0.0F, 0.0F, var7); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(-1.0F, 0.0F, 0.0F); + var4.addTranslation(var7, 0.0F, 0.0F); + this.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 4)); + var4.addTranslation(-var7, 0.0F, 0.0F); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(1.0F, 0.0F, 0.0F); + var4.addTranslation(-var7, 0.0F, 0.0F); + this.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 5)); + var4.addTranslation(var7, 0.0F, 0.0F); + var4.draw(); + EaglerAdapter.glTranslatef(0.5F, 0.5F, 0.5F); + } else if (var6 == 22) { + EaglerAdapter.glRotatef(90.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glTranslatef(-0.5F, -0.5F, -0.5F); + ChestItemRenderHelper.instance.renderChest(par1Block, par2, par3); + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + } else if (var6 == 6) { + var4.startDrawingQuads(); + var4.setNormal(0.0F, -1.0F, 0.0F); + this.renderBlockCropsImpl(par1Block, par2, -0.5D, -0.5D, -0.5D); + var4.draw(); + } else if (var6 == 2) { + var4.startDrawingQuads(); + var4.setNormal(0.0F, -1.0F, 0.0F); + this.renderTorchAtAngle(par1Block, -0.5D, -0.5D, -0.5D, 0.0D, 0.0D, 0); + var4.draw(); + } else if (var6 == 10) { + for (var14 = 0; var14 < 2; ++var14) { + if (var14 == 0) { + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.5D); + } + + if (var14 == 1) { + this.setRenderBounds(0.0D, 0.0D, 0.5D, 1.0D, 0.5D, 1.0D); + } + + EaglerAdapter.glTranslatef(-0.5F, -0.5F, -0.5F); + var4.startDrawingQuads(); + var4.setNormal(0.0F, -1.0F, 0.0F); + this.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 0)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 1.0F, 0.0F); + this.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 1)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 0.0F, -1.0F); + this.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 0.0F, 1.0F); + this.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 3)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(-1.0F, 0.0F, 0.0F); + this.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 4)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(1.0F, 0.0F, 0.0F); + this.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 5)); + var4.draw(); + EaglerAdapter.glTranslatef(0.5F, 0.5F, 0.5F); + } + } else if (var6 == 27) { + var14 = 0; + EaglerAdapter.glTranslatef(-0.5F, -0.5F, -0.5F); + var4.startDrawingQuads(); + + for (int var15 = 0; var15 < 8; ++var15) { + byte var16 = 0; + byte var17 = 1; + + if (var15 == 0) { + var16 = 2; + } + + if (var15 == 1) { + var16 = 3; + } + + if (var15 == 2) { + var16 = 4; + } + + if (var15 == 3) { + var16 = 5; + var17 = 2; + } + + if (var15 == 4) { + var16 = 6; + var17 = 3; + } + + if (var15 == 5) { + var16 = 7; + var17 = 5; + } + + if (var15 == 6) { + var16 = 6; + var17 = 2; + } + + if (var15 == 7) { + var16 = 3; + } + + float var11 = (float) var16 / 16.0F; + float var12 = 1.0F - (float) var14 / 16.0F; + float var13 = 1.0F - (float) (var14 + var17) / 16.0F; + var14 += var17; + this.setRenderBounds((double) (0.5F - var11), (double) var13, (double) (0.5F - var11), (double) (0.5F + var11), (double) var12, (double) (0.5F + var11)); + var4.setNormal(0.0F, -1.0F, 0.0F); + this.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 0)); + var4.setNormal(0.0F, 1.0F, 0.0F); + this.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 1)); + var4.setNormal(0.0F, 0.0F, -1.0F); + this.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 2)); + var4.setNormal(0.0F, 0.0F, 1.0F); + this.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 3)); + var4.setNormal(-1.0F, 0.0F, 0.0F); + this.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 4)); + var4.setNormal(1.0F, 0.0F, 0.0F); + this.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 5)); + } + + var4.draw(); + EaglerAdapter.glTranslatef(0.5F, 0.5F, 0.5F); + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + } else if (var6 == 11) { + for (var14 = 0; var14 < 4; ++var14) { + var8 = 0.125F; + + if (var14 == 0) { + this.setRenderBounds((double) (0.5F - var8), 0.0D, 0.0D, (double) (0.5F + var8), 1.0D, (double) (var8 * 2.0F)); + } + + if (var14 == 1) { + this.setRenderBounds((double) (0.5F - var8), 0.0D, (double) (1.0F - var8 * 2.0F), (double) (0.5F + var8), 1.0D, 1.0D); + } + + var8 = 0.0625F; + + if (var14 == 2) { + this.setRenderBounds((double) (0.5F - var8), (double) (1.0F - var8 * 3.0F), (double) (-var8 * 2.0F), (double) (0.5F + var8), (double) (1.0F - var8), (double) (1.0F + var8 * 2.0F)); + } + + if (var14 == 3) { + this.setRenderBounds((double) (0.5F - var8), (double) (0.5F - var8 * 3.0F), (double) (-var8 * 2.0F), (double) (0.5F + var8), (double) (0.5F - var8), (double) (1.0F + var8 * 2.0F)); + } + + EaglerAdapter.glTranslatef(-0.5F, -0.5F, -0.5F); + var4.startDrawingQuads(); + var4.setNormal(0.0F, -1.0F, 0.0F); + this.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 0)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 1.0F, 0.0F); + this.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 1)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 0.0F, -1.0F); + this.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 0.0F, 1.0F); + this.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 3)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(-1.0F, 0.0F, 0.0F); + this.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 4)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(1.0F, 0.0F, 0.0F); + this.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 5)); + var4.draw(); + EaglerAdapter.glTranslatef(0.5F, 0.5F, 0.5F); + } + + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + } else if (var6 == 21) { + for (var14 = 0; var14 < 3; ++var14) { + var8 = 0.0625F; + + if (var14 == 0) { + this.setRenderBounds((double) (0.5F - var8), 0.30000001192092896D, 0.0D, (double) (0.5F + var8), 1.0D, (double) (var8 * 2.0F)); + } + + if (var14 == 1) { + this.setRenderBounds((double) (0.5F - var8), 0.30000001192092896D, (double) (1.0F - var8 * 2.0F), (double) (0.5F + var8), 1.0D, 1.0D); + } + + var8 = 0.0625F; + + if (var14 == 2) { + this.setRenderBounds((double) (0.5F - var8), 0.5D, 0.0D, (double) (0.5F + var8), (double) (1.0F - var8), 1.0D); + } + + EaglerAdapter.glTranslatef(-0.5F, -0.5F, -0.5F); + var4.startDrawingQuads(); + var4.setNormal(0.0F, -1.0F, 0.0F); + this.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 0)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 1.0F, 0.0F); + this.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 1)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 0.0F, -1.0F); + this.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 0.0F, 1.0F); + this.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 3)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(-1.0F, 0.0F, 0.0F); + this.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 4)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(1.0F, 0.0F, 0.0F); + this.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSide(par1Block, 5)); + var4.draw(); + EaglerAdapter.glTranslatef(0.5F, 0.5F, 0.5F); + } + } else if (var6 == 32) { + for (var14 = 0; var14 < 2; ++var14) { + if (var14 == 0) { + this.setRenderBounds(0.0D, 0.0D, 0.3125D, 1.0D, 0.8125D, 0.6875D); + } + + if (var14 == 1) { + this.setRenderBounds(0.25D, 0.0D, 0.25D, 0.75D, 1.0D, 0.75D); + } + + EaglerAdapter.glTranslatef(-0.5F, -0.5F, -0.5F); + var4.startDrawingQuads(); + var4.setNormal(0.0F, -1.0F, 0.0F); + this.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 0, par2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 1.0F, 0.0F); + this.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 1, par2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 0.0F, -1.0F); + this.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 2, par2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 0.0F, 1.0F); + this.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 3, par2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(-1.0F, 0.0F, 0.0F); + this.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 4, par2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(1.0F, 0.0F, 0.0F); + this.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 5, par2)); + var4.draw(); + EaglerAdapter.glTranslatef(0.5F, 0.5F, 0.5F); + } + + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + } else if (var6 == 35) { + EaglerAdapter.glTranslatef(-0.5F, -0.5F, -0.5F); + this.renderBlockAnvilOrient((BlockAnvil) par1Block, 0, 0, 0, par2, true); + EaglerAdapter.glTranslatef(0.5F, 0.5F, 0.5F); + } else if (var6 == 34) { + for (var14 = 0; var14 < 3; ++var14) { + if (var14 == 0) { + this.setRenderBounds(0.125D, 0.0D, 0.125D, 0.875D, 0.1875D, 0.875D); + this.setOverrideBlockTexture(this.getBlockIcon(Block.obsidian)); + } else if (var14 == 1) { + this.setRenderBounds(0.1875D, 0.1875D, 0.1875D, 0.8125D, 0.875D, 0.8125D); + this.setOverrideBlockTexture(Block.beacon.getBeaconIcon()); + } else if (var14 == 2) { + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + this.setOverrideBlockTexture(this.getBlockIcon(Block.glass)); + } + + EaglerAdapter.glTranslatef(-0.5F, -0.5F, -0.5F); + var4.startDrawingQuads(); + var4.setNormal(0.0F, -1.0F, 0.0F); + this.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 0, par2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 1.0F, 0.0F); + this.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 1, par2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 0.0F, -1.0F); + this.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 2, par2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 0.0F, 1.0F); + this.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 3, par2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(-1.0F, 0.0F, 0.0F); + this.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 4, par2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(1.0F, 0.0F, 0.0F); + this.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 5, par2)); + var4.draw(); + EaglerAdapter.glTranslatef(0.5F, 0.5F, 0.5F); + } + + this.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + this.clearOverrideBlockTexture(); + } else if (var6 == 38) { + EaglerAdapter.glTranslatef(-0.5F, -0.5F, -0.5F); + this.renderBlockHopperMetadata((BlockHopper) par1Block, 0, 0, 0, 0, true); + EaglerAdapter.glTranslatef(0.5F, 0.5F, 0.5F); + } + } else { + if (var6 == 16) { + par2 = 1; + } + + par1Block.setBlockBoundsForItemRender(); + this.setRenderBoundsFromBlock(par1Block); + EaglerAdapter.glRotatef(90.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glTranslatef(-0.5F, -0.5F, -0.5F); + var4.startDrawingQuads(); + var4.setNormal(0.0F, -1.0F, 0.0F); + this.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 0, par2)); + var4.draw(); + + if (var5 && this.useInventoryTint) { + var14 = par1Block.getRenderColor(par2); + var8 = (float) (var14 >> 16 & 255) / 255.0F; + var9 = (float) (var14 >> 8 & 255) / 255.0F; + float var10 = (float) (var14 & 255) / 255.0F; + EaglerAdapter.glColor4f(var8 * par3, var9 * par3, var10 * par3, 1.0F); + } + + var4.startDrawingQuads(); + var4.setNormal(0.0F, 1.0F, 0.0F); + this.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 1, par2)); + var4.draw(); + + if (var5 && this.useInventoryTint) { + EaglerAdapter.glColor4f(par3, par3, par3, 1.0F); + } + + var4.startDrawingQuads(); + var4.setNormal(0.0F, 0.0F, -1.0F); + this.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 2, par2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(0.0F, 0.0F, 1.0F); + this.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 3, par2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(-1.0F, 0.0F, 0.0F); + this.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 4, par2)); + var4.draw(); + var4.startDrawingQuads(); + var4.setNormal(1.0F, 0.0F, 0.0F); + this.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, this.getBlockIconFromSideAndMetadata(par1Block, 5, par2)); + var4.draw(); + EaglerAdapter.glTranslatef(0.5F, 0.5F, 0.5F); + } + } + + /** + * Checks to see if the item's render type indicates that it should be rendered + * as a regular block or not. + */ + public static boolean renderItemIn3d(int par0) { + return par0 == 0 ? true + : (par0 == 31 ? true + : (par0 == 39 ? true + : (par0 == 13 ? true + : (par0 == 10 ? true + : (par0 == 11 ? true + : (par0 == 27 ? true : (par0 == 22 ? true : (par0 == 21 ? true : (par0 == 16 ? true : (par0 == 26 ? true : (par0 == 32 ? true : (par0 == 34 ? true : par0 == 35)))))))))))); + } + + public Icon getBlockIcon(Block par1Block, IBlockAccess par2IBlockAccess, int par3, int par4, int par5, int par6) { + return this.getIconSafe(par1Block.getBlockTexture(par2IBlockAccess, par3, par4, par5, par6)); + } + + public Icon getBlockIconFromSideAndMetadata(Block par1Block, int par2, int par3) { + return this.getIconSafe(par1Block.getIcon(par2, par3)); + } + + public Icon getBlockIconFromSide(Block par1Block, int par2) { + return this.getIconSafe(par1Block.getBlockTextureFromSide(par2)); + } + + public Icon getBlockIcon(Block par1Block) { + return this.getIconSafe(par1Block.getBlockTextureFromSide(1)); + } + + public Icon getIconSafe(Icon par1Icon) { + return par1Icon == null ? this.minecraftRB.renderEngine.getMissingIcon(0) : par1Icon; + } +} diff --git a/src/main/java/net/minecraft/src/RenderBoat.java b/src/main/java/net/minecraft/src/RenderBoat.java new file mode 100644 index 0000000..8416f33 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderBoat.java @@ -0,0 +1,55 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class RenderBoat extends Render { + /** instance of ModelBoat for rendering */ + protected ModelBase modelBoat; + + public RenderBoat() { + this.shadowSize = 0.5F; + this.modelBoat = new ModelBoat(); + } + + private static final TextureLocation tex = new TextureLocation("/item/boat.png"); + + /** + * The render method used in RenderBoat that renders the boat model. + */ + public void renderBoat(EntityBoat par1EntityBoat, double par2, double par4, double par6, float par8, float par9) { + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef((float) par2, (float) par4, (float) par6); + EaglerAdapter.glRotatef(180.0F - par8, 0.0F, 1.0F, 0.0F); + float var10 = (float) par1EntityBoat.getTimeSinceHit() - par9; + float var11 = (float) par1EntityBoat.getDamageTaken() - par9; + + if (var11 < 0.0F) { + var11 = 0.0F; + } + + if (var10 > 0.0F) { + EaglerAdapter.glRotatef(MathHelper.sin(var10) * var10 * var11 / 10.0F * (float) par1EntityBoat.getForwardDirection(), 1.0F, 0.0F, 0.0F); + } + + float var12 = 0.75F; + EaglerAdapter.glScalef(var12, var12, var12); + EaglerAdapter.glScalef(1.0F / var12, 1.0F / var12, 1.0F / var12); + tex.bindTexture(); + EaglerAdapter.glScalef(-1.0F, -1.0F, 1.0F); + this.modelBoat.render(par1EntityBoat, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F); + EaglerAdapter.glPopMatrix(); + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, + * always casting down its argument and then handing it off to a worker function + * which does the actual work. In all probabilty, the class Render is generic + * (Render 1.0F) { + var4 = 1.0F; + } + + var4 *= var4; + var4 *= var4; + float var6 = (1.0F + var4 * 0.4F) * var5; + float var7 = (1.0F + var4 * 0.1F) / var5; + EaglerAdapter.glScalef(var6, var7, var6); + } + + /** + * Updates color multiplier based on creeper state called by getColorMultiplier + */ + protected int updateCreeperColorMultiplier(EntityCreeper par1EntityCreeper, float par2, float par3) { + float var5 = par1EntityCreeper.getCreeperFlashIntensity(par3); + + if ((int) (var5 * 10.0F) % 2 == 0) { + return 0; + } else { + int var6 = (int) (var5 * 0.2F * 255.0F); + + if (var6 < 0) { + var6 = 0; + } + + if (var6 > 255) { + var6 = 255; + } + + short var7 = 255; + short var8 = 255; + short var9 = 255; + return var6 << 24 | var7 << 16 | var8 << 8 | var9; + } + } + + private static final TextureLocation tex_power = new TextureLocation("/armor/power.png"); + + /** + * A method used to render a creeper's powered form as a pass model. + */ + protected int renderCreeperPassModel(EntityCreeper par1EntityCreeper, int par2, float par3) { + if (par1EntityCreeper.getPowered()) { + if (par1EntityCreeper.isInvisible()) { + EaglerAdapter.glDepthMask(false); + } else { + EaglerAdapter.glDepthMask(true); + } + + if (par2 == 1) { + float var4 = (float) par1EntityCreeper.ticksExisted + par3; + tex_power.bindTexture(); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_TEXTURE); + EaglerAdapter.glLoadIdentity(); + float var5 = var4 * 0.01F; + float var6 = var4 * 0.01F; + EaglerAdapter.glTranslatef(var5, var6, 0.0F); + this.setRenderPassModel(this.creeperModel); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + float var7 = 0.5F; + EaglerAdapter.glColor4f(var7, var7, var7, 1.0F); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_ONE, EaglerAdapter.GL_ONE); + return 1; + } + + if (par2 == 2) { + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_TEXTURE); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + } + } + + return -1; + } + + protected int func_77061_b(EntityCreeper par1EntityCreeper, int par2, float par3) { + return -1; + } + + /** + * Allows the render to do any OpenGL state modifications necessary before the + * model is rendered. Args: entityLiving, partialTickTime + */ + protected void preRenderCallback(EntityLiving par1EntityLiving, float par2) { + this.updateCreeperScale((EntityCreeper) par1EntityLiving, par2); + } + + /** + * Returns an ARGB int color back. Args: entityLiving, lightBrightness, + * partialTickTime + */ + protected int getColorMultiplier(EntityLiving par1EntityLiving, float par2, float par3) { + return this.updateCreeperColorMultiplier((EntityCreeper) par1EntityLiving, par2, par3); + } + + /** + * Queries whether should render the specified pass or not. + */ + protected int shouldRenderPass(EntityLiving par1EntityLiving, int par2, float par3) { + return this.renderCreeperPassModel((EntityCreeper) par1EntityLiving, par2, par3); + } + + protected int inheritRenderPass(EntityLiving par1EntityLiving, int par2, float par3) { + return this.func_77061_b((EntityCreeper) par1EntityLiving, par2, par3); + } + + private static final TextureLocation entityTexture = new TextureLocation("/mob/creeper.png"); + + @Override + protected void bindTexture(EntityLiving par1EntityLiving) { + entityTexture.bindTexture(); + } +} diff --git a/src/main/java/net/minecraft/src/RenderDragon.java b/src/main/java/net/minecraft/src/RenderDragon.java new file mode 100644 index 0000000..4e578f3 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderDragon.java @@ -0,0 +1,271 @@ +package net.minecraft.src; + +import java.util.Random; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class RenderDragon extends RenderLiving { + /** + * Reloads the dragon model if not equal to 4. Presumably a leftover debugging + * field. + */ + private static int updateModelState = 0; + + /** An instance of the dragon model in RenderDragon */ + protected ModelDragon modelDragon; + + public RenderDragon() { + super(new ModelDragon(0.0F), 0.5F); + this.modelDragon = (ModelDragon) this.mainModel; + this.setRenderPassModel(this.mainModel); + } + + /** + * Used to rotate the dragon as a whole in RenderDragon. It's called in the + * rotateCorpse method. + */ + protected void rotateDragonBody(EntityDragon par1EntityDragon, float par2, float par3, float par4) { + float var5 = (float) par1EntityDragon.getMovementOffsets(7, par4)[0]; + float var6 = (float) (par1EntityDragon.getMovementOffsets(5, par4)[1] - par1EntityDragon.getMovementOffsets(10, par4)[1]); + EaglerAdapter.glRotatef(-var5, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(var6 * 10.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glTranslatef(0.0F, 0.0F, 1.0F); + + if (par1EntityDragon.deathTime > 0) { + float var7 = ((float) par1EntityDragon.deathTime + par4 - 1.0F) / 20.0F * 1.6F; + var7 = MathHelper.sqrt_float(var7); + + if (var7 > 1.0F) { + var7 = 1.0F; + } + + EaglerAdapter.glRotatef(var7 * this.getDeathMaxRotation(par1EntityDragon), 0.0F, 0.0F, 1.0F); + } + } + + private static final TextureLocation tex_shuffle = new TextureLocation("/mob/enderdragon/shuffle.png"); + private static final TextureLocation tex_beam = new TextureLocation("/mob/enderdragon/beam.png"); + private static final TextureLocation tex_eyes = new TextureLocation("/mob/enderdragon/ender_eyes.png"); + + private static final TextureLocation entityTexture = new TextureLocation("/mob/enderdragon/ender.png"); + + @Override + protected void bindTexture(EntityLiving par1EntityLiving) { + entityTexture.bindTexture(); + } + + /** + * Renders the dragon model. Called by renderModel. + */ + protected void renderDragonModel(EntityDragon par1EntityDragon, float par2, float par3, float par4, float par5, float par6, float par7) { + if (par1EntityDragon.deathTicks > 0) { + float var8 = (float) par1EntityDragon.deathTicks / 200.0F; + EaglerAdapter.glDepthFunc(EaglerAdapter.GL_LEQUAL); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glAlphaFunc(EaglerAdapter.GL_GREATER, var8); + tex_shuffle.bindTexture(); + this.mainModel.render(par1EntityDragon, par2, par3, par4, par5, par6, par7); + EaglerAdapter.glAlphaFunc(EaglerAdapter.GL_GREATER, 0.1F); + EaglerAdapter.glDepthFunc(EaglerAdapter.GL_EQUAL); + } + + this.bindTexture(par1EntityDragon); + this.mainModel.render(par1EntityDragon, par2, par3, par4, par5, par6, par7); + + if (par1EntityDragon.hurtTime > 0) { + EaglerAdapter.glDepthFunc(EaglerAdapter.GL_EQUAL); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glColor4f(1.0F, 0.0F, 0.0F, 0.5F); + this.mainModel.render(par1EntityDragon, par2, par3, par4, par5, par6, par7); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glDepthFunc(EaglerAdapter.GL_LEQUAL); + } + } + + /** + * Renders the dragon, along with its dying animation + */ + public void renderDragon(EntityDragon par1EntityDragon, double par2, double par4, double par6, float par8, float par9) { + BossStatus.func_82824_a(par1EntityDragon, false); + + if (updateModelState != 4) { + this.mainModel = new ModelDragon(0.0F); + updateModelState = 4; + } + + super.doRenderLiving(par1EntityDragon, par2, par4, par6, par8, par9); + + if (par1EntityDragon.healingEnderCrystal != null) { + float var10 = (float) par1EntityDragon.healingEnderCrystal.innerRotation + par9; + float var11 = MathHelper.sin(var10 * 0.2F) / 2.0F + 0.5F; + var11 = (var11 * var11 + var11) * 0.2F; + float var12 = (float) (par1EntityDragon.healingEnderCrystal.posX - par1EntityDragon.posX - (par1EntityDragon.prevPosX - par1EntityDragon.posX) * (double) (1.0F - par9)); + float var13 = (float) ((double) var11 + par1EntityDragon.healingEnderCrystal.posY - 1.0D - par1EntityDragon.posY - (par1EntityDragon.prevPosY - par1EntityDragon.posY) * (double) (1.0F - par9)); + float var14 = (float) (par1EntityDragon.healingEnderCrystal.posZ - par1EntityDragon.posZ - (par1EntityDragon.prevPosZ - par1EntityDragon.posZ) * (double) (1.0F - par9)); + float var15 = MathHelper.sqrt_float(var12 * var12 + var14 * var14); + float var16 = MathHelper.sqrt_float(var12 * var12 + var13 * var13 + var14 * var14); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef((float) par2, (float) par4 + 2.0F, (float) par6); + EaglerAdapter.glRotatef((float) (-Math.atan2((double) var14, (double) var12)) * 180.0F / (float) Math.PI - 90.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef((float) (-Math.atan2((double) var15, (double) var13)) * 180.0F / (float) Math.PI - 90.0F, 1.0F, 0.0F, 0.0F); + Tessellator var17 = Tessellator.instance; + RenderHelper.disableStandardItemLighting(); + EaglerAdapter.glDisable(EaglerAdapter.GL_CULL_FACE); + tex_beam.bindTexture(); + EaglerAdapter.glShadeModel(EaglerAdapter.GL_SMOOTH); + float var18 = 0.0F - ((float) par1EntityDragon.ticksExisted + par9) * 0.01F; + float var19 = MathHelper.sqrt_float(var12 * var12 + var13 * var13 + var14 * var14) / 32.0F - ((float) par1EntityDragon.ticksExisted + par9) * 0.01F; + var17.startDrawing(EaglerAdapter.GL_TRIANGLE_STRIP); + byte var20 = 8; + + for (int var21 = 0; var21 <= var20; ++var21) { + float var22 = MathHelper.sin((float) (var21 % var20) * (float) Math.PI * 2.0F / (float) var20) * 0.75F; + float var23 = MathHelper.cos((float) (var21 % var20) * (float) Math.PI * 2.0F / (float) var20) * 0.75F; + float var24 = (float) (var21 % var20) * 1.0F / (float) var20; + var17.setColorOpaque_I(0); + var17.addVertexWithUV((double) (var22 * 0.2F), (double) (var23 * 0.2F), 0.0D, (double) var24, (double) var19); + var17.setColorOpaque_I(16777215); + var17.addVertexWithUV((double) var22, (double) var23, (double) var16, (double) var24, (double) var18); + } + + var17.draw(); + EaglerAdapter.glEnable(EaglerAdapter.GL_CULL_FACE); + EaglerAdapter.glShadeModel(EaglerAdapter.GL_FLAT); + RenderHelper.enableStandardItemLighting(); + EaglerAdapter.glPopMatrix(); + } + } + + /** + * Renders the animation for when an enderdragon dies + */ + protected void renderDragonDying(EntityDragon par1EntityDragon, float par2) { + super.renderEquippedItems(par1EntityDragon, par2); + Tessellator var3 = Tessellator.instance; + + if (par1EntityDragon.deathTicks > 0) { + RenderHelper.disableStandardItemLighting(); + float var4 = ((float) par1EntityDragon.deathTicks + par2) / 200.0F; + float var5 = 0.0F; + + if (var4 > 0.8F) { + var5 = (var4 - 0.8F) / 0.2F; + } + + Random var6 = new Random(432L); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glShadeModel(EaglerAdapter.GL_SMOOTH); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE); + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glEnable(EaglerAdapter.GL_CULL_FACE); + EaglerAdapter.glDepthMask(false); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(0.0F, -1.0F, -2.0F); + + for (int var7 = 0; (float) var7 < (var4 + var4 * var4) / 2.0F * 60.0F; ++var7) { + EaglerAdapter.glRotatef(var6.nextFloat() * 360.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(var6.nextFloat() * 360.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(var6.nextFloat() * 360.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glRotatef(var6.nextFloat() * 360.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(var6.nextFloat() * 360.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(var6.nextFloat() * 360.0F + var4 * 90.0F, 0.0F, 0.0F, 1.0F); + var3.startDrawing(EaglerAdapter.GL_TRIANGLE_FAN); + float var8 = var6.nextFloat() * 20.0F + 5.0F + var5 * 10.0F; + float var9 = var6.nextFloat() * 2.0F + 1.0F + var5 * 2.0F; + var3.setColorRGBA_I(16777215, (int) (255.0F * (1.0F - var5))); + var3.addVertex(0.0D, 0.0D, 0.0D); + var3.setColorRGBA_I(16711935, 0); + var3.addVertex(-0.866D * (double) var9, (double) var8, (double) (-0.5F * var9)); + var3.addVertex(0.866D * (double) var9, (double) var8, (double) (-0.5F * var9)); + var3.addVertex(0.0D, (double) var8, (double) (1.0F * var9)); + var3.addVertex(-0.866D * (double) var9, (double) var8, (double) (-0.5F * var9)); + var3.draw(); + } + + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glDepthMask(true); + EaglerAdapter.glDisable(EaglerAdapter.GL_CULL_FACE); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glShadeModel(EaglerAdapter.GL_FLAT); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + RenderHelper.enableStandardItemLighting(); + } + } + + /** + * Renders the overlay for glowing eyes and the mouth. Called by + * shouldRenderPass. + */ + protected int renderGlow(EntityDragon par1EntityDragon, int par2, float par3) { + if (par2 == 1) { + EaglerAdapter.glDepthFunc(EaglerAdapter.GL_LEQUAL); + } + + if (par2 != 0) { + return -1; + } else { + tex_eyes.bindTexture(); + float var4 = 1.0F; + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_ONE, EaglerAdapter.GL_ONE); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glDepthFunc(EaglerAdapter.GL_EQUAL); + char var5 = 61680; + int var6 = var5 % 65536; + int var7 = var5 / 65536; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) var6 / 1.0F, (float) var7 / 1.0F); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, var4); + return 1; + } + } + + /** + * Queries whether should render the specified pass or not. + */ + protected int shouldRenderPass(EntityLiving par1EntityLiving, int par2, float par3) { + return this.renderGlow((EntityDragon) par1EntityLiving, par2, par3); + } + + protected void renderEquippedItems(EntityLiving par1EntityLiving, float par2) { + this.renderDragonDying((EntityDragon) par1EntityLiving, par2); + } + + protected void rotateCorpse(EntityLiving par1EntityLiving, float par2, float par3, float par4) { + this.rotateDragonBody((EntityDragon) par1EntityLiving, par2, par3, par4); + } + + /** + * Renders the model in RenderLiving + */ + protected void renderModel(EntityLiving par1EntityLiving, float par2, float par3, float par4, float par5, float par6, float par7) { + this.renderDragonModel((EntityDragon) par1EntityLiving, par2, par3, par4, par5, par6, par7); + } + + public void doRenderLiving(EntityLiving par1EntityLiving, double par2, double par4, double par6, float par8, float par9) { + this.renderDragon((EntityDragon) par1EntityLiving, par2, par4, par6, par8, par9); + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, + * always casting down its argument and then handing it off to a worker function + * which does the actual work. In all probabilty, the class Render is generic + * (Render= (float) Math.PI; var10 -= ((float) Math.PI * 2F)) { + ; + } + + while (var10 < -(float) Math.PI) { + var10 += ((float) Math.PI * 2F); + } + + float var11 = par1TileEntityEnchantmentTable.bookRotationPrev + var10 * par8; + EaglerAdapter.glRotatef(-var11 * 180.0F / (float) Math.PI, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(80.0F, 0.0F, 0.0F, 1.0F); + tex_book.bindTexture(); + float var12 = par1TileEntityEnchantmentTable.pageFlipPrev + (par1TileEntityEnchantmentTable.pageFlip - par1TileEntityEnchantmentTable.pageFlipPrev) * par8 + 0.25F; + float var13 = par1TileEntityEnchantmentTable.pageFlipPrev + (par1TileEntityEnchantmentTable.pageFlip - par1TileEntityEnchantmentTable.pageFlipPrev) * par8 + 0.75F; + var12 = (var12 - (float) MathHelper.truncateDoubleToInt((double) var12)) * 1.6F - 0.3F; + var13 = (var13 - (float) MathHelper.truncateDoubleToInt((double) var13)) * 1.6F - 0.3F; + + if (var12 < 0.0F) { + var12 = 0.0F; + } + + if (var13 < 0.0F) { + var13 = 0.0F; + } + + if (var12 > 1.0F) { + var12 = 1.0F; + } + + if (var13 > 1.0F) { + var13 = 1.0F; + } + + float var14 = par1TileEntityEnchantmentTable.bookSpreadPrev + (par1TileEntityEnchantmentTable.bookSpread - par1TileEntityEnchantmentTable.bookSpreadPrev) * par8; + EaglerAdapter.glEnable(EaglerAdapter.GL_CULL_FACE); + this.enchantmentBook.render((Entity) null, var9, var12, var13, var14, 0.0F, 0.0625F); + EaglerAdapter.glPopMatrix(); + } + + public void renderTileEntityAt(TileEntity par1TileEntity, double par2, double par4, double par6, float par8) { + this.renderTileEntityEnchantmentTableAt((TileEntityEnchantmentTable) par1TileEntity, par2, par4, par6, par8); + } +} diff --git a/src/main/java/net/minecraft/src/RenderEndPortal.java b/src/main/java/net/minecraft/src/RenderEndPortal.java new file mode 100644 index 0000000..a4ce09a --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderEndPortal.java @@ -0,0 +1,123 @@ +package net.minecraft.src; + +import java.nio.FloatBuffer; +import java.util.Random; +import net.minecraft.client.Minecraft; +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; +import net.lax1dude.eaglercraft.adapter.Tessellator; + +public class RenderEndPortal extends TileEntitySpecialRenderer { + FloatBuffer field_76908_a = GLAllocation.createDirectFloatBuffer(16); + + private static final TextureLocation tex_tunnel = new TextureLocation("/misc/tunnel.png"); + private static final TextureLocation tex_particlefield = new TextureLocation("/misc/particlefield.png"); + + /** + * Renders the End Portal. + */ + public void renderEndPortalTileEntity(TileEntityEndPortal par1TileEntityEndPortal, double par2, double par4, double par6, float par8) { + float var9 = (float) this.tileEntityRenderer.playerX; + float var10 = (float) this.tileEntityRenderer.playerY; + float var11 = (float) this.tileEntityRenderer.playerZ; + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + Random var12 = new Random(31100L); + float var13 = 0.75F; + + for (int var14 = 0; var14 < 16; ++var14) { + EaglerAdapter.glPushMatrix(); + float var15 = (float) (16 - var14); + float var16 = 0.0625F; + float var17 = 1.0F / (var15 + 1.0F); + + if (var14 == 0) { + tex_tunnel.bindTexture(); + var17 = 0.1F; + var15 = 65.0F; + var16 = 0.125F; + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + } + + if (var14 == 1) { + tex_particlefield.bindTexture(); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_ONE, EaglerAdapter.GL_ONE); + var16 = 0.5F; + } + + var16 *= 3.0f; + + float var18 = (float) (-(par4 + (double) var13)); + float var19 = var18 + ActiveRenderInfo.objectY; + float var20 = var18 + var15 + ActiveRenderInfo.objectY; + float var21 = var19 / var20; + var21 += (float) (par4 + (double) var13); + EaglerAdapter.glTranslatef(var9, var21, var11); + EaglerAdapter.glTexGeni(EaglerAdapter.GL_S, EaglerAdapter.GL_TEXTURE_GEN_MODE, EaglerAdapter.GL_OBJECT_LINEAR); + EaglerAdapter.glTexGeni(EaglerAdapter.GL_T, EaglerAdapter.GL_TEXTURE_GEN_MODE, EaglerAdapter.GL_OBJECT_LINEAR); + EaglerAdapter.glTexGeni(EaglerAdapter.GL_R, EaglerAdapter.GL_TEXTURE_GEN_MODE, EaglerAdapter.GL_OBJECT_LINEAR); + EaglerAdapter.glTexGeni(EaglerAdapter.GL_Q, EaglerAdapter.GL_TEXTURE_GEN_MODE, EaglerAdapter.GL_EYE_LINEAR); + EaglerAdapter.glTexGen(EaglerAdapter.GL_S, EaglerAdapter.GL_OBJECT_PLANE, this.func_76907_a(1.0F, 0.0F, 0.0F, 0.0F)); + EaglerAdapter.glTexGen(EaglerAdapter.GL_T, EaglerAdapter.GL_OBJECT_PLANE, this.func_76907_a(0.0F, 0.0F, 1.0F, 0.0F)); + EaglerAdapter.glTexGen(EaglerAdapter.GL_R, EaglerAdapter.GL_OBJECT_PLANE, this.func_76907_a(0.0F, 0.0F, 0.0F, 1.0F)); + EaglerAdapter.glTexGen(EaglerAdapter.GL_Q, EaglerAdapter.GL_EYE_PLANE, this.func_76907_a(0.0F, 1.0F, 0.0F, 0.0F)); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_GEN_S); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_GEN_T); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_GEN_R); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_GEN_Q); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_TEXTURE); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glLoadIdentity(); + EaglerAdapter.glTranslatef(0.0F, (float) (Minecraft.getSystemTime() % 400000L) / 400000.0F, 0.0F); + EaglerAdapter.glScalef(var16, var16, var16); + EaglerAdapter.glTranslatef(0.5F, 0.5F, 0.0F); + EaglerAdapter.glRotatef((float) (var14 * var14 * 4321 + var14 * 9) * 2.0F, 0.0F, 0.0F, 1.0F); + EaglerAdapter.glTranslatef(-0.5F, -0.5F, 0.0F); + //EaglerAdapter.glTranslatef(-var9, -var11, -var10); + var19 = var18 + ActiveRenderInfo.objectY; + EaglerAdapter.glTranslatef(ActiveRenderInfo.objectX * var15 / var19, ActiveRenderInfo.objectZ * var15 / var19, -var10); + Tessellator var24 = Tessellator.instance; + var24.startDrawingQuads(); + var21 = var12.nextFloat() * 0.5F + 0.1F; + float var22 = var12.nextFloat() * 0.5F + 0.4F; + float var23 = var12.nextFloat() * 0.5F + 0.5F; + + if (var14 == 0) { + var23 = 1.0F; + var22 = 1.0F; + var21 = 1.0F; + } + + var24.setColorRGBA_F(var21 * var17, var22 * var17, var23 * var17, 1.0F); + var24.addVertex(par2, par4 + (double) var13, par6); + var24.addVertex(par2, par4 + (double) var13, par6 + 1.0D); + var24.addVertex(par2 + 1.0D, par4 + (double) var13, par6 + 1.0D); + var24.addVertex(par2 + 1.0D, par4 + (double) var13, par6); + var24.draw(); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glMatrixMode(EaglerAdapter.GL_MODELVIEW); + } + + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_GEN_S); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_GEN_T); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_GEN_R); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_GEN_Q); + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + } + + private FloatBuffer func_76907_a(float par1, float par2, float par3, float par4) { + this.field_76908_a.clear(); + this.field_76908_a.put(par1).put(par2).put(par3).put(par4); + this.field_76908_a.flip(); + return this.field_76908_a; + } + + public void renderTileEntityAt(TileEntity par1TileEntity, double par2, double par4, double par6, float par8) { + this.renderEndPortalTileEntity((TileEntityEndPortal) par1TileEntity, par2, par4, par6, par8); + } +} diff --git a/src/main/java/net/minecraft/src/RenderEnderCrystal.java b/src/main/java/net/minecraft/src/RenderEnderCrystal.java new file mode 100644 index 0000000..96852c0 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderEnderCrystal.java @@ -0,0 +1,46 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.TextureLocation; + +public class RenderEnderCrystal extends Render { + private int field_76996_a = -1; + private ModelBase field_76995_b; + + public RenderEnderCrystal() { + this.shadowSize = 0.5F; + } + + private static final TextureLocation tex = new TextureLocation("/mob/enderdragon/crystal.png"); + + /** + * Renders the Ender Crystal. + */ + public void doRenderEnderCrystal(EntityEnderCrystal par1EntityEnderCrystal, double par2, double par4, double par6, float par8, float par9) { + if (this.field_76996_a != 1) { + this.field_76995_b = new ModelEnderCrystal(0.0F, true); + this.field_76996_a = 1; + } + + float var10 = (float) par1EntityEnderCrystal.innerRotation + par9; + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef((float) par2, (float) par4, (float) par6); + tex.bindTexture(); + float var11 = MathHelper.sin(var10 * 0.2F) / 2.0F + 0.5F; + var11 += var11 * var11; + this.field_76995_b.render(par1EntityEnderCrystal, 0.0F, var10 * 3.0F, var11 * 0.2F, 0.0F, 0.0F, 0.0625F); + EaglerAdapter.glPopMatrix(); + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, + * always casting down its argument and then handing it off to a worker function + * which does the actual work. In all probabilty, the class Render is generic + * (Render 0; + this.endermanModel.isAttacking = par1EntityEnderman.isScreaming(); + + if (par1EntityEnderman.isScreaming()) { + double var10 = 0.02D; + par2 += this.rnd.nextGaussian() * var10; + par6 += this.rnd.nextGaussian() * var10; + } + + super.doRenderLiving(par1EntityEnderman, par2, par4, par6, par8, par9); + } + + private static final TextureLocation terrain = new TextureLocation("/terrain.png"); + + /** + * Render the block an enderman is carrying + */ + protected void renderCarrying(EntityEnderman par1EntityEnderman, float par2) { + super.renderEquippedItems(par1EntityEnderman, par2); + + if (par1EntityEnderman.getCarried() > 0) { + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + EaglerAdapter.glPushMatrix(); + float var3 = 0.5F; + EaglerAdapter.glTranslatef(0.0F, 0.6875F, -0.75F); + var3 *= 1.0F; + EaglerAdapter.glRotatef(20.0F, 1.0F, 0.0F, 0.0F); + EaglerAdapter.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + EaglerAdapter.glScalef(-var3, -var3, var3); + int var4 = par1EntityEnderman.getBrightnessForRender(par2); + int var5 = var4 % 65536; + int var6 = var4 / 65536; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) var5 / 1.0F, (float) var6 / 1.0F); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + terrain.bindTexture(); + this.renderBlocks.renderBlockAsItem(Block.blocksList[par1EntityEnderman.getCarried()], par1EntityEnderman.getCarryingData(), 1.0F); + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + } + } + + public static final TextureLocation tex_eyes = new TextureLocation("/mob/enderman_eyes.png"); + + /** + * Render the endermans eyes + */ + protected int renderEyes(EntityEnderman par1EntityEnderman, int par2, float par3) { + if (par2 != 0) { + return -1; + } else { + tex_eyes.bindTexture(); + float var4 = 1.0F; + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_ONE, EaglerAdapter.GL_ONE); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + + if (par1EntityEnderman.isInvisible()) { + EaglerAdapter.glDepthMask(false); + } else { + EaglerAdapter.glDepthMask(true); + } + + char var5 = 61680; + int var6 = var5 % 65536; + int var7 = var5 / 65536; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) var6 / 1.0F, (float) var7 / 1.0F); + EaglerAdapter.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glColor4f(2.3F, 2.3F, 2.3F, var4); + return 1; + } + } + + /** + * Queries whether should render the specified pass or not. + */ + protected int shouldRenderPass(EntityLiving par1EntityLiving, int par2, float par3) { + return this.renderEyes((EntityEnderman) par1EntityLiving, par2, par3); + } + + protected void renderEquippedItems(EntityLiving par1EntityLiving, float par2) { + this.renderCarrying((EntityEnderman) par1EntityLiving, par2); + } + + public void doRenderLiving(EntityLiving par1EntityLiving, double par2, double par4, double par6, float par8, float par9) { + this.renderEnderman((EntityEnderman) par1EntityLiving, par2, par4, par6, par8, par9); + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, + * always casting down its argument and then handing it off to a worker function + * which does the actual work. In all probabilty, the class Render is generic + * (Render> 2); + this.texturePack = par1TexturePackList; + this.options = par2GameSettings; + int[] missingTex = new int[256]; + for(int i = 0; i < 256; ++i) { + missingTex[i] = ((i / 16 + (i % 16)) % 2 == 0) ? 0xffff00ff : 0xff000000; + } + this.missingTextureImage = new EaglerImage(missingTex, 16, 16, true); + this.textureMapBlocks = new TextureTerrainMap(1024, "terrain", "textures/blocks/", this.missingTextureImage); + this.textureMapItems = new TextureMap(1, "items", "textures/items/", this.missingTextureImage); + } + + public int[] getTextureContents(String par1Str) { + ITexturePack var2 = this.texturePack.getSelectedTexturePack(); + int[] var3 = (int[]) this.textureContentsMap.get(par1Str); + + if (var3 != null) { + return var3; + } else { + byte[] var7 = var2.getResourceAsBytes(par1Str); + int[] var4; + + if (var7 == null) { + var4 = this.missingTextureImage.data; + } else { + var4 = EaglerImage.loadImage(var7).data; + } + + this.textureContentsMap.put(par1Str, var4); + return var4; + } + } + + + public void bindTexture(String par1Str) { + this.bindTexture(this.getTexture(par1Str)); + } + + public void bindTexture(int par1) { + if (par1 != this.boundTexture) { + EaglerAdapter.glBindTexture(EaglerAdapter.GL_TEXTURE_2D, par1); + this.boundTexture = par1; + } + } + + public void resetBoundTexture() { + this.boundTexture = -1; + } + + public int getTexture(String par1Str) { + if (par1Str.equals("/terrain.png")) { + return this.textureMapBlocks.texture; + } else if (par1Str.equals("/gui/items.png")) { + this.textureMapItems.getTexture().bindTexture(0); + return this.textureMapItems.getTexture().getGlTextureId(); + } else { + Integer var2 = (Integer) this.textureMap.get(par1Str); + + if (var2 != null) { + return var2.intValue(); + } else { + String var8 = par1Str; + + try { + int var3 = GLAllocation.generateTextureNames(); + boolean var9 = par1Str.startsWith("%blur%"); + + if (var9) { + par1Str = par1Str.substring(6); + } + + boolean var5 = par1Str.startsWith("%clamp%"); + + if (var5) { + par1Str = par1Str.substring(7); + } + + byte[] var6 = this.texturePack.getSelectedTexturePack().getResourceAsBytes(par1Str); + + if (var6 == null) { + this.setupTextureExt(this.missingTextureImage, var3, var9, var5); + } else { + this.setupTextureExt(this.readTextureImage(var6), var3, var9, var5); + } + + this.textureMap.put(var8, Integer.valueOf(var3)); + return var3; + } catch (Exception var7) { + var7.printStackTrace(); + int var4 = GLAllocation.generateTextureNames(); + this.setupTexture(this.missingTextureImage, var4); + this.textureMap.put(par1Str, Integer.valueOf(var4)); + return var4; + } + } + } + } + + /** + * Copy the supplied image onto a newly-allocated OpenGL texture, returning the + * allocated texture name + */ + public int allocateAndSetupTexture(EaglerImage par1BufferedImage) { + int var2 = GLAllocation.generateTextureNames(); + this.setupTexture(par1BufferedImage, var2); + this.textureNameToImageMap.addKey(var2, par1BufferedImage); + return var2; + } + + /** + * Copy the supplied image onto the specified OpenGL texture + */ + public void setupTexture(EaglerImage par1BufferedImage, int par2) { + this.setupTextureExt(par1BufferedImage, par2, false, false); + } + + public int makeViewportTexture(int w, int h) { + int t = EaglerAdapter.glGenTextures(); + this.bindTexture(t); + this.imageData.position(0).limit(w * h); + EaglerAdapter.glTexImage2D_2(EaglerAdapter.GL_TEXTURE_2D, 0, EaglerAdapter.GL_RGBA, w, h, 0, EaglerAdapter.GL_BGRA, EaglerAdapter.GL_UNSIGNED_INT_8_8_8_8_REV, this.imageData); + return t; + } + + public void setupTextureExt(EaglerImage par1BufferedImage, int par2, boolean par3, boolean par4) { + this.bindTexture(par2); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MIN_FILTER, EaglerAdapter.GL_NEAREST); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MAG_FILTER, EaglerAdapter.GL_NEAREST); + + if (par3) { + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MIN_FILTER, EaglerAdapter.GL_LINEAR); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MAG_FILTER, EaglerAdapter.GL_LINEAR); + } + + if (par4) { + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_WRAP_S, EaglerAdapter.GL_CLAMP); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_WRAP_T, EaglerAdapter.GL_CLAMP); + } else { + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_WRAP_S, EaglerAdapter.GL_REPEAT); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_WRAP_T, EaglerAdapter.GL_REPEAT); + } + + int var5 = par1BufferedImage.w; + int var6 = par1BufferedImage.h; + int[] var7 = par1BufferedImage.data; + + if (this.options != null && this.options.anaglyph) { + var7 = this.colorToAnaglyph(var7); + } + + this.imageData.clear(); + this.imageData.put(var7); + this.imageData.position(0).limit(var7.length); + EaglerAdapter.glTexImage2D(EaglerAdapter.GL_TEXTURE_2D, 0, EaglerAdapter.GL_RGBA, var5, var6, 0, EaglerAdapter.GL_BGRA, EaglerAdapter.GL_UNSIGNED_INT_8_8_8_8_REV, this.imageData); + } + + public int setupTextureRaw(byte[] data, int w, int h) { + int e = GLAllocation.generateTextureNames(); + this.bindTexture(e); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MIN_FILTER, EaglerAdapter.GL_NEAREST); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MAG_FILTER, EaglerAdapter.GL_NEAREST); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_WRAP_S, EaglerAdapter.GL_CLAMP); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_WRAP_T, EaglerAdapter.GL_CLAMP); + this.imageData.clear(); + int[] upload = new int[data.length / 4]; + for(int i = 0; i < upload.length; ++i) { + upload[i] = ((data[i*4+3] & 255) << 24) | ((data[i*4+2] & 255) << 16) | ((data[i*4+1] & 255) << 8) | (data[i*4] & 255); + } + this.imageData.put(upload).flip(); + EaglerAdapter.glTexImage2D(EaglerAdapter.GL_TEXTURE_2D, 0, EaglerAdapter.GL_RGBA, w, h, 0, EaglerAdapter.GL_BGRA, EaglerAdapter.GL_UNSIGNED_INT_8_8_8_8_REV, this.imageData); + return e; + } + + private int[] colorToAnaglyph(int[] par1ArrayOfInteger) { + int[] var2 = new int[par1ArrayOfInteger.length]; + + for (int var3 = 0; var3 < par1ArrayOfInteger.length; ++var3) { + int var4 = par1ArrayOfInteger[var3] >> 24 & 255; + int var5 = par1ArrayOfInteger[var3] >> 16 & 255; + int var6 = par1ArrayOfInteger[var3] >> 8 & 255; + int var7 = par1ArrayOfInteger[var3] & 255; + int var8 = (var5 * 30 + var6 * 59 + var7 * 11) / 100; + int var9 = (var5 * 30 + var6 * 70) / 100; + int var10 = (var5 * 30 + var7 * 70) / 100; + var2[var3] = var4 << 24 | var8 << 16 | var9 << 8 | var10; + } + + return var2; + } + + public void createTextureFromBytes(int[] par1ArrayOfInteger, int par2, int par3, int par4) { + this.bindTexture(par4); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MIN_FILTER, EaglerAdapter.GL_NEAREST); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_MAG_FILTER, EaglerAdapter.GL_NEAREST); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_WRAP_S, EaglerAdapter.GL_REPEAT); + EaglerAdapter.glTexParameteri(EaglerAdapter.GL_TEXTURE_2D, EaglerAdapter.GL_TEXTURE_WRAP_T, EaglerAdapter.GL_REPEAT); + + if (this.options != null && this.options.anaglyph) { + par1ArrayOfInteger = this.colorToAnaglyph(par1ArrayOfInteger); + } + + this.imageData.clear(); + this.imageData.put(par1ArrayOfInteger); + this.imageData.position(0).limit(par1ArrayOfInteger.length); + EaglerAdapter.glTexSubImage2D(EaglerAdapter.GL_TEXTURE_2D, 0, 0, 0, par2, par3, EaglerAdapter.GL_BGRA, EaglerAdapter.GL_UNSIGNED_INT_8_8_8_8_REV, this.imageData); + } + + /** + * Deletes a single GL texture + */ + public void deleteTexture(int par1) { + this.textureNameToImageMap.removeObject(par1); + EaglerAdapter.glDeleteTextures(par1); + } + + public void updateDynamicTextures() { + this.textureMapBlocks.updateAnimations(); + this.textureMapItems.updateAnimations(); + } + + /** + * Call setupTexture on all currently-loaded textures again to account for + * changes in rendering options + */ + public void refreshTextures() { + TextureLocation.freeTextures(); + ITexturePack var1 = this.texturePack.getSelectedTexturePack(); + this.refreshTextureMaps(); + Iterator var2 = this.textureNameToImageMap.getKeySet().iterator(); + EaglerImage var4; + + while (var2.hasNext()) { + int var3 = ((Integer) var2.next()).intValue(); + var4 = (EaglerImage) this.textureNameToImageMap.lookup(var3); + this.setupTexture(var4, var3); + } + + var2 = this.textureMap.keySet().iterator(); + String var11; + + while (var2.hasNext()) { + var11 = (String) var2.next(); + + try { + int var12 = ((Integer) this.textureMap.get(var11)).intValue(); + boolean var6 = var11.startsWith("%blur%"); + + if (var6) { + var11 = var11.substring(6); + } + + boolean var7 = var11.startsWith("%clamp%"); + + if (var7) { + var11 = var11.substring(7); + } + + byte[] b = var1.getResourceAsBytes(var11); + if(b != null) { + EaglerImage var5 = this.readTextureImage(b); + this.setupTextureExt(var5, var12, var6, var7); + }else { + System.err.println("could not reload: "+var11); + } + } catch (IOException var9) { + var9.printStackTrace(); + } + } + + var2 = this.textureContentsMap.keySet().iterator(); + + while (var2.hasNext()) { + var11 = (String) var2.next(); + + try { + var4 = this.readTextureImage(var1.getResourceAsBytes(var11)); + System.arraycopy(var4.data, 0, (int[]) this.textureContentsMap.get(var11), 0, var4.data.length); + } catch (IOException var8) { + var8.printStackTrace(); + } + } + + Minecraft.getMinecraft().fontRenderer.readFontData(); + Minecraft.getMinecraft().standardGalacticFontRenderer.readFontData(); + } + + /** + * Returns a BufferedImage read off the provided input stream. Args: inputStream + */ + private EaglerImage readTextureImage(byte[] par1InputStream) throws IOException { + return EaglerImage.loadImage(par1InputStream); + } + + public void refreshTextureMaps() { + this.textureMapBlocks.refreshTextures(); + this.textureMapItems.refreshTextures(); + } + + public Icon getMissingIcon(int par1) { + switch (par1) { + case 0: + return this.textureMapBlocks.getMissingIcon(); + + case 1: + default: + return this.textureMapItems.getMissingIcon(); + } + } +} diff --git a/src/main/java/net/minecraft/src/RenderEntity.java b/src/main/java/net/minecraft/src/RenderEntity.java new file mode 100644 index 0000000..860b047 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderEntity.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +public class RenderEntity extends Render { + /** + * Actually renders the given argument. This is a synthetic bridge method, + * always casting down its argument and then handing it off to a worker function + * which does the actual work. In all probabilty, the class Render is generic + * (Render 0 || par1EntityFishHook.angler != Minecraft.getMinecraft().thePlayer) { + float var31 = (par1EntityFishHook.angler.prevRenderYawOffset + (par1EntityFishHook.angler.renderYawOffset - par1EntityFishHook.angler.prevRenderYawOffset) * par9) * (float) Math.PI / 180.0F; + double var32 = (double) MathHelper.sin(var31); + double var34 = (double) MathHelper.cos(var31); + var23 = par1EntityFishHook.angler.prevPosX + (par1EntityFishHook.angler.posX - par1EntityFishHook.angler.prevPosX) * (double) par9 - var34 * 0.35D - var32 * 0.85D; + var25 = par1EntityFishHook.angler.prevPosY + var29 + (par1EntityFishHook.angler.posY - par1EntityFishHook.angler.prevPosY) * (double) par9 - 0.45D; + var27 = par1EntityFishHook.angler.prevPosZ + (par1EntityFishHook.angler.posZ - par1EntityFishHook.angler.prevPosZ) * (double) par9 - var32 * 0.35D + var34 * 0.85D; + } + + double var46 = par1EntityFishHook.prevPosX + (par1EntityFishHook.posX - par1EntityFishHook.prevPosX) * (double) par9; + double var33 = par1EntityFishHook.prevPosY + (par1EntityFishHook.posY - par1EntityFishHook.prevPosY) * (double) par9 + 0.25D; + double var35 = par1EntityFishHook.prevPosZ + (par1EntityFishHook.posZ - par1EntityFishHook.prevPosZ) * (double) par9; + double var37 = (double) ((float) (var23 - var46)); + double var39 = (double) ((float) (var25 - var33)); + double var41 = (double) ((float) (var27 - var35)); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + var12.startDrawing(EaglerAdapter.GL_LINE_STRIP); + var12.setColorOpaque_I(0); + byte var43 = 16; + + for (int var44 = 0; var44 <= var43; ++var44) { + float var45 = (float) var44 / (float) var43; + var12.addVertex(par2 + var37 * (double) var45, par4 + var39 * (double) (var45 * var45 + var45) * 0.5D + 0.25D, par6 + var41 * (double) var45); + } + + var12.draw(); + EaglerAdapter.glEnable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + } + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, + * always casting down its argument and then handing it off to a worker function + * which does the actual work. In all probabilty, the class Render is generic + * (Render