mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 17:14:44 +00:00
Compare commits
329
Commits
1.6
...
v164-pregradle
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f7ad51a02 | ||
|
|
45cc0bd87c | ||
|
|
77c5caffd5 | ||
|
|
28abe2cc3c | ||
|
|
745d601831 | ||
|
|
9fd39ebe79 | ||
|
|
4f05808b8e | ||
|
|
c8e249f919 | ||
|
|
7adccac8ec | ||
|
|
0a12840e68 | ||
|
|
1bd3e96e6e | ||
|
|
84fd2a147e | ||
|
|
cfd368e18f | ||
|
|
a9c795b54c | ||
|
|
8fb4546437 | ||
|
|
d316d74933 | ||
|
|
ebfaf83bd9 | ||
|
|
a103fbc0e6 | ||
|
|
a4fa417114 | ||
|
|
a47cca7e42 | ||
|
|
80ac3017bd | ||
|
|
ec517d5f28 | ||
|
|
899b28bffe | ||
|
|
217d5562ff | ||
|
|
b0f8d495bb | ||
|
|
295542c357 | ||
|
|
4db6c4cfc4 | ||
|
|
efc6b9abbb | ||
|
|
430d94de95 | ||
|
|
e0cb56381f | ||
|
|
f9c283a2e5 | ||
|
|
6c45b43eee | ||
|
|
de69b7dfd0 | ||
|
|
5f5b509c7a | ||
|
|
29606e2c39 | ||
|
|
412952be5b | ||
|
|
79e0165362 | ||
|
|
e47a6402e1 | ||
|
|
465525119c | ||
|
|
43a16d5389 | ||
|
|
303288e8b1 | ||
|
|
eb5940664c | ||
|
|
1a6743331b | ||
|
|
c8df5b832e | ||
|
|
fc1089713f | ||
|
|
0866d88126 | ||
|
|
8d0b58ee6f | ||
|
|
fa41058ba1 | ||
|
|
296a484f4b | ||
|
|
7d5d191fc2 | ||
|
|
d55ddfcebc | ||
|
|
7147cdb1c1 | ||
|
|
cba1de122a | ||
|
|
68669e2679 | ||
|
|
4374f67759 | ||
|
|
5e998776cb | ||
|
|
b09e72a2fc | ||
|
|
2e3d1a3c09 | ||
|
|
96b4fd1da1 | ||
|
|
d3c80c326a | ||
|
|
b74d977225 | ||
|
|
73202259fa | ||
|
|
01cf29a202 | ||
|
|
71ececdbb4 | ||
|
|
81efd38fee | ||
|
|
b3c715c312 | ||
|
|
8c54873afd | ||
|
|
50b9abc13f | ||
|
|
ca351b527d | ||
|
|
e4714bc4c5 | ||
|
|
06e2f914c1 | ||
|
|
3805eddd34 | ||
|
|
e842fd95b4 | ||
|
|
5f752fc967 | ||
|
|
f40bdeca97 | ||
|
|
24017d6810 | ||
|
|
5a24b2d73c | ||
|
|
4c38edf532 | ||
|
|
af24dc6096 | ||
|
|
865e4e2b45 | ||
|
|
41617a0227 | ||
|
|
ab2d8fa01b | ||
|
|
80dfdbf749 | ||
|
|
dbd19b0cad | ||
|
|
70671858c2 | ||
|
|
0c064485b1 | ||
|
|
0d090070a9 | ||
|
|
9029d380a3 | ||
|
|
71c14b815e | ||
|
|
64d7c4eaa5 | ||
|
|
62079e3549 | ||
|
|
a632ec6ce6 | ||
|
|
be8bccc72e | ||
|
|
a7fde237bb | ||
|
|
f68bdb0493 | ||
|
|
e03a4db2b9 | ||
|
|
54594ee1de | ||
|
|
98aecd7f6b | ||
|
|
f58df75bea | ||
|
|
43a6d0da62 | ||
|
|
a525cab5ff | ||
|
|
d39c279203 | ||
|
|
0a7095afa9 | ||
|
|
36672fef83 | ||
|
|
57ea20d083 | ||
|
|
6c5ef9347c | ||
|
|
60da9094ef | ||
|
|
f9087cb291 | ||
|
|
635f13f825 | ||
|
|
55830256d3 | ||
|
|
ac58bb2f5a | ||
|
|
a066018c9f | ||
|
|
0bc9138aa4 | ||
|
|
b626c888b0 | ||
|
|
492cbc3628 | ||
|
|
32353f0db1 | ||
|
|
7aa43a4217 | ||
|
|
09580515a0 | ||
|
|
65165cd41c | ||
|
|
391668114d | ||
|
|
ae80a7b322 | ||
|
|
9093263d8c | ||
|
|
e008ae3ef1 | ||
|
|
c0164f29cd | ||
|
|
9ddb57297f | ||
|
|
eb4688bf5e | ||
|
|
519da32391 | ||
|
|
f9728e8f3f | ||
|
|
25bfc1407b | ||
|
|
303bd03533 | ||
|
|
6b54b52ec4 | ||
|
|
89becaca02 | ||
|
|
d9ca67e162 | ||
|
|
ff655de27e | ||
|
|
ee0cb12810 | ||
|
|
6da6e9da07 | ||
|
|
ad41dfaeaf | ||
|
|
7a0a7bf8e0 | ||
|
|
65551ce233 | ||
|
|
c63efa917d | ||
|
|
7544055fa4 | ||
|
|
cb5b5cde1f | ||
|
|
a58a7fd365 | ||
|
|
99c6662f9d | ||
|
|
ca0e32cfd2 | ||
|
|
c84d99aa22 | ||
|
|
0443ef5a9e | ||
|
|
e962c2a94d | ||
|
|
8c2e171a16 | ||
|
|
4fb8eb96d0 | ||
|
|
7549eb90a7 | ||
|
|
df132a0296 | ||
|
|
e499a6d375 | ||
|
|
fe5f5e690e | ||
|
|
21cd975ae3 | ||
|
|
32073a5bc1 | ||
|
|
6cf8408752 | ||
|
|
7a77b61ddd | ||
|
|
ad09526bee | ||
|
|
e3e3ea54f9 | ||
|
|
cb9c26d49c | ||
|
|
cf88896ad7 | ||
|
|
0d44234239 | ||
|
|
96c045137d | ||
|
|
0e3037e85d | ||
|
|
5c334d7627 | ||
|
|
7246914605 | ||
|
|
d9b72a2282 | ||
|
|
4eb05ed571 | ||
|
|
5a8def7d00 | ||
|
|
90be31ddc8 | ||
|
|
dddb9b3189 | ||
|
|
0c06d3b47a | ||
|
|
cc96840aa8 | ||
|
|
f78eba09fd | ||
|
|
b2c1eae652 | ||
|
|
8fed427251 | ||
|
|
b2d309b17e | ||
|
|
8d6f893083 | ||
|
|
faba7e2a07 | ||
|
|
baf1e771e9 | ||
|
|
461a30812b | ||
|
|
4b64c15ae8 | ||
|
|
3625a409a5 | ||
|
|
8533f974e8 | ||
|
|
667db45b1d | ||
|
|
bafbac3d51 | ||
|
|
92c095412d | ||
|
|
ea31a51285 | ||
|
|
8f66346aeb | ||
|
|
9741d6348f | ||
|
|
8c762223a4 | ||
|
|
ffd2fbcc84 | ||
|
|
b0f4497bbe | ||
|
|
97f6138cf8 | ||
|
|
f65f042910 | ||
|
|
7ad79b42bc | ||
|
|
4f172ae9a5 | ||
|
|
5fadba7ddc | ||
|
|
ffd4d4afc3 | ||
|
|
d304f40295 | ||
|
|
ffd4b38801 | ||
|
|
efb27ed1ea | ||
|
|
aab3385c2d | ||
|
|
9e732ee935 | ||
|
|
571e441502 | ||
|
|
18c8ac0b31 | ||
|
|
7d700916d9 | ||
|
|
b0f5f88482 | ||
|
|
c6030b9125 | ||
|
|
81e4ae2af9 | ||
|
|
543535e1a0 | ||
|
|
647f6fdf34 | ||
|
|
90e0eaf5f5 | ||
|
|
4ea7e8d828 | ||
|
|
cf4f1377d4 | ||
|
|
bf8f5aa306 | ||
|
|
9564575d77 | ||
|
|
9776e0937a | ||
|
|
7b9971b20f | ||
|
|
89d9fb3556 | ||
|
|
c3f62ed8bf | ||
|
|
5c5cf3e7e7 | ||
|
|
94045ea73e | ||
|
|
e15c596e42 | ||
|
|
b317d10ade | ||
|
|
31bd8d438d | ||
|
|
8b78f21199 | ||
|
|
8a8f5af084 | ||
|
|
f5a8974bb6 | ||
|
|
fd5b7359e2 | ||
|
|
077e05e0ed | ||
|
|
abdcd23d8b | ||
|
|
fb04d10886 | ||
|
|
3e8711580e | ||
|
|
f48dafda7e | ||
|
|
a42369e081 | ||
|
|
6397939c9e | ||
|
|
c9af365d44 | ||
|
|
b6d543f15e | ||
|
|
8c3ebc7f87 | ||
|
|
ee70b21460 | ||
|
|
acb6777ab5 | ||
|
|
f7ab5684e9 | ||
|
|
8a8af5265e | ||
|
|
f72d672e0d | ||
|
|
094c2bca2e | ||
|
|
5d5d4cb448 | ||
|
|
380c4ad2da | ||
|
|
e57f1c230c | ||
|
|
88e0ecf2cf | ||
|
|
56ab2fd797 | ||
|
|
81cce7b6ac | ||
|
|
745fa93f3f | ||
|
|
c5af747da9 | ||
|
|
c40499ab05 | ||
|
|
2e1aa99f54 | ||
|
|
70a6a316d7 | ||
|
|
e418dddbcf | ||
|
|
bf127348c9 | ||
|
|
75907e3815 | ||
|
|
c4ad7c3e2c | ||
|
|
562e8e8021 | ||
|
|
c3fbd27a8d | ||
|
|
a990c0bdc8 | ||
|
|
561b0fbe55 | ||
|
|
475918a1ca | ||
|
|
a85d82a859 | ||
|
|
ae97ad2bca | ||
|
|
8eddb7f1b9 | ||
|
|
29fabb12e0 | ||
|
|
34bcca2640 | ||
|
|
38bd039a93 | ||
|
|
033eedb50f | ||
|
|
51ca5e028b | ||
|
|
9b5208fa30 | ||
|
|
85fd1d010d | ||
|
|
499610e44f | ||
|
|
13294083a9 | ||
|
|
5f203ce808 | ||
|
|
dfc26937ca | ||
|
|
22be4b49d5 | ||
|
|
bc932a28ae | ||
|
|
e9f1c83ff8 | ||
|
|
30be6d4bab | ||
|
|
1169ba9efb | ||
|
|
33ec5cdc44 | ||
|
|
be14c33ed1 | ||
|
|
b12872eed1 | ||
|
|
35caa32ad1 | ||
|
|
98aab2083b | ||
|
|
2b588ebce6 | ||
|
|
d4ba95f606 | ||
|
|
83504eb2e1 | ||
|
|
7f5ec0eaef | ||
|
|
68ba3a84d6 | ||
|
|
125b134d87 | ||
|
|
f9236c4c98 | ||
|
|
02e857827d | ||
|
|
7e5560e60d | ||
|
|
f35783f0fb | ||
|
|
e74ef3e86e | ||
|
|
ae59f1abb4 | ||
|
|
c0b09854b3 | ||
|
|
2b61ea417b | ||
|
|
e57886e05a | ||
|
|
b0520f3656 | ||
|
|
3e9349bf7b | ||
|
|
d5549d770d | ||
|
|
4034cfe9dc | ||
|
|
7864f2c8ea | ||
|
|
c157875ecd | ||
|
|
dac329bcf1 | ||
|
|
d072d91081 | ||
|
|
e156ec2940 | ||
|
|
14295fd4b3 | ||
|
|
895580de42 | ||
|
|
2c9e11299e | ||
|
|
ca011729d3 | ||
|
|
0f25e6ec6b | ||
|
|
af2b5eb6f6 | ||
|
|
b207111c50 | ||
|
|
05b2a19bac | ||
|
|
0c308a5f07 | ||
|
|
ab62ca7b1f | ||
|
|
50992f2112 | ||
|
|
6cd56ebed6 | ||
|
|
f3caada13a | ||
|
|
27d922d470 |
No files matched your search
@@ -5,3 +5,5 @@
|
||||
/patches-old/
|
||||
/mcp/
|
||||
/eclipse/
|
||||
/target/
|
||||
/temp/
|
||||
@@ -1,6 +0,0 @@
|
||||
Manifest-Version: 1.0
|
||||
Ant-Version: Apache Ant 1.8.2
|
||||
Created-By: 1.7.0_09-b30 (Oracle Corporation)
|
||||
Main-Class: net.minecraft.server.MinecraftServer
|
||||
Class-Path: minecraft_server.jar
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
import os
|
||||
import sys
|
||||
import fnmatch
|
||||
import shlex
|
||||
import difflib
|
||||
import time, subprocess
|
||||
from optparse import OptionParser
|
||||
|
||||
def cmdsplit(args):
|
||||
if os.sep == '\\':
|
||||
args = args.replace('\\', '\\\\')
|
||||
return shlex.split(args)
|
||||
|
||||
def main():
|
||||
print("Applying patches")
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option('-m', '--mcp-dir', action='store', dest='mcp_dir', help='Path to MCP', default=None)
|
||||
parser.add_option('-p', '--patch-dir', action='store', dest='patch_dir', help='Patches Directory', default=None)
|
||||
parser.add_option('-t', '--target-dir', action='store', dest='target_dir', help='Target Directory', default=None)
|
||||
options, _ = parser.parse_args()
|
||||
|
||||
if options.mcp_dir is None:
|
||||
print 'Must supply MCP directory with --mcp-dir'
|
||||
return
|
||||
elif options.patch_dir is None:
|
||||
print 'Must supply patches directory with --patch-dir'
|
||||
return
|
||||
elif options.target_dir is None:
|
||||
print 'Must supplt target directory with --target-dir'
|
||||
return
|
||||
|
||||
print "Applying patches from '%s' to '%s'" % (options.patch_dir, options.target_dir)
|
||||
apply_patches(options.mcp_dir, options.patch_dir, options.target_dir)
|
||||
|
||||
def apply_patches(mcp_dir, patch_dir, target_dir, find=None, rep=None):
|
||||
# Attempts to apply a directory full of patch files onto a target directory.
|
||||
sys.path.append(mcp_dir)
|
||||
|
||||
temp = os.path.abspath('temp.patch')
|
||||
cmd = cmdsplit('patch -p2 -i "%s" ' % temp)
|
||||
|
||||
if os.name == 'nt':
|
||||
applydiff = os.path.abspath(os.path.join(mcp_dir, 'runtime', 'bin', 'applydiff.exe'))
|
||||
cmd = cmdsplit('"%s" -uf -p2 -i "%s"' % (applydiff, temp))
|
||||
|
||||
for path, _, filelist in os.walk(patch_dir, followlinks=True):
|
||||
for cur_file in fnmatch.filter(filelist, '*.patch'):
|
||||
patch_file = os.path.normpath(os.path.join(patch_dir, path[len(patch_dir)+1:], cur_file))
|
||||
target_file = os.path.join(target_dir, fix_patch(patch_file, temp, find, rep))
|
||||
process = subprocess.Popen(cmd, cwd=target_dir, bufsize=-1)
|
||||
process.communicate()
|
||||
|
||||
if os.path.isfile(temp):
|
||||
os.remove(temp)
|
||||
|
||||
def fix_patch(in_file, out_file, find=None, rep=None):
|
||||
#Fixes the following issues in the patch file if they exist:
|
||||
# Normalizes the path seperators for the current OS
|
||||
# Normalizes the line endings
|
||||
# Returns the path that the file wants to apply to
|
||||
|
||||
in_file = os.path.normpath(in_file)
|
||||
if out_file is None:
|
||||
tmp_file = in_file + '.tmp'
|
||||
else:
|
||||
out_file = os.path.normpath(out_file)
|
||||
tmp_file = out_file
|
||||
dir_name = os.path.dirname(out_file)
|
||||
if dir_name:
|
||||
if not os.path.exists(dir_name):
|
||||
os.makedirs(dir_name)
|
||||
|
||||
file = 'not found'
|
||||
with open(in_file, 'rb') as inpatch:
|
||||
with open(tmp_file, 'wb') as outpatch:
|
||||
for line in inpatch:
|
||||
line = line.rstrip('\r\n')
|
||||
if line[:3] in ['+++', '---', 'Onl', 'dif']:
|
||||
if not find == None and not rep == None:
|
||||
line = line.replace('\\', '/').replace(find, rep).replace('/', os.sep)
|
||||
else:
|
||||
line = line.replace('\\', '/').replace('/', os.sep)
|
||||
outpatch.write(line + os.linesep)
|
||||
else:
|
||||
outpatch.write(line + os.linesep)
|
||||
if line[:3] == '---':
|
||||
file = line[line.find(os.sep, line.find(os.sep)+1)+1:]
|
||||
|
||||
if out_file is None:
|
||||
shutil.move(tmp_file, in_file)
|
||||
return file
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+27
-3
@@ -24,12 +24,16 @@ class PreemptiveBasicAuthHandler(urllib2.BaseHandler):
|
||||
def https_request(self,req):
|
||||
return self.http_request(req)
|
||||
|
||||
def getBuildInfo(url, current_version=None):
|
||||
def read_url(url):
|
||||
handler = PreemptiveBasicAuthHandler()
|
||||
handler.add_password(None, 'jenkins.minecraftforge.net:81', 'console_script', 'fd584bffa72fcac12181f37f80001200')
|
||||
handler.add_password(None, 'ci.jenkins.minecraftforge.net', 'console_script', 'dc6d48ca20a474beeac280a9a16a926e')
|
||||
file = urllib2.build_opener(handler).open(url)
|
||||
data = file.read()
|
||||
file.close()
|
||||
return data
|
||||
|
||||
def getBuildInfo(url, current_version=None):
|
||||
data = read_url(url)
|
||||
data = ast.literal_eval(data)['allBuilds']
|
||||
data = sorted(data, key=lambda key: key['number'], reverse=False)
|
||||
|
||||
@@ -57,9 +61,29 @@ def getBuildInfo(url, current_version=None):
|
||||
build.pop('changeSet')
|
||||
build.pop('actions')
|
||||
return sorted(output, key=lambda key: key['number'], reverse=True)
|
||||
|
||||
def add_latest_build(url, builds, current_version=None):
|
||||
data = read_url(url)
|
||||
data = ast.literal_eval(data)
|
||||
number = data['number']
|
||||
|
||||
if builds[0]['number'] == data['number']:
|
||||
return builds
|
||||
|
||||
for item in data['changeSet']['items']:
|
||||
item['author'] = item['author']['fullName']
|
||||
|
||||
build = {
|
||||
'number' : data['number'],
|
||||
'result' : 'SUCCESS', #Currently build should always be success... Else things derp after words
|
||||
'version' : current_version,
|
||||
'items' : data['changeSet']['items']
|
||||
}
|
||||
return [build] + builds
|
||||
|
||||
def make_changelog(job_path, target_build, change_file, current_version=None):
|
||||
builds = getBuildInfo('%s/api/python?tree=allBuilds[result,number,actions[text],changeSet[items[author[fullName],comment]]]&pretty=true' % job_path, current_version)
|
||||
builds = add_latest_build('%s/lastBuild/api/python?pretty=true&tree=number,changeSet[items[author[fullName],comment]]' % job_path, builds, current_version)
|
||||
|
||||
log = [ "Changelog:" ]
|
||||
|
||||
@@ -86,4 +110,4 @@ def make_changelog(job_path, target_build, change_file, current_version=None):
|
||||
file.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
make_changelog("http://jenkins.minecraftforge.net:81/job/minecraftforge/", 70000, 'changelog.txt', 'pinecone')
|
||||
make_changelog("http://ci.jenkins.minecraftforge.net/job/minecraftforge/", 70000, 'changelog.txt', 'pinecone')
|
||||
@@ -0,0 +1,141 @@
|
||||
package net.minecraftforge.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiChat;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.CommandHandler;
|
||||
import net.minecraft.command.ICommand;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.command.WrongUsageException;
|
||||
import net.minecraft.util.ChatMessageComponent;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.CommandEvent;
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import static net.minecraft.util.EnumChatFormatting.*;
|
||||
|
||||
/**
|
||||
* The class that handles client-side chat commands. You should register any
|
||||
* commands that you want handled on the client with this command handler.
|
||||
*
|
||||
* If there is a command with the same name registered both on the server and
|
||||
* client, the client takes precedence!
|
||||
*
|
||||
*/
|
||||
public class ClientCommandHandler extends CommandHandler
|
||||
{
|
||||
public static final ClientCommandHandler instance = new ClientCommandHandler();
|
||||
|
||||
public String[] latestAutoComplete = null;
|
||||
|
||||
/**
|
||||
* @return 1 if successfully executed, 0 if wrong usage, it doesn't exist or
|
||||
* it was canceled.
|
||||
*/
|
||||
@Override
|
||||
public int executeCommand(ICommandSender sender, String message)
|
||||
{
|
||||
message = message.trim();
|
||||
|
||||
if (message.startsWith("/"))
|
||||
{
|
||||
message = message.substring(1);
|
||||
}
|
||||
|
||||
String[] temp = message.split(" ");
|
||||
String[] args = new String[temp.length - 1];
|
||||
String commandName = temp[0];
|
||||
System.arraycopy(temp, 1, args, 0, args.length);
|
||||
ICommand icommand = (ICommand) getCommands().get(commandName);
|
||||
|
||||
try
|
||||
{
|
||||
if (icommand == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (icommand.canCommandSenderUseCommand(sender))
|
||||
{
|
||||
CommandEvent event = new CommandEvent(icommand, sender, args);
|
||||
if (MinecraftForge.EVENT_BUS.post(event))
|
||||
{
|
||||
if (event.exception != null)
|
||||
{
|
||||
throw event.exception;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
icommand.processCommand(sender, args);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.sendChatToPlayer(format("commands.generic.permission").setColor(RED));
|
||||
}
|
||||
}
|
||||
catch (WrongUsageException wue)
|
||||
{
|
||||
sender.sendChatToPlayer(format("commands.generic.usage", format(wue.getMessage(), wue.getErrorOjbects())).setColor(RED));
|
||||
}
|
||||
catch (CommandException ce)
|
||||
{
|
||||
sender.sendChatToPlayer(format(ce.getMessage(), ce.getErrorOjbects()).setColor(RED));
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
sender.sendChatToPlayer(format("commands.generic.exception").setColor(RED));
|
||||
t.printStackTrace();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Couple of helpers because the mcp names are stupid and long...
|
||||
private ChatMessageComponent format(String str, Object... args)
|
||||
{
|
||||
return ChatMessageComponent.createFromTranslationWithSubstitutions(str, args);
|
||||
}
|
||||
|
||||
private ChatMessageComponent format(String str)
|
||||
{
|
||||
return ChatMessageComponent.createFromTranslationKey(str);
|
||||
}
|
||||
|
||||
public void autoComplete(String leftOfCursor, String full)
|
||||
{
|
||||
latestAutoComplete = null;
|
||||
|
||||
if (leftOfCursor.charAt(0) == '/')
|
||||
{
|
||||
leftOfCursor = leftOfCursor.substring(1);
|
||||
|
||||
Minecraft mc = FMLClientHandler.instance().getClient();
|
||||
if (mc.currentScreen instanceof GuiChat)
|
||||
{
|
||||
List<String> commands = getPossibleCommands(mc.thePlayer, leftOfCursor);
|
||||
if (commands != null && !commands.isEmpty())
|
||||
{
|
||||
if (leftOfCursor.indexOf(' ') == -1)
|
||||
{
|
||||
for (int i = 0; i < commands.size(); i++)
|
||||
{
|
||||
commands.set(i, GRAY + "/" + commands.get(i) + RESET);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < commands.size(); i++)
|
||||
{
|
||||
commands.set(i, GRAY + commands.get(i) + RESET);
|
||||
}
|
||||
}
|
||||
|
||||
latestAutoComplete = commands.toArray(new String[commands.size()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,9 @@ import java.util.TreeSet;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import net.minecraftforge.client.event.MouseEvent;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraftforge.client.event.FOVUpdateEvent;
|
||||
import org.lwjgl.LWJGLException;
|
||||
import org.lwjgl.opengl.Display;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
@@ -13,19 +16,22 @@ import org.lwjgl.opengl.GL12;
|
||||
import org.lwjgl.opengl.PixelFormat;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockFluid;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.BiomeGenBase;
|
||||
import net.minecraft.client.model.ModelBiped;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.client.renderer.RenderGlobal;
|
||||
@@ -37,20 +43,31 @@ import net.minecraftforge.client.IItemRenderer.ItemRenderType;
|
||||
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
|
||||
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.common.ForgeDummyContainer;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fluids.FluidRegistry;
|
||||
import net.minecraftforge.fluids.RenderBlockFluid;
|
||||
import static net.minecraftforge.client.IItemRenderer.ItemRenderType.*;
|
||||
import static net.minecraftforge.client.IItemRenderer.ItemRendererHelper.*;
|
||||
|
||||
public class ForgeHooksClient
|
||||
{
|
||||
private static final ResourceLocation ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png");
|
||||
|
||||
static TextureManager engine()
|
||||
{
|
||||
return FMLClientHandler.instance().getClient().renderEngine;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String getArmorTexture(Entity entity, ItemStack armor, String _default, int slot, int layer, String type)
|
||||
{
|
||||
String result = armor.getItem().getArmorTexture(armor, entity, slot, layer);
|
||||
return getArmorTexture(entity, armor, _default, slot, type);
|
||||
}
|
||||
|
||||
public static String getArmorTexture(Entity entity, ItemStack armor, String _default, int slot, String type)
|
||||
{
|
||||
String result = armor.getItem().getArmorTexture(armor, entity, slot, type);
|
||||
return result != null ? result : _default;
|
||||
}
|
||||
|
||||
@@ -72,7 +89,7 @@ public class ForgeHooksClient
|
||||
}
|
||||
boolean is3D = customRenderer.shouldUseRenderHelper(ENTITY, item, BLOCK_3D);
|
||||
|
||||
engine.func_110577_a(item.getItemSpriteNumber() == 0 ? TextureMap.field_110575_b : TextureMap.field_110576_c);
|
||||
engine.bindTexture(item.getItemSpriteNumber() == 0 ? TextureMap.locationBlocksTexture : TextureMap.locationItemsTexture);
|
||||
Block block = (item.itemID < Block.blocksList.length ? Block.blocksList[item.itemID] : null);
|
||||
if (is3D || (block != null && RenderBlocks.renderItemIn3d(block.getRenderType())))
|
||||
{
|
||||
@@ -87,7 +104,7 @@ public class ForgeHooksClient
|
||||
}
|
||||
|
||||
GL11.glScalef(scale, scale, scale);
|
||||
|
||||
|
||||
int size = item.stackSize;
|
||||
int count = (size > 40 ? 5 : (size > 20 ? 4 : (size > 5 ? 3 : (size > 1 ? 2 : 1))));
|
||||
|
||||
@@ -121,7 +138,7 @@ public class ForgeHooksClient
|
||||
return false;
|
||||
}
|
||||
|
||||
engine.func_110577_a(item.getItemSpriteNumber() == 0 ? TextureMap.field_110575_b : TextureMap.field_110576_c);
|
||||
engine.bindTexture(item.getItemSpriteNumber() == 0 ? TextureMap.locationBlocksTexture : TextureMap.locationItemsTexture);
|
||||
if (customRenderer.shouldUseRenderHelper(INVENTORY, item, INVENTORY_BLOCK))
|
||||
{
|
||||
GL11.glPushMatrix();
|
||||
@@ -166,9 +183,14 @@ public class ForgeHooksClient
|
||||
GL11.glPopMatrix();
|
||||
GL11.glEnable(GL11.GL_LIGHTING);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void renderEffectOverlay(TextureManager manager, RenderItem render)
|
||||
{
|
||||
}
|
||||
|
||||
public static void renderEquippedItem(ItemRenderType type, IItemRenderer customRenderer, RenderBlocks renderBlocks, EntityLivingBase entity, ItemStack item)
|
||||
{
|
||||
if (customRenderer.shouldUseRenderHelper(type, item, EQUIPPED_BLOCK))
|
||||
@@ -228,6 +250,9 @@ public class ForgeHooksClient
|
||||
public static void onTextureStitchedPost(TextureMap map)
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.post(new TextureStitchEvent.Post(map));
|
||||
|
||||
FluidRegistry.WATER.setIcons(BlockFluid.getFluidIcon("water_still"), BlockFluid.getFluidIcon("water_flow"));
|
||||
FluidRegistry.LAVA.setIcons(BlockFluid.getFluidIcon("lava_still"), BlockFluid.getFluidIcon("lava_flow"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -283,4 +308,86 @@ public class ForgeHooksClient
|
||||
stencilBits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//This properly moves the domain, if provided, to the front of the string before concatenating
|
||||
public static String fixDomain(String base, String complex)
|
||||
{
|
||||
int idx = complex.indexOf(':');
|
||||
if (idx == -1)
|
||||
{
|
||||
return base + complex;
|
||||
}
|
||||
|
||||
String name = complex.substring(idx + 1, complex.length());
|
||||
if (idx > 1)
|
||||
{
|
||||
String domain = complex.substring(0, idx);
|
||||
return domain + ':' + base + name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return base + name;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean postMouseEvent()
|
||||
{
|
||||
return MinecraftForge.EVENT_BUS.post(new MouseEvent());
|
||||
}
|
||||
|
||||
public static float getOffsetFOV(EntityPlayerSP entity, float fov)
|
||||
{
|
||||
FOVUpdateEvent fovUpdateEvent = new FOVUpdateEvent(entity, fov);
|
||||
MinecraftForge.EVENT_BUS.post(fovUpdateEvent);
|
||||
return fovUpdateEvent.newfov;
|
||||
}
|
||||
|
||||
private static int skyX, skyZ;
|
||||
|
||||
private static boolean skyInit;
|
||||
private static int skyRGBMultiplier;
|
||||
|
||||
public static int getSkyBlendColour(World world, int playerX, int playerZ)
|
||||
{
|
||||
if (playerX == skyX && playerZ == skyZ && skyInit)
|
||||
{
|
||||
return skyRGBMultiplier;
|
||||
}
|
||||
skyInit = true;
|
||||
|
||||
int distance = Minecraft.getMinecraft().gameSettings.fancyGraphics ? ForgeDummyContainer.blendRanges[Minecraft.getMinecraft().gameSettings.renderDistance] : 0;
|
||||
|
||||
int r = 0;
|
||||
int g = 0;
|
||||
int b = 0;
|
||||
|
||||
int divider = 0;
|
||||
for (int x = -distance; x <= distance; ++x)
|
||||
{
|
||||
for (int z = -distance; z <= distance; ++z)
|
||||
{
|
||||
BiomeGenBase biome = world.getBiomeGenForCoords(playerX + x, playerZ + z);
|
||||
int colour = biome.getSkyColorByTemp(biome.getFloatTemperature());
|
||||
r += (colour & 0xFF0000) >> 16;
|
||||
g += (colour & 0x00FF00) >> 8;
|
||||
b += colour & 0x0000FF;
|
||||
divider++;
|
||||
}
|
||||
}
|
||||
|
||||
int multiplier = (r / divider & 255) << 16 | (g / divider & 255) << 8 | b / divider & 255;
|
||||
|
||||
skyX = playerX;
|
||||
skyZ = playerZ;
|
||||
skyRGBMultiplier = multiplier;
|
||||
return skyRGBMultiplier;
|
||||
}
|
||||
/**
|
||||
* Initialization of Forge Renderers.
|
||||
*/
|
||||
static
|
||||
{
|
||||
FluidRegistry.renderIdFluid = RenderingRegistry.getNextAvailableRenderId();
|
||||
RenderingRegistry.registerBlockHandler(RenderBlockFluid.instance);
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,11 @@ import net.minecraft.client.settings.KeyBinding;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class GuiControlsScrollPanel extends GuiSlot
|
||||
{
|
||||
protected static final ResourceLocation WIDGITS = new ResourceLocation("textures/gui/widgets.png");
|
||||
private GuiControls controls;
|
||||
private GameSettings options;
|
||||
private Minecraft mc;
|
||||
@@ -61,7 +63,7 @@ public class GuiControlsScrollPanel extends GuiSlot
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void func_130003_c() {}
|
||||
protected void drawBackground() {}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int mX, int mY, float f)
|
||||
@@ -73,7 +75,6 @@ public class GuiControlsScrollPanel extends GuiSlot
|
||||
{
|
||||
if (Mouse.next() && Mouse.getEventButtonState())
|
||||
{
|
||||
System.out.println(Mouse.getEventButton());
|
||||
options.setKeyBinding(selected, -100 + Mouse.getEventButton());
|
||||
selected = -1;
|
||||
KeyBinding.resetKeyBindingArrayAndHash();
|
||||
@@ -92,7 +93,7 @@ public class GuiControlsScrollPanel extends GuiSlot
|
||||
boolean flag = _mouseX >= xPosition && _mouseY >= yPosition && _mouseX < xPosition + width && _mouseY < yPosition + height;
|
||||
int k = (flag ? 2 : 1);
|
||||
|
||||
mc.renderEngine.func_110577_a(TextureMap.field_110576_c);
|
||||
mc.renderEngine.bindTexture(WIDGITS);
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
controls.drawTexturedModalRect(xPosition, yPosition, 0, 46 + k * 20, width / 2, height);
|
||||
controls.drawTexturedModalRect(xPosition + width / 2, yPosition, 200 - width / 2, 46 + k * 20, width / 2, height);
|
||||
|
||||
@@ -17,7 +17,6 @@ import net.minecraft.client.gui.ScaledResolution;
|
||||
import net.minecraft.client.multiplayer.NetClientHandler;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.client.resources.ResourceLocation;
|
||||
import net.minecraft.crash.CallableMinecraftVersion;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
@@ -33,6 +32,7 @@ import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.util.FoodStats;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import net.minecraft.util.StringUtils;
|
||||
import net.minecraft.world.EnumSkyBlock;
|
||||
@@ -52,7 +52,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
private static final ResourceLocation VIGNETTE = new ResourceLocation("textures/misc/vignette.png");
|
||||
private static final ResourceLocation WIDGITS = new ResourceLocation("textures/gui/widgets.png");
|
||||
private static final ResourceLocation PUMPKIN_BLUR = new ResourceLocation("textures/misc/pumpkinblur.png");
|
||||
|
||||
|
||||
private static final int WHITE = 0xFFFFFF;
|
||||
|
||||
//Flags to toggle the rendering of certain aspects of the HUD, valid conditions
|
||||
@@ -71,7 +71,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
public static boolean renderExperiance = true;
|
||||
public static boolean renderJumpBar = true;
|
||||
public static boolean renderObjective = true;
|
||||
|
||||
|
||||
public static int left_height = 39;
|
||||
public static int right_height = 39;
|
||||
|
||||
@@ -94,8 +94,8 @@ public class GuiIngameForge extends GuiIngame
|
||||
int height = res.getScaledHeight();
|
||||
renderHealthMount = mc.thePlayer.ridingEntity instanceof EntityLivingBase;
|
||||
renderFood = mc.thePlayer.ridingEntity == null;
|
||||
renderJumpBar = mc.thePlayer.func_110317_t();
|
||||
|
||||
renderJumpBar = mc.thePlayer.isRidingHorse();
|
||||
|
||||
right_height = 39;
|
||||
left_height = 39;
|
||||
|
||||
@@ -129,7 +129,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
|
||||
if (renderCrosshairs) renderCrosshairs(width, height);
|
||||
if (renderBossHealth) renderBossHealth();
|
||||
|
||||
|
||||
if (this.mc.playerController.shouldDrawHUD())
|
||||
{
|
||||
if (renderHealth) renderHealth(width, height);
|
||||
@@ -145,7 +145,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
{
|
||||
renderJumpBar(width, height);
|
||||
}
|
||||
else if (renderExperiance)
|
||||
else if (renderExperiance)
|
||||
{
|
||||
renderExperience(width, height);
|
||||
}
|
||||
@@ -189,7 +189,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
mc.renderEngine.func_110577_a(WIDGITS);
|
||||
mc.renderEngine.bindTexture(WIDGITS);
|
||||
|
||||
InventoryPlayer inv = mc.thePlayer.inventory;
|
||||
drawTexturedModalRect(width / 2 - 91, height - 22, 0, 0, 182, 22);
|
||||
@@ -215,7 +215,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
protected void renderCrosshairs(int width, int height)
|
||||
{
|
||||
if (pre(CROSSHAIRS)) return;
|
||||
bind(Gui.field_110324_m);
|
||||
bind(Gui.icons);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glBlendFunc(GL11.GL_ONE_MINUS_DST_COLOR, GL11.GL_ONE_MINUS_SRC_COLOR);
|
||||
drawTexturedModalRect(width / 2 - 7, height / 2 - 7, 0, 0, 16, 16);
|
||||
@@ -325,7 +325,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
|
||||
public void renderHealth(int width, int height)
|
||||
{
|
||||
bind(field_110324_m);
|
||||
bind(icons);
|
||||
if (pre(HEALTH)) return;
|
||||
mc.mcProfiler.startSection("health");
|
||||
|
||||
@@ -336,17 +336,17 @@ public class GuiIngameForge extends GuiIngame
|
||||
highlight = false;
|
||||
}
|
||||
|
||||
AttributeInstance attrMaxHealth = this.mc.thePlayer.func_110148_a(SharedMonsterAttributes.field_111267_a);
|
||||
int health = MathHelper.ceiling_float_int(mc.thePlayer.func_110143_aJ());
|
||||
AttributeInstance attrMaxHealth = this.mc.thePlayer.getEntityAttribute(SharedMonsterAttributes.maxHealth);
|
||||
int health = MathHelper.ceiling_float_int(mc.thePlayer.getHealth());
|
||||
int healthLast = MathHelper.ceiling_float_int(mc.thePlayer.prevHealth);
|
||||
float healthMax = (float)attrMaxHealth.func_111126_e();
|
||||
float absorb = this.mc.thePlayer.func_110139_bj();
|
||||
float healthMax = (float)attrMaxHealth.getAttributeValue();
|
||||
float absorb = this.mc.thePlayer.getAbsorptionAmount();
|
||||
|
||||
int healthRows = MathHelper.ceiling_float_int((healthMax + absorb) / 2.0F / 10.0F);
|
||||
int rowHeight = Math.max(10 - (healthRows - 2), 3);
|
||||
|
||||
|
||||
this.rand.setSeed((long)(updateCounter * 312871));
|
||||
|
||||
|
||||
int left = width / 2 - 91;
|
||||
int top = height - left_height;
|
||||
left_height += (healthRows * rowHeight);
|
||||
@@ -357,14 +357,14 @@ public class GuiIngameForge extends GuiIngame
|
||||
{
|
||||
regen = updateCounter % 25;
|
||||
}
|
||||
|
||||
|
||||
final int TOP = 9 * (mc.theWorld.getWorldInfo().isHardcoreModeEnabled() ? 5 : 0);
|
||||
final int BACKGROUND = (highlight ? 25 : 16);
|
||||
int MARGIN = 16;
|
||||
if (mc.thePlayer.isPotionActive(Potion.poison)) MARGIN += 36;
|
||||
else if (mc.thePlayer.isPotionActive(Potion.wither)) MARGIN += 72;
|
||||
float absorbRemaining = absorb;
|
||||
|
||||
|
||||
for (int i = MathHelper.ceiling_float_int((healthMax + absorb) / 2.0F) - 1; i >= 0; --i)
|
||||
{
|
||||
int b0 = (highlight ? 1 : 0);
|
||||
@@ -373,7 +373,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
int y = top - row * rowHeight;
|
||||
|
||||
if (health <= 4) y += rand.nextInt(2);
|
||||
if (i == regen) y -= 2;
|
||||
if (i == regen) y -= 2;
|
||||
|
||||
drawTexturedModalRect(x, y, BACKGROUND, TOP, 9, 9);
|
||||
|
||||
@@ -401,7 +401,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
drawTexturedModalRect(x, y, MARGIN + 45, TOP, 9, 9); //5
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mc.mcProfiler.endSection();
|
||||
post(HEALTH);
|
||||
}
|
||||
@@ -484,23 +484,23 @@ public class GuiIngameForge extends GuiIngame
|
||||
|
||||
protected void renderExperience(int width, int height)
|
||||
{
|
||||
bind(field_110324_m);
|
||||
bind(icons);
|
||||
if (pre(EXPERIENCE)) return;
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
|
||||
if (mc.playerController.func_78763_f())
|
||||
{
|
||||
mc.mcProfiler.startSection("expBar");
|
||||
int cap = this.mc.thePlayer.xpBarCap();
|
||||
int left = width / 2 - 91;
|
||||
|
||||
|
||||
if (cap > 0)
|
||||
{
|
||||
short barWidth = 182;
|
||||
int filled = (int)(mc.thePlayer.experience * (float)(barWidth + 1));
|
||||
int top = height - 32 + 3;
|
||||
drawTexturedModalRect(left, top, 0, 64, barWidth, 5);
|
||||
|
||||
|
||||
if (filled > 0)
|
||||
{
|
||||
drawTexturedModalRect(left, top, 0, 69, filled, 5);
|
||||
@@ -508,8 +508,8 @@ public class GuiIngameForge extends GuiIngame
|
||||
}
|
||||
|
||||
this.mc.mcProfiler.endSection();
|
||||
|
||||
|
||||
|
||||
|
||||
if (mc.playerController.func_78763_f() && mc.thePlayer.experienceLevel > 0)
|
||||
{
|
||||
mc.mcProfiler.startSection("expLevel");
|
||||
@@ -533,12 +533,12 @@ public class GuiIngameForge extends GuiIngame
|
||||
|
||||
protected void renderJumpBar(int width, int height)
|
||||
{
|
||||
bind(field_110324_m);
|
||||
bind(icons);
|
||||
if (pre(JUMPBAR)) return;
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
|
||||
mc.mcProfiler.startSection("jumpBar");
|
||||
float charge = mc.thePlayer.func_110319_bJ();
|
||||
float charge = mc.thePlayer.getHorseJumpPower();
|
||||
final int barWidth = 182;
|
||||
int x = (width / 2) - (barWidth / 2);
|
||||
int filled = (int)(charge * (float)(barWidth + 1));
|
||||
@@ -723,12 +723,19 @@ public class GuiIngameForge extends GuiIngame
|
||||
|
||||
protected void renderChat(int width, int height)
|
||||
{
|
||||
GL11.glPushMatrix();
|
||||
GL11.glTranslatef(0.0F, (float)(height - 48), 0.0F);
|
||||
mc.mcProfiler.startSection("chat");
|
||||
|
||||
RenderGameOverlayEvent.Chat event = new RenderGameOverlayEvent.Chat(eventParent, 0, height - 48);
|
||||
if (MinecraftForge.EVENT_BUS.post(event)) return;
|
||||
|
||||
GL11.glPushMatrix();
|
||||
GL11.glTranslatef((float)event.posX, (float)event.posY, 0.0F);
|
||||
persistantChatGUI.drawChat(updateCounter);
|
||||
mc.mcProfiler.endSection();
|
||||
GL11.glPopMatrix();
|
||||
|
||||
post(CHAT);
|
||||
|
||||
mc.mcProfiler.endSection();
|
||||
}
|
||||
|
||||
protected void renderPlayerList(int width, int height)
|
||||
@@ -738,6 +745,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
|
||||
if (mc.gameSettings.keyBindPlayerList.pressed && (!mc.isIntegratedServerRunning() || handler.playerInfoList.size() > 1 || scoreobjective != null))
|
||||
{
|
||||
if (pre(PLAYER_LIST)) return;
|
||||
this.mc.mcProfiler.startSection("playerList");
|
||||
List players = handler.playerInfoList;
|
||||
int maxPlayers = handler.currentServerMaxPlayers;
|
||||
@@ -772,7 +780,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
{
|
||||
GuiPlayerInfo player = (GuiPlayerInfo)players.get(i);
|
||||
ScorePlayerTeam team = mc.theWorld.getScoreboard().getPlayersTeam(player.name);
|
||||
String displayName = ScorePlayerTeam.func_96667_a(team, player.name);
|
||||
String displayName = ScorePlayerTeam.formatPlayerName(team, player.name);
|
||||
fontrenderer.drawStringWithShadow(displayName, xPos, yPos, 16777215);
|
||||
|
||||
if (scoreobjective != null)
|
||||
@@ -783,14 +791,14 @@ public class GuiIngameForge extends GuiIngame
|
||||
if (maxX - endX > 5)
|
||||
{
|
||||
Score score = scoreobjective.getScoreboard().func_96529_a(player.name, scoreobjective);
|
||||
String scoreDisplay = EnumChatFormatting.YELLOW + "" + score.func_96652_c();
|
||||
String scoreDisplay = EnumChatFormatting.YELLOW + "" + score.getScorePoints();
|
||||
fontrenderer.drawStringWithShadow(scoreDisplay, maxX - fontrenderer.getStringWidth(scoreDisplay), yPos, 16777215);
|
||||
}
|
||||
}
|
||||
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
mc.func_110434_K().func_110577_a(Gui.field_110324_m);
|
||||
mc.getTextureManager().bindTexture(Gui.icons);
|
||||
int pingIndex = 4;
|
||||
int ping = player.responseTime;
|
||||
if (ping < 0) pingIndex = 5;
|
||||
@@ -804,6 +812,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
zLevel -= 100.0F;
|
||||
}
|
||||
}
|
||||
post(PLAYER_LIST);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -812,21 +821,21 @@ public class GuiIngameForge extends GuiIngame
|
||||
Entity tmp = mc.thePlayer.ridingEntity;
|
||||
if (!(tmp instanceof EntityLivingBase)) return;
|
||||
|
||||
bind(field_110324_m);
|
||||
|
||||
bind(icons);
|
||||
|
||||
if (pre(HEALTHMOUNT)) return;
|
||||
|
||||
|
||||
boolean unused = false;
|
||||
int left_align = width / 2 + 91;
|
||||
|
||||
|
||||
mc.mcProfiler.endStartSection("mountHealth");
|
||||
EntityLivingBase mount = (EntityLivingBase)tmp;
|
||||
int health = (int)Math.ceil((double)mount.func_110143_aJ());
|
||||
float healthMax = mount.func_110138_aP();
|
||||
int health = (int)Math.ceil((double)mount.getHealth());
|
||||
float healthMax = mount.getMaxHealth();
|
||||
int hearts = (int)(healthMax + 0.5F) / 2;
|
||||
|
||||
if (hearts > 30) hearts = 30;
|
||||
|
||||
|
||||
final int MARGIN = 52;
|
||||
final int BACKGROUND = MARGIN + (unused ? 1 : 0);
|
||||
final int HALF = MARGIN + 45;
|
||||
@@ -835,7 +844,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
for (int heart = 0; hearts > 0; heart += 20)
|
||||
{
|
||||
int top = height - right_height;
|
||||
|
||||
|
||||
int rowCount = Math.min(hearts, 10);
|
||||
hearts -= rowCount;
|
||||
|
||||
@@ -866,6 +875,6 @@ public class GuiIngameForge extends GuiIngame
|
||||
}
|
||||
private void bind(ResourceLocation res)
|
||||
{
|
||||
mc.func_110434_K().func_110577_a(res);
|
||||
mc.getTextureManager().bindTexture(res);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.renderer.EntityRenderer;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
/**
|
||||
* Author: MachineMuse (Claire Semple)
|
||||
* Created: 6:07 PM, 9/5/13
|
||||
*/
|
||||
public class FOVUpdateEvent extends Event
|
||||
{
|
||||
public final EntityPlayerSP entity;
|
||||
public final float fov;
|
||||
public float newfov;
|
||||
|
||||
public FOVUpdateEvent(EntityPlayerSP entity, float fov)
|
||||
{
|
||||
this.entity = entity;
|
||||
this.fov = fov;
|
||||
this.newfov = fov;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraftforge.event.Cancelable;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
/**
|
||||
* This event is called before any Gui will open.
|
||||
* If you don't want this to happen, cancel the event.
|
||||
* If you want to override this Gui, simply set the gui variable to your own Gui.
|
||||
*
|
||||
* @author jk-5
|
||||
*/
|
||||
@Cancelable
|
||||
public class GuiOpenEvent extends Event
|
||||
{
|
||||
public GuiScreen gui;
|
||||
public GuiOpenEvent(GuiScreen gui)
|
||||
{
|
||||
this.gui = gui;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraftforge.event.Cancelable;
|
||||
import net.minecraftforge.event.Event;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
/**
|
||||
* Author: MachineMuse (Claire Semple)
|
||||
* Created: 2:46 PM, 9/4/13
|
||||
*/
|
||||
@Cancelable
|
||||
public class MouseEvent extends Event
|
||||
{
|
||||
public final int x;
|
||||
public final int y;
|
||||
public final int dx;
|
||||
public final int dy;
|
||||
public final int dwheel;
|
||||
public final int button;
|
||||
public final boolean buttonstate;
|
||||
public final long nanoseconds;
|
||||
|
||||
public MouseEvent()
|
||||
{
|
||||
this.x = Mouse.getEventX();
|
||||
this.y = Mouse.getEventY();
|
||||
this.dx = Mouse.getEventDX();
|
||||
this.dy = Mouse.getEventDY();
|
||||
this.dwheel = Mouse.getEventDWheel();
|
||||
this.button = Mouse.getEventButton();
|
||||
this.buttonstate = Mouse.getEventButtonState();
|
||||
this.nanoseconds = Mouse.getEventNanoseconds();
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,9 @@ public class RenderGameOverlayEvent extends Event
|
||||
EXPERIENCE,
|
||||
TEXT,
|
||||
HEALTHMOUNT,
|
||||
JUMPBAR
|
||||
JUMPBAR,
|
||||
CHAT,
|
||||
PLAYER_LIST
|
||||
}
|
||||
|
||||
public final float partialTicks;
|
||||
@@ -79,4 +81,17 @@ public class RenderGameOverlayEvent extends Event
|
||||
this.right = right;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Chat extends Pre
|
||||
{
|
||||
public int posX;
|
||||
public int posY;
|
||||
|
||||
public Chat(RenderGameOverlayEvent parent, int posX, int posY)
|
||||
{
|
||||
super(parent, ElementType.CHAT);
|
||||
this.posX = posX;
|
||||
this.posY = posY;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,16 @@ public abstract class RenderLivingEvent extends Event
|
||||
this.entity = entity;
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
@Cancelable
|
||||
public static class Pre extends RenderLivingEvent
|
||||
{
|
||||
public Pre(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
|
||||
}
|
||||
public static class Post extends RenderLivingEvent
|
||||
{
|
||||
public Post(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
|
||||
}
|
||||
|
||||
public abstract static class Specials extends RenderLivingEvent
|
||||
{
|
||||
|
||||
@@ -9,30 +9,33 @@ import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
public abstract class RenderPlayerEvent extends PlayerEvent
|
||||
{
|
||||
public final RenderPlayer renderer;
|
||||
public final float partialRenderTick;
|
||||
|
||||
public RenderPlayerEvent(EntityPlayer player, RenderPlayer renderer)
|
||||
public RenderPlayerEvent(EntityPlayer player, RenderPlayer renderer, float partialRenderTick)
|
||||
{
|
||||
super(player);
|
||||
this.renderer = renderer;
|
||||
this.partialRenderTick = partialRenderTick;
|
||||
}
|
||||
|
||||
@Cancelable
|
||||
public static class Pre extends RenderPlayerEvent
|
||||
{
|
||||
public Pre(EntityPlayer player, RenderPlayer renderer){ super(player, renderer); }
|
||||
public Pre(EntityPlayer player, RenderPlayer renderer, float tick){ super(player, renderer, tick); }
|
||||
}
|
||||
|
||||
public static class Post extends RenderPlayerEvent
|
||||
{
|
||||
public Post(EntityPlayer player, RenderPlayer renderer){ super(player, renderer); }
|
||||
public Post(EntityPlayer player, RenderPlayer renderer, float tick){ super(player, renderer, tick); }
|
||||
}
|
||||
|
||||
public abstract static class Specials extends RenderPlayerEvent
|
||||
{
|
||||
@Deprecated
|
||||
public final float partialTicks;
|
||||
public Specials(EntityPlayer player, RenderPlayer renderer, float partialTicks)
|
||||
{
|
||||
super(player, renderer);
|
||||
super(player, renderer, partialTicks);
|
||||
this.partialTicks = partialTicks;
|
||||
}
|
||||
|
||||
@@ -59,11 +62,12 @@ public abstract class RenderPlayerEvent extends PlayerEvent
|
||||
*/
|
||||
public int result = -1;
|
||||
public final int slot;
|
||||
@Deprecated
|
||||
public final float partialTick;
|
||||
public final ItemStack stack;
|
||||
public SetArmorModel(EntityPlayer player, RenderPlayer renderer, int slot, float partialTick, ItemStack stack)
|
||||
{
|
||||
super(player, renderer);
|
||||
super(player, renderer, partialTick);
|
||||
this.slot = slot;
|
||||
this.partialTick = partialTick;
|
||||
this.stack = stack;
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraftforge.client.model.obj.ObjModelLoader;
|
||||
import net.minecraftforge.client.model.techne.TechneModelLoader;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
@@ -78,5 +79,6 @@ public class AdvancedModelLoader {
|
||||
static
|
||||
{
|
||||
registerModelHandler(new ObjModelLoader());
|
||||
registerModelHandler(new TechneModelLoader());
|
||||
}
|
||||
}
|
||||
@@ -5,5 +5,7 @@ package net.minecraftforge.client.model;
|
||||
public interface IModelCustom {
|
||||
String getType();
|
||||
void renderAll();
|
||||
void renderOnly(String... groupNames);
|
||||
void renderPart(String partName);
|
||||
void renderAllExcept(String... excludedGroupNames);
|
||||
}
|
||||
@@ -49,20 +49,32 @@ public class WavefrontObject implements IModelCustom
|
||||
public WavefrontObject(String fileName, URL resource) throws ModelFormatException
|
||||
{
|
||||
this.fileName = fileName;
|
||||
loadObjModel(resource);
|
||||
|
||||
try
|
||||
{
|
||||
loadObjModel(resource.openStream());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ModelFormatException("IO Exception reading model format", e);
|
||||
}
|
||||
}
|
||||
|
||||
public WavefrontObject(String filename, InputStream inputStream) throws ModelFormatException
|
||||
{
|
||||
this.fileName = filename;
|
||||
loadObjModel(inputStream);
|
||||
}
|
||||
|
||||
private void loadObjModel(URL fileURL) throws ModelFormatException
|
||||
private void loadObjModel(InputStream inputStream) throws ModelFormatException
|
||||
{
|
||||
BufferedReader reader = null;
|
||||
InputStream inputStream = null;
|
||||
|
||||
String currentLine = null;
|
||||
int lineCount = 0;
|
||||
|
||||
try
|
||||
{
|
||||
inputStream = fileURL.openStream();
|
||||
reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
|
||||
while ((currentLine = reader.readLine()) != null)
|
||||
@@ -157,6 +169,7 @@ public class WavefrontObject implements IModelCustom
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAll()
|
||||
{
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
@@ -169,15 +182,20 @@ public class WavefrontObject implements IModelCustom
|
||||
{
|
||||
tessellator.startDrawing(GL11.GL_TRIANGLES);
|
||||
}
|
||||
|
||||
for (GroupObject groupObject : groupObjects)
|
||||
{
|
||||
groupObject.render(tessellator);
|
||||
}
|
||||
tessellateAll(tessellator);
|
||||
|
||||
tessellator.draw();
|
||||
}
|
||||
|
||||
public void tessellateAll(Tessellator tessellator)
|
||||
{
|
||||
for (GroupObject groupObject : groupObjects)
|
||||
{
|
||||
groupObject.render(tessellator);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderOnly(String... groupNames)
|
||||
{
|
||||
for (GroupObject groupObject : groupObjects)
|
||||
@@ -192,6 +210,20 @@ public class WavefrontObject implements IModelCustom
|
||||
}
|
||||
}
|
||||
|
||||
public void tessellateOnly(Tessellator tessellator, String... groupNames) {
|
||||
for (GroupObject groupObject : groupObjects)
|
||||
{
|
||||
for (String groupName : groupNames)
|
||||
{
|
||||
if (groupName.equalsIgnoreCase(groupObject.name))
|
||||
{
|
||||
groupObject.render(tessellator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderPart(String partName)
|
||||
{
|
||||
for (GroupObject groupObject : groupObjects)
|
||||
@@ -203,17 +235,52 @@ public class WavefrontObject implements IModelCustom
|
||||
}
|
||||
}
|
||||
|
||||
public void tessellatePart(Tessellator tessellator, String partName) {
|
||||
for (GroupObject groupObject : groupObjects)
|
||||
{
|
||||
if (partName.equalsIgnoreCase(groupObject.name))
|
||||
{
|
||||
groupObject.render(tessellator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void renderAllExcept(String... excludedGroupNames)
|
||||
{
|
||||
for (GroupObject groupObject : groupObjects)
|
||||
{
|
||||
boolean skipPart=false;
|
||||
for (String excludedGroupName : excludedGroupNames)
|
||||
{
|
||||
if (!excludedGroupName.equalsIgnoreCase(groupObject.name))
|
||||
if (excludedGroupName.equalsIgnoreCase(groupObject.name))
|
||||
{
|
||||
groupObject.render();
|
||||
skipPart=true;
|
||||
}
|
||||
}
|
||||
if(!skipPart)
|
||||
{
|
||||
groupObject.render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void tessellateAllExcept(Tessellator tessellator, String... excludedGroupNames)
|
||||
{
|
||||
boolean exclude;
|
||||
for (GroupObject groupObject : groupObjects)
|
||||
{
|
||||
exclude=false;
|
||||
for (String excludedGroupName : excludedGroupNames)
|
||||
{
|
||||
if (excludedGroupName.equalsIgnoreCase(groupObject.name))
|
||||
{
|
||||
exclude=true;
|
||||
}
|
||||
}
|
||||
if(!exclude)
|
||||
{
|
||||
groupObject.render(tessellator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,7 +414,7 @@ public class WavefrontObject implements IModelCustom
|
||||
face.vertices = new Vertex[tokens.length];
|
||||
face.textureCoordinates = new TextureCoordinate[tokens.length];
|
||||
face.vertexNormals = new Vertex[tokens.length];
|
||||
|
||||
|
||||
for (int i = 0; i < tokens.length; ++i)
|
||||
{
|
||||
subTokens = tokens[i].split("/");
|
||||
@@ -364,7 +431,7 @@ public class WavefrontObject implements IModelCustom
|
||||
{
|
||||
face.vertices = new Vertex[tokens.length];
|
||||
face.textureCoordinates = new TextureCoordinate[tokens.length];
|
||||
|
||||
|
||||
for (int i = 0; i < tokens.length; ++i)
|
||||
{
|
||||
subTokens = tokens[i].split("/");
|
||||
@@ -380,7 +447,7 @@ public class WavefrontObject implements IModelCustom
|
||||
{
|
||||
face.vertices = new Vertex[tokens.length];
|
||||
face.vertexNormals = new Vertex[tokens.length];
|
||||
|
||||
|
||||
for (int i = 0; i < tokens.length; ++i)
|
||||
{
|
||||
subTokens = tokens[i].split("//");
|
||||
@@ -395,7 +462,7 @@ public class WavefrontObject implements IModelCustom
|
||||
else if (isValidFace_V_Line(line))
|
||||
{
|
||||
face.vertices = new Vertex[tokens.length];
|
||||
|
||||
|
||||
for (int i = 0; i < tokens.length; ++i)
|
||||
{
|
||||
face.vertices[i] = vertices.get(Integer.parseInt(tokens[i]) - 1);
|
||||
|
||||
@@ -0,0 +1,338 @@
|
||||
package net.minecraftforge.client.model.techne;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipException;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.model.ModelBase;
|
||||
import net.minecraft.client.model.ModelRenderer;
|
||||
import net.minecraftforge.client.model.IModelCustom;
|
||||
import net.minecraftforge.client.model.ModelFormatException;
|
||||
import net.minecraftforge.client.model.obj.GroupObject;
|
||||
|
||||
/**
|
||||
* Techne model importer, based on iChun's Hats importer
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class TechneModel extends ModelBase implements IModelCustom {
|
||||
public static final List<String> cubeTypes = Arrays.asList(
|
||||
"d9e621f7-957f-4b77-b1ae-20dcd0da7751",
|
||||
"de81aa14-bd60-4228-8d8d-5238bcd3caaa"
|
||||
);
|
||||
|
||||
private String fileName;
|
||||
private Map<String, byte[]> zipContents = new HashMap<String, byte[]>();
|
||||
|
||||
private Map<String, ModelRenderer> parts = new LinkedHashMap<String, ModelRenderer>();
|
||||
private String texture = null;
|
||||
private int textureName;
|
||||
private boolean textureNameSet = false;
|
||||
|
||||
public TechneModel(String fileName, URL resource) throws ModelFormatException
|
||||
{
|
||||
this.fileName = fileName;
|
||||
loadTechneModel(resource);
|
||||
}
|
||||
|
||||
private void loadTechneModel(URL fileURL) throws ModelFormatException
|
||||
{
|
||||
try
|
||||
{
|
||||
ZipInputStream zipInput = new ZipInputStream(fileURL.openStream());
|
||||
|
||||
ZipEntry entry;
|
||||
while ((entry = zipInput.getNextEntry()) != null)
|
||||
{
|
||||
byte[] data = new byte[(int) entry.getSize()];
|
||||
// For some reason, using read(byte[]) makes reading stall upon reaching a 0x1E byte
|
||||
int i = 0;
|
||||
while (zipInput.available() > 0 && i < data.length)
|
||||
{
|
||||
data[i++] = (byte)zipInput.read();
|
||||
}
|
||||
zipContents.put(entry.getName(), data);
|
||||
}
|
||||
|
||||
byte[] modelXml = zipContents.get("model.xml");
|
||||
if (modelXml == null)
|
||||
{
|
||||
throw new ModelFormatException("Model " + fileName + " contains no model.xml file");
|
||||
}
|
||||
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||
Document document = documentBuilder.parse(new ByteArrayInputStream(modelXml));
|
||||
|
||||
NodeList nodeListTechne = document.getElementsByTagName("Techne");
|
||||
if (nodeListTechne.getLength() < 1)
|
||||
{
|
||||
throw new ModelFormatException("Model " + fileName + " contains no Techne tag");
|
||||
}
|
||||
|
||||
NodeList nodeListModel = document.getElementsByTagName("Model");
|
||||
if (nodeListModel.getLength() < 1)
|
||||
{
|
||||
throw new ModelFormatException("Model " + fileName + " contains no Model tag");
|
||||
}
|
||||
|
||||
NamedNodeMap modelAttributes = nodeListModel.item(0).getAttributes();
|
||||
if (modelAttributes == null)
|
||||
{
|
||||
throw new ModelFormatException("Model " + fileName + " contains a Model tag with no attributes");
|
||||
}
|
||||
|
||||
Node modelTexture = modelAttributes.getNamedItem("texture");
|
||||
if (modelTexture != null)
|
||||
{
|
||||
texture = modelTexture.getTextContent();
|
||||
}
|
||||
|
||||
NodeList shapes = document.getElementsByTagName("Shape");
|
||||
for (int i = 0; i < shapes.getLength(); i++)
|
||||
{
|
||||
Node shape = shapes.item(i);
|
||||
NamedNodeMap shapeAttributes = shape.getAttributes();
|
||||
if (shapeAttributes == null)
|
||||
{
|
||||
throw new ModelFormatException("Shape #" + (i + 1) + " in " + fileName + " has no attributes");
|
||||
}
|
||||
|
||||
Node name = shapeAttributes.getNamedItem("name");
|
||||
String shapeName = null;
|
||||
if (name != null)
|
||||
{
|
||||
shapeName = name.getNodeValue();
|
||||
}
|
||||
if (shapeName == null)
|
||||
{
|
||||
shapeName = "Shape #" + (i + 1);
|
||||
}
|
||||
|
||||
String shapeType = null;
|
||||
Node type = shapeAttributes.getNamedItem("type");
|
||||
if (type != null)
|
||||
{
|
||||
shapeType = type.getNodeValue();
|
||||
}
|
||||
if (shapeType != null && !cubeTypes.contains(shapeType))
|
||||
{
|
||||
FMLLog.warning("Model shape [" + shapeName + "] in " + fileName + " is not a cube, ignoring");
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
boolean mirrored = false;
|
||||
String[] offset = new String[3];
|
||||
String[] position = new String[3];
|
||||
String[] rotation = new String[3];
|
||||
String[] size = new String[3];
|
||||
String[] textureOffset = new String[2];
|
||||
|
||||
NodeList shapeChildren = shape.getChildNodes();
|
||||
for (int j = 0; j < shapeChildren.getLength(); j++)
|
||||
{
|
||||
Node shapeChild = shapeChildren.item(j);
|
||||
|
||||
String shapeChildName = shapeChild.getNodeName();
|
||||
String shapeChildValue = shapeChild.getTextContent();
|
||||
if (shapeChildValue != null)
|
||||
{
|
||||
shapeChildValue = shapeChildValue.trim();
|
||||
|
||||
if (shapeChildName.equals("IsMirrored"))
|
||||
{
|
||||
mirrored = !shapeChildValue.equals("False");
|
||||
}
|
||||
else if (shapeChildName.equals("Offset"))
|
||||
{
|
||||
offset = shapeChildValue.split(",");
|
||||
}
|
||||
else if (shapeChildName.equals("Position"))
|
||||
{
|
||||
position = shapeChildValue.split(",");
|
||||
}
|
||||
else if (shapeChildName.equals("Rotation"))
|
||||
{
|
||||
rotation = shapeChildValue.split(",");
|
||||
}
|
||||
else if (shapeChildName.equals("Size"))
|
||||
{
|
||||
size = shapeChildValue.split(",");
|
||||
}
|
||||
else if (shapeChildName.equals("TextureOffset"))
|
||||
{
|
||||
textureOffset = shapeChildValue.split(",");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// That's what the ModelBase subclassing is needed for
|
||||
ModelRenderer cube = new ModelRenderer(this, Integer.parseInt(textureOffset[0]), Integer.parseInt(textureOffset[1]));
|
||||
cube.mirror = mirrored;
|
||||
cube.addBox(Float.parseFloat(offset[0]), Float.parseFloat(offset[1]), Float.parseFloat(offset[2]), Integer.parseInt(size[0]), Integer.parseInt(size[1]), Integer.parseInt(size[2]));
|
||||
cube.setRotationPoint(Float.parseFloat(position[0]), Float.parseFloat(position[1]) - 23.4F, Float.parseFloat(position[2]));
|
||||
|
||||
cube.rotateAngleX = (float)Math.toRadians(Float.parseFloat(rotation[0]));
|
||||
cube.rotateAngleY = (float)Math.toRadians(Float.parseFloat(rotation[1]));
|
||||
cube.rotateAngleZ = (float)Math.toRadians(Float.parseFloat(rotation[2]));
|
||||
|
||||
parts.put(shapeName, cube);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
FMLLog.warning("Model shape [" + shapeName + "] in " + fileName + " contains malformed integers within its data, ignoring");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ZipException e)
|
||||
{
|
||||
throw new ModelFormatException("Model " + fileName + " is not a valid zip file");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ModelFormatException("Model " + fileName + " could not be read", e);
|
||||
}
|
||||
catch (ParserConfigurationException e)
|
||||
{
|
||||
// hush
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
throw new ModelFormatException("Model " + fileName + " contains invalid XML", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void bindTexture()
|
||||
{
|
||||
/* TODO: Update to 1.6
|
||||
if (texture != null)
|
||||
{
|
||||
if (!textureNameSet)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] textureEntry = zipContents.get(texture);
|
||||
if (textureEntry == null)
|
||||
{
|
||||
throw new ModelFormatException("Model " + fileName + " has no such texture " + texture);
|
||||
}
|
||||
|
||||
BufferedImage image = ImageIO.read(new ByteArrayInputStream(textureEntry));
|
||||
textureName = Minecraft.getMinecraft().renderEngine.allocateAndSetupTexture(image);
|
||||
textureNameSet = true;
|
||||
}
|
||||
catch (ZipException e)
|
||||
{
|
||||
throw new ModelFormatException("Model " + fileName + " is not a valid zip file");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ModelFormatException("Texture for model " + fileName + " could not be read", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (textureNameSet)
|
||||
{
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureName);
|
||||
Minecraft.getMinecraft().renderEngine.resetBoundTexture();
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType()
|
||||
{
|
||||
return "tcn";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAll()
|
||||
{
|
||||
bindTexture();
|
||||
|
||||
for (ModelRenderer part : parts.values())
|
||||
{
|
||||
part.renderWithRotation(1.0F);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderPart(String partName)
|
||||
{
|
||||
ModelRenderer part = parts.get(partName);
|
||||
if (part != null)
|
||||
{
|
||||
bindTexture();
|
||||
|
||||
part.renderWithRotation(1.0F);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderOnly(String... groupNames)
|
||||
{
|
||||
bindTexture();
|
||||
for (ModelRenderer part : parts.values())
|
||||
{
|
||||
for (String groupName : groupNames)
|
||||
{
|
||||
if (groupName.equalsIgnoreCase(part.boxName))
|
||||
{
|
||||
part.render(1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAllExcept(String... excludedGroupNames)
|
||||
{
|
||||
for (ModelRenderer part : parts.values())
|
||||
{
|
||||
boolean skipPart=false;
|
||||
for (String excludedGroupName : excludedGroupNames)
|
||||
{
|
||||
if (excludedGroupName.equalsIgnoreCase(part.boxName))
|
||||
{
|
||||
skipPart=true;
|
||||
}
|
||||
}
|
||||
if(!skipPart)
|
||||
{
|
||||
part.render(1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package net.minecraftforge.client.model.techne;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
import net.minecraftforge.client.model.IModelCustom;
|
||||
import net.minecraftforge.client.model.IModelCustomLoader;
|
||||
import net.minecraftforge.client.model.ModelFormatException;
|
||||
|
||||
public class TechneModelLoader implements IModelCustomLoader {
|
||||
|
||||
@Override
|
||||
public String getType()
|
||||
{
|
||||
return "Techne model";
|
||||
}
|
||||
|
||||
private static final String[] types = { "tcn" };
|
||||
@Override
|
||||
public String[] getSuffixes()
|
||||
{
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IModelCustom loadInstance(String resourceName, URL resource) throws ModelFormatException
|
||||
{
|
||||
return new TechneModel(resourceName, resource);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
commands.forge.usage=Use /forge <subcommand>. Subcommands are tps, track
|
||||
commands.forge.usage.tracking=Use /forge track <type> <duration>. Valid types are te (Tile Entities). Duration is < 60.
|
||||
commands.forge.tps.summary=%s : Mean tick time: %d ms. Mean TPS: %d
|
||||
|
||||
commands.forge.tracking.te.enabled=Tile Entity tracking enabled for %d seconds.
|
||||
@@ -0,0 +1,5 @@
|
||||
commands.forge.usage=Usa /forge <subcomando>. Los subcomandos son tps, track
|
||||
commands.forge.usage.tracking=Usa /forge track <tipo> <duración>. Los tipos válidos te (Tile Entities). La duración es < 60.
|
||||
commands.forge.tps.summary=%s : Tiempo de tick medio: %d ms. TPS medio: %d
|
||||
|
||||
commands.forge.tracking.te.enabled=Rastreo de Tile Entity activado durante %d segundos.
|
||||
@@ -0,0 +1,5 @@
|
||||
commands.forge.usage=Utilisez /forge <sous-commande>. Les sous-commandes sont tps, track
|
||||
commands.forge.usage.tracking=Utilisez /forge track <type> <durée>. Les types valides sont te (Tile Entities). La durée doit être inférieur à 60.
|
||||
commands.forge.tps.summary=%s : Duré de tick : %d ms. TPS moyen : %d
|
||||
|
||||
commands.forge.tracking.te.enabled=Trackage des Tile Entity activé pour %d secondes.
|
||||
+111
-113
@@ -1,162 +1,160 @@
|
||||
#Main Forge Access Transformer configuration file
|
||||
# Tessellator
|
||||
public-f bff.a #FD:Tessellator/field_78398_a #instance
|
||||
public bff.u #FD:Tessellator/field_78409_u #drawMode
|
||||
public bff.v #FD:Tessellator/field_78408_v #xOffset
|
||||
public bff.w #FD:Tessellator/field_78407_w #yOffset
|
||||
public bff.x #FD:Tessellator/field_78417_x #zOffset
|
||||
public bff.z #FD:Tessellator/field_78415_z #isDrawing
|
||||
public-f bfq.a #FD:Tessellator/field_78398_a #instance
|
||||
public bfq.u #FD:Tessellator/field_78409_u #drawMode
|
||||
public bfq.v #FD:Tessellator/field_78408_v #xOffset
|
||||
public bfq.w #FD:Tessellator/field_78407_w #yOffset
|
||||
public bfq.x #FD:Tessellator/field_78417_x #zOffset
|
||||
public bfq.z #FD:Tessellator/field_78415_z #isDrawing
|
||||
# ItemPickaxe
|
||||
public yi.<init>(ILxy;)V #MD:ItemPickaxe/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
|
||||
public+f yi.c #FD:ItemPickaxe/field_77867_c #blocksEffectiveAgainst
|
||||
public yn.<init>(ILyd;)V #MD:ItemPickaxe/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
|
||||
public+f yn.c #FD:ItemPickaxe/field_77867_c #blocksEffectiveAgainst
|
||||
# ItemAxe
|
||||
public xv.<init>(ILxy;)V #MD:ItemAxe/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
|
||||
public+f xv.c #FD:ItemAxe/field_77868_c #blocksEffectiveAgainst
|
||||
public ya.<init>(ILyd;)V #MD:ItemAxe/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
|
||||
public+f ya.c #FD:ItemAxe/field_77868_c #blocksEffectiveAgainst
|
||||
# ItemSpade
|
||||
public yt.<init>(ILxy;)V #MD:ItemSpade/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
|
||||
public+f yt.c #FD:ItemSpade/field_77866_c #blocksEffectiveAgainst
|
||||
public yy.<init>(ILyd;)V #MD:ItemSpade/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
|
||||
public+f yy.c #FD:ItemSpade/field_77866_c #blocksEffectiveAgainst
|
||||
# ItemTool
|
||||
public xe.a #FD:ItemTool/field_77864_a #efficiencyOnProperMaterial
|
||||
public xe.d #FD:ItemTool/field_77865_bY #damageVsEntity
|
||||
public xj.a #FD:ItemTool/field_77864_a #efficiencyOnProperMaterial
|
||||
public xj.d #FD:ItemTool/field_77865_bY #damageVsEntity
|
||||
# EntityEnderman
|
||||
public td.br #FD:EntityEnderman/field_70827_d #carriableBlocks
|
||||
# RenderEngine
|
||||
# -- MISSING MAPPING public bge.f(Ljava/lang/String;)I #MD:RenderEngine/func_78341_b #getTexture
|
||||
# -- MISSING MAPPING public bge.i #FD:RenderEngine/field_94154_l #terrainTextureMap
|
||||
# -- MISSING MAPPING public bge.j #FD:RenderEngine/field_94155_m #itemTextureMap
|
||||
public tg.br #FD:EntityEnderman/field_70827_d #carriableBlocks
|
||||
# RenderGlobal
|
||||
public bfa.k #FD:RenderGlobal/field_72769_h #theWorld
|
||||
public bfa.l #FD:RenderGlobal/field_72770_i #renderEngine
|
||||
public bfa.t #FD:RenderGlobal/field_72777_q #mc
|
||||
public bfa.u #FD:RenderGlobal/field_72776_r #globalRenderBlocks
|
||||
public bfa.H #FD:RenderGlobal/field_72738_E #damagedBlocks
|
||||
public bfl.k #FD:RenderGlobal/field_72769_h #theWorld
|
||||
public bfl.l #FD:RenderGlobal/field_72770_i #renderEngine
|
||||
public bfl.t #FD:RenderGlobal/field_72777_q #mc
|
||||
public bfl.u #FD:RenderGlobal/field_72776_r #globalRenderBlocks
|
||||
public bfl.H #FD:RenderGlobal/field_72738_E #damagedBlocks
|
||||
# SoundManager
|
||||
public blc.b #FD:SoundManager/field_77381_a #sndSystem
|
||||
public blc.d #FD:SoundManager/field_77379_b #soundPoolSounds
|
||||
public blc.e #FD:SoundManager/field_77380_c #soundPoolStreaming
|
||||
public blc.f #FD:SoundManager/field_77377_d #soundPoolMusic
|
||||
public bln.b #FD:SoundManager/field_77381_a #sndSystem
|
||||
public bln.d #FD:SoundManager/field_77379_b #soundPoolSounds
|
||||
public bln.e #FD:SoundManager/field_77380_c #soundPoolStreaming
|
||||
public bln.f #FD:SoundManager/field_77377_d #soundPoolMusic
|
||||
# EntityMinecart
|
||||
protected sq.* #FD:EntityMinecart/* # All private -> protected
|
||||
# -- MISSING MAPPING public py.h()Z #MD:EntityMinecart/func_70490_h #isMinecartPowered
|
||||
protected st.* #FD:EntityMinecart/* # All private -> protected
|
||||
# Block
|
||||
public aqs.<init>(ILajv;)V #MD:Block/<init>(ILnet/minecraft/src/Material;) #Constructor
|
||||
public aqs.<init>(IILajv;)V #MD:Block/<init>(IILnet/minecraft/src/Material;) #Constructor
|
||||
public aqs.cH #FD:Block/field_72029_cc #blockResistance
|
||||
public aqs.cG #FD:Block/field_71989_cb #blockHardness
|
||||
# -- MISSING MAPPING public amq.r()Lamq; #MD:Block/func_71912_p #setRequiresSelfNotify
|
||||
public aqs.a(Laqw;)Laqs; #MD:Block/func_71884_a #setStepSound
|
||||
public aqs.b(F)Laqs; #MD:Block/func_71894_b #setResistance
|
||||
public aqs.c(F)Laqs; #MD:Block/func_71848_c #setHardness
|
||||
public aqs.k(I)Laqs; #MD:Block/func_71868_h #setLightOpacity
|
||||
public aqs.a(F)Laqs; #MD:Block/func_71900_a #setLightValue
|
||||
public aqs.r()Laqs; #MD:Block/func_71875_q #setBlockUnbreakable
|
||||
public aqs.b(Z)Laqs; #MD:Block/func_71907_b #setTickRandomly
|
||||
public aqs.a(FFFFFF)V #MD:Block/func_71905_a #setBlockBounds
|
||||
public aqz.<init>(ILakc;)V #MD:Block/<init>(ILnet/minecraft/src/Material;) #Constructor
|
||||
public aqz.<init>(IILakc;)V #MD:Block/<init>(IILnet/minecraft/src/Material;) #Constructor
|
||||
public aqz.cH #FD:Block/field_72029_cc #blockResistance
|
||||
public aqz.cG #FD:Block/field_71989_cb #blockHardness
|
||||
public aqz.d(Ljava/lang/String;)Laqz; #MD:Block/func_111022_d #setIconName
|
||||
public aqz.a(Lard;)Laqz; #MD:Block/func_71884_a #setStepSound
|
||||
public aqz.b(F)Laqz; #MD:Block/func_71894_b #setResistance
|
||||
public aqz.c(F)Laqz; #MD:Block/func_71848_c #setHardness
|
||||
public aqz.k(I)Laqz; #MD:Block/func_71868_h #setLightOpacity
|
||||
public aqz.a(F)Laqz; #MD:Block/func_71900_a #setLightValue
|
||||
public aqz.r()Laqz; #MD:Block/func_71875_q #setBlockUnbreakable
|
||||
public aqz.b(Z)Laqz; #MD:Block/func_71907_b #setTickRandomly
|
||||
public aqz.a(FFFFFF)V #MD:Block/func_71905_a #setBlockBounds
|
||||
public aqz.j(Labw;IIII)V #MD:Block/func_71923_g #dropXpOnBlockBreak
|
||||
# NetServerHandler
|
||||
public jx.f #FD:NetServerHandler/field_72572_g #playerInAirTime
|
||||
public ka.f #FD:NetServerHandler/field_72572_g #playerInAirTime
|
||||
# TileEntity
|
||||
public asi.k #FD:TileEntity/field_70331_k #worldObj
|
||||
public asp.k #FD:TileEntity/field_70331_k #worldObj
|
||||
# BlockLeavesBase
|
||||
public ara.d #FD:BlockLeavesBase/field_72131_c #graphicsLevel
|
||||
public arh.d #FD:BlockLeavesBase/field_72131_c #graphicsLevel
|
||||
# Item
|
||||
public xx.<init>(I)V #MD:Item/<init>(I) #Constructor
|
||||
public xx.e(I)Lxx; #MD:Item/func_77656_e #setMaxDamage
|
||||
public-f xx.h(Lxz;)Lmp; #MD:Item/func_77650_f #getIconIndex
|
||||
public xx.c(Ljava/lang/String;)Lxx; #MD:Item/func_77631_c #setPotionEffect
|
||||
public yc.<init>(I)V #MD:Item/<init>(I) #Constructor
|
||||
public yc.e(I)Lyc; #MD:Item/func_77656_e #setMaxDamage
|
||||
public-f yc.h(Lye;)Lms; #MD:Item/func_77650_f #getIconIndex
|
||||
public yc.c(Ljava/lang/String;)Lyc; #MD:Item/func_77631_c #setPotionEffect
|
||||
public yc.d(Ljava/lang/String;)Lyc; #MD:Item/func_111206_d #setIconName
|
||||
# RailLogic
|
||||
public ams #CL:BlockBaseRailLogic
|
||||
public ams.a()I #MD:BlockBaseRailLogic/func_94505_a #getNAdjacentTiles
|
||||
public amz #CL:BlockBaseRailLogic
|
||||
public amz.a()I #MD:BlockBaseRailLogic/func_94505_a #getNAdjacentTiles
|
||||
# EntityPlayer
|
||||
public ua.a(Lsp;)V #MD:EntityPlayer/func_71012_a #joinEntityItemWithWorld
|
||||
public ua.i()V #MD:EntityPlayer/func_71053_j #closeScreen
|
||||
public ua.b #FD:EntityPlayer/field_71076_b #sleepTimer
|
||||
public uf.a(Lss;)V #MD:EntityPlayer/func_71012_a #joinEntityItemWithWorld
|
||||
public uf.i()V #MD:EntityPlayer/func_71053_j #closeScreen
|
||||
public uf.b #FD:EntityPlayer/field_71076_b #sleepTimer
|
||||
# EntityPlayerMP
|
||||
public bcx.a(Lsp;)V #MD:EntityClientPlayerMP/func_71012_a #joinEntityItemWithWorld
|
||||
public bdi.a(Lss;)V #MD:EntityClientPlayerMP/func_71012_a #joinEntityItemWithWorld
|
||||
# World Gen Chests Related
|
||||
public mh.* #FD:WeightedRandomChestContent/* #all
|
||||
public jp.T #FD:WorldServer/field_73069_S #bonusChestContent
|
||||
public agc.a #FD:StructureMineshaftPieces/field_78818_a #mineshaftChestContents
|
||||
public ahg.i #FD:ComponentScatteredFeatureDesertPyramid/field_74941_i #itemsToGenerateInTemple
|
||||
public ahh.l #FD:ComponentScatteredFeatureJunglePyramid/field_74943_l #junglePyramidsChestContents
|
||||
public ahh.m #FD:ComponentScatteredFeatureJunglePyramid/field_74944_m #junglePyramidsDispenserContents
|
||||
public ahr.a #FD:ComponentStrongholdChestCorridor/field_75003_a #strongholdChestContents
|
||||
public ahv.b #FD:ComponentStrongholdLibrary/field_75007_b #strongholdLibraryChestContents
|
||||
public aia.c #FD:ComponentStrongholdRoomCrossing/field_75014_c #strongholdCorridorChestContents
|
||||
public ajb.a #FD:ComponentVillageHouse2/field_74918_a #villageBlacksmithChestContents
|
||||
public mk.* #FD:WeightedRandomChestContent/* #all
|
||||
public js.T #FD:WorldServer/field_73069_S #bonusChestContent
|
||||
public agh.a #FD:StructureMineshaftPieces/field_78818_a #mineshaftChestContents
|
||||
public ahl.i #FD:ComponentScatteredFeatureDesertPyramid/field_74941_i #itemsToGenerateInTemple
|
||||
public ahm.l #FD:ComponentScatteredFeatureJunglePyramid/field_74943_l #junglePyramidsChestContents
|
||||
public ahm.m #FD:ComponentScatteredFeatureJunglePyramid/field_74944_m #junglePyramidsDispenserContents
|
||||
public ahw.a #FD:ComponentStrongholdChestCorridor/field_75003_a #strongholdChestContents
|
||||
public aia.a #FD:ComponentStrongholdLibrary/field_75007_b #strongholdLibraryChestContents
|
||||
public aif.b #FD:ComponentStrongholdRoomCrossing/field_75014_c #strongholdCorridorChestContents
|
||||
public aji.a #FD:ComponentVillageHouse2/field_74918_a #villageBlacksmithChestContents
|
||||
public afp.a #FD:WorldGenDungeons/field_111189_a #chestContents
|
||||
# AnvilChunkLoader.chunkSaveLocation
|
||||
public adz.d #FD:AnvilChunkLoader/field_75825_d
|
||||
public aee.d #FD:AnvilChunkLoader/field_75825_d
|
||||
# ChunkProviderServer.currentChunkLoader
|
||||
public jo.e #FD:ChunkProviderServer/field_73247_e
|
||||
public jr.e #FD:ChunkProviderServer/field_73247_e
|
||||
# PlayerManager
|
||||
public jm.a(IIZ)Ljn; #MD:PlayerManager/func_72690_a #getOrCreateChunkWatcher
|
||||
public jp.a(IIZ)Ljq; #MD:PlayerManager/func_72690_a #getOrCreateChunkWatcher
|
||||
# PlayerInstance
|
||||
public jn #CL:PlayerInstance
|
||||
public jq #CL:PlayerInstance
|
||||
# World
|
||||
public-f abr.A #FD:World/field_72982_D #villageCollectionObj
|
||||
public abr.G #FD:World/field_72993_I #activeChunkSet
|
||||
public-f abw.A #FD:World/field_72982_D #villageCollectionObj
|
||||
public abw.G #FD:World/field_72993_I #activeChunkSet
|
||||
# EntityLiving
|
||||
public od.b #FD:EntityLiving/field_70728_aV #experienceValue
|
||||
# -- MISSING MAPPING public ng.bt #FD:EntityLiving/field_94063_bt #combatTracker
|
||||
public od.d #FD:EntityLiving/field_70715_bh #targetTasks
|
||||
public og.b #FD:EntityLiving/field_70728_aV #experienceValue
|
||||
public og.d #FD:EntityLiving/field_70715_bh #targetTasks
|
||||
# GuiFlatPresets
|
||||
public avq.a(Ljava/lang/String;ILacl;Ljava/util/List;[Lafy;)V #MD:GuiFlatPresets/func_82294_a
|
||||
public avq.a(Ljava/lang/String;ILacl;[Lafy;)V #MD:GuiFlatPresets/func_82297_a
|
||||
public avz.a(Ljava/lang/String;ILacq;Ljava/util/List;[Lagd;)V #MD:GuiFlatPresets/func_82294_a
|
||||
public avz.a(Ljava/lang/String;ILacq;[Lagd;)V #MD:GuiFlatPresets/func_82297_a
|
||||
# BiomeGenBase
|
||||
public acl.*() #MD:BiomeGenBase/* #Everything protected->public
|
||||
public acq.*() #MD:BiomeGenBase/* #Everything protected->public
|
||||
# MapGenVillage
|
||||
public-f aip.e #FD:MapGenVillage/field_75055_e #villageSpawnBiomes
|
||||
public-f aiw.e #FD:MapGenVillage/field_75055_e #villageSpawnBiomes
|
||||
# ShapedRecipes
|
||||
public+f aad.d #FD:ShapedRecipes/field_77574_d #recipeItems
|
||||
public+f aad.b #FD:ShapedRecipes/field_77576_b #recipeWidth
|
||||
public+f aad.c #FD:ShapedRecipes/field_77577_c #recipeHeight
|
||||
public+f aai.d #FD:ShapedRecipes/field_77574_d #recipeItems
|
||||
public+f aai.b #FD:ShapedRecipes/field_77576_b #recipeWidth
|
||||
public+f aai.c #FD:ShapedRecipes/field_77577_c #recipeHeight
|
||||
# ShapelessRecipes
|
||||
public aae.b #FD:ShapelessRecipes/field_77579_b #recipeItems
|
||||
public aaj.b #FD:ShapelessRecipes/field_77579_b #recipeItems
|
||||
# GuiContainer
|
||||
protected awp.a(Lvz;)V #MD:GuiContainer/func_74192_a #drawSlotInventory
|
||||
protected awy.a(Lwe;)V #MD:GuiContainer/func_74192_a #drawSlotInventory
|
||||
# ContainerPlayer
|
||||
protected vq.h #FD:ContainerPlayer/field_82862_h #player
|
||||
protected vv.h #FD:ContainerPlayer/field_82862_h #player
|
||||
# BlockButton
|
||||
protected amy.n(Labr;III)V #MD:BlockButton/func_82535_o #checkActivation
|
||||
protected-f amy.a #FD:BlockButton/field_82537_a #sensible
|
||||
protected anf.n(Labw;III)V #MD:BlockButton/func_82535_o #checkActivation
|
||||
protected-f anf.a #FD:BlockButton/field_82537_a #sensible
|
||||
# BiomeDecorator
|
||||
public acp.* #FD:BiomeDecorator/* # All private -> protected
|
||||
public acu.* #FD:BiomeDecorator/* # All private -> protected
|
||||
# CreativeTabs
|
||||
public-f wr.a #FD:CreativeTabs/field_78032_a # creativeTabArray non-final
|
||||
public-f ww.a #FD:CreativeTabs/field_78032_a # creativeTabArray non-final
|
||||
# Packet
|
||||
public ex.a(IZZLjava/lang/Class;)V #MD:Packet/func_73285_a #addIdClassMapping
|
||||
public ey.a(IZZLjava/lang/Class;)V #MD:Packet/func_73285_a #addIdClassMapping
|
||||
# SaveHandler
|
||||
public alj.b()Ljava/io/File; #MD:SaveHandler/func_75765_b
|
||||
public alq.b()Ljava/io/File; #MD:SaveHandler/func_75765_b
|
||||
# World stuff
|
||||
public abr.b(Lnk;)V #MD:World/func_72847_b #releaseEntitySkin
|
||||
public abr.m #FD:World/field_73003_n #prevRainingStrength
|
||||
public abr.n #FD:World/field_73004_o #rainingStrength
|
||||
public abr.p #FD:World/field_73017_q #thunderingStrength
|
||||
public abr.o #FD:World/field_73018_p #prevThunderingStrength
|
||||
public abw.b(Lnn;)V #MD:World/func_72847_b #releaseEntitySkin
|
||||
public abw.m #FD:World/field_73003_n #prevRainingStrength
|
||||
public abw.n #FD:World/field_73004_o #rainingStrength
|
||||
public abw.p #FD:World/field_73017_q #thunderingStrength
|
||||
public abw.o #FD:World/field_73018_p #prevThunderingStrength
|
||||
#WorldClient
|
||||
public bcu.b(Lnk;)V #MD:WorldClient/func_72847_b #releaseEntitySkin
|
||||
public bdd.b(Lnn;)V #MD:WorldClient/func_72847_b #releaseEntitySkin
|
||||
#WorldServer
|
||||
public jp.b(Lnk;)V #MD:WorldServer/func_72847_b #releaseEntitySkin
|
||||
public jp.N #FD:WorldServer/field_73068_P #allPlayersSleeping
|
||||
public js.b(Lnn;)V #MD:WorldServer/func_72847_b #releaseEntitySkin
|
||||
public js.N #FD:WorldServer/field_73068_P #allPlayersSleeping
|
||||
#TextureMap
|
||||
public bhz.g #FD:TextureMap/field_94255_a
|
||||
# -- MISSING MAPPING public bir.b #FD:TextureMap/field_94253_b
|
||||
public bhz.h #FD:TextureMap/field_94254_c
|
||||
# -- MISSING MAPPING public bir.d #FD:TextureMap/field_94251_d
|
||||
public bik.g #FD:TextureMap/field_94255_a
|
||||
public bik.h #FD:TextureMap/field_94254_c
|
||||
#Potion
|
||||
public nf.b(II)Lnf; #MD:Potion/func_76399_b #setIconIndex
|
||||
public ni.b(II)Lni; #MD:Potion/func_76399_b #setIconIndex
|
||||
#PotionHelper
|
||||
public zk.m #FD:PotionHelper/field_77927_l #potionRequirements
|
||||
public zk.n #FD:PotionHelper/field_77928_m #potionAmplifiers
|
||||
public zp.m #FD:PotionHelper/field_77927_l #potionRequirements
|
||||
public zp.n #FD:PotionHelper/field_77928_m #potionAmplifiers
|
||||
#PotionEffect
|
||||
public ng.b #FD:PotionEffect/field_76460_b #duration
|
||||
public nj.b #FD:PotionEffect/field_76460_b #duration
|
||||
#BlockFluid
|
||||
protected aov.a #FD:BlockFluid/field_94425_a #theIcon
|
||||
protected apc.a #FD:BlockFluid/field_94425_a #theIcon
|
||||
#GuiIngame
|
||||
protected ava.* #FD:GuiIngame/* # All private -> protected
|
||||
protected ava.*() #MD:GuiIngame/* # All private -> protected
|
||||
protected avj.* #FD:GuiIngame/* # All private -> protected
|
||||
protected avj.*() #MD:GuiIngame/* # All private -> protected
|
||||
#ItemStack
|
||||
default xz.f #FD:ItemStack/field_77991_e # make default access for itemDamage
|
||||
default ye.f #FD:ItemStack/field_77991_e # make default access for itemDamage
|
||||
#GuiSlot
|
||||
protected avx.b(IIII)V #MD:GuiSlot/func_77206_b #overlayBackground
|
||||
protected awg.b(IIII)V #MD:GuiSlot/func_77206_b #overlayBackground
|
||||
#EntityPlayer
|
||||
public ua.bu #FD:EntityPlayer/field_71092_bJ #username
|
||||
public uf.bu #FD:EntityPlayer/field_71092_bJ #username
|
||||
#MapGenStructureIO
|
||||
public air.b(Ljava/lang/Class;Ljava/lang/String;)V #MD:MapGenStructureIO/func_143034_b #registerStart
|
||||
public air.a(Ljava/lang/Class;Ljava/lang/String;)V #MD:MapGenStructureIO/func_143031_a #registerPiece
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.minecraftforge.classloading;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
|
||||
@@ -7,6 +8,7 @@ import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
|
||||
public class FMLForgePlugin implements IFMLLoadingPlugin
|
||||
{
|
||||
public static boolean RUNTIME_DEOBF = false;
|
||||
public static File forgeLocation;
|
||||
|
||||
@Override
|
||||
public String[] getLibraryRequestClass()
|
||||
@@ -39,5 +41,6 @@ public class FMLForgePlugin implements IFMLLoadingPlugin
|
||||
public void injectData(Map<String, Object> data)
|
||||
{
|
||||
RUNTIME_DEOBF = (Boolean)data.get("runtimeDeobfuscationEnabled");
|
||||
forgeLocation = (File)data.get("coremodLocation");
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import net.minecraft.world.biome.*;
|
||||
import net.minecraftforge.event.terraingen.DeferredBiomeDecorator;
|
||||
import static net.minecraft.world.biome.BiomeGenBase.*;
|
||||
import static net.minecraftforge.common.BiomeDictionary.Type.*;
|
||||
|
||||
@@ -185,20 +188,35 @@ public class BiomeDictionary
|
||||
return biomeList[biomeID] != null;
|
||||
}
|
||||
|
||||
public static void registerAllBiomes()
|
||||
{
|
||||
FMLLog.warning("Redundant call to BiomeDictionary.registerAllBiomes ignored");
|
||||
}
|
||||
/**
|
||||
* Loops through the biome list and automatically adds tags to any biome that does not have any
|
||||
* This should be called in postInit to make sure all biomes have been registered
|
||||
* This is called by Forge at postinit time. It will additionally dispatch any deferred decorator
|
||||
* creation events.
|
||||
*
|
||||
* DO NOT call this during world generation
|
||||
*/
|
||||
public static void registerAllBiomes()
|
||||
public static void registerAllBiomesAndGenerateEvents()
|
||||
{
|
||||
for(int i = 0; i < BIOME_LIST_SIZE; i++)
|
||||
for(int i = 0; i < BiomeGenBase.biomeList.length; i++)
|
||||
{
|
||||
if(BiomeGenBase.biomeList[i] != null)
|
||||
BiomeGenBase biome = BiomeGenBase.biomeList[i];
|
||||
|
||||
if(biome == null)
|
||||
{
|
||||
checkRegistration(BiomeGenBase.biomeList[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (biome.theBiomeDecorator instanceof DeferredBiomeDecorator)
|
||||
{
|
||||
DeferredBiomeDecorator decorator = (DeferredBiomeDecorator) biome.theBiomeDecorator;
|
||||
decorator.fireCreateEventAndReplace();
|
||||
}
|
||||
|
||||
checkRegistration(biome);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.WeightedRandom;
|
||||
import net.minecraft.util.WeightedRandomChestContent;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraft.world.gen.feature.WorldGenDungeons;
|
||||
import net.minecraft.world.gen.structure.*;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
@@ -49,6 +50,7 @@ public class ChestGenHooks
|
||||
addInfo(STRONGHOLD_CROSSING, ComponentStrongholdRoomCrossing.strongholdRoomCrossingChestContents, 1, 5);
|
||||
addInfo(VILLAGE_BLACKSMITH, ComponentVillageHouse2.villageBlacksmithChestContents, 3, 9);
|
||||
addInfo(BONUS_CHEST, WorldServer.bonusChestContent, 10, 10);
|
||||
addInfo(DUNGEON_CHEST, WorldGenDungeons.field_111189_a, 8, 8);
|
||||
|
||||
ItemStack book = new ItemStack(Item.enchantedBook, 1, 0);
|
||||
WeightedRandomChestContent tmp = new WeightedRandomChestContent(book, 1, 1, 1);
|
||||
@@ -58,25 +60,7 @@ public class ChestGenHooks
|
||||
getInfo(STRONGHOLD_CORRIDOR ).addItem(tmp);
|
||||
getInfo(STRONGHOLD_LIBRARY ).addItem(new WeightedRandomChestContent(book, 1, 5, 2));
|
||||
getInfo(STRONGHOLD_CROSSING ).addItem(tmp);
|
||||
|
||||
//Wish Dungeons would get on the same wave length as other world gen...
|
||||
ChestGenHooks d = new ChestGenHooks(DUNGEON_CHEST);
|
||||
d.countMin = 8;
|
||||
d.countMax = 8;
|
||||
chestInfo.put(DUNGEON_CHEST, d);
|
||||
addDungeonLoot(d, new ItemStack(Item.saddle), 100, 1, 1);
|
||||
addDungeonLoot(d, new ItemStack(Item.ingotIron), 100, 1, 4);
|
||||
addDungeonLoot(d, new ItemStack(Item.bread), 100, 1, 1);
|
||||
addDungeonLoot(d, new ItemStack(Item.wheat), 100, 1, 4);
|
||||
addDungeonLoot(d, new ItemStack(Item.gunpowder), 100, 1, 4);
|
||||
addDungeonLoot(d, new ItemStack(Item.silk), 100, 1, 4);
|
||||
addDungeonLoot(d, new ItemStack(Item.bucketEmpty), 100, 1, 1);
|
||||
addDungeonLoot(d, new ItemStack(Item.appleGold), 1, 1, 1);
|
||||
addDungeonLoot(d, new ItemStack(Item.redstone), 50, 1, 4);
|
||||
addDungeonLoot(d, new ItemStack(Item.record13), 5, 1, 1);
|
||||
addDungeonLoot(d, new ItemStack(Item.recordCat), 5, 1, 1);
|
||||
addDungeonLoot(d, new ItemStack(Item.dyePowder, 1, 3), 100, 1, 1);
|
||||
addDungeonLoot(d, book, 100, 1, 1);
|
||||
getInfo(DUNGEON_CHEST ).addItem(tmp);
|
||||
}
|
||||
|
||||
static void addDungeonLoot(ChestGenHooks dungeon, ItemStack item, int weight, int min, int max)
|
||||
@@ -124,7 +108,7 @@ public class ChestGenHooks
|
||||
{
|
||||
ret = new ItemStack[0];
|
||||
}
|
||||
else if (count > source.getItem().getItemStackLimit())
|
||||
else if (count > source.getMaxStackSize())
|
||||
{
|
||||
ret = new ItemStack[count];
|
||||
for (int x = 0; x < count; x++)
|
||||
|
||||
@@ -197,12 +197,15 @@ public class DimensionManager
|
||||
|
||||
public static void setWorld(int id, WorldServer world)
|
||||
{
|
||||
if (world != null) {
|
||||
if (world != null)
|
||||
{
|
||||
worlds.put(id, world);
|
||||
weakWorldMap.put(world, world);
|
||||
MinecraftServer.getServer().worldTickTimes.put(id, new long[100]);
|
||||
FMLLog.info("Loading dimension %d (%s) (%s)", id, world.getWorldInfo().getWorldName(), world.getMinecraftServer());
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
worlds.remove(id);
|
||||
MinecraftServer.getServer().worldTickTimes.remove(id);
|
||||
FMLLog.info("Unloading dimension %d", id);
|
||||
@@ -231,14 +234,18 @@ public class DimensionManager
|
||||
|
||||
public static void initDimension(int dim) {
|
||||
WorldServer overworld = getWorld(0);
|
||||
if (overworld == null) {
|
||||
if (overworld == null)
|
||||
{
|
||||
throw new RuntimeException("Cannot Hotload Dim: Overworld is not Loaded!");
|
||||
}
|
||||
try {
|
||||
try
|
||||
{
|
||||
DimensionManager.getProviderType(dim);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("Cannot Hotload Dim: " + e.getMessage());
|
||||
return; //If a provider hasn't been registered then we can't hotload the dim
|
||||
return; // If a provider hasn't been registered then we can't hotload the dim
|
||||
}
|
||||
MinecraftServer mcServer = overworld.getMinecraftServer();
|
||||
ISaveHandler savehandler = overworld.getSaveHandler();
|
||||
|
||||
@@ -46,7 +46,7 @@ public class EnumHelper
|
||||
{EnumMovingObjectType.class},
|
||||
{EnumSkyBlock.class, int.class},
|
||||
{EnumStatus.class},
|
||||
{EnumToolMaterial.class, int.class, int.class, float.class, int.class, int.class}
|
||||
{EnumToolMaterial.class, int.class, int.class, float.class, float.class, int.class}
|
||||
};
|
||||
|
||||
public static EnumAction addAction(String name)
|
||||
@@ -102,7 +102,7 @@ public class EnumHelper
|
||||
{
|
||||
return addEnum(EnumStatus.class, name);
|
||||
}
|
||||
public static EnumToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, int damage, int enchantability)
|
||||
public static EnumToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, float damage, int enchantability)
|
||||
{
|
||||
return addEnum(EnumToolMaterial.class, name, harvestLevel, maxUses, efficiency, damage, enchantability);
|
||||
}
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.ItemInWorldManager;
|
||||
import net.minecraft.network.packet.Packet204ClientInfo;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.stats.StatBase;
|
||||
import net.minecraft.util.ChatMessageComponent;
|
||||
import net.minecraft.util.ChunkCoordinates;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
//Preliminary, simple Fake Player class
|
||||
public class FakePlayer extends EntityPlayer
|
||||
public class FakePlayer extends EntityPlayerMP
|
||||
{
|
||||
public FakePlayer(World world, String name)
|
||||
{
|
||||
super(world, name);
|
||||
super(FMLCommonHandler.instance().getMinecraftServerInstance(), world, name, new ItemInWorldManager(world));
|
||||
}
|
||||
|
||||
public void sendChatToPlayer(String s){}
|
||||
@@ -21,5 +28,21 @@ public class FakePlayer extends EntityPlayer
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_110122_a(ChatMessageComponent chatmessagecomponent){}
|
||||
public void sendChatToPlayer(ChatMessageComponent chatmessagecomponent){}
|
||||
@Override
|
||||
public void addStat(StatBase par1StatBase, int par2){}
|
||||
@Override
|
||||
public void openGui(Object mod, int modGuiId, World world, int x, int y, int z){}
|
||||
@Override
|
||||
public boolean isEntityInvulnerable(){ return true; }
|
||||
@Override
|
||||
public boolean canAttackPlayer(EntityPlayer player){ return false; }
|
||||
@Override
|
||||
public void onDeath(DamageSource source){ return; }
|
||||
@Override
|
||||
public void onUpdate(){ return; }
|
||||
@Override
|
||||
public void travelToDimension(int dim){ return; }
|
||||
@Override
|
||||
public void updateClientInfo(Packet204ClientInfo pkt){ return; }
|
||||
}
|
||||
@@ -5,14 +5,30 @@ import net.minecraft.world.World;
|
||||
//To be expanded for generic Mod fake players?
|
||||
public class FakePlayerFactory
|
||||
{
|
||||
// Map of all active fake player usernames to their entities
|
||||
private static java.util.Map<String, FakePlayer> fakePlayers = new java.util.HashMap<String, FakePlayer>();
|
||||
private static FakePlayer MINECRAFT_PLAYER = null;
|
||||
|
||||
public static FakePlayer getMinecraft(World world)
|
||||
{
|
||||
if (MINECRAFT_PLAYER == null)
|
||||
{
|
||||
MINECRAFT_PLAYER = new FakePlayer(world, "[Minecraft]");
|
||||
MINECRAFT_PLAYER = FakePlayerFactory.get(world, "[Minecraft]");
|
||||
}
|
||||
return MINECRAFT_PLAYER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a fake player with a given username
|
||||
*/
|
||||
public static FakePlayer get(World world, String username)
|
||||
{
|
||||
if (!fakePlayers.containsKey(username))
|
||||
{
|
||||
FakePlayer fakePlayer = new FakePlayer(world, username);
|
||||
fakePlayers.put(username, fakePlayer);
|
||||
}
|
||||
|
||||
return fakePlayers.get(username);
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,10 @@ import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.ForwardingSet;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.HashMultiset;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.ImmutableMultiset;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
@@ -34,6 +36,7 @@ import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import com.google.common.collect.Multiset;
|
||||
import com.google.common.collect.Multisets;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.TreeMultiset;
|
||||
@@ -813,7 +816,10 @@ public class ForgeChunkManager
|
||||
static void saveWorld(World world)
|
||||
{
|
||||
// only persist persistent worlds
|
||||
if (!(world instanceof WorldServer)) { return; }
|
||||
if (!(world instanceof WorldServer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
WorldServer worldServer = (WorldServer) world;
|
||||
File chunkDir = worldServer.getChunkSaveLocation();
|
||||
File chunkLoaderData = new File(chunkDir, "forcedchunks.dat");
|
||||
@@ -846,7 +852,7 @@ public class ForgeChunkManager
|
||||
{
|
||||
ticket.setCompoundTag("ModData", tick.modData);
|
||||
}
|
||||
if (tick.ticketType == Type.ENTITY && tick.entity != null && tick.entity.addEntityID(new NBTTagCompound()))
|
||||
if (tick.ticketType == Type.ENTITY && tick.entity != null && tick.entity.writeToNBTOptional(new NBTTagCompound()))
|
||||
{
|
||||
ticket.setInteger("chunkX", MathHelper.floor_double(tick.entity.chunkCoordX));
|
||||
ticket.setInteger("chunkZ", MathHelper.floor_double(tick.entity.chunkCoordZ));
|
||||
|
||||
@@ -10,14 +10,19 @@ import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.server.management.PlayerInstance;
|
||||
import net.minecraft.world.storage.SaveHandler;
|
||||
import net.minecraft.world.storage.WorldInfo;
|
||||
import net.minecraftforge.classloading.FMLForgePlugin;
|
||||
import net.minecraftforge.common.network.ForgeConnectionHandler;
|
||||
import net.minecraftforge.common.network.ForgeNetworkHandler;
|
||||
import net.minecraftforge.common.network.ForgePacketHandler;
|
||||
import net.minecraftforge.common.network.ForgeTinyPacketHandler;
|
||||
import net.minecraftforge.oredict.RecipeSorter;
|
||||
import net.minecraftforge.server.command.ForgeCommand;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import cpw.mods.fml.client.FMLFileResourcePack;
|
||||
import cpw.mods.fml.client.FMLFolderResourcePack;
|
||||
import cpw.mods.fml.common.DummyModContainer;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.LoadController;
|
||||
@@ -25,12 +30,14 @@ import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModMetadata;
|
||||
import cpw.mods.fml.common.WorldAccessContainer;
|
||||
import cpw.mods.fml.common.event.FMLConstructionEvent;
|
||||
import cpw.mods.fml.common.event.FMLLoadCompleteEvent;
|
||||
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStartingEvent;
|
||||
import cpw.mods.fml.common.network.FMLNetworkHandler;
|
||||
import cpw.mods.fml.common.network.NetworkMod;
|
||||
|
||||
import static net.minecraftforge.common.ForgeVersion.*;
|
||||
import static net.minecraftforge.common.Configuration.*;
|
||||
|
||||
@NetworkMod(
|
||||
channels = "FORGE",
|
||||
@@ -41,10 +48,15 @@ import static net.minecraftforge.common.ForgeVersion.*;
|
||||
public class ForgeDummyContainer extends DummyModContainer implements WorldAccessContainer
|
||||
{
|
||||
public static int clumpingThreshold = 64;
|
||||
public static boolean legacyFurnaceSides = false;
|
||||
public static boolean removeErroringEntities = false;
|
||||
public static boolean removeErroringTileEntities = false;
|
||||
public static boolean disableStitchedFileSaving = false;
|
||||
public static boolean forceDuplicateFluidBlockCrash = true;
|
||||
public static boolean fullBoundingBoxLadders = false;
|
||||
public static double zombieSummonBaseChance = 0.1;
|
||||
public static int[] blendRanges = { 20, 15, 10, 5 };
|
||||
public static float zombieBabyChance = 0.05f;
|
||||
public static boolean shouldSortRecipies = false;
|
||||
|
||||
public ForgeDummyContainer()
|
||||
{
|
||||
@@ -98,17 +110,13 @@ public class ForgeDummyContainer extends DummyModContainer implements WorldAcces
|
||||
prop.set(64);
|
||||
}
|
||||
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "legacyFurnaceOutput", false);
|
||||
prop.comment = "Controls the sides of vanilla furnaces for Forge's ISidedInventroy, Vanilla defines the output as the bottom, but mods/Forge define it as the sides. Settings this to true will restore the old side relations.";
|
||||
legacyFurnaceSides = prop.getBoolean(false);
|
||||
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "removeErroringEntities", false);
|
||||
prop.comment = "Set this to just remove any TileEntity that throws a error in there update method instead of closing the server and reporting a crash log. BE WARNED THIS COULD SCREW UP EVERYTHING USE SPARINGLY WE ARE NOT RESPONSIBLE FOR DAMAGES.";
|
||||
removeErroringEntities = prop.getBoolean(false);
|
||||
|
||||
if (removeErroringEntities)
|
||||
{
|
||||
FMLLog.warning("Enableing removal of erroring Entities USE AT YOUR OWN RISK");
|
||||
FMLLog.warning("Enabling removal of erroring Entities - USE AT YOUR OWN RISK");
|
||||
}
|
||||
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "removeErroringTileEntities", false);
|
||||
@@ -117,12 +125,41 @@ public class ForgeDummyContainer extends DummyModContainer implements WorldAcces
|
||||
|
||||
if (removeErroringTileEntities)
|
||||
{
|
||||
FMLLog.warning("Enableing removal of erroring Tile Entities USE AT YOUR OWN RISK");
|
||||
FMLLog.warning("Enabling removal of erroring Tile Entities - USE AT YOUR OWN RISK");
|
||||
}
|
||||
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "disableStitchedFileSaving", true);
|
||||
prop.comment = "Set this to just disable the texture stitcher from writing the 'debug.stitched_{name}.png file to disc. Just a small performance tweak. Default: true";
|
||||
disableStitchedFileSaving = prop.getBoolean(true);
|
||||
//prop = config.get(Configuration.CATEGORY_GENERAL, "disableStitchedFileSaving", true);
|
||||
//prop.comment = "Set this to just disable the texture stitcher from writing the 'debug.stitched_{name}.png file to disc. Just a small performance tweak. Default: true";
|
||||
//disableStitchedFileSaving = prop.getBoolean(true);
|
||||
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "fullBoundingBoxLadders", false);
|
||||
prop.comment = "Set this to check the entire entity's collision bounding box for ladders instead of just the block they are in. Causes noticable differences in mechanics so default is vanilla behavior. Default: false";
|
||||
fullBoundingBoxLadders = prop.getBoolean(false);
|
||||
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "forceDuplicateFluidBlockCrash", true);
|
||||
prop.comment = "Set this to force a crash if more than one block attempts to link back to the same Fluid. Enabled by default.";
|
||||
forceDuplicateFluidBlockCrash = prop.getBoolean(true);
|
||||
|
||||
if (!forceDuplicateFluidBlockCrash)
|
||||
{
|
||||
FMLLog.warning("Disabling forced crashes on duplicate Fluid Blocks - USE AT YOUR OWN RISK");
|
||||
}
|
||||
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "biomeSkyBlendRange", new int[] { 20, 15, 10, 5 });
|
||||
prop.comment = "Control the range of sky blending for colored skies in biomes.";
|
||||
blendRanges = prop.getIntList();
|
||||
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "zombieBaseSummonChance", 0.1);
|
||||
prop.comment = "Base zombie summoning spawn chance. Allows changing the bonus zombie summoning mechanic.";
|
||||
zombieSummonBaseChance = prop.getDouble(0.1);
|
||||
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "zombieBabyChance", 0.05);
|
||||
prop.comment = "Chance that a zombie (or subclass) is a baby. Allows changing the zombie spawning mechanic.";
|
||||
zombieBabyChance = (float) prop.getDouble(0.05);
|
||||
|
||||
prop = config.get(CATEGORY_GENERAL, "sortRecipies", shouldSortRecipies);
|
||||
prop.comment = "Set to true to enable the post initlization sorting of crafting recipes using Froge's sorter. May cause desyncing on conflicting recipies. ToDo: Set to true by default in 1.7";
|
||||
shouldSortRecipies = prop.getBoolean(shouldSortRecipies);
|
||||
|
||||
if (config.hasChanged())
|
||||
{
|
||||
@@ -133,7 +170,7 @@ public class ForgeDummyContainer extends DummyModContainer implements WorldAcces
|
||||
@Override
|
||||
public boolean registerBus(EventBus bus, LoadController controller)
|
||||
{
|
||||
bus.register(this);
|
||||
bus.register(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -161,9 +198,24 @@ public class ForgeDummyContainer extends DummyModContainer implements WorldAcces
|
||||
@Subscribe
|
||||
public void postInit(FMLPostInitializationEvent evt)
|
||||
{
|
||||
ForgeChunkManager.loadConfiguration();
|
||||
BiomeDictionary.registerAllBiomesAndGenerateEvents();
|
||||
ForgeChunkManager.loadConfiguration();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onAvalible(FMLLoadCompleteEvent evt)
|
||||
{
|
||||
if (shouldSortRecipies)
|
||||
{
|
||||
RecipeSorter.sortCraftManager();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void serverStarting(FMLServerStartingEvent evt)
|
||||
{
|
||||
evt.registerServerCommand(new ForgeCommand(evt.getServer()));
|
||||
}
|
||||
@Override
|
||||
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info)
|
||||
{
|
||||
@@ -181,4 +233,22 @@ public class ForgeDummyContainer extends DummyModContainer implements WorldAcces
|
||||
DimensionManager.loadDimensionDataMap(tag.hasKey("DimensionData") ? tag.getCompoundTag("DimensionData") : null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getSource()
|
||||
{
|
||||
return FMLForgePlugin.forgeLocation;
|
||||
}
|
||||
@Override
|
||||
public Class<?> getCustomResourcePackClass()
|
||||
{
|
||||
if (getSource().isDirectory())
|
||||
{
|
||||
return FMLFolderResourcePack.class;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FMLFileResourcePack.class;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,24 +7,35 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemArmor;
|
||||
import net.minecraft.item.ItemAxe;
|
||||
import net.minecraft.item.ItemPickaxe;
|
||||
import net.minecraft.item.ItemSpade;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemSword;
|
||||
import net.minecraft.network.NetServerHandler;
|
||||
import net.minecraft.network.packet.Packet;
|
||||
import net.minecraft.network.packet.Packet53BlockChange;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.ChatMessageComponent;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.EnumMovingObjectType;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.util.WeightedRandom;
|
||||
import net.minecraft.util.WeightedRandomItem;
|
||||
import net.minecraft.world.EnumGameType;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.event.Event;
|
||||
import net.minecraftforge.event.ForgeEventFactory;
|
||||
import net.minecraftforge.event.ServerChatEvent;
|
||||
import net.minecraftforge.event.entity.item.ItemTossEvent;
|
||||
@@ -36,6 +47,8 @@ import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingFallEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingHurtEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerOpenContainerEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
|
||||
public class ForgeHooks
|
||||
{
|
||||
@@ -353,7 +366,32 @@ public class ForgeHooks
|
||||
|
||||
public static boolean isLivingOnLadder(Block block, World world, int x, int y, int z, EntityLivingBase entity)
|
||||
{
|
||||
return block != null && block.isLadder(world, x, y, z, entity);
|
||||
if (!ForgeDummyContainer.fullBoundingBoxLadders)
|
||||
{
|
||||
return block != null && block.isLadder(world, x, y, z, entity);
|
||||
}
|
||||
else
|
||||
{
|
||||
AxisAlignedBB bb = entity.boundingBox;
|
||||
int mX = MathHelper.floor_double(bb.minX);
|
||||
int mY = MathHelper.floor_double(bb.minY);
|
||||
int mZ = MathHelper.floor_double(bb.minZ);
|
||||
for (int y2 = mY; y2 < bb.maxY; y2++)
|
||||
{
|
||||
for (int x2 = mX; x2 < bb.maxX; x2++)
|
||||
{
|
||||
for (int z2 = mZ; z2 < bb.maxZ; z2++)
|
||||
{
|
||||
block = Block.blocksList[world.getBlockId(x2, y2, z2)];
|
||||
if (block != null && block.isLadder(world, x2, y2, z2, entity))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void onLivingJump(EntityLivingBase entity)
|
||||
@@ -368,6 +406,11 @@ public class ForgeHooks
|
||||
player.capturedDrops.clear();
|
||||
player.captureDrops = false;
|
||||
|
||||
if (ret == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ItemTossEvent event = new ItemTossEvent(ret, player);
|
||||
if (MinecraftForge.EVENT_BUS.post(event))
|
||||
{
|
||||
@@ -398,4 +441,60 @@ public class ForgeHooks
|
||||
}
|
||||
return event.component;
|
||||
}
|
||||
|
||||
public static boolean canInteractWith(EntityPlayer player, Container openContainer)
|
||||
{
|
||||
PlayerOpenContainerEvent event = new PlayerOpenContainerEvent(player, openContainer);
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
return event.getResult() == Event.Result.DEFAULT ? event.canInteractWith : event.getResult() == Event.Result.ALLOW ? true : false;
|
||||
}
|
||||
|
||||
public static BlockEvent.BreakEvent onBlockBreakEvent(World world, EnumGameType gameType, EntityPlayerMP entityPlayer, int x, int y, int z)
|
||||
{
|
||||
// Logic from tryHarvestBlock for pre-canceling the event
|
||||
boolean preCancelEvent = false;
|
||||
if (gameType.isAdventure() && !entityPlayer.isCurrentToolAdventureModeExempt(x, y, z))
|
||||
{
|
||||
preCancelEvent = true;
|
||||
}
|
||||
else if (gameType.isCreative() && entityPlayer.getHeldItem() != null && entityPlayer.getHeldItem().getItem() instanceof ItemSword)
|
||||
{
|
||||
preCancelEvent = true;
|
||||
}
|
||||
|
||||
// Tell client the block is gone immediately then process events
|
||||
if (world.getBlockTileEntity(x, y, z) == null)
|
||||
{
|
||||
Packet53BlockChange packet = new Packet53BlockChange(x, y, z, world);
|
||||
packet.type = 0;
|
||||
packet.metadata = 0;
|
||||
entityPlayer.playerNetServerHandler.sendPacketToPlayer(packet);
|
||||
}
|
||||
|
||||
// Post the block break event
|
||||
Block block = Block.blocksList[world.getBlockId(x, y, z)];
|
||||
int blockMetadata = world.getBlockMetadata(x, y, z);
|
||||
BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(x, y, z, world, block, blockMetadata, entityPlayer);
|
||||
event.setCanceled(preCancelEvent);
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
|
||||
// Handle if the event is canceled
|
||||
if (event.isCanceled())
|
||||
{
|
||||
// Let the client know the block still exists
|
||||
entityPlayer.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(x, y, z, world));
|
||||
|
||||
// Update any tile entity data for this block
|
||||
TileEntity tileentity = world.getBlockTileEntity(x, y, z);
|
||||
if (tileentity != null)
|
||||
{
|
||||
Packet pkt = tileentity.getDescriptionPacket();
|
||||
if (pkt != null)
|
||||
{
|
||||
entityPlayer.playerNetServerHandler.sendPacketToPlayer(pkt);
|
||||
}
|
||||
}
|
||||
}
|
||||
return event;
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,11 @@ package net.minecraftforge.common;
|
||||
public class ForgeVersion
|
||||
{
|
||||
//This number is incremented every time we remove deprecated code/major API changes, never reset
|
||||
public static final int majorVersion = 8;
|
||||
public static final int majorVersion = 9;
|
||||
//This number is incremented every minecraft release, never reset
|
||||
public static final int minorVersion = 9;
|
||||
public static final int minorVersion = 11;
|
||||
//This number is incremented every time a interface changes or new major feature is added, and reset every Minecraft version
|
||||
public static final int revisionVersion = 0;
|
||||
public static final int revisionVersion = 1;
|
||||
//This number is incremented every time Jenkins builds Forge, and never reset. Should always be 0 in the repo code.
|
||||
public static final int buildVersion = 0;
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* This software is provided under the terms of the Minecraft Forge Public
|
||||
* License v1.0.
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import net.minecraft.inventory.IInventory;
|
||||
|
||||
/** Inventory ranges mapped by side. This class is implemented by TileEntities
|
||||
* that provide different inventory slot ranges to different sides.
|
||||
*/
|
||||
@Deprecated //A equivalent Interface is now in Minecraft Vanilla will be removed next major MC version
|
||||
public interface ISidedInventory extends IInventory
|
||||
{
|
||||
|
||||
/**
|
||||
* Get the start of the side inventory.
|
||||
* @param side The global side to get the start of range.
|
||||
*/
|
||||
@Deprecated
|
||||
int getStartInventorySide(ForgeDirection side);
|
||||
|
||||
/**
|
||||
* Get the size of the side inventory.
|
||||
* @param side The global side.
|
||||
*/
|
||||
@Deprecated
|
||||
int getSizeInventorySide(ForgeDirection side);
|
||||
}
|
||||
|
||||
@@ -187,7 +187,9 @@ public class MinecraftForge
|
||||
|
||||
Block filler = new Block(0, Material.air)
|
||||
{
|
||||
@SideOnly(Side.CLIENT) public void func_94332_a(IconRegister register){}
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void registerIcons(IconRegister register){}
|
||||
};
|
||||
Block.blocksList[0] = null;
|
||||
Block.opaqueCubeLookup[0] = false;
|
||||
|
||||
@@ -1,19 +1,82 @@
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockAnvil;
|
||||
import net.minecraft.block.BlockBed;
|
||||
import net.minecraft.block.BlockButton;
|
||||
import net.minecraft.block.BlockChest;
|
||||
import net.minecraft.block.BlockCocoa;
|
||||
import net.minecraft.block.BlockComparator;
|
||||
import net.minecraft.block.BlockDetectorRail;
|
||||
import net.minecraft.block.BlockDispenser;
|
||||
import net.minecraft.block.BlockDropper;
|
||||
import net.minecraft.block.BlockDoor;
|
||||
import net.minecraft.block.BlockEndPortalFrame;
|
||||
import net.minecraft.block.BlockEnderChest;
|
||||
import net.minecraft.block.BlockFenceGate;
|
||||
import net.minecraft.block.BlockFurnace;
|
||||
import net.minecraft.block.BlockHopper;
|
||||
import net.minecraft.block.BlockLadder;
|
||||
import net.minecraft.block.BlockLever;
|
||||
import net.minecraft.block.BlockLog;
|
||||
import net.minecraft.block.BlockMushroomCap;
|
||||
import net.minecraft.block.BlockPistonBase;
|
||||
import net.minecraft.block.BlockPistonExtension;
|
||||
import net.minecraft.block.BlockPumpkin;
|
||||
import net.minecraft.block.BlockRail;
|
||||
import net.minecraft.block.BlockRailPowered;
|
||||
import net.minecraft.block.BlockRedstoneRepeater;
|
||||
import net.minecraft.block.BlockSkull;
|
||||
import net.minecraft.block.BlockStairs;
|
||||
import net.minecraft.block.BlockTorch;
|
||||
import net.minecraft.block.BlockTrapDoor;
|
||||
import net.minecraft.block.BlockTripWireSource;
|
||||
import net.minecraft.block.BlockVine;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static net.minecraftforge.common.ForgeDirection.*;
|
||||
|
||||
public class RotationHelper {
|
||||
/**
|
||||
* Some blocks have the same rotation.
|
||||
* The first of these blocks (sorted by itemID) should be listed as a type.
|
||||
* Some of the types aren't actual blocks (helper types).
|
||||
*/
|
||||
private static enum BlockType {
|
||||
LOG,
|
||||
DISPENSER,
|
||||
BED,
|
||||
RAIL,
|
||||
RAIL_POWERED,
|
||||
RAIL_ASCENDING,
|
||||
RAIL_CORNER,
|
||||
TORCH,
|
||||
STAIR,
|
||||
CHEST,
|
||||
SIGNPOST,
|
||||
DOOR,
|
||||
LEVER,
|
||||
BUTTON,
|
||||
REDSTONE_REPEATER,
|
||||
TRAPDOOR,
|
||||
MUSHROOM_CAP,
|
||||
MUSHROOM_CAP_CORNER,
|
||||
MUSHROOM_CAP_SIDE,
|
||||
VINE,
|
||||
SKULL,
|
||||
ANVIL
|
||||
}
|
||||
|
||||
private static final ForgeDirection[] UP_DOWN_AXES = new ForgeDirection[] { UP, DOWN };
|
||||
private static final Map<BlockType, BiMap<Integer, ForgeDirection>> MAPPINGS = new HashMap<BlockType, BiMap<Integer, ForgeDirection>>();
|
||||
|
||||
public static ForgeDirection[] getValidVanillaBlockRotations(Block block)
|
||||
{
|
||||
return block instanceof BlockChest ? UP_DOWN_AXES : VALID_DIRECTIONS;
|
||||
return (block instanceof BlockBed || block instanceof BlockPumpkin || block instanceof BlockFenceGate || block instanceof BlockEndPortalFrame || block instanceof BlockTripWireSource || block instanceof BlockCocoa || block instanceof BlockRailPowered || block instanceof BlockDetectorRail || block instanceof BlockStairs || block instanceof BlockChest || block instanceof BlockEnderChest || block instanceof BlockFurnace || block instanceof BlockLadder || block.blockID == Block.signWall.blockID || block.blockID == Block.signPost.blockID || block instanceof BlockDoor || block instanceof BlockRail || block instanceof BlockButton || block instanceof BlockRedstoneRepeater || block instanceof BlockComparator || block instanceof BlockTrapDoor || block instanceof BlockMushroomCap || block instanceof BlockVine || block instanceof BlockSkull || block instanceof BlockAnvil) ? UP_DOWN_AXES : VALID_DIRECTIONS;
|
||||
}
|
||||
|
||||
public static boolean rotateVanillaBlock(Block block, World worldObj, int x, int y, int z, ForgeDirection axis)
|
||||
@@ -23,25 +86,323 @@ public class RotationHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (block instanceof BlockChest && (axis == UP || axis == DOWN))
|
||||
if (axis == UP || axis == DOWN)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0x7);
|
||||
if (block instanceof BlockBed || block instanceof BlockPumpkin || block instanceof BlockFenceGate || block instanceof BlockEndPortalFrame || block instanceof BlockTripWireSource || block instanceof BlockCocoa)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0x3, BlockType.BED);
|
||||
}
|
||||
if (block instanceof BlockRail)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0xF, BlockType.RAIL);
|
||||
}
|
||||
if (block instanceof BlockRailPowered || block instanceof BlockDetectorRail)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.RAIL_POWERED);
|
||||
}
|
||||
if (block instanceof BlockStairs)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0x3, BlockType.STAIR);
|
||||
}
|
||||
if (block instanceof BlockChest || block instanceof BlockEnderChest || block instanceof BlockFurnace || block instanceof BlockLadder || block.blockID == Block.signWall.blockID)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.CHEST);
|
||||
}
|
||||
if (block.blockID == Block.signPost.blockID)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0xF, BlockType.SIGNPOST);
|
||||
}
|
||||
if (block instanceof BlockDoor)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0x3, BlockType.DOOR);
|
||||
}
|
||||
if (block instanceof BlockButton)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.BUTTON);
|
||||
}
|
||||
if (block instanceof BlockRedstoneRepeater || block instanceof BlockComparator)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0x3, BlockType.REDSTONE_REPEATER);
|
||||
}
|
||||
if (block instanceof BlockTrapDoor)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0x3, BlockType.TRAPDOOR);
|
||||
}
|
||||
if (block instanceof BlockMushroomCap)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0xF, BlockType.MUSHROOM_CAP);
|
||||
}
|
||||
if (block instanceof BlockVine)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0xF, BlockType.VINE);
|
||||
}
|
||||
if (block instanceof BlockSkull)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.SKULL);
|
||||
}
|
||||
if (block instanceof BlockAnvil)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0x1, BlockType.ANVIL);
|
||||
}
|
||||
}
|
||||
if (block instanceof BlockPistonBase || block instanceof BlockDropper || block instanceof BlockDispenser)
|
||||
|
||||
if (block instanceof BlockLog)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0x7);
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0xC, BlockType.LOG);
|
||||
}
|
||||
if (block instanceof BlockDispenser || block instanceof BlockPistonBase || block instanceof BlockPistonExtension || block instanceof BlockHopper)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.DISPENSER);
|
||||
}
|
||||
if (block instanceof BlockTorch)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0xF, BlockType.TORCH);
|
||||
}
|
||||
if (block instanceof BlockLever)
|
||||
{
|
||||
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.LEVER);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean rotateBlock(World worldObj, int x, int y, int z, ForgeDirection axis, int mask)
|
||||
private static boolean rotateBlock(World worldObj, int x, int y, int z, ForgeDirection axis, int mask, BlockType blockType)
|
||||
{
|
||||
int rotMeta = worldObj.getBlockMetadata(x, y, z);
|
||||
if (blockType == BlockType.DOOR && (rotMeta & 0x8) == 0x8)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int masked = rotMeta & ~mask;
|
||||
ForgeDirection orientation = ForgeDirection.getOrientation(rotMeta & mask);
|
||||
ForgeDirection rotated = orientation.getRotation(axis);
|
||||
worldObj.setBlockMetadataWithNotify(x,y,z,rotated.ordinal() & mask | masked,3);
|
||||
int meta = rotateMetadata(axis, blockType, rotMeta & mask);
|
||||
if (meta == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
worldObj.setBlockMetadataWithNotify(x, y, z, meta & mask | masked, 3);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static int rotateMetadata(ForgeDirection axis, BlockType blockType, int meta)
|
||||
{
|
||||
if (blockType == BlockType.RAIL || blockType == BlockType.RAIL_POWERED)
|
||||
{
|
||||
if (meta == 0x0 || meta == 0x1)
|
||||
{
|
||||
return ~meta & 0x1;
|
||||
}
|
||||
if (meta >= 0x2 && meta <= 0x5)
|
||||
{
|
||||
blockType = BlockType.RAIL_ASCENDING;
|
||||
}
|
||||
if (meta >= 0x6 && meta <= 0x9 && blockType == BlockType.RAIL)
|
||||
{
|
||||
blockType = BlockType.RAIL_CORNER;
|
||||
}
|
||||
}
|
||||
if (blockType == BlockType.SIGNPOST)
|
||||
{
|
||||
return (axis == UP) ? (meta + 0x4) % 0x10 : (meta + 0xC) % 0x10;
|
||||
}
|
||||
if (blockType == BlockType.LEVER && (axis == UP || axis == DOWN))
|
||||
{
|
||||
switch (meta)
|
||||
{
|
||||
case 0x5:
|
||||
return 0x6;
|
||||
case 0x6:
|
||||
return 0x5;
|
||||
case 0x7:
|
||||
return 0x0;
|
||||
case 0x0:
|
||||
return 0x7;
|
||||
}
|
||||
}
|
||||
if (blockType == BlockType.MUSHROOM_CAP)
|
||||
{
|
||||
if (meta % 0x2 == 0)
|
||||
{
|
||||
blockType = BlockType.MUSHROOM_CAP_SIDE;
|
||||
}
|
||||
else
|
||||
{
|
||||
blockType = BlockType.MUSHROOM_CAP_CORNER;
|
||||
}
|
||||
}
|
||||
if (blockType == BlockType.VINE)
|
||||
{
|
||||
return ((meta << 1) | ((meta & 0x8) >> 3));
|
||||
}
|
||||
|
||||
ForgeDirection orientation = metadataToDirection(blockType, meta);
|
||||
ForgeDirection rotated = orientation.getRotation(axis);
|
||||
return directionToMetadata(blockType, rotated);
|
||||
}
|
||||
|
||||
private static ForgeDirection metadataToDirection(BlockType blockType, int meta)
|
||||
{
|
||||
if (blockType == BlockType.LEVER)
|
||||
{
|
||||
if (meta == 0x6)
|
||||
{
|
||||
meta = 0x5;
|
||||
}
|
||||
else if (meta == 0x0)
|
||||
{
|
||||
meta = 0x7;
|
||||
}
|
||||
}
|
||||
|
||||
if (MAPPINGS.containsKey(blockType))
|
||||
{
|
||||
BiMap<Integer, ForgeDirection> biMap = MAPPINGS.get(blockType);
|
||||
if (biMap.containsKey(meta))
|
||||
{
|
||||
return biMap.get(meta);
|
||||
}
|
||||
}
|
||||
|
||||
if (blockType == BlockType.TORCH)
|
||||
{
|
||||
return ForgeDirection.getOrientation(6 - meta);
|
||||
}
|
||||
if (blockType == BlockType.STAIR)
|
||||
{
|
||||
return ForgeDirection.getOrientation(5 - meta);
|
||||
}
|
||||
if (blockType == BlockType.CHEST || blockType == BlockType.DISPENSER || blockType == BlockType.SKULL)
|
||||
{
|
||||
return ForgeDirection.getOrientation(meta);
|
||||
}
|
||||
if (blockType == BlockType.BUTTON)
|
||||
{
|
||||
return ForgeDirection.getOrientation(6 - meta);
|
||||
}
|
||||
if (blockType == BlockType.TRAPDOOR)
|
||||
{
|
||||
return ForgeDirection.getOrientation(meta + 2).getOpposite();
|
||||
}
|
||||
|
||||
return ForgeDirection.UNKNOWN;
|
||||
}
|
||||
|
||||
private static int directionToMetadata(BlockType blockType, ForgeDirection direction)
|
||||
{
|
||||
if ((blockType == BlockType.LOG || blockType == BlockType.ANVIL) && (direction.offsetX + direction.offsetY + direction.offsetZ) < 0)
|
||||
{
|
||||
direction = direction.getOpposite();
|
||||
}
|
||||
|
||||
if (MAPPINGS.containsKey(blockType))
|
||||
{
|
||||
BiMap<ForgeDirection, Integer> biMap = MAPPINGS.get(blockType).inverse();
|
||||
if (biMap.containsKey(direction))
|
||||
{
|
||||
return biMap.get(direction);
|
||||
}
|
||||
}
|
||||
|
||||
if (blockType == BlockType.TORCH)
|
||||
{
|
||||
if (direction.ordinal() >= 1)
|
||||
{
|
||||
return 6 - direction.ordinal();
|
||||
}
|
||||
}
|
||||
if (blockType == BlockType.STAIR)
|
||||
{
|
||||
return 5 - direction.ordinal();
|
||||
}
|
||||
if (blockType == BlockType.CHEST || blockType == BlockType.DISPENSER || blockType == BlockType.SKULL)
|
||||
{
|
||||
return direction.ordinal();
|
||||
}
|
||||
if (blockType == BlockType.BUTTON)
|
||||
{
|
||||
if (direction.ordinal() >= 2)
|
||||
{
|
||||
return 6 - direction.ordinal();
|
||||
}
|
||||
}
|
||||
if (blockType == BlockType.TRAPDOOR)
|
||||
{
|
||||
return direction.getOpposite().ordinal() - 2;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
BiMap<Integer, ForgeDirection> biMap;
|
||||
|
||||
biMap = HashBiMap.create(3);
|
||||
biMap.put(0x0, UP);
|
||||
biMap.put(0x4, EAST);
|
||||
biMap.put(0x8, SOUTH);
|
||||
MAPPINGS.put(BlockType.LOG, biMap);
|
||||
|
||||
biMap = HashBiMap.create(4);
|
||||
biMap.put(0x0, SOUTH);
|
||||
biMap.put(0x1, WEST);
|
||||
biMap.put(0x2, NORTH);
|
||||
biMap.put(0x3, EAST);
|
||||
MAPPINGS.put(BlockType.BED, biMap);
|
||||
|
||||
biMap = HashBiMap.create(4);
|
||||
biMap.put(0x2, EAST);
|
||||
biMap.put(0x3, WEST);
|
||||
biMap.put(0x4, NORTH);
|
||||
biMap.put(0x5, SOUTH);
|
||||
MAPPINGS.put(BlockType.RAIL_ASCENDING, biMap);
|
||||
|
||||
biMap = HashBiMap.create(4);
|
||||
biMap.put(0x6, WEST);
|
||||
biMap.put(0x7, NORTH);
|
||||
biMap.put(0x8, EAST);
|
||||
biMap.put(0x9, SOUTH);
|
||||
MAPPINGS.put(BlockType.RAIL_CORNER, biMap);
|
||||
|
||||
biMap = HashBiMap.create(6);
|
||||
biMap.put(0x1, EAST);
|
||||
biMap.put(0x2, WEST);
|
||||
biMap.put(0x3, SOUTH);
|
||||
biMap.put(0x4, NORTH);
|
||||
biMap.put(0x5, UP);
|
||||
biMap.put(0x7, DOWN);
|
||||
MAPPINGS.put(BlockType.LEVER, biMap);
|
||||
|
||||
biMap = HashBiMap.create(4);
|
||||
biMap.put(0x0, WEST);
|
||||
biMap.put(0x1, NORTH);
|
||||
biMap.put(0x2, EAST);
|
||||
biMap.put(0x3, SOUTH);
|
||||
MAPPINGS.put(BlockType.DOOR, biMap);
|
||||
|
||||
biMap = HashBiMap.create(4);
|
||||
biMap.put(0x0, NORTH);
|
||||
biMap.put(0x1, EAST);
|
||||
biMap.put(0x2, SOUTH);
|
||||
biMap.put(0x3, WEST);
|
||||
MAPPINGS.put(BlockType.REDSTONE_REPEATER, biMap);
|
||||
|
||||
biMap = HashBiMap.create(4);
|
||||
biMap.put(0x1, EAST);
|
||||
biMap.put(0x3, SOUTH);
|
||||
biMap.put(0x7, NORTH);
|
||||
biMap.put(0x9, WEST);
|
||||
MAPPINGS.put(BlockType.MUSHROOM_CAP_CORNER, biMap);
|
||||
|
||||
biMap = HashBiMap.create(4);
|
||||
biMap.put(0x2, NORTH);
|
||||
biMap.put(0x4, WEST);
|
||||
biMap.put(0x6, EAST);
|
||||
biMap.put(0x8, SOUTH);
|
||||
MAPPINGS.put(BlockType.MUSHROOM_CAP_SIDE, biMap);
|
||||
|
||||
biMap = HashBiMap.create(2);
|
||||
biMap.put(0x0, SOUTH);
|
||||
biMap.put(0x1, EAST);
|
||||
MAPPINGS.put(BlockType.ANVIL, biMap);
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,11 @@ import net.minecraft.network.INetworkManager;
|
||||
import net.minecraft.network.NetLoginHandler;
|
||||
import net.minecraft.network.packet.NetHandler;
|
||||
import net.minecraft.network.packet.Packet1Login;
|
||||
import net.minecraft.network.packet.Packet250CustomPayload;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraftforge.fluids.FluidIdMapPacket;
|
||||
import cpw.mods.fml.common.network.IConnectionHandler;
|
||||
import cpw.mods.fml.common.network.PacketDispatcher;
|
||||
import cpw.mods.fml.common.network.Player;
|
||||
|
||||
public class ForgeConnectionHandler implements IConnectionHandler {
|
||||
@@ -13,7 +16,10 @@ public class ForgeConnectionHandler implements IConnectionHandler {
|
||||
@Override
|
||||
public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager)
|
||||
{
|
||||
|
||||
Packet250CustomPayload[] fluidPackets = ForgePacket.makePacketSet(new FluidIdMapPacket());
|
||||
for (int i = 0; i < fluidPackets.length; i++) {
|
||||
PacketDispatcher.sendPacketToPlayer(fluidPackets[i], player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.minecraft.network.INetworkManager;
|
||||
import net.minecraft.network.packet.NetHandler;
|
||||
import net.minecraft.network.packet.Packet250CustomPayload;
|
||||
import net.minecraftforge.common.network.packet.DimensionRegisterPacket;
|
||||
import net.minecraftforge.fluids.FluidIdMapPacket;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.MapMaker;
|
||||
@@ -29,7 +30,11 @@ public abstract class ForgePacket
|
||||
/**
|
||||
* Registers a dimension for a provider on client
|
||||
*/
|
||||
REGISTERDIMENSION(DimensionRegisterPacket.class);
|
||||
REGISTERDIMENSION(DimensionRegisterPacket.class),
|
||||
/**
|
||||
* The Fluid ID map to send to the client
|
||||
*/
|
||||
FLUID_IDMAP(FluidIdMapPacket.class);
|
||||
|
||||
private Class<? extends ForgePacket> packetType;
|
||||
private ConcurrentMap<INetworkManager, ForgePacket> partTracker;
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package net.minecraftforge.event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.EnumCreatureType;
|
||||
import net.minecraft.entity.monster.EntityZombie;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
@@ -13,10 +16,14 @@ import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.Event.Result;
|
||||
import net.minecraftforge.event.entity.living.LivingPackSizeEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingSpawnEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingSpawnEvent.AllowDespawn;
|
||||
import net.minecraftforge.event.entity.living.ZombieEvent.SummonAidEvent;
|
||||
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@@ -59,6 +66,13 @@ public class ForgeEventFactory
|
||||
return MinecraftForge.EVENT_BUS.post(new LivingSpawnEvent.SpecialSpawn(entity, world, x, y, z));
|
||||
}
|
||||
|
||||
public static Result canEntityDespawn(EntityLiving entity)
|
||||
{
|
||||
AllowDespawn event = new AllowDespawn(entity);
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
return event.getResult();
|
||||
}
|
||||
|
||||
public static List getPotentialSpawns(WorldServer world, EnumCreatureType type, int x, int y, int z, List oldList)
|
||||
{
|
||||
WorldEvent.PotentialSpawns event = new WorldEvent.PotentialSpawns(world, type, x, y, z, oldList);
|
||||
@@ -75,4 +89,32 @@ public class ForgeEventFactory
|
||||
MinecraftForge.EVENT_BUS.post(maxCanSpawnEvent);
|
||||
return maxCanSpawnEvent.getResult() == Result.ALLOW ? maxCanSpawnEvent.maxPackSize : entity.getMaxSpawnedInChunk();
|
||||
}
|
||||
|
||||
public static String getPlayerDisplayName(EntityPlayer player, String username)
|
||||
{
|
||||
PlayerEvent.NameFormat event = new PlayerEvent.NameFormat(player, username);
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
return event.displayname;
|
||||
}
|
||||
|
||||
public static float fireBlockHarvesting(ArrayList<ItemStack> drops, World world, Block block, int x, int y, int z, int meta, int fortune, float dropChance, boolean silkTouch, EntityPlayer player)
|
||||
{
|
||||
BlockEvent.HarvestDropsEvent event = new BlockEvent.HarvestDropsEvent(x, y, z, world, block, meta, fortune, dropChance, drops, player, silkTouch);
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
return event.dropChance;
|
||||
}
|
||||
|
||||
public static ItemTooltipEvent onItemTooltip(ItemStack itemStack, EntityPlayer entityPlayer, List<String> toolTip, boolean showAdvancedItemTooltips)
|
||||
{
|
||||
ItemTooltipEvent event = new ItemTooltipEvent(itemStack, entityPlayer, toolTip, showAdvancedItemTooltips);
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
public static SummonAidEvent fireZombieSummonAid(EntityZombie zombie, World world, int x, int y, int z, EntityLivingBase attacker, double summonChance)
|
||||
{
|
||||
SummonAidEvent summonEvent = new SummonAidEvent(zombie, world, x, y, z, attacker, summonChance);
|
||||
MinecraftForge.EVENT_BUS.post(summonEvent);
|
||||
return summonEvent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package net.minecraftforge.event.entity;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.effect.EntityLightningBolt;
|
||||
import net.minecraftforge.event.Cancelable;
|
||||
|
||||
@Cancelable
|
||||
public class EntityStruckByLightningEvent extends EntityEvent
|
||||
{
|
||||
public final EntityLightningBolt lightning;
|
||||
|
||||
public EntityStruckByLightningEvent(Entity entity, EntityLightningBolt lightning)
|
||||
{
|
||||
super(entity);
|
||||
this.lightning = lightning;
|
||||
}
|
||||
}
|
||||
@@ -47,4 +47,27 @@ public class LivingSpawnEvent extends LivingEvent
|
||||
super(entity, world, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired each tick for despawnable mobs to allow control over despawning.
|
||||
* {@link Result#DEFAULT} will pass the mob on to vanilla despawn mechanics.
|
||||
* {@link Result#ALLOW} will force the mob to despawn.
|
||||
* {@link Result#DENY} will force the mob to remain.
|
||||
* This is fired every tick for every despawnable entity. Be efficient in your handlers.
|
||||
*
|
||||
* Note: this is not fired <em>if</em> the mob is definitely going to otherwise despawn. It is fired to check if
|
||||
* the mob can be allowed to despawn. See {@link EntityLiving#despawnEntity}
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@HasResult
|
||||
public static class AllowDespawn extends LivingSpawnEvent
|
||||
{
|
||||
public AllowDespawn(EntityLiving entity)
|
||||
{
|
||||
super(entity, entity.worldObj, (float)entity.posX, (float)entity.posY, (float)entity.posZ);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package net.minecraftforge.event.entity.living;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.monster.EntityZombie;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.event.Cancelable;
|
||||
import net.minecraftforge.event.entity.EntityEvent;
|
||||
|
||||
public class ZombieEvent extends EntityEvent {
|
||||
|
||||
public ZombieEvent(EntityZombie entity)
|
||||
{
|
||||
super(entity);
|
||||
}
|
||||
|
||||
public EntityZombie getSummoner()
|
||||
{
|
||||
return (EntityZombie) entity;
|
||||
}
|
||||
|
||||
@HasResult
|
||||
public static class SummonAidEvent extends ZombieEvent {
|
||||
/**
|
||||
* Populate this field to have a custom zombie instead of a normal zombie summoned
|
||||
*/
|
||||
public EntityZombie customSummonedAid;
|
||||
|
||||
public final World world;
|
||||
public final int x;
|
||||
public final int y;
|
||||
public final int z;
|
||||
public final EntityLivingBase attacker;
|
||||
public final double summonChance;
|
||||
|
||||
public SummonAidEvent(EntityZombie entity, World world, int x, int y, int z, EntityLivingBase attacker, double summonChance)
|
||||
{
|
||||
super(entity);
|
||||
this.world = world;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.attacker = attacker;
|
||||
this.summonChance = summonChance;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package net.minecraftforge.event.entity.player;
|
||||
|
||||
import java.util.List;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class ItemTooltipEvent extends PlayerEvent
|
||||
{
|
||||
/**
|
||||
* Whether the advanced information on item tooltips is being shown, toggled by F3+H.
|
||||
*/
|
||||
public final boolean showAdvancedItemTooltips;
|
||||
/**
|
||||
* The {@link ItemStack} with the tooltip.
|
||||
*/
|
||||
public final ItemStack itemStack;
|
||||
/**
|
||||
* The {@link ItemStack} tooltip.
|
||||
*/
|
||||
public final List<String> toolTip;
|
||||
|
||||
/**
|
||||
* This event is fired in {@link ItemStack#getTooltip(EntityPlayer, boolean)}, which in turn is called from it's respective GUIContainer.
|
||||
*/
|
||||
public ItemTooltipEvent(ItemStack itemStack, EntityPlayer entityPlayer, List<String> toolTip, boolean showAdvancedItemTooltips)
|
||||
{
|
||||
super(entityPlayer);
|
||||
this.itemStack = itemStack;
|
||||
this.toolTip = toolTip;
|
||||
this.showAdvancedItemTooltips = showAdvancedItemTooltips;
|
||||
}
|
||||
}
|
||||
@@ -45,4 +45,16 @@ public class PlayerEvent extends LivingEvent
|
||||
this.newSpeed = original;
|
||||
}
|
||||
}
|
||||
|
||||
public static class NameFormat extends PlayerEvent
|
||||
{
|
||||
public final String username;
|
||||
public String displayname;
|
||||
|
||||
public NameFormat(EntityPlayer player, String username) {
|
||||
super(player);
|
||||
this.username = username;
|
||||
this.displayname = username;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package net.minecraftforge.event.entity.player;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraftforge.event.Event.HasResult;
|
||||
|
||||
@HasResult
|
||||
public class PlayerOpenContainerEvent extends PlayerEvent
|
||||
{
|
||||
|
||||
public final boolean canInteractWith;
|
||||
|
||||
/**
|
||||
* This event is fired when a player attempts to view a container during
|
||||
* player tick.
|
||||
*
|
||||
* setResult ALLOW to allow the container to stay open
|
||||
* setResult DENY to force close the container (denying access)
|
||||
*
|
||||
* DEFAULT is vanilla behaviour
|
||||
*
|
||||
*/
|
||||
|
||||
public PlayerOpenContainerEvent(EntityPlayer player, Container openContainer)
|
||||
{
|
||||
super(player);
|
||||
this.canInteractWith = openContainer.canInteractWith(player);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.minecraftforge.event.terraingen;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.world.biome.BiomeDecorator;
|
||||
@@ -40,9 +41,7 @@ public class BiomeEvent extends Event
|
||||
this.replacement = replacement;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static class BiomeColor extends BiomeEvent
|
||||
{
|
||||
public final int originalColor;
|
||||
@@ -89,8 +88,6 @@ public class BiomeEvent extends Event
|
||||
/**
|
||||
* This event is fired when a biome is queried for its grass color.
|
||||
*/
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static class GetGrassColor extends BiomeColor
|
||||
{
|
||||
public GetGrassColor(BiomeGenBase biome, int original)
|
||||
@@ -102,7 +99,6 @@ public class BiomeEvent extends Event
|
||||
/**
|
||||
* This event is fired when a biome is queried for its grass color.
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static class GetFoliageColor extends BiomeColor
|
||||
{
|
||||
public GetFoliageColor(BiomeGenBase biome, int original)
|
||||
@@ -114,7 +110,6 @@ public class BiomeEvent extends Event
|
||||
/**
|
||||
* This event is fired when a biome is queried for its water color.
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static class GetWaterColor extends BiomeColor
|
||||
{
|
||||
public GetWaterColor(BiomeGenBase biome, int original)
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package net.minecraftforge.event.terraingen;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.BiomeDecorator;
|
||||
import net.minecraft.world.biome.BiomeGenBase;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
public class DeferredBiomeDecorator extends BiomeDecorator {
|
||||
private BiomeDecorator wrapped;
|
||||
|
||||
public DeferredBiomeDecorator(BiomeGenBase biomeGenBase, BiomeDecorator wrappedOriginal)
|
||||
{
|
||||
super(biomeGenBase);
|
||||
this.wrapped = wrappedOriginal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decorate(World par1World, Random par2Random, int par3, int par4)
|
||||
{
|
||||
fireCreateEventAndReplace();
|
||||
// On first call to decorate, we fire and substitute ourselves, if we haven't already done so
|
||||
biome.theBiomeDecorator.decorate(par1World, par2Random, par3, par4);
|
||||
}
|
||||
public void fireCreateEventAndReplace()
|
||||
{
|
||||
// Copy any configuration from us to the real instance.
|
||||
wrapped.bigMushroomsPerChunk = bigMushroomsPerChunk;
|
||||
wrapped.cactiPerChunk = cactiPerChunk;
|
||||
wrapped.clayPerChunk = clayPerChunk;
|
||||
wrapped.deadBushPerChunk = deadBushPerChunk;
|
||||
wrapped.flowersPerChunk = flowersPerChunk;
|
||||
wrapped.generateLakes = generateLakes;
|
||||
wrapped.grassPerChunk = grassPerChunk;
|
||||
wrapped.mushroomsPerChunk = mushroomsPerChunk;
|
||||
wrapped.reedsPerChunk = reedsPerChunk;
|
||||
wrapped.sandPerChunk = sandPerChunk;
|
||||
wrapped.sandPerChunk2 = sandPerChunk2;
|
||||
wrapped.treesPerChunk = treesPerChunk;
|
||||
wrapped.waterlilyPerChunk = waterlilyPerChunk;
|
||||
|
||||
BiomeEvent.CreateDecorator event = new BiomeEvent.CreateDecorator(biome, wrapped);
|
||||
MinecraftForge.TERRAIN_GEN_BUS.post(event);
|
||||
biome.theBiomeDecorator = event.newBiomeDecorator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package net.minecraftforge.event.world;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.event.Cancelable;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
public class BlockEvent extends Event {
|
||||
public final int x;
|
||||
public final int y;
|
||||
public final int z;
|
||||
public final World world;
|
||||
public final Block block;
|
||||
public final int blockMetadata;
|
||||
public BlockEvent(int x, int y, int z, World world, Block block, int blockMetadata)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.world = world;
|
||||
this.block = block;
|
||||
this.blockMetadata = blockMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when a block is about to drop it's harvested items. The {@link #drops} array can be amended, as can the {@link #dropChance}.
|
||||
* <strong>Note well:</strong> the {@link #harvester} player field is null in a variety of scenarios. Code expecting null.
|
||||
*
|
||||
* The {@link #dropChance} is used to determine which items in this array will actually drop, compared to a random number. If you wish, you
|
||||
* can pre-filter yourself, and set {@link #dropChance} to 1.0f to always drop the contents of the {@link #drops} array.
|
||||
*
|
||||
* {@link #isSilkTouching} is set if this is considered a silk touch harvesting operation, vs a normal harvesting operation. Act accordingly.
|
||||
*
|
||||
* @author cpw
|
||||
*/
|
||||
public static class HarvestDropsEvent extends BlockEvent {
|
||||
public final int fortuneLevel;
|
||||
public final ArrayList<ItemStack> drops;
|
||||
public final boolean isSilkTouching;
|
||||
public float dropChance; // Change to e.g. 1.0f, if you manipulate the list and want to guarantee it always drops
|
||||
public final EntityPlayer harvester; // May be null for non-player harvesting such as explosions or machines
|
||||
|
||||
public HarvestDropsEvent(int x, int y, int z, World world, Block block, int blockMetadata, int fortuneLevel, float dropChance, ArrayList<ItemStack> drops, EntityPlayer harvester, boolean isSilkTouching)
|
||||
{
|
||||
super(x, y, z, world, block, blockMetadata);
|
||||
this.fortuneLevel = fortuneLevel;
|
||||
this.dropChance = dropChance;
|
||||
this.drops = drops;
|
||||
this.isSilkTouching = isSilkTouching;
|
||||
this.harvester = harvester;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event that is fired when an Block is about to be broken by a player
|
||||
* Canceling this event will prevent the Block from being broken.
|
||||
*/
|
||||
@Cancelable
|
||||
public static class BreakEvent extends BlockEvent
|
||||
{
|
||||
/** Reference to the Player who broke the block. If no player is available, use a EntityFakePlayer */
|
||||
private final EntityPlayer player;
|
||||
private int exp;
|
||||
|
||||
public BreakEvent(int x, int y, int z, World world, Block block, int blockMetadata, EntityPlayer player)
|
||||
{
|
||||
super(x, y, z, world, block, blockMetadata);
|
||||
this.player = player;
|
||||
|
||||
if (block == null || !player.canHarvestBlock(block) || // Handle empty block or player unable to break block scenario
|
||||
block.canSilkHarvest(world, player, x, y, z, blockMetadata) && EnchantmentHelper.getSilkTouchModifier(player)) // If the block is being silk harvested, the exp dropped is 0
|
||||
{
|
||||
this.exp = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int meta = block.getDamageValue(world, x, y, z);
|
||||
int bonusLevel = EnchantmentHelper.getFortuneModifier(player);
|
||||
this.exp = block.getExpDrop(world, meta, bonusLevel);
|
||||
}
|
||||
}
|
||||
|
||||
public EntityPlayer getPlayer()
|
||||
{
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the experience dropped by the block after the event has processed
|
||||
*
|
||||
* @return The experience to drop or 0 if the event was canceled
|
||||
*/
|
||||
public int getExpToDrop()
|
||||
{
|
||||
return this.isCanceled() ? 0 : exp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the amount of experience dropped by the block after the event has processed
|
||||
*
|
||||
* @param exp 1 or higher to drop experience, else nothing will drop
|
||||
*/
|
||||
public void setExpToDrop(int exp)
|
||||
{
|
||||
this.exp = exp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,464 @@
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* This is a base implementation for Fluid blocks.
|
||||
*
|
||||
* It is highly recommended that you extend this class or one of the Forge-provided child classes.
|
||||
*
|
||||
* @author King Lemming, OvermindDL1
|
||||
*
|
||||
*/
|
||||
public abstract class BlockFluidBase extends Block implements IFluidBlock
|
||||
{
|
||||
protected final static Map<Integer, Boolean> defaultDisplacementIds = new HashMap<Integer, Boolean>();
|
||||
|
||||
static
|
||||
{
|
||||
defaultDisplacementIds.put(Block.doorWood.blockID, false);
|
||||
defaultDisplacementIds.put(Block.doorIron.blockID, false);
|
||||
defaultDisplacementIds.put(Block.signPost.blockID, false);
|
||||
defaultDisplacementIds.put(Block.signWall.blockID, false);
|
||||
defaultDisplacementIds.put(Block.reed.blockID, false);
|
||||
}
|
||||
protected Map<Integer, Boolean> displacementIds = new HashMap<Integer, Boolean>();
|
||||
|
||||
protected int quantaPerBlock = 8;
|
||||
protected float quantaPerBlockFloat = 8F;
|
||||
protected int density = 1;
|
||||
protected int densityDir = -1;
|
||||
protected int temperature = 295;
|
||||
|
||||
protected int tickRate = 20;
|
||||
protected int renderPass = 1;
|
||||
protected int maxScaledLight = 0;
|
||||
|
||||
protected final String fluidName;
|
||||
|
||||
public BlockFluidBase(int id, Fluid fluid, Material material)
|
||||
{
|
||||
super(id, material);
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||
this.setTickRandomly(true);
|
||||
this.disableStats();
|
||||
|
||||
this.fluidName = fluid.getName();
|
||||
this.density = fluid.density;
|
||||
this.temperature = fluid.temperature;
|
||||
this.maxScaledLight = fluid.luminosity;
|
||||
this.tickRate = fluid.viscosity / 200;
|
||||
this.densityDir = fluid.density > 0 ? -1 : 1;
|
||||
fluid.setBlockID(id);
|
||||
|
||||
displacementIds.putAll(defaultDisplacementIds);
|
||||
}
|
||||
|
||||
public BlockFluidBase setQuantaPerBlock(int quantaPerBlock)
|
||||
{
|
||||
if (quantaPerBlock > 16 || quantaPerBlock < 1) quantaPerBlock = 8;
|
||||
this.quantaPerBlock = quantaPerBlock;
|
||||
this.quantaPerBlockFloat = quantaPerBlock;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockFluidBase setDensity(int density)
|
||||
{
|
||||
if (density == 0) density = 1;
|
||||
this.density = density;
|
||||
this.densityDir = density > 0 ? -1 : 1;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockFluidBase setTemperature(int temperature)
|
||||
{
|
||||
this.temperature = temperature;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockFluidBase setTickRate(int tickRate)
|
||||
{
|
||||
if (tickRate <= 0) tickRate = 20;
|
||||
this.tickRate = tickRate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockFluidBase setRenderPass(int renderPass)
|
||||
{
|
||||
this.renderPass = renderPass;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockFluidBase setMaxScaledLight(int maxScaledLight)
|
||||
{
|
||||
this.maxScaledLight = maxScaledLight;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the block at (x, y, z) is displaceable. Does not displace the block.
|
||||
*/
|
||||
public boolean canDisplace(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
if (world.isAirBlock(x, y, z)) return true;
|
||||
|
||||
int bId = world.getBlockId(x, y, z);
|
||||
|
||||
if (bId == blockID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (displacementIds.containsKey(bId))
|
||||
{
|
||||
return displacementIds.get(bId);
|
||||
}
|
||||
|
||||
Material material = Block.blocksList[bId].blockMaterial;
|
||||
if (material.blocksMovement() || material == Material.portal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int density = getDensity(world, x, y, z);
|
||||
if (density == Integer.MAX_VALUE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.density > density)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to displace the block at (x, y, z), return true if it was displaced.
|
||||
*/
|
||||
public boolean displaceIfPossible(World world, int x, int y, int z)
|
||||
{
|
||||
if (world.isAirBlock(x, y, z))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int bId = world.getBlockId(x, y, z);
|
||||
if (bId == blockID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (displacementIds.containsKey(bId))
|
||||
{
|
||||
if (displacementIds.get(bId))
|
||||
{
|
||||
Block.blocksList[bId].dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Material material = Block.blocksList[bId].blockMaterial;
|
||||
if (material.blocksMovement() || material == Material.portal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int density = getDensity(world, x, y, z);
|
||||
if (density == Integer.MAX_VALUE)
|
||||
{
|
||||
Block.blocksList[bId].dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.density > density)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract int getQuantaValue(IBlockAccess world, int x, int y, int z);
|
||||
|
||||
@Override
|
||||
public abstract boolean canCollideCheck(int meta, boolean fullHit);
|
||||
|
||||
public abstract int getMaxRenderHeightMeta();
|
||||
|
||||
/* BLOCK FUNCTIONS */
|
||||
@Override
|
||||
public void onBlockAdded(World world, int x, int y, int z)
|
||||
{
|
||||
world.scheduleBlockUpdate(x, y, z, blockID, tickRate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborBlockChange(World world, int x, int y, int z, int blockId)
|
||||
{
|
||||
world.scheduleBlockUpdate(x, y, z, blockID, tickRate);
|
||||
}
|
||||
|
||||
// Used to prevent updates on chunk generation
|
||||
@Override
|
||||
public boolean func_82506_l()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBlocksMovement(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int idDropped(int par1, Random par2Random, int par3)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int quantityDropped(Random par1Random)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int tickRate(World world)
|
||||
{
|
||||
return tickRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void velocityToAddToEntity(World world, int x, int y, int z, Entity entity, Vec3 vec)
|
||||
{
|
||||
if (densityDir > 0) return;
|
||||
Vec3 vec_flow = this.getFlowVector(world, x, y, z);
|
||||
vec.xCoord += vec_flow.xCoord * (quantaPerBlock * 4);
|
||||
vec.yCoord += vec_flow.yCoord * (quantaPerBlock * 4);
|
||||
vec.zCoord += vec_flow.zCoord * (quantaPerBlock * 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightValue(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
if (maxScaledLight == 0)
|
||||
{
|
||||
return super.getLightValue(world, x, y, z);
|
||||
}
|
||||
int data = world.getBlockMetadata(x, y, z);
|
||||
return (int) (data / quantaPerBlockFloat * maxScaledLight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderType()
|
||||
{
|
||||
return FluidRegistry.renderIdFluid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderAsNormalBlock()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getBlockBrightness(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
float lightThis = world.getLightBrightness(x, y, z);
|
||||
float lightUp = world.getLightBrightness(x, y + 1, z);
|
||||
return lightThis > lightUp ? lightThis : lightUp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMixedBrightnessForBlock(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
int lightThis = world.getLightBrightnessForSkyBlocks(x, y, z, 0);
|
||||
int lightUp = world.getLightBrightnessForSkyBlocks(x, y + 1, z, 0);
|
||||
int lightThisBase = lightThis & 255;
|
||||
int lightUpBase = lightUp & 255;
|
||||
int lightThisExt = lightThis >> 16 & 255;
|
||||
int lightUpExt = lightUp >> 16 & 255;
|
||||
return (lightThisBase > lightUpBase ? lightThisBase : lightUpBase) |
|
||||
((lightThisExt > lightUpExt ? lightThisExt : lightUpExt) << 16);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderBlockPass()
|
||||
{
|
||||
return renderPass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSideBeRendered(IBlockAccess world, int x, int y, int z, int side)
|
||||
{
|
||||
if (world.getBlockId(x, y, z) != blockID)
|
||||
{
|
||||
return !world.isBlockOpaqueCube(x, y, z);
|
||||
}
|
||||
Material mat = world.getBlockMaterial(x, y, z);
|
||||
return mat == this.blockMaterial ? false : super.shouldSideBeRendered(world, x, y, z, side);
|
||||
}
|
||||
|
||||
/* FLUID FUNCTIONS */
|
||||
public static final int getDensity(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
Block block = Block.blocksList[world.getBlockId(x, y, z)];
|
||||
if (!(block instanceof BlockFluidBase))
|
||||
{
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
return ((BlockFluidBase)block).density;
|
||||
}
|
||||
|
||||
public static final int getTemperature(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
Block block = Block.blocksList[world.getBlockId(x, y, z)];
|
||||
if (!(block instanceof BlockFluidBase))
|
||||
{
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
return ((BlockFluidBase)block).temperature;
|
||||
}
|
||||
|
||||
public static double getFlowDirection(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
Block block = Block.blocksList[world.getBlockId(x, y, z)];
|
||||
if (!world.getBlockMaterial(x, y, z).isLiquid())
|
||||
{
|
||||
return -1000.0;
|
||||
}
|
||||
Vec3 vec = ((BlockFluidBase) block).getFlowVector(world, x, y, z);
|
||||
return vec.xCoord == 0.0D && vec.zCoord == 0.0D ? -1000.0D : Math.atan2(vec.zCoord, vec.xCoord) - Math.PI / 2D;
|
||||
}
|
||||
|
||||
public final int getQuantaValueBelow(IBlockAccess world, int x, int y, int z, int belowThis)
|
||||
{
|
||||
int quantaRemaining = getQuantaValue(world, x, y, z);
|
||||
if (quantaRemaining >= belowThis)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return quantaRemaining;
|
||||
}
|
||||
|
||||
public final int getQuantaValueAbove(IBlockAccess world, int x, int y, int z, int aboveThis)
|
||||
{
|
||||
int quantaRemaining = getQuantaValue(world, x, y, z);
|
||||
if (quantaRemaining <= aboveThis)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return quantaRemaining;
|
||||
}
|
||||
|
||||
public final float getQuantaPercentage(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
int quantaRemaining = getQuantaValue(world, x, y, z);
|
||||
return quantaRemaining / quantaPerBlockFloat;
|
||||
}
|
||||
|
||||
public Vec3 getFlowVector(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
Vec3 vec = world.getWorldVec3Pool().getVecFromPool(0.0D, 0.0D, 0.0D);
|
||||
int decay = quantaPerBlock - getQuantaValue(world, x, y, z);
|
||||
|
||||
for (int side = 0; side < 4; ++side)
|
||||
{
|
||||
int x2 = x;
|
||||
int z2 = z;
|
||||
|
||||
switch (side)
|
||||
{
|
||||
case 0: --x2; break;
|
||||
case 1: --z2; break;
|
||||
case 2: ++x2; break;
|
||||
case 3: ++z2; break;
|
||||
}
|
||||
|
||||
int otherDecay = quantaPerBlock - getQuantaValue(world, x2, y, z2);
|
||||
if (otherDecay >= quantaPerBlock)
|
||||
{
|
||||
if (!world.getBlockMaterial(x2, y, z2).blocksMovement())
|
||||
{
|
||||
otherDecay = quantaPerBlock - getQuantaValue(world, x2, y - 1, z2);
|
||||
if (otherDecay >= 0)
|
||||
{
|
||||
int power = otherDecay - (decay - quantaPerBlock);
|
||||
vec = vec.addVector((x2 - x) * power, (y - y) * power, (z2 - z) * power);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (otherDecay >= 0)
|
||||
{
|
||||
int power = otherDecay - decay;
|
||||
vec = vec.addVector((x2 - x) * power, (y - y) * power, (z2 - z) * power);
|
||||
}
|
||||
}
|
||||
|
||||
if (world.getBlockId(x, y + 1, z) == blockID)
|
||||
{
|
||||
boolean flag =
|
||||
isBlockSolid(world, x, y, z - 1, 2) ||
|
||||
isBlockSolid(world, x, y, z + 1, 3) ||
|
||||
isBlockSolid(world, x - 1, y, z, 4) ||
|
||||
isBlockSolid(world, x + 1, y, z, 5) ||
|
||||
isBlockSolid(world, x, y + 1, z - 1, 2) ||
|
||||
isBlockSolid(world, x, y + 1, z + 1, 3) ||
|
||||
isBlockSolid(world, x - 1, y + 1, z, 4) ||
|
||||
isBlockSolid(world, x + 1, y + 1, z, 5);
|
||||
|
||||
if (flag)
|
||||
{
|
||||
vec = vec.normalize().addVector(0.0D, -6.0D, 0.0D);
|
||||
}
|
||||
}
|
||||
vec = vec.normalize();
|
||||
return vec;
|
||||
}
|
||||
|
||||
/* IFluidBlock */
|
||||
@Override
|
||||
public Fluid getFluid()
|
||||
{
|
||||
return FluidRegistry.getFluid(fluidName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFilledPercentage(World world, int x, int y, int z)
|
||||
{
|
||||
int quantaRemaining = getQuantaValue(world, x, y, z) + 1;
|
||||
float remaining = quantaRemaining / quantaPerBlockFloat;
|
||||
if (remaining > 1) remaining = 1.0f;
|
||||
return remaining * (density > 0 ? 1 : -1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* This is a fluid block implementation which emulates vanilla Minecraft fluid behavior.
|
||||
*
|
||||
* It is highly recommended that you use/extend this class for "classic" fluid blocks.
|
||||
*
|
||||
* @author King Lemming
|
||||
*
|
||||
*/
|
||||
public class BlockFluidClassic extends BlockFluidBase
|
||||
{
|
||||
protected boolean[] isOptimalFlowDirection = new boolean[4];
|
||||
protected int[] flowCost = new int[4];
|
||||
|
||||
protected FluidStack stack;
|
||||
|
||||
public BlockFluidClassic(int id, Fluid fluid, Material material)
|
||||
{
|
||||
super(id, fluid, material);
|
||||
stack = new FluidStack(fluid, FluidContainerRegistry.BUCKET_VOLUME);
|
||||
}
|
||||
|
||||
public BlockFluidClassic setFluidStack(FluidStack stack)
|
||||
{
|
||||
this.stack = stack;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockFluidClassic setFluidStackAmount(int amount)
|
||||
{
|
||||
this.stack.amount = amount;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getQuantaValue(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
if (world.getBlockId(x, y, z) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (world.getBlockId(x, y, z) != blockID)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int quantaRemaining = quantaPerBlock - world.getBlockMetadata(x, y, z);
|
||||
return quantaRemaining;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCollideCheck(int meta, boolean fullHit)
|
||||
{
|
||||
return fullHit && meta == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxRenderHeightMeta()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightValue(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
if (maxScaledLight == 0)
|
||||
{
|
||||
return super.getLightValue(world, x, y, z);
|
||||
}
|
||||
int data = quantaPerBlock - world.getBlockMetadata(x, y, z) - 1;
|
||||
return (int) (data / quantaPerBlockFloat * maxScaledLight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTick(World world, int x, int y, int z, Random rand)
|
||||
{
|
||||
int quantaRemaining = quantaPerBlock - world.getBlockMetadata(x, y, z);
|
||||
int expQuanta = -101;
|
||||
|
||||
// check adjacent block levels if non-source
|
||||
if (quantaRemaining < quantaPerBlock)
|
||||
{
|
||||
int y2 = y - densityDir;
|
||||
|
||||
if (world.getBlockId(x, y2, z ) == blockID ||
|
||||
world.getBlockId(x - 1, y2, z ) == blockID ||
|
||||
world.getBlockId(x + 1, y2, z ) == blockID ||
|
||||
world.getBlockId(x, y2, z - 1) == blockID ||
|
||||
world.getBlockId(x, y2, z + 1) == blockID)
|
||||
{
|
||||
expQuanta = quantaPerBlock - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int maxQuanta = -100;
|
||||
maxQuanta = getLargerQuanta(world, x - 1, y, z, maxQuanta);
|
||||
maxQuanta = getLargerQuanta(world, x + 1, y, z, maxQuanta);
|
||||
maxQuanta = getLargerQuanta(world, x, y, z - 1, maxQuanta);
|
||||
maxQuanta = getLargerQuanta(world, x, y, z + 1, maxQuanta);
|
||||
|
||||
expQuanta = maxQuanta - 1;
|
||||
}
|
||||
|
||||
// decay calculation
|
||||
if (expQuanta != quantaRemaining)
|
||||
{
|
||||
quantaRemaining = expQuanta;
|
||||
|
||||
if (expQuanta <= 0)
|
||||
{
|
||||
world.setBlockToAir(x, y, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
world.setBlockMetadataWithNotify(x, y, z, quantaPerBlock - expQuanta, 3);
|
||||
world.scheduleBlockUpdate(x, y, z, blockID, tickRate);
|
||||
world.notifyBlocksOfNeighborChange(x, y, z, blockID);
|
||||
}
|
||||
}
|
||||
}
|
||||
// This is a "source" block, set meta to zero, and send a server only update
|
||||
else if (quantaRemaining >= quantaPerBlock)
|
||||
{
|
||||
world.setBlockMetadataWithNotify(x, y, z, 0, 2);
|
||||
}
|
||||
|
||||
// Flow vertically if possible
|
||||
if (canDisplace(world, x, y + densityDir, z))
|
||||
{
|
||||
flowIntoBlock(world, x, y + densityDir, z, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Flow outward if possible
|
||||
int flowMeta = quantaPerBlock - quantaRemaining + 1;
|
||||
if (flowMeta >= quantaPerBlock)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSourceBlock(world, x, y, z) || !isFlowingVertically(world, x, y, z))
|
||||
{
|
||||
if (world.getBlockId(x, y - densityDir, z) == blockID)
|
||||
{
|
||||
flowMeta = 1;
|
||||
}
|
||||
boolean flowTo[] = getOptimalFlowDirections(world, x, y, z);
|
||||
|
||||
if (flowTo[0]) flowIntoBlock(world, x - 1, y, z, flowMeta);
|
||||
if (flowTo[1]) flowIntoBlock(world, x + 1, y, z, flowMeta);
|
||||
if (flowTo[2]) flowIntoBlock(world, x, y, z - 1, flowMeta);
|
||||
if (flowTo[3]) flowIntoBlock(world, x, y, z + 1, flowMeta);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFlowingVertically(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
return world.getBlockId(x, y + densityDir, z) == blockID ||
|
||||
(world.getBlockId(x, y, z) == blockID && canFlowInto(world, x, y + densityDir, z));
|
||||
}
|
||||
|
||||
public boolean isSourceBlock(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
return world.getBlockId(x, y, z) == blockID && world.getBlockMetadata(x, y, z) == 0;
|
||||
}
|
||||
|
||||
protected boolean[] getOptimalFlowDirections(World world, int x, int y, int z)
|
||||
{
|
||||
for (int side = 0; side < 4; side++)
|
||||
{
|
||||
flowCost[side] = 1000;
|
||||
|
||||
int x2 = x;
|
||||
int y2 = y;
|
||||
int z2 = z;
|
||||
|
||||
switch (side)
|
||||
{
|
||||
case 0: --x2; break;
|
||||
case 1: ++x2; break;
|
||||
case 2: --z2; break;
|
||||
case 3: ++z2; break;
|
||||
}
|
||||
|
||||
if (!canFlowInto(world, x2, y2, z2) || isSourceBlock(world, x2, y2, z2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (canFlowInto(world, x2, y2 + densityDir, z2))
|
||||
{
|
||||
flowCost[side] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
flowCost[side] = calculateFlowCost(world, x2, y2, z2, 1, side);
|
||||
}
|
||||
}
|
||||
|
||||
int min = flowCost[0];
|
||||
for (int side = 1; side < 4; side++)
|
||||
{
|
||||
if (flowCost[side] < min)
|
||||
{
|
||||
min = flowCost[side];
|
||||
}
|
||||
}
|
||||
for (int side = 0; side < 4; side++)
|
||||
{
|
||||
isOptimalFlowDirection[side] = flowCost[side] == min;
|
||||
}
|
||||
return isOptimalFlowDirection;
|
||||
}
|
||||
|
||||
protected int calculateFlowCost(World world, int x, int y, int z, int recurseDepth, int side)
|
||||
{
|
||||
int cost = 1000;
|
||||
for (int adjSide = 0; adjSide < 4; adjSide++)
|
||||
{
|
||||
if ((adjSide == 0 && side == 1) ||
|
||||
(adjSide == 1 && side == 0) ||
|
||||
(adjSide == 2 && side == 3) ||
|
||||
(adjSide == 3 && side == 2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int x2 = x;
|
||||
int y2 = y;
|
||||
int z2 = z;
|
||||
|
||||
switch (adjSide)
|
||||
{
|
||||
case 0: --x2; break;
|
||||
case 1: ++x2; break;
|
||||
case 2: --z2; break;
|
||||
case 3: ++z2; break;
|
||||
}
|
||||
|
||||
if (!canFlowInto(world, x2, y2, z2) || isSourceBlock(world, x2, y2, z2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (canFlowInto(world, x2, y2 + densityDir, z2))
|
||||
{
|
||||
return recurseDepth;
|
||||
}
|
||||
|
||||
if (recurseDepth >= 4)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int min = calculateFlowCost(world, x2, y2, z2, recurseDepth + 1, adjSide);
|
||||
if (min < cost)
|
||||
{
|
||||
cost = min;
|
||||
}
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
protected void flowIntoBlock(World world, int x, int y, int z, int meta)
|
||||
{
|
||||
if (meta < 0) return;
|
||||
if (displaceIfPossible(world, x, y, z))
|
||||
{
|
||||
world.setBlock(x, y, z, this.blockID, meta, 3);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean canFlowInto(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
if (world.isAirBlock(x, y, z)) return true;
|
||||
|
||||
int bId = world.getBlockId(x, y, z);
|
||||
if (bId == blockID)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (displacementIds.containsKey(bId))
|
||||
{
|
||||
return displacementIds.get(bId);
|
||||
}
|
||||
|
||||
Material material = Block.blocksList[bId].blockMaterial;
|
||||
if (material.blocksMovement() ||
|
||||
material == Material.water ||
|
||||
material == Material.lava ||
|
||||
material == Material.portal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int density = getDensity(world, x, y, z);
|
||||
if (density == Integer.MAX_VALUE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.density > density)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected int getLargerQuanta(IBlockAccess world, int x, int y, int z, int compare)
|
||||
{
|
||||
int quantaRemaining = getQuantaValue(world, x, y, z);
|
||||
if (quantaRemaining <= 0)
|
||||
{
|
||||
return compare;
|
||||
}
|
||||
return quantaRemaining >= compare ? quantaRemaining : compare;
|
||||
}
|
||||
|
||||
/* IFluidBlock */
|
||||
@Override
|
||||
public FluidStack drain(World world, int x, int y, int z, boolean doDrain)
|
||||
{
|
||||
if (!isSourceBlock(world, x, y, z))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (doDrain)
|
||||
{
|
||||
world.setBlockToAir(x, y, z);
|
||||
}
|
||||
|
||||
return stack.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDrain(World world, int x, int y, int z)
|
||||
{
|
||||
return isSourceBlock(world, x, y, z);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* This is a cellular-automata based finite fluid block implementation.
|
||||
*
|
||||
* It is highly recommended that you use/extend this class for finite fluid blocks.
|
||||
*
|
||||
* @author OvermindDL1, KingLemming
|
||||
*
|
||||
*/
|
||||
public class BlockFluidFinite extends BlockFluidBase
|
||||
{
|
||||
public BlockFluidFinite(int id, Fluid fluid, Material material)
|
||||
{
|
||||
super(id, fluid, material);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getQuantaValue(IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
if (world.isAirBlock(x, y, z))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (world.getBlockId(x, y, z) != blockID)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int quantaRemaining = world.getBlockMetadata(x, y, z) + 1;
|
||||
return quantaRemaining;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCollideCheck(int meta, boolean fullHit)
|
||||
{
|
||||
return fullHit && meta == quantaPerBlock - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxRenderHeightMeta()
|
||||
{
|
||||
return quantaPerBlock - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTick(World world, int x, int y, int z, Random rand)
|
||||
{
|
||||
boolean changed = false;
|
||||
int quantaRemaining = world.getBlockMetadata(x, y, z) + 1;
|
||||
|
||||
// Flow vertically if possible
|
||||
int prevRemaining = quantaRemaining;
|
||||
quantaRemaining = tryToFlowVerticallyInto(world, x, y, z, quantaRemaining);
|
||||
|
||||
if (quantaRemaining < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (quantaRemaining != prevRemaining)
|
||||
{
|
||||
changed = true;
|
||||
if (quantaRemaining == 1)
|
||||
{
|
||||
world.setBlockMetadataWithNotify(x, y, z, quantaRemaining - 1, 2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (quantaRemaining == 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Flow out if possible
|
||||
int lowerthan = quantaRemaining - 1;
|
||||
if (displaceIfPossible(world, x, y, z - 1)) world.setBlock(x, y, z - 1, 0);
|
||||
if (displaceIfPossible(world, x, y, z + 1)) world.setBlock(x, y, z + 1, 0);
|
||||
if (displaceIfPossible(world, x - 1, y, z )) world.setBlock(x - 1, y, z, 0);
|
||||
if (displaceIfPossible(world, x + 1, y, z )) world.setBlock(x + 1, y, z, 0);
|
||||
int north = getQuantaValueBelow(world, x, y, z - 1, lowerthan);
|
||||
int south = getQuantaValueBelow(world, x, y, z + 1, lowerthan);
|
||||
int west = getQuantaValueBelow(world, x - 1, y, z, lowerthan);
|
||||
int east = getQuantaValueBelow(world, x + 1, y, z, lowerthan);
|
||||
int total = quantaRemaining;
|
||||
int count = 1;
|
||||
|
||||
if (north >= 0)
|
||||
{
|
||||
count++;
|
||||
total += north;
|
||||
}
|
||||
|
||||
if (south >= 0)
|
||||
{
|
||||
count++;
|
||||
total += south;
|
||||
}
|
||||
|
||||
if (west >= 0)
|
||||
{
|
||||
count++;
|
||||
total += west;
|
||||
}
|
||||
|
||||
if (east >= 0)
|
||||
{
|
||||
++count;
|
||||
total += east;
|
||||
}
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
if (changed)
|
||||
{
|
||||
world.setBlockMetadataWithNotify(x, y, z, quantaRemaining - 1, 2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int each = total / count;
|
||||
int rem = total % count;
|
||||
if (north >= 0)
|
||||
{
|
||||
int newnorth = each;
|
||||
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
|
||||
{
|
||||
++newnorth;
|
||||
--rem;
|
||||
}
|
||||
|
||||
if (newnorth != north)
|
||||
{
|
||||
if (newnorth == 0)
|
||||
{
|
||||
world.setBlock(x, y, z - 1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
world.setBlock(x, y, z - 1, blockID, newnorth - 1, 2);
|
||||
}
|
||||
world.scheduleBlockUpdate(x, y, z - 1, blockID, tickRate);
|
||||
}
|
||||
--count;
|
||||
}
|
||||
|
||||
if (south >= 0)
|
||||
{
|
||||
int newsouth = each;
|
||||
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
|
||||
{
|
||||
++newsouth;
|
||||
--rem;
|
||||
}
|
||||
|
||||
if (newsouth != south)
|
||||
{
|
||||
if (newsouth == 0)
|
||||
{
|
||||
world.setBlock(x, y, z + 1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
world.setBlock(x, y, z + 1, blockID, newsouth - 1, 2);
|
||||
}
|
||||
world.scheduleBlockUpdate(x, y, z + 1, blockID, tickRate);
|
||||
}
|
||||
--count;
|
||||
}
|
||||
|
||||
if (west >= 0)
|
||||
{
|
||||
int newwest = each;
|
||||
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
|
||||
{
|
||||
++newwest;
|
||||
--rem;
|
||||
}
|
||||
if (newwest != west)
|
||||
{
|
||||
if (newwest == 0)
|
||||
{
|
||||
world.setBlock(x - 1, y, z, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
world.setBlock(x - 1, y, z, blockID, newwest - 1, 2);
|
||||
}
|
||||
world.scheduleBlockUpdate(x - 1, y, z, blockID, tickRate);
|
||||
}
|
||||
--count;
|
||||
}
|
||||
|
||||
if (east >= 0)
|
||||
{
|
||||
int neweast = each;
|
||||
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
|
||||
{
|
||||
++neweast;
|
||||
--rem;
|
||||
}
|
||||
|
||||
if (neweast != east)
|
||||
{
|
||||
if (neweast == 0)
|
||||
{
|
||||
world.setBlock(x + 1, y, z, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
world.setBlock(x + 1, y, z, blockID, neweast - 1, 2);
|
||||
}
|
||||
world.scheduleBlockUpdate(x + 1, y, z, blockID, tickRate);
|
||||
}
|
||||
--count;
|
||||
}
|
||||
|
||||
if (rem > 0)
|
||||
{
|
||||
++each;
|
||||
}
|
||||
world.setBlockMetadataWithNotify(x, y, z, each - 1, 2);
|
||||
}
|
||||
|
||||
public int tryToFlowVerticallyInto(World world, int x, int y, int z, int amtToInput)
|
||||
{
|
||||
int otherY = y + densityDir;
|
||||
if (otherY < 0 || otherY >= world.getHeight())
|
||||
{
|
||||
world.setBlockToAir(x, y, z);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amt = getQuantaValueBelow(world, x, otherY, z, quantaPerBlock);
|
||||
if (amt >= 0)
|
||||
{
|
||||
amt += amtToInput;
|
||||
if (amt > quantaPerBlock)
|
||||
{
|
||||
world.setBlock(x, otherY, z, blockID, quantaPerBlock - 1, 3);
|
||||
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
|
||||
return amt - quantaPerBlock;
|
||||
}
|
||||
else if (amt > 0)
|
||||
{
|
||||
world.setBlock(x, otherY, z, blockID, amt - 1, 3);
|
||||
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
|
||||
world.setBlockToAir(x, y, z);
|
||||
return 0;
|
||||
}
|
||||
return amtToInput;
|
||||
}
|
||||
else
|
||||
{
|
||||
int density_other = getDensity(world, x, otherY, z);
|
||||
if (density_other == Integer.MAX_VALUE)
|
||||
{
|
||||
if (displaceIfPossible(world, x, otherY, z))
|
||||
{
|
||||
world.setBlock(x, otherY, z, blockID, amtToInput - 1, 3);
|
||||
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
|
||||
world.setBlockToAir(x, y, z);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return amtToInput;
|
||||
}
|
||||
}
|
||||
|
||||
if (densityDir < 0)
|
||||
{
|
||||
if (density_other < density) // then swap
|
||||
{
|
||||
int bId = world.getBlockId(x, otherY, z);
|
||||
BlockFluidBase block = (BlockFluidBase) Block.blocksList[bId];
|
||||
int otherData = world.getBlockMetadata(x, otherY, z);
|
||||
world.setBlock(x, otherY, z, blockID, amtToInput - 1, 3);
|
||||
world.setBlock(x, y, z, bId, otherData, 3);
|
||||
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
|
||||
world.scheduleBlockUpdate(x, y, z, bId, block.tickRate(world));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (density_other > density)
|
||||
{
|
||||
int bId = world.getBlockId(x, otherY, z);
|
||||
BlockFluidBase block = (BlockFluidBase) Block.blocksList[bId];
|
||||
int otherData = world.getBlockMetadata(x, otherY, z);
|
||||
world.setBlock(x, otherY, z, blockID, amtToInput - 1, 3);
|
||||
world.setBlock(x, y, z, bId, otherData, 3);
|
||||
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
|
||||
world.scheduleBlockUpdate(x, y, z, bId, block.tickRate(world));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return amtToInput;
|
||||
}
|
||||
}
|
||||
|
||||
/* IFluidBlock */
|
||||
@Override
|
||||
public FluidStack drain(World world, int x, int y, int z, boolean doDrain)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDrain(World world, int x, int y, int z)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,324 @@
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.Icon;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ForgeDummyContainer;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
import net.minecraft.item.EnumRarity;
|
||||
|
||||
/**
|
||||
* Minecraft Forge Fluid Implementation
|
||||
*
|
||||
* This class is a fluid (liquid or gas) equivalent to "Item." It describes the nature of a fluid
|
||||
* and contains its general properties.
|
||||
*
|
||||
* These properties do not have inherent gameplay mechanics - they are provided so that mods may
|
||||
* choose to take advantage of them.
|
||||
*
|
||||
* Fluid implementations are not required to actively use these properties, nor are objects
|
||||
* interfacing with fluids required to make use of them, but it is encouraged.
|
||||
*
|
||||
* The default values can be used as a reference point for mods adding fluids such as oil or heavy
|
||||
* water.
|
||||
*
|
||||
* @author King Lemming
|
||||
*
|
||||
*/
|
||||
public class Fluid
|
||||
{
|
||||
/** The unique identification name for this fluid. */
|
||||
protected final String fluidName;
|
||||
|
||||
/** The unlocalized name of this fluid. */
|
||||
protected String unlocalizedName;
|
||||
|
||||
/** The Icons for this fluid. */
|
||||
protected Icon stillIcon;
|
||||
protected Icon flowingIcon;
|
||||
|
||||
/**
|
||||
* The light level emitted by this fluid.
|
||||
*
|
||||
* Default value is 0, as most fluids do not actively emit light.
|
||||
*/
|
||||
protected int luminosity = 0;
|
||||
|
||||
/**
|
||||
* Density of the fluid - completely arbitrary; negative density indicates that the fluid is
|
||||
* lighter than air.
|
||||
*
|
||||
* Default value is approximately the real-life density of water in kg/m^3.
|
||||
*/
|
||||
protected int density = 1000;
|
||||
|
||||
/**
|
||||
* Temperature of the fluid - completely arbitrary; higher temperature indicates that the fluid is
|
||||
* hotter than air.
|
||||
*
|
||||
* Default value is approximately the real-life room temperature of water in degrees Kelvin.
|
||||
*/
|
||||
protected int temperature = 295;
|
||||
|
||||
/**
|
||||
* Viscosity ("thickness") of the fluid - completely arbitrary; negative values are not
|
||||
* permissible.
|
||||
*
|
||||
* Default value is approximately the real-life density of water in m/s^2 (x10^-3).
|
||||
*/
|
||||
protected int viscosity = 1000;
|
||||
|
||||
/**
|
||||
* This indicates if the fluid is gaseous.
|
||||
*
|
||||
* Useful for rendering the fluid in containers and the world.
|
||||
*
|
||||
* Generally this is associated with negative density fluids.
|
||||
*/
|
||||
protected boolean isGaseous;
|
||||
|
||||
/**
|
||||
* The rarity of the fluid.
|
||||
*
|
||||
* Used primarily in tool tips.
|
||||
*/
|
||||
protected EnumRarity rarity = EnumRarity.common;
|
||||
|
||||
/**
|
||||
* If there is a Block implementation of the Fluid, the BlockID is linked here.
|
||||
*
|
||||
* The default value of -1 should remain for any Fluid without a Block implementation.
|
||||
*/
|
||||
protected int blockID = -1;
|
||||
|
||||
public Fluid(String fluidName)
|
||||
{
|
||||
this.fluidName = fluidName.toLowerCase(Locale.ENGLISH);
|
||||
this.unlocalizedName = fluidName;
|
||||
}
|
||||
|
||||
public Fluid setUnlocalizedName(String unlocalizedName)
|
||||
{
|
||||
this.unlocalizedName = unlocalizedName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fluid setBlockID(int blockID)
|
||||
{
|
||||
if (this.blockID == -1 || this.blockID == blockID)
|
||||
{
|
||||
this.blockID = blockID;
|
||||
}
|
||||
else if (!ForgeDummyContainer.forceDuplicateFluidBlockCrash)
|
||||
{
|
||||
FMLLog.warning("A mod has attempted to assign BlockID " + blockID + " to the Fluid '" + fluidName + "' but this Fluid has already been linked to BlockID "
|
||||
+ this.blockID + ". Configure your mods to prevent this from happening.");
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.severe("A mod has attempted to assign BlockID " + blockID + " to the Fluid '" + fluidName + "' but this Fluid has already been linked to BlockID "
|
||||
+ this.blockID + ". Configure your mods to prevent this from happening.");
|
||||
throw new LoaderException(new RuntimeException("A mod has attempted to assign BlockID " + blockID + " to the Fluid '" + fluidName
|
||||
+ "' but this Fluid has already been linked to BlockID " + this.blockID + ". Configure your mods to prevent this from happening."));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fluid setBlockID(Block block)
|
||||
{
|
||||
return setBlockID(block.blockID);
|
||||
}
|
||||
|
||||
public Fluid setLuminosity(int luminosity)
|
||||
{
|
||||
this.luminosity = luminosity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fluid setDensity(int density)
|
||||
{
|
||||
this.density = density;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fluid setTemperature(int temperature)
|
||||
{
|
||||
this.temperature = temperature;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fluid setViscosity(int viscosity)
|
||||
{
|
||||
this.viscosity = viscosity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fluid setGaseous(boolean isGaseous)
|
||||
{
|
||||
this.isGaseous = isGaseous;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fluid setRarity(EnumRarity rarity)
|
||||
{
|
||||
this.rarity = rarity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final String getName()
|
||||
{
|
||||
return this.fluidName;
|
||||
}
|
||||
|
||||
public final int getID()
|
||||
{
|
||||
return FluidRegistry.getFluidID(this.fluidName);
|
||||
}
|
||||
|
||||
public final int getBlockID()
|
||||
{
|
||||
return blockID;
|
||||
}
|
||||
|
||||
public final boolean canBePlacedInWorld()
|
||||
{
|
||||
return blockID != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the localized name of this fluid.
|
||||
*/
|
||||
public String getLocalizedName()
|
||||
{
|
||||
String s = this.getUnlocalizedName();
|
||||
return s == null ? "" : StatCollector.translateToLocal(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unlocalized name of this fluid.
|
||||
*/
|
||||
public String getUnlocalizedName()
|
||||
{
|
||||
return "fluid." + this.unlocalizedName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 0 for "/terrain.png". ALL FLUID TEXTURES MUST BE ON THIS SHEET.
|
||||
*/
|
||||
public final int getSpriteNumber()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Default Accessors */
|
||||
public final int getLuminosity()
|
||||
{
|
||||
return this.luminosity;
|
||||
}
|
||||
|
||||
public final int getDensity()
|
||||
{
|
||||
return this.density;
|
||||
}
|
||||
|
||||
public final int getTemperature()
|
||||
{
|
||||
return this.temperature;
|
||||
}
|
||||
|
||||
public final int getViscosity()
|
||||
{
|
||||
return this.viscosity;
|
||||
}
|
||||
|
||||
public final boolean isGaseous()
|
||||
{
|
||||
return this.isGaseous;
|
||||
}
|
||||
|
||||
public EnumRarity getRarity()
|
||||
{
|
||||
return rarity;
|
||||
}
|
||||
|
||||
public int getColor()
|
||||
{
|
||||
return 0xFFFFFF;
|
||||
}
|
||||
|
||||
public final Fluid setStillIcon(Icon stillIcon)
|
||||
{
|
||||
this.stillIcon = stillIcon;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Fluid setFlowingIcon(Icon flowingIcon)
|
||||
{
|
||||
this.flowingIcon = flowingIcon;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Fluid setIcons(Icon stillIcon, Icon flowingIcon)
|
||||
{
|
||||
return this.setStillIcon(stillIcon).setFlowingIcon(flowingIcon);
|
||||
}
|
||||
|
||||
public final Fluid setIcons(Icon commonIcon)
|
||||
{
|
||||
return this.setStillIcon(commonIcon).setFlowingIcon(commonIcon);
|
||||
}
|
||||
|
||||
public Icon getIcon(){ return getStillIcon(); }
|
||||
|
||||
public Icon getStillIcon()
|
||||
{
|
||||
return this.stillIcon;
|
||||
}
|
||||
|
||||
public Icon getFlowingIcon()
|
||||
{
|
||||
return this.flowingIcon;
|
||||
}
|
||||
|
||||
/* Stack-based Accessors */
|
||||
public int getLuminosity(FluidStack stack){ return getLuminosity(); }
|
||||
public int getDensity(FluidStack stack){ return getDensity(); }
|
||||
public int getTemperature(FluidStack stack){ return getTemperature(); }
|
||||
public int getViscosity(FluidStack stack){ return getViscosity(); }
|
||||
public boolean isGaseous(FluidStack stack){ return isGaseous(); }
|
||||
public EnumRarity getRarity(FluidStack stack){ return getRarity(); }
|
||||
public int getColor(FluidStack stack){ return getColor(); }
|
||||
public Icon getIcon(FluidStack stack){ return getIcon(); }
|
||||
/* World-based Accessors */
|
||||
public int getLuminosity(World world, int x, int y, int z){ return getLuminosity(); }
|
||||
public int getDensity(World world, int x, int y, int z){ return getDensity(); }
|
||||
public int getTemperature(World world, int x, int y, int z){ return getTemperature(); }
|
||||
public int getViscosity(World world, int x, int y, int z){ return getViscosity(); }
|
||||
public boolean isGaseous(World world, int x, int y, int z){ return isGaseous(); }
|
||||
public EnumRarity getRarity(World world, int x, int y, int z){ return getRarity(); }
|
||||
public int getColor(World world, int x, int y, int z){ return getColor(); }
|
||||
public Icon getIcon(World world, int x, int y, int z){ return getIcon(); }
|
||||
|
||||
private static Map<String, String> legacyNames = Maps.newHashMap();
|
||||
static String convertLegacyName(String fluidName)
|
||||
{
|
||||
return fluidName != null && legacyNames.containsKey(fluidName) ? legacyNames.get(fluidName) : fluidName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a legacy liquid name with the Fluids system
|
||||
* @param legacyName The legacy name to recognize
|
||||
* @param canonicalName The canonical fluid name it will become
|
||||
*/
|
||||
public static void registerLegacyName(String legacyName, String canonicalName)
|
||||
{
|
||||
legacyNames.put(legacyName.toLowerCase(Locale.ENGLISH), canonicalName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
/**
|
||||
* Register simple items that contain fluids here. Useful for buckets, bottles, and things that have
|
||||
* ID/metadata mappings.
|
||||
*
|
||||
* For more complex items, use {@link IFluidContainerItem} instead.
|
||||
*
|
||||
* @author King Lemming
|
||||
*
|
||||
*/
|
||||
public abstract class FluidContainerRegistry
|
||||
{
|
||||
private static Map<List, FluidContainerData> containerFluidMap = new HashMap();
|
||||
private static Map<List, FluidContainerData> filledContainerMap = new HashMap();
|
||||
private static Set<List> emptyContainers = new HashSet();
|
||||
|
||||
public static final int BUCKET_VOLUME = 1000;
|
||||
public static final ItemStack EMPTY_BUCKET = new ItemStack(Item.bucketEmpty);
|
||||
public static final ItemStack EMPTY_BOTTLE = new ItemStack(Item.glassBottle);
|
||||
private static final ItemStack NULL_EMPTYCONTAINER = new ItemStack(Item.bucketEmpty);
|
||||
|
||||
static
|
||||
{
|
||||
registerFluidContainer(FluidRegistry.WATER, new ItemStack(Item.bucketWater), EMPTY_BUCKET);
|
||||
registerFluidContainer(FluidRegistry.LAVA, new ItemStack(Item.bucketLava), EMPTY_BUCKET);
|
||||
registerFluidContainer(FluidRegistry.WATER, new ItemStack(Item.potion), EMPTY_BOTTLE);
|
||||
}
|
||||
|
||||
private FluidContainerRegistry(){}
|
||||
|
||||
/**
|
||||
* Register a new fluid containing item.
|
||||
*
|
||||
* @param stack
|
||||
* FluidStack containing the type and amount of the fluid stored in the item.
|
||||
* @param filledContainer
|
||||
* ItemStack representing the container when it is full.
|
||||
* @param emptyContainer
|
||||
* ItemStack representing the container when it is empty.
|
||||
* @return True if container was successfully registered; false if it already is.
|
||||
*/
|
||||
public static boolean registerFluidContainer(FluidStack stack, ItemStack filledContainer, ItemStack emptyContainer)
|
||||
{
|
||||
return registerFluidContainer(new FluidContainerData(stack, filledContainer, emptyContainer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new fluid containing item. The item is assumed to hold 1000 mB of fluid. Also
|
||||
* registers the Fluid if possible.
|
||||
*
|
||||
* @param fluid
|
||||
* Fluid type that is stored in the item.
|
||||
* @param filledContainer
|
||||
* ItemStack representing the container when it is full.
|
||||
* @param emptyContainer
|
||||
* ItemStack representing the container when it is empty.
|
||||
* @return True if container was successfully registered; false if it already is.
|
||||
*/
|
||||
public static boolean registerFluidContainer(Fluid fluid, ItemStack filledContainer, ItemStack emptyContainer)
|
||||
{
|
||||
if (!FluidRegistry.isFluidRegistered(fluid))
|
||||
{
|
||||
FluidRegistry.registerFluid(fluid);
|
||||
}
|
||||
return registerFluidContainer(new FluidStack(fluid, BUCKET_VOLUME), filledContainer, emptyContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new fluid containing item that does not have an empty container.
|
||||
*
|
||||
* @param stack
|
||||
* FluidStack containing the type and amount of the fluid stored in the item.
|
||||
* @param filledContainer
|
||||
* ItemStack representing the container when it is full.
|
||||
* @return True if container was successfully registered; false if it already is.
|
||||
*/
|
||||
public static boolean registerFluidContainer(FluidStack stack, ItemStack filledContainer)
|
||||
{
|
||||
return registerFluidContainer(new FluidContainerData(stack, filledContainer, null, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new fluid containing item that does not have an empty container. The item is
|
||||
* assumed to hold 1000 mB of fluid. Also registers the Fluid if possible.
|
||||
*
|
||||
* @param fluid
|
||||
* Fluid type that is stored in the item.
|
||||
* @param filledContainer
|
||||
* ItemStack representing the container when it is full.
|
||||
* @return True if container was successfully registered; false if it already is.
|
||||
*/
|
||||
public static boolean registerFluidContainer(Fluid fluid, ItemStack filledContainer)
|
||||
{
|
||||
if (!FluidRegistry.isFluidRegistered(fluid))
|
||||
{
|
||||
FluidRegistry.registerFluid(fluid);
|
||||
}
|
||||
return registerFluidContainer(new FluidStack(fluid, BUCKET_VOLUME), filledContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new fluid containing item.
|
||||
*
|
||||
* @param data
|
||||
* See {@link FluidContainerData}.
|
||||
* @return True if container was successfully registered; false if it already is.
|
||||
*/
|
||||
public static boolean registerFluidContainer(FluidContainerData data)
|
||||
{
|
||||
if (isFilledContainer(data.filledContainer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
containerFluidMap.put(Arrays.asList(data.filledContainer.itemID, data.filledContainer.getItemDamage()), data);
|
||||
|
||||
if (data.emptyContainer != null && data.emptyContainer != NULL_EMPTYCONTAINER)
|
||||
{
|
||||
filledContainerMap.put(Arrays.asList(data.emptyContainer.itemID, data.emptyContainer.getItemDamage(), data.fluid.fluidID), data);
|
||||
emptyContainers.add(Arrays.asList(data.emptyContainer.itemID, data.emptyContainer.getItemDamage()));
|
||||
}
|
||||
|
||||
MinecraftForge.EVENT_BUS.post(new FluidContainerRegisterEvent(data));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the fluid type and amount inside a container.
|
||||
*
|
||||
* @param container
|
||||
* The fluid container.
|
||||
* @return FluidStack representing stored fluid.
|
||||
*/
|
||||
public static FluidStack getFluidForFilledItem(ItemStack container)
|
||||
{
|
||||
if (container == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
FluidContainerData data = containerFluidMap.get(Arrays.asList(container.itemID, container.getItemDamage()));
|
||||
return data == null ? null : data.fluid.copy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to fill an empty container with a fluid.
|
||||
*
|
||||
* NOTE: Returns null on fail, NOT the empty container.
|
||||
*
|
||||
* @param fluid
|
||||
* FluidStack containing the type and amount of fluid to fill.
|
||||
* @param container
|
||||
* ItemStack representing the empty container.
|
||||
* @return Filled container if successful, otherwise null.
|
||||
*/
|
||||
public static ItemStack fillFluidContainer(FluidStack fluid, ItemStack container)
|
||||
{
|
||||
if (container == null || fluid == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
FluidContainerData data = filledContainerMap.get(Arrays.asList(container.itemID, container.getItemDamage(), fluid.fluidID));
|
||||
if (data != null && fluid.amount >= data.fluid.amount)
|
||||
{
|
||||
return data.filledContainer.copy();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a container holds a specific fluid.
|
||||
*/
|
||||
public static boolean containsFluid(ItemStack container, FluidStack fluid)
|
||||
{
|
||||
if (container == null || fluid == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FluidContainerData data = filledContainerMap.get(Arrays.asList(container.itemID, container.getItemDamage(), fluid.fluidID));
|
||||
return data == null ? false : data.fluid.isFluidEqual(fluid);
|
||||
}
|
||||
|
||||
public static boolean isBucket(ItemStack container)
|
||||
{
|
||||
if (container == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (container.isItemEqual(EMPTY_BUCKET))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
FluidContainerData data = containerFluidMap.get(Arrays.asList(container.itemID, container.getItemDamage()));
|
||||
return data != null && data.emptyContainer.isItemEqual(EMPTY_BUCKET);
|
||||
}
|
||||
|
||||
public static boolean isContainer(ItemStack container)
|
||||
{
|
||||
return isEmptyContainer(container) || isFilledContainer(container);
|
||||
}
|
||||
|
||||
public static boolean isEmptyContainer(ItemStack container)
|
||||
{
|
||||
return container != null && emptyContainers.contains(Arrays.asList(container.itemID, container.getItemDamage()));
|
||||
}
|
||||
|
||||
public static boolean isFilledContainer(ItemStack container)
|
||||
{
|
||||
return container != null && getFluidForFilledItem(container) != null;
|
||||
}
|
||||
|
||||
public static FluidContainerData[] getRegisteredFluidContainerData()
|
||||
{
|
||||
return containerFluidMap.values().toArray(new FluidContainerData[containerFluidMap.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for the registry entries. Ensures that none of the attempted registrations
|
||||
* contain null references unless permitted.
|
||||
*/
|
||||
public static class FluidContainerData
|
||||
{
|
||||
public final FluidStack fluid;
|
||||
public final ItemStack filledContainer;
|
||||
public final ItemStack emptyContainer;
|
||||
|
||||
|
||||
public FluidContainerData(FluidStack stack, ItemStack filledContainer, ItemStack emptyContainer)
|
||||
{
|
||||
this(stack, filledContainer, emptyContainer, false);
|
||||
}
|
||||
|
||||
public FluidContainerData(FluidStack stack, ItemStack filledContainer, ItemStack emptyContainer, boolean nullEmpty)
|
||||
{
|
||||
this.fluid = stack;
|
||||
this.filledContainer = filledContainer;
|
||||
this.emptyContainer = emptyContainer == null ? NULL_EMPTYCONTAINER : emptyContainer;
|
||||
|
||||
if (stack == null || filledContainer == null || emptyContainer == null && !nullEmpty)
|
||||
{
|
||||
throw new RuntimeException("Invalid FluidContainerData - a parameter was null.");
|
||||
}
|
||||
}
|
||||
|
||||
public FluidContainerData copy()
|
||||
{
|
||||
return new FluidContainerData(fluid, filledContainer, emptyContainer, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static class FluidContainerRegisterEvent extends Event
|
||||
{
|
||||
public final FluidContainerData data;
|
||||
|
||||
public FluidContainerRegisterEvent(FluidContainerData data)
|
||||
{
|
||||
this.data = data.copy();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
public class FluidEvent extends Event
|
||||
{
|
||||
public final FluidStack fluid;
|
||||
public final int x;
|
||||
public final int y;
|
||||
public final int z;
|
||||
public final World world;
|
||||
|
||||
public FluidEvent(FluidStack fluid, World world, int x, int y, int z)
|
||||
{
|
||||
this.fluid = fluid;
|
||||
this.world = world;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mods should fire this event when they move fluids around.
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public static class FluidMotionEvent extends FluidEvent
|
||||
{
|
||||
public FluidMotionEvent(FluidStack fluid, World world, int x, int y, int z)
|
||||
{
|
||||
super(fluid, world, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mods should fire this event when a fluid is {@link IFluidTank#fill(FluidStack, boolean)}
|
||||
* their tank implementation. {@link FluidTank} does.
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public static class FluidFillingEvent extends FluidEvent
|
||||
{
|
||||
public final IFluidTank tank;
|
||||
public FluidFillingEvent(FluidStack fluid, World world, int x, int y, int z, IFluidTank tank)
|
||||
{
|
||||
super(fluid, world, x, y, z);
|
||||
this.tank = tank;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mods should fire this event when a fluid is {@link IFluidTank#drain(int, boolean)} from their
|
||||
* tank.
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public static class FluidDrainingEvent extends FluidEvent
|
||||
{
|
||||
public final IFluidTank tank;
|
||||
public FluidDrainingEvent(FluidStack fluid, World world, int x, int y, int z, IFluidTank tank)
|
||||
{
|
||||
super(fluid, world, x, y, z);
|
||||
this.tank = tank;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mods should fire this event when a fluid "spills", for example, if a block containing fluid
|
||||
* is broken.
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public static class FluidSpilledEvent extends FluidEvent
|
||||
{
|
||||
public FluidSpilledEvent(FluidStack fluid, World world, int x, int y, int z)
|
||||
{
|
||||
super(fluid, world, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A handy shortcut for firing the various fluid events.
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
public static final void fireEvent(FluidEvent event)
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.network.INetworkManager;
|
||||
import net.minecraftforge.common.network.ForgePacket;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
public class FluidIdMapPacket extends ForgePacket
|
||||
{
|
||||
private BiMap<String, Integer> fluidIds = HashBiMap.create();
|
||||
|
||||
@Override
|
||||
public byte[] generatePacket()
|
||||
{
|
||||
ByteArrayDataOutput dat = ByteStreams.newDataOutput();
|
||||
|
||||
dat.writeInt(FluidRegistry.maxID);
|
||||
for (Map.Entry<String, Integer> entry : FluidRegistry.fluidIDs.entrySet())
|
||||
{
|
||||
dat.writeUTF(entry.getKey());
|
||||
dat.writeInt(entry.getValue());
|
||||
}
|
||||
return dat.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForgePacket consumePacket(byte[] data)
|
||||
{
|
||||
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
|
||||
int listSize = dat.readInt();
|
||||
for (int i = 0; i < listSize; i++) {
|
||||
String fluidName = dat.readUTF();
|
||||
int fluidId = dat.readInt();
|
||||
fluidIds.put(fluidName, fluidId);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(INetworkManager network, EntityPlayer player)
|
||||
{
|
||||
FluidRegistry.initFluidIDs(fluidIds);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
* Handles Fluid registrations. Fluids MUST be registered in order to function.
|
||||
*
|
||||
* @author King Lemming, CovertJaguar (LiquidDictionary)
|
||||
*
|
||||
*/
|
||||
public abstract class FluidRegistry
|
||||
{
|
||||
static int maxID = 0;
|
||||
|
||||
static HashMap<String, Fluid> fluids = new HashMap();
|
||||
static BiMap<String, Integer> fluidIDs = HashBiMap.create();
|
||||
static BiMap<Block, Fluid> fluidBlocks;
|
||||
|
||||
public static final Fluid WATER = new Fluid("water") {
|
||||
@Override
|
||||
public String getLocalizedName() {
|
||||
return StatCollector.translateToLocal("tile.water.name");
|
||||
}
|
||||
}.setBlockID(Block.waterStill.blockID).setUnlocalizedName(Block.waterStill.getUnlocalizedName());
|
||||
|
||||
public static final Fluid LAVA = new Fluid("lava") {
|
||||
@Override
|
||||
public String getLocalizedName() {
|
||||
return StatCollector.translateToLocal("tile.lava.name");
|
||||
}
|
||||
}.setBlockID(Block.lavaStill.blockID).setLuminosity(15).setDensity(3000).setViscosity(6000).setTemperature(1300).setUnlocalizedName(Block.lavaStill.getUnlocalizedName());
|
||||
|
||||
public static int renderIdFluid = -1;
|
||||
|
||||
static
|
||||
{
|
||||
registerFluid(WATER);
|
||||
registerFluid(LAVA);
|
||||
}
|
||||
|
||||
private FluidRegistry(){}
|
||||
|
||||
/**
|
||||
* Called by Forge to prepare the ID map for server -> client sync.
|
||||
*/
|
||||
static void initFluidIDs(BiMap<String, Integer> newfluidIDs)
|
||||
{
|
||||
maxID = newfluidIDs.size();
|
||||
fluidIDs.clear();
|
||||
fluidIDs.putAll(newfluidIDs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new Fluid. If a fluid with the same name already exists, registration is denied.
|
||||
*
|
||||
* @param fluid
|
||||
* The fluid to register.
|
||||
* @return True if the fluid was successfully registered; false if there is a name clash.
|
||||
*/
|
||||
public static boolean registerFluid(Fluid fluid)
|
||||
{
|
||||
if (fluidIDs.containsKey(fluid.getName()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
fluids.put(fluid.getName(), fluid);
|
||||
fluidIDs.put(fluid.getName(), ++maxID);
|
||||
|
||||
MinecraftForge.EVENT_BUS.post(new FluidRegisterEvent(fluid.getName(), maxID));
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isFluidRegistered(Fluid fluid)
|
||||
{
|
||||
return fluidIDs.containsKey(fluid.getName());
|
||||
}
|
||||
|
||||
public static boolean isFluidRegistered(String fluidName)
|
||||
{
|
||||
return fluidIDs.containsKey(fluidName);
|
||||
}
|
||||
|
||||
public static Fluid getFluid(String fluidName)
|
||||
{
|
||||
return fluids.get(fluidName);
|
||||
}
|
||||
|
||||
public static Fluid getFluid(int fluidID)
|
||||
{
|
||||
return fluids.get(getFluidName(fluidID));
|
||||
}
|
||||
|
||||
public static String getFluidName(int fluidID)
|
||||
{
|
||||
return fluidIDs.inverse().get(fluidID);
|
||||
}
|
||||
|
||||
public static String getFluidName(FluidStack stack)
|
||||
{
|
||||
return getFluidName(stack.fluidID);
|
||||
}
|
||||
|
||||
public static int getFluidID(String fluidName)
|
||||
{
|
||||
return fluidIDs.get(fluidName);
|
||||
}
|
||||
|
||||
public static FluidStack getFluidStack(String fluidName, int amount)
|
||||
{
|
||||
if (!fluidIDs.containsKey(fluidName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new FluidStack(getFluidID(fluidName), amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a read-only map containing Fluid Names and their associated Fluids.
|
||||
*/
|
||||
public static Map<String, Fluid> getRegisteredFluids()
|
||||
{
|
||||
return ImmutableMap.copyOf(fluids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a read-only map containing Fluid Names and their associated IDs.
|
||||
*/
|
||||
public static Map<String, Integer> getRegisteredFluidIDs()
|
||||
{
|
||||
return ImmutableMap.copyOf(fluidIDs);
|
||||
}
|
||||
|
||||
public static Fluid lookupFluidForBlock(Block block)
|
||||
{
|
||||
if (fluidBlocks == null)
|
||||
{
|
||||
fluidBlocks = HashBiMap.create();
|
||||
for (Fluid fluid : fluids.values())
|
||||
{
|
||||
if (fluid.canBePlacedInWorld() && Block.blocksList[fluid.getBlockID()] != null)
|
||||
{
|
||||
fluidBlocks.put(Block.blocksList[fluid.getBlockID()], fluid);
|
||||
}
|
||||
}
|
||||
}
|
||||
return fluidBlocks.get(block);
|
||||
}
|
||||
|
||||
public static class FluidRegisterEvent extends Event
|
||||
{
|
||||
public final String fluidName;
|
||||
public final int fluidID;
|
||||
|
||||
public FluidRegisterEvent(String fluidName, int fluidID)
|
||||
{
|
||||
this.fluidName = fluidName;
|
||||
this.fluidID = fluidID;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
/**
|
||||
* ItemStack substitute for Fluids.
|
||||
*
|
||||
* NOTE: Equality is based on the Fluid, not the amount. Use
|
||||
* {@link #isFluidStackIdentical(FluidStack)} to determine if FluidID, Amount and NBT Tag are all
|
||||
* equal.
|
||||
*
|
||||
* @author King Lemming, SirSengir (LiquidStack)
|
||||
*
|
||||
*/
|
||||
public class FluidStack
|
||||
{
|
||||
public int fluidID;
|
||||
public int amount;
|
||||
public NBTTagCompound tag;
|
||||
|
||||
public FluidStack(Fluid fluid, int amount)
|
||||
{
|
||||
this.fluidID = fluid.getID();
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public FluidStack(int fluidID, int amount)
|
||||
{
|
||||
this.fluidID = fluidID;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public FluidStack(int fluidID, int amount, NBTTagCompound nbt)
|
||||
{
|
||||
this(fluidID, amount);
|
||||
|
||||
if (nbt != null)
|
||||
{
|
||||
tag = (NBTTagCompound) nbt.copy();
|
||||
}
|
||||
}
|
||||
|
||||
public FluidStack(FluidStack stack, int amount)
|
||||
{
|
||||
this(stack.fluidID, amount, stack.tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* This provides a safe method for retrieving a FluidStack - if the Fluid is invalid, the stack
|
||||
* will return as null.
|
||||
*/
|
||||
public static FluidStack loadFluidStackFromNBT(NBTTagCompound nbt)
|
||||
{
|
||||
if (nbt == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String fluidName = nbt.getString("FluidName");
|
||||
if (fluidName == null)
|
||||
{
|
||||
fluidName = nbt.hasKey("LiquidName") ? nbt.getString("LiquidName").toLowerCase(Locale.ENGLISH) : null;
|
||||
fluidName = Fluid.convertLegacyName(fluidName);
|
||||
}
|
||||
|
||||
if (fluidName ==null || FluidRegistry.getFluid(fluidName) == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
FluidStack stack = new FluidStack(FluidRegistry.getFluidID(fluidName), nbt.getInteger("Amount"));
|
||||
|
||||
if (nbt.hasKey("Tag"))
|
||||
{
|
||||
stack.tag = nbt.getCompoundTag("Tag");
|
||||
}
|
||||
else if (nbt.hasKey("extra"))
|
||||
{
|
||||
stack.tag = nbt.getCompoundTag("extra");
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound nbt)
|
||||
{
|
||||
nbt.setString("FluidName", FluidRegistry.getFluidName(fluidID));
|
||||
nbt.setInteger("Amount", amount);
|
||||
|
||||
if (tag != null)
|
||||
{
|
||||
nbt.setTag("Tag", tag);
|
||||
}
|
||||
return nbt;
|
||||
}
|
||||
|
||||
public final Fluid getFluid()
|
||||
{
|
||||
return FluidRegistry.getFluid(fluidID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A copy of this FluidStack
|
||||
*/
|
||||
public FluidStack copy()
|
||||
{
|
||||
return new FluidStack(fluidID, amount, tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the FluidIDs and NBT Tags are equal. This does not check amounts.
|
||||
*
|
||||
* @param other
|
||||
* The FluidStack for comparison
|
||||
* @return true if the Fluids (IDs and NBT Tags) are the same
|
||||
*/
|
||||
public boolean isFluidEqual(FluidStack other)
|
||||
{
|
||||
return other != null && fluidID == other.fluidID && isFluidStackTagEqual(other);
|
||||
}
|
||||
|
||||
private boolean isFluidStackTagEqual(FluidStack other)
|
||||
{
|
||||
return tag == null ? other.tag == null : other.tag == null ? false : tag.equals(other.tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the NBT Tags are equal. Useful if the FluidIDs are known to be equal.
|
||||
*/
|
||||
public static boolean areFluidStackTagsEqual(FluidStack stack1, FluidStack stack2)
|
||||
{
|
||||
return stack1 == null && stack2 == null ? true : stack1 == null || stack2 == null ? false : stack1.isFluidStackTagEqual(stack2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the Fluids are equal and this stack is larger.
|
||||
*
|
||||
* @param other
|
||||
* @return true if this FluidStack contains the other FluidStack (same fluid and >= amount)
|
||||
*/
|
||||
public boolean containsFluid(FluidStack other)
|
||||
{
|
||||
return isFluidEqual(other) && amount >= other.amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the FluidIDs, Amounts, and NBT Tags are all equal.
|
||||
*
|
||||
* @param other
|
||||
* - the FluidStack for comparison
|
||||
* @return true if the two FluidStacks are exactly the same
|
||||
*/
|
||||
public boolean isFluidStackIdentical(FluidStack other)
|
||||
{
|
||||
return isFluidEqual(other) && amount == other.amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the FluidIDs and NBT Tags are equal compared to a registered container
|
||||
* ItemStack. This does not check amounts.
|
||||
*
|
||||
* @param other
|
||||
* The ItemStack for comparison
|
||||
* @return true if the Fluids (IDs and NBT Tags) are the same
|
||||
*/
|
||||
public boolean isFluidEqual(ItemStack other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (other.getItem() instanceof IFluidContainerItem)
|
||||
{
|
||||
return isFluidEqual(((IFluidContainerItem) other.getItem()).getFluid(other));
|
||||
}
|
||||
|
||||
return isFluidEqual(FluidContainerRegistry.getFluidForFilledItem(other));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode()
|
||||
{
|
||||
return fluidID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default equality comparison for a FluidStack. Same functionality as isFluidEqual().
|
||||
*
|
||||
* This is included for use in data structures.
|
||||
*/
|
||||
@Override
|
||||
public final boolean equals(Object o)
|
||||
{
|
||||
if (!(o instanceof FluidStack))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return isFluidEqual((FluidStack) o);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
/**
|
||||
* Reference implementation of {@link IFluidTank}. Use/extend this or implement your own.
|
||||
*
|
||||
* @author King Lemming, cpw (LiquidTank)
|
||||
*
|
||||
*/
|
||||
public class FluidTank implements IFluidTank
|
||||
{
|
||||
protected FluidStack fluid;
|
||||
protected int capacity;
|
||||
protected TileEntity tile;
|
||||
|
||||
public FluidTank(int capacity)
|
||||
{
|
||||
this(null, capacity);
|
||||
}
|
||||
|
||||
public FluidTank(FluidStack stack, int capacity)
|
||||
{
|
||||
this.fluid = stack;
|
||||
this.capacity = capacity;
|
||||
}
|
||||
|
||||
public FluidTank(Fluid fluid, int amount, int capacity)
|
||||
{
|
||||
this(new FluidStack(fluid, amount), capacity);
|
||||
}
|
||||
|
||||
public FluidTank readFromNBT(NBTTagCompound nbt)
|
||||
{
|
||||
if (!nbt.hasKey("Empty"))
|
||||
{
|
||||
FluidStack fluid = FluidStack.loadFluidStackFromNBT(nbt);
|
||||
|
||||
if (fluid != null)
|
||||
{
|
||||
setFluid(fluid);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound nbt)
|
||||
{
|
||||
if (fluid != null)
|
||||
{
|
||||
fluid.writeToNBT(nbt);
|
||||
}
|
||||
else
|
||||
{
|
||||
nbt.setString("Empty", "");
|
||||
}
|
||||
return nbt;
|
||||
}
|
||||
|
||||
public void setFluid(FluidStack fluid)
|
||||
{
|
||||
this.fluid = fluid;
|
||||
}
|
||||
|
||||
public void setCapacity(int capacity)
|
||||
{
|
||||
this.capacity = capacity;
|
||||
}
|
||||
|
||||
/* IFluidTank */
|
||||
@Override
|
||||
public FluidStack getFluid()
|
||||
{
|
||||
return fluid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFluidAmount()
|
||||
{
|
||||
if (fluid == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return fluid.amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCapacity()
|
||||
{
|
||||
return capacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidTankInfo getInfo()
|
||||
{
|
||||
return new FluidTankInfo(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fill(FluidStack resource, boolean doFill)
|
||||
{
|
||||
if (resource == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!doFill)
|
||||
{
|
||||
if (fluid == null)
|
||||
{
|
||||
return Math.min(capacity, resource.amount);
|
||||
}
|
||||
|
||||
if (!fluid.isFluidEqual(resource))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.min(capacity - fluid.amount, resource.amount);
|
||||
}
|
||||
|
||||
if (fluid == null)
|
||||
{
|
||||
fluid = new FluidStack(resource, Math.min(capacity, resource.amount));
|
||||
|
||||
if (tile != null)
|
||||
{
|
||||
FluidEvent.fireEvent(new FluidEvent.FluidFillingEvent(fluid, tile.worldObj, tile.xCoord, tile.yCoord, tile.zCoord, this));
|
||||
}
|
||||
return fluid.amount;
|
||||
}
|
||||
|
||||
if (!fluid.isFluidEqual(resource))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int filled = capacity - fluid.amount;
|
||||
|
||||
if (resource.amount < filled)
|
||||
{
|
||||
fluid.amount += resource.amount;
|
||||
filled = resource.amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
fluid.amount = capacity;
|
||||
}
|
||||
|
||||
if (tile != null)
|
||||
{
|
||||
FluidEvent.fireEvent(new FluidEvent.FluidFillingEvent(fluid, tile.worldObj, tile.xCoord, tile.yCoord, tile.zCoord, this));
|
||||
}
|
||||
return filled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidStack drain(int maxDrain, boolean doDrain)
|
||||
{
|
||||
if (fluid == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int drained = maxDrain;
|
||||
if (fluid.amount < drained)
|
||||
{
|
||||
drained = fluid.amount;
|
||||
}
|
||||
|
||||
FluidStack stack = new FluidStack(fluid, drained);
|
||||
if (doDrain)
|
||||
{
|
||||
fluid.amount -= drained;
|
||||
if (fluid.amount <= 0)
|
||||
{
|
||||
fluid = null;
|
||||
}
|
||||
|
||||
if (tile != null)
|
||||
{
|
||||
FluidEvent.fireEvent(new FluidEvent.FluidDrainingEvent(fluid, tile.worldObj, tile.xCoord, tile.yCoord, tile.zCoord, this));
|
||||
}
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
/**
|
||||
* Wrapper class used to encapsulate information about an IFluidTank.
|
||||
*
|
||||
* @author King Lemming
|
||||
*
|
||||
*/
|
||||
public final class FluidTankInfo
|
||||
{
|
||||
public final FluidStack fluid;
|
||||
public final int capacity;
|
||||
|
||||
public FluidTankInfo(FluidStack fluid, int capacity)
|
||||
{
|
||||
this.fluid = fluid;
|
||||
this.capacity = capacity;
|
||||
}
|
||||
|
||||
public FluidTankInfo(IFluidTank tank)
|
||||
{
|
||||
this.fluid = tank.getFluid();
|
||||
this.capacity = tank.getCapacity();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* Implement this interface on Block classes which represent world-placeable Fluids.
|
||||
*
|
||||
* NOTE: Using/extending the reference implementations {@link BlockFluidBase} is encouraged.
|
||||
*
|
||||
* @author King Lemming
|
||||
*
|
||||
*/
|
||||
public interface IFluidBlock
|
||||
{
|
||||
/**
|
||||
* Returns the Fluid associated with this Block.
|
||||
*/
|
||||
Fluid getFluid();
|
||||
|
||||
/**
|
||||
* Attempt to drain the block. This method should be called by devices such as pumps.
|
||||
*
|
||||
* NOTE: The block is intended to handle its own state changes.
|
||||
*
|
||||
* @param doDrain
|
||||
* If false, the drain will only be simulated.
|
||||
* @return
|
||||
*/
|
||||
FluidStack drain(World world, int x, int y, int z, boolean doDrain);
|
||||
|
||||
/**
|
||||
* Check to see if a block can be drained. This method should be called by devices such as
|
||||
* pumps.
|
||||
*
|
||||
* @param doDrain
|
||||
* If false, the drain will only be simulated.
|
||||
* @return
|
||||
*/
|
||||
boolean canDrain(World world, int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Returns the amount of a single block is filled. Value between 0 and 1.
|
||||
* 1 meaning the entire 1x1x1 cube is full, 0 meaning completely empty.
|
||||
*
|
||||
* If the return value is negative. It will be treated as filling the block
|
||||
* from the top down instead of bottom up.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
float getFilledPercentage(World world, int x, int y, int z);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
/**
|
||||
* Implement this interface on Item classes that support external manipulation of their internal
|
||||
* fluid storage.
|
||||
*
|
||||
* A reference implementation is provided {@link ItemFluidContainer}.
|
||||
*
|
||||
* NOTE: Use of NBT data on the containing ItemStack is encouraged.
|
||||
*
|
||||
* @author King Lemming
|
||||
*
|
||||
*/
|
||||
public interface IFluidContainerItem
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param container
|
||||
* ItemStack which is the fluid container.
|
||||
* @return FluidStack representing the fluid in the container, null if the container is empty.
|
||||
*/
|
||||
FluidStack getFluid(ItemStack container);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param container
|
||||
* ItemStack which is the fluid container.
|
||||
* @return Capacity of this fluid container.
|
||||
*/
|
||||
int getCapacity(ItemStack container);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param container
|
||||
* ItemStack which is the fluid container.
|
||||
* @param resource
|
||||
* FluidStack attempting to fill the container.
|
||||
* @param doFill
|
||||
* If false, the fill will only be simulated.
|
||||
* @return Amount of fluid that was (or would have been, if simulated) filled into the
|
||||
* container.
|
||||
*/
|
||||
int fill(ItemStack container, FluidStack resource, boolean doFill);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param container
|
||||
* ItemStack which is the fluid container.
|
||||
* @param maxDrain
|
||||
* Maximum amount of fluid to be removed from the container.
|
||||
* @param doFill
|
||||
* If false, the drain will only be simulated.
|
||||
* @return Amount of fluid that was (or would have been, if simulated) drained from the
|
||||
* container.
|
||||
*/
|
||||
FluidStack drain(ItemStack container, int maxDrain, boolean doDrain);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import net.minecraftforge.common.ForgeDirection;
|
||||
|
||||
/**
|
||||
* Implement this interface on TileEntities which should handle fluids, generally storing them in
|
||||
* one or more internal {@link IFluidTank} objects.
|
||||
*
|
||||
* A reference implementation is provided {@link TileFluidHandler}.
|
||||
*
|
||||
* @author King Lemming
|
||||
*
|
||||
*/
|
||||
public interface IFluidHandler
|
||||
{
|
||||
/**
|
||||
* Fills fluid into internal tanks, distribution is left entirely to the IFluidHandler.
|
||||
*
|
||||
* @param from
|
||||
* Orientation the Fluid is pumped in from.
|
||||
* @param resource
|
||||
* FluidStack representing the Fluid and maximum amount of fluid to be filled.
|
||||
* @param doFill
|
||||
* If false, fill will only be simulated.
|
||||
* @return Amount of resource that was (or would have been, if simulated) filled.
|
||||
*/
|
||||
int fill(ForgeDirection from, FluidStack resource, boolean doFill);
|
||||
|
||||
/**
|
||||
* Drains fluid out of internal tanks, distribution is left entirely to the IFluidHandler.
|
||||
*
|
||||
* @param from
|
||||
* Orientation the Fluid is drained to.
|
||||
* @param resource
|
||||
* FluidStack representing the Fluid and maximum amount of fluid to be drained.
|
||||
* @param doDrain
|
||||
* If false, drain will only be simulated.
|
||||
* @return FluidStack representing the Fluid and amount that was (or would have been, if
|
||||
* simulated) drained.
|
||||
*/
|
||||
FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain);
|
||||
|
||||
/**
|
||||
* Drains fluid out of internal tanks, distribution is left entirely to the IFluidHandler.
|
||||
*
|
||||
* This method is not Fluid-sensitive.
|
||||
*
|
||||
* @param from
|
||||
* Orientation the fluid is drained to.
|
||||
* @param maxDrain
|
||||
* Maximum amount of fluid to drain.
|
||||
* @param doDrain
|
||||
* If false, drain will only be simulated.
|
||||
* @return FluidStack representing the Fluid and amount that was (or would have been, if
|
||||
* simulated) drained.
|
||||
*/
|
||||
FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain);
|
||||
|
||||
/**
|
||||
* Returns true if the given fluid can be inserted into the given direction.
|
||||
*
|
||||
* More formally, this should return true if fluid is able to enter from the given direction.
|
||||
*/
|
||||
boolean canFill(ForgeDirection from, Fluid fluid);
|
||||
|
||||
/**
|
||||
* Returns true if the given fluid can be extracted from the given direction.
|
||||
*
|
||||
* More formally, this should return true if fluid is able to leave from the given direction.
|
||||
*/
|
||||
boolean canDrain(ForgeDirection from, Fluid fluid);
|
||||
|
||||
/**
|
||||
* Returns an array of objects which represent the internal tanks. These objects cannot be used
|
||||
* to manipulate the internal tanks. See {@link FluidTankInfo}.
|
||||
*
|
||||
* @param from
|
||||
* Orientation determining which tanks should be queried.
|
||||
* @return Info for the relevant internal tanks.
|
||||
*/
|
||||
FluidTankInfo[] getTankInfo(ForgeDirection from);
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
/**
|
||||
* A tank is the unit of interaction with Fluid inventories.
|
||||
*
|
||||
* A reference implementation can be found at {@link FluidTank}.
|
||||
*
|
||||
* @author King Lemming, cpw (ILiquidTank)
|
||||
*
|
||||
*/
|
||||
public interface IFluidTank
|
||||
{
|
||||
/**
|
||||
* @return FluidStack representing the fluid in the tank, null if the tank is empty.
|
||||
*/
|
||||
FluidStack getFluid();
|
||||
|
||||
/**
|
||||
* @return Current amount of fluid in the tank.
|
||||
*/
|
||||
int getFluidAmount();
|
||||
|
||||
/**
|
||||
* @return Capacity of this fluid tank.
|
||||
*/
|
||||
int getCapacity();
|
||||
|
||||
/**
|
||||
* Returns a wrapper object {@link FluidTankInfo } containing the capacity of the tank and the
|
||||
* FluidStack it holds.
|
||||
*
|
||||
* Should prevent manipulation of the IFluidTank. See {@link FluidTank}.
|
||||
*
|
||||
* @return State information for the IFluidTank.
|
||||
*/
|
||||
FluidTankInfo getInfo();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param resource
|
||||
* FluidStack attempting to fill the tank.
|
||||
* @param doFill
|
||||
* If false, the fill will only be simulated.
|
||||
* @return Amount of fluid that was accepted by the tank.
|
||||
*/
|
||||
int fill(FluidStack resource, boolean doFill);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param maxDrain
|
||||
* Maximum amount of fluid to be removed from the container.
|
||||
* @param doFill
|
||||
* If false, the fill will only be simulated.
|
||||
* @return Amount of fluid that was removed from the tank.
|
||||
*/
|
||||
FluidStack drain(int maxDrain, boolean doDrain);
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
/**
|
||||
* Reference implementation of {@link IFluidContainerItem}. Use/extend this or implement your own.
|
||||
*
|
||||
* @author King Lemming
|
||||
*
|
||||
*/
|
||||
public class ItemFluidContainer extends Item implements IFluidContainerItem
|
||||
{
|
||||
protected int capacity;
|
||||
|
||||
public ItemFluidContainer(int itemID)
|
||||
{
|
||||
super(itemID);
|
||||
}
|
||||
|
||||
public ItemFluidContainer(int itemID, int capacity)
|
||||
{
|
||||
super(itemID);
|
||||
this.capacity = capacity;
|
||||
}
|
||||
|
||||
public ItemFluidContainer setCapacity(int capacity)
|
||||
{
|
||||
this.capacity = capacity;
|
||||
return this;
|
||||
}
|
||||
|
||||
/* IFluidContainerItem */
|
||||
@Override
|
||||
public FluidStack getFluid(ItemStack container)
|
||||
{
|
||||
if (container.stackTagCompound == null || !container.stackTagCompound.hasKey("Fluid"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return FluidStack.loadFluidStackFromNBT(container.stackTagCompound.getCompoundTag("Fluid"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCapacity(ItemStack container)
|
||||
{
|
||||
return capacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fill(ItemStack container, FluidStack resource, boolean doFill)
|
||||
{
|
||||
if (resource == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!doFill)
|
||||
{
|
||||
if (container.stackTagCompound == null || !container.stackTagCompound.hasKey("Fluid"))
|
||||
{
|
||||
return Math.min(capacity, resource.amount);
|
||||
}
|
||||
|
||||
FluidStack stack = FluidStack.loadFluidStackFromNBT(container.stackTagCompound.getCompoundTag("Fluid"));
|
||||
|
||||
if (stack == null)
|
||||
{
|
||||
return Math.min(capacity, resource.amount);
|
||||
}
|
||||
|
||||
if (!stack.isFluidEqual(resource))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.min(capacity - stack.amount, resource.amount);
|
||||
}
|
||||
|
||||
if (container.stackTagCompound == null)
|
||||
{
|
||||
container.stackTagCompound = new NBTTagCompound();
|
||||
}
|
||||
|
||||
if (!container.stackTagCompound.hasKey("Fluid"))
|
||||
{
|
||||
NBTTagCompound fluidTag = resource.writeToNBT(new NBTTagCompound());
|
||||
|
||||
if (capacity < resource.amount)
|
||||
{
|
||||
fluidTag.setInteger("Amount", capacity);
|
||||
container.stackTagCompound.setTag("Fluid", fluidTag);
|
||||
return capacity;
|
||||
}
|
||||
|
||||
container.stackTagCompound.setTag("Fluid", fluidTag);
|
||||
return resource.amount;
|
||||
}
|
||||
|
||||
NBTTagCompound fluidTag = container.stackTagCompound.getCompoundTag("Fluid");
|
||||
FluidStack stack = FluidStack.loadFluidStackFromNBT(fluidTag);
|
||||
|
||||
if (!stack.isFluidEqual(resource))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int filled = capacity - stack.amount;
|
||||
if (resource.amount < filled)
|
||||
{
|
||||
stack.amount += resource.amount;
|
||||
filled = resource.amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.amount = capacity;
|
||||
}
|
||||
|
||||
container.stackTagCompound.setTag("Fluid", stack.writeToNBT(fluidTag));
|
||||
return filled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidStack drain(ItemStack container, int maxDrain, boolean doDrain)
|
||||
{
|
||||
if (container.stackTagCompound == null || !container.stackTagCompound.hasKey("Fluid") || maxDrain == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
FluidStack stack = FluidStack.loadFluidStackFromNBT(container.stackTagCompound.getCompoundTag("Fluid"));
|
||||
if (stack == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int drained = Math.min(stack.amount, maxDrain);
|
||||
if (doDrain)
|
||||
{
|
||||
if (maxDrain >= stack.amount)
|
||||
{
|
||||
container.stackTagCompound.removeTag("Fluid");
|
||||
|
||||
if (container.stackTagCompound.hasNoTags())
|
||||
{
|
||||
container.stackTagCompound = null;
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
NBTTagCompound fluidTag = container.stackTagCompound.getCompoundTag("Fluid");
|
||||
fluidTag.setInteger("Amount", fluidTag.getInteger("Amount") - maxDrain);
|
||||
container.stackTagCompound.setTag("Fluid", fluidTag);
|
||||
}
|
||||
stack.amount = drained;
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,327 @@
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.util.Icon;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
|
||||
|
||||
/**
|
||||
* Default renderer for Forge fluid blocks.
|
||||
*
|
||||
* @author King Lemming
|
||||
*
|
||||
*/
|
||||
public class RenderBlockFluid implements ISimpleBlockRenderingHandler
|
||||
{
|
||||
public static RenderBlockFluid instance = new RenderBlockFluid();
|
||||
|
||||
static final float LIGHT_Y_NEG = 0.5F;
|
||||
static final float LIGHT_Y_POS = 1.0F;
|
||||
static final float LIGHT_XZ_NEG = 0.8F;
|
||||
static final float LIGHT_XZ_POS = 0.6F;
|
||||
static final double RENDER_OFFSET = 0.0010000000474974513D;
|
||||
|
||||
public float getFluidHeightAverage(float[] flow)
|
||||
{
|
||||
float total = 0;
|
||||
int count = 0;
|
||||
|
||||
float end = 0;
|
||||
|
||||
for (int i = 0; i < flow.length; i++)
|
||||
{
|
||||
if (flow[i] >= 0.875F && end != 1F)
|
||||
{
|
||||
end = flow[i];
|
||||
}
|
||||
|
||||
if (flow[i] >= 0)
|
||||
{
|
||||
total += flow[i];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (end == 0)
|
||||
end = total / count;
|
||||
|
||||
return end;
|
||||
}
|
||||
|
||||
public float getFluidHeightForRender(IBlockAccess world, int x, int y, int z, BlockFluidBase block)
|
||||
{
|
||||
if (world.getBlockId(x, y, z) == block.blockID)
|
||||
{
|
||||
if (world.getBlockMaterial(x, y - block.densityDir, z).isLiquid())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (world.getBlockMetadata(x, y, z) == block.getMaxRenderHeightMeta())
|
||||
{
|
||||
return 0.875F;
|
||||
}
|
||||
}
|
||||
return !world.getBlockMaterial(x, y, z).isSolid() && world.getBlockId(x, y - block.densityDir, z) == block.blockID ? 1 : block.getQuantaPercentage(world, x, y, z) * 0.875F;
|
||||
}
|
||||
|
||||
/* ISimpleBlockRenderingHandler */
|
||||
@Override
|
||||
public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer){}
|
||||
|
||||
@Override
|
||||
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer)
|
||||
{
|
||||
if (!(block instanceof BlockFluidBase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
int color = block.colorMultiplier(world, x, y, z);
|
||||
float red = (color >> 16 & 255) / 255.0F;
|
||||
float green = (color >> 8 & 255) / 255.0F;
|
||||
float blue = (color & 255) / 255.0F;
|
||||
|
||||
BlockFluidBase theFluid = (BlockFluidBase) block;
|
||||
int bMeta = world.getBlockMetadata(x, y, z);
|
||||
|
||||
boolean renderTop = world.getBlockId(x, y - theFluid.densityDir, z) != theFluid.blockID;
|
||||
|
||||
boolean renderBottom = block.shouldSideBeRendered(world, x, y + theFluid.densityDir, z, 0) && world.getBlockId(x, y + theFluid.densityDir, z) != theFluid.blockID;
|
||||
|
||||
boolean[] renderSides = new boolean[]
|
||||
{
|
||||
block.shouldSideBeRendered(world, x, y, z - 1, 2),
|
||||
block.shouldSideBeRendered(world, x, y, z + 1, 3),
|
||||
block.shouldSideBeRendered(world, x - 1, y, z, 4),
|
||||
block.shouldSideBeRendered(world, x + 1, y, z, 5)
|
||||
};
|
||||
|
||||
if (!renderTop && !renderBottom && !renderSides[0] && !renderSides[1] && !renderSides[2] && !renderSides[3])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean rendered = false;
|
||||
double heightNW, heightSW, heightSE, heightNE;
|
||||
float flow11 = getFluidHeightForRender(world, x, y, z, theFluid);
|
||||
|
||||
if (flow11 != 1)
|
||||
{
|
||||
float flow00 = getFluidHeightForRender(world, x - 1, y, z - 1, theFluid);
|
||||
float flow01 = getFluidHeightForRender(world, x - 1, y, z, theFluid);
|
||||
float flow02 = getFluidHeightForRender(world, x - 1, y, z + 1, theFluid);
|
||||
float flow10 = getFluidHeightForRender(world, x, y, z - 1, theFluid);
|
||||
float flow12 = getFluidHeightForRender(world, x, y, z + 1, theFluid);
|
||||
float flow20 = getFluidHeightForRender(world, x + 1, y, z - 1, theFluid);
|
||||
float flow21 = getFluidHeightForRender(world, x + 1, y, z, theFluid);
|
||||
float flow22 = getFluidHeightForRender(world, x + 1, y, z + 1, theFluid);
|
||||
|
||||
heightNW = getFluidHeightAverage(new float[]{ flow00, flow01, flow10, flow11 });
|
||||
heightSW = getFluidHeightAverage(new float[]{ flow01, flow02, flow12, flow11 });
|
||||
heightSE = getFluidHeightAverage(new float[]{ flow12, flow21, flow22, flow11 });
|
||||
heightNE = getFluidHeightAverage(new float[]{ flow10, flow20, flow21, flow11 });
|
||||
}
|
||||
else
|
||||
{
|
||||
heightNW = flow11;
|
||||
heightSW = flow11;
|
||||
heightSE = flow11;
|
||||
heightNE = flow11;
|
||||
}
|
||||
|
||||
boolean rises = theFluid.densityDir == 1;
|
||||
if (renderer.renderAllFaces || renderTop)
|
||||
{
|
||||
rendered = true;
|
||||
Icon iconStill = block.getIcon(1, bMeta);
|
||||
float flowDir = (float) BlockFluidBase.getFlowDirection(world, x, y, z);
|
||||
|
||||
if (flowDir > -999.0F)
|
||||
{
|
||||
iconStill = block.getIcon(2, bMeta);
|
||||
}
|
||||
|
||||
heightNW -= RENDER_OFFSET;
|
||||
heightSW -= RENDER_OFFSET;
|
||||
heightSE -= RENDER_OFFSET;
|
||||
heightNE -= RENDER_OFFSET;
|
||||
|
||||
double u1, u2, u3, u4, v1, v2, v3, v4;
|
||||
|
||||
if (flowDir < -999.0F)
|
||||
{
|
||||
u2 = iconStill.getInterpolatedU(0.0D);
|
||||
v2 = iconStill.getInterpolatedV(0.0D);
|
||||
u1 = u2;
|
||||
v1 = iconStill.getInterpolatedV(16.0D);
|
||||
u4 = iconStill.getInterpolatedU(16.0D);
|
||||
v4 = v1;
|
||||
u3 = u4;
|
||||
v3 = v2;
|
||||
}
|
||||
else
|
||||
{
|
||||
float xFlow = MathHelper.sin(flowDir) * 0.25F;
|
||||
float zFlow = MathHelper.cos(flowDir) * 0.25F;
|
||||
u2 = iconStill.getInterpolatedU(8.0F + (-zFlow - xFlow) * 16.0F);
|
||||
v2 = iconStill.getInterpolatedV(8.0F + (-zFlow + xFlow) * 16.0F);
|
||||
u1 = iconStill.getInterpolatedU(8.0F + (-zFlow + xFlow) * 16.0F);
|
||||
v1 = iconStill.getInterpolatedV(8.0F + (zFlow + xFlow) * 16.0F);
|
||||
u4 = iconStill.getInterpolatedU(8.0F + (zFlow + xFlow) * 16.0F);
|
||||
v4 = iconStill.getInterpolatedV(8.0F + (zFlow - xFlow) * 16.0F);
|
||||
u3 = iconStill.getInterpolatedU(8.0F + (zFlow - xFlow) * 16.0F);
|
||||
v3 = iconStill.getInterpolatedV(8.0F + (-zFlow - xFlow) * 16.0F);
|
||||
}
|
||||
|
||||
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x, y, z));
|
||||
tessellator.setColorOpaque_F(LIGHT_Y_POS * red, LIGHT_Y_POS * green, LIGHT_Y_POS * blue);
|
||||
|
||||
if (!rises)
|
||||
{
|
||||
tessellator.addVertexWithUV(x + 0, y + heightNW, z + 0, u2, v2);
|
||||
tessellator.addVertexWithUV(x + 0, y + heightSW, z + 1, u1, v1);
|
||||
tessellator.addVertexWithUV(x + 1, y + heightSE, z + 1, u4, v4);
|
||||
tessellator.addVertexWithUV(x + 1, y + heightNE, z + 0, u3, v3);
|
||||
}
|
||||
else
|
||||
{
|
||||
tessellator.addVertexWithUV(x + 1, y + 1 - heightNE, z + 0, u3, v3);
|
||||
tessellator.addVertexWithUV(x + 1, y + 1 - heightSE, z + 1, u4, v4);
|
||||
tessellator.addVertexWithUV(x + 0, y + 1 - heightSW, z + 1, u1, v1);
|
||||
tessellator.addVertexWithUV(x + 0, y + 1 - heightNW, z + 0, u2, v2);
|
||||
}
|
||||
}
|
||||
|
||||
if (renderer.renderAllFaces || renderBottom)
|
||||
{
|
||||
rendered = true;
|
||||
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x, y - 1, z));
|
||||
if (!rises)
|
||||
{
|
||||
tessellator.setColorOpaque_F(LIGHT_Y_NEG * red, LIGHT_Y_NEG * green, LIGHT_Y_NEG * blue);
|
||||
renderer.renderFaceYNeg(block, x, y + RENDER_OFFSET, z, block.getIcon(0, bMeta));
|
||||
}
|
||||
else
|
||||
{
|
||||
tessellator.setColorOpaque_F(LIGHT_Y_POS * red, LIGHT_Y_POS * green, LIGHT_Y_POS * blue);
|
||||
renderer.renderFaceYPos(block, x, y + RENDER_OFFSET, z, block.getIcon(1, bMeta));
|
||||
}
|
||||
}
|
||||
|
||||
for (int side = 0; side < 4; ++side)
|
||||
{
|
||||
int x2 = x;
|
||||
int z2 = z;
|
||||
|
||||
switch (side)
|
||||
{
|
||||
case 0: --z2; break;
|
||||
case 1: ++z2; break;
|
||||
case 2: --x2; break;
|
||||
case 3: ++x2; break;
|
||||
}
|
||||
|
||||
Icon iconFlow = block.getIcon(side + 2, bMeta);
|
||||
if (renderer.renderAllFaces || renderSides[side])
|
||||
{
|
||||
rendered = true;
|
||||
|
||||
double ty1;
|
||||
double tx1;
|
||||
double ty2;
|
||||
double tx2;
|
||||
double tz1;
|
||||
double tz2;
|
||||
|
||||
if (side == 0)
|
||||
{
|
||||
ty1 = heightNW;
|
||||
ty2 = heightNE;
|
||||
tx1 = x;
|
||||
tx2 = x + 1;
|
||||
tz1 = z + RENDER_OFFSET;
|
||||
tz2 = z + RENDER_OFFSET;
|
||||
}
|
||||
else if (side == 1)
|
||||
{
|
||||
ty1 = heightSE;
|
||||
ty2 = heightSW;
|
||||
tx1 = x + 1;
|
||||
tx2 = x;
|
||||
tz1 = z + 1 - RENDER_OFFSET;
|
||||
tz2 = z + 1 - RENDER_OFFSET;
|
||||
}
|
||||
else if (side == 2)
|
||||
{
|
||||
ty1 = heightSW;
|
||||
ty2 = heightNW;
|
||||
tx1 = x + RENDER_OFFSET;
|
||||
tx2 = x + RENDER_OFFSET;
|
||||
tz1 = z + 1;
|
||||
tz2 = z;
|
||||
}
|
||||
else
|
||||
{
|
||||
ty1 = heightNE;
|
||||
ty2 = heightSE;
|
||||
tx1 = x + 1 - RENDER_OFFSET;
|
||||
tx2 = x + 1 - RENDER_OFFSET;
|
||||
tz1 = z;
|
||||
tz2 = z + 1;
|
||||
}
|
||||
|
||||
float u1Flow = iconFlow.getInterpolatedU(0.0D);
|
||||
float u2Flow = iconFlow.getInterpolatedU(8.0D);
|
||||
float v1Flow = iconFlow.getInterpolatedV((1.0D - ty1) * 16.0D * 0.5D);
|
||||
float v2Flow = iconFlow.getInterpolatedV((1.0D - ty2) * 16.0D * 0.5D);
|
||||
float v3Flow = iconFlow.getInterpolatedV(8.0D);
|
||||
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x2, y, z2));
|
||||
float sideLighting = 1.0F;
|
||||
|
||||
if (side < 2)
|
||||
{
|
||||
sideLighting = LIGHT_XZ_NEG;
|
||||
}
|
||||
else
|
||||
{
|
||||
sideLighting = LIGHT_XZ_POS;
|
||||
}
|
||||
|
||||
tessellator.setColorOpaque_F(LIGHT_Y_POS * sideLighting * red, LIGHT_Y_POS * sideLighting * green, LIGHT_Y_POS * sideLighting * blue);
|
||||
|
||||
if (!rises)
|
||||
{
|
||||
tessellator.addVertexWithUV(tx1, y + ty1, tz1, u1Flow, v1Flow);
|
||||
tessellator.addVertexWithUV(tx2, y + ty2, tz2, u2Flow, v2Flow);
|
||||
tessellator.addVertexWithUV(tx2, y + 0, tz2, u2Flow, v3Flow);
|
||||
tessellator.addVertexWithUV(tx1, y + 0, tz1, u1Flow, v3Flow);
|
||||
}
|
||||
else
|
||||
{
|
||||
tessellator.addVertexWithUV(tx1, y + 1 - 0, tz1, u1Flow, v3Flow);
|
||||
tessellator.addVertexWithUV(tx2, y + 1 - 0, tz2, u2Flow, v3Flow);
|
||||
tessellator.addVertexWithUV(tx2, y + 1 - ty2, tz2, u2Flow, v2Flow);
|
||||
tessellator.addVertexWithUV(tx1, y + 1 - ty1, tz1, u1Flow, v1Flow);
|
||||
}
|
||||
}
|
||||
}
|
||||
renderer.renderMinY = 0;
|
||||
renderer.renderMaxY = 1;
|
||||
return rendered;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender3DInInventory(){ return false; }
|
||||
@Override
|
||||
public int getRenderId()
|
||||
{
|
||||
return FluidRegistry.renderIdFluid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
|
||||
package net.minecraftforge.fluids;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.common.ForgeDirection;
|
||||
|
||||
/**
|
||||
* Reference Tile Entity implementation of {@link IFluidHandler}. Use/extend this or write your own.
|
||||
*
|
||||
* @author King Lemming
|
||||
*
|
||||
*/
|
||||
public class TileFluidHandler extends TileEntity implements IFluidHandler
|
||||
{
|
||||
protected FluidTank tank = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME);
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound tag)
|
||||
{
|
||||
super.readFromNBT(tag);
|
||||
tank.writeToNBT(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT(NBTTagCompound tag)
|
||||
{
|
||||
super.writeToNBT(tag);
|
||||
tank.readFromNBT(tag);
|
||||
}
|
||||
|
||||
/* IFluidHandler */
|
||||
@Override
|
||||
public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
|
||||
{
|
||||
return tank.fill(resource, doFill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
|
||||
{
|
||||
if (resource == null || !resource.isFluidEqual(tank.getFluid()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return tank.drain(resource.amount, doDrain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
|
||||
{
|
||||
return tank.drain(maxDrain, doDrain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canFill(ForgeDirection from, Fluid fluid)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDrain(ForgeDirection from, Fluid fluid)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidTankInfo[] getTankInfo(ForgeDirection from)
|
||||
{
|
||||
return new FluidTankInfo[] { tank.getInfo() };
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import net.minecraft.nbt.NBTTagCompound;
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Deprecated //See new net.minecraftforge.fluids
|
||||
public interface IBlockLiquid extends ILiquid {
|
||||
/**
|
||||
* Controls the type of block that is generated by this IBlockLiquid
|
||||
|
||||
@@ -13,6 +13,7 @@ package net.minecraftforge.liquids;
|
||||
* Liquids implement this interface
|
||||
*
|
||||
*/
|
||||
@Deprecated //See new net.minecraftforge.fluids
|
||||
public interface ILiquid {
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@ package net.minecraftforge.liquids;
|
||||
*
|
||||
* @author cpw
|
||||
*/
|
||||
@Deprecated //See new net.minecraftforge.fluids
|
||||
public interface ILiquidTank {
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package net.minecraftforge.liquids;
|
||||
|
||||
import net.minecraftforge.common.ForgeDirection;
|
||||
|
||||
@Deprecated //See new net.minecraftforge.fluids
|
||||
public interface ITankContainer {
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,7 +11,7 @@ package net.minecraftforge.liquids;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
@Deprecated //See new net.minecraftforge.fluids
|
||||
public class LiquidContainerData {
|
||||
|
||||
public final LiquidStack stillLiquid;
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.Set;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
@Deprecated //See new net.minecraftforge.fluids
|
||||
public class LiquidContainerRegistry
|
||||
{
|
||||
public static final int BUCKET_VOLUME = 1000;
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.google.common.collect.ImmutableMap;
|
||||
*
|
||||
* @author CovertJaguar <railcraft.wikispaces.com>
|
||||
*/
|
||||
@Deprecated //See new net.minecraftforge.fluids
|
||||
public abstract class LiquidDictionary
|
||||
{
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
@Deprecated //See new net.minecraftforge.fluids
|
||||
public class LiquidEvent extends Event {
|
||||
public final LiquidStack liquid;
|
||||
public final int x;
|
||||
|
||||
@@ -22,6 +22,7 @@ import net.minecraft.util.Icon;
|
||||
*
|
||||
* @author SirSengir
|
||||
*/
|
||||
@Deprecated //See new net.minecraftforge.fluids
|
||||
public class LiquidStack
|
||||
{
|
||||
public final int itemID;
|
||||
@@ -202,11 +203,11 @@ public class LiquidStack
|
||||
{
|
||||
if (itemID == Block.waterStill.blockID)
|
||||
{
|
||||
return BlockFluid.func_94424_b("water");
|
||||
return BlockFluid.getFluidIcon("water");
|
||||
}
|
||||
else if (itemID == Block.lavaStill.blockID)
|
||||
{
|
||||
return BlockFluid.func_94424_b("lava");
|
||||
return BlockFluid.getFluidIcon("lava");
|
||||
}
|
||||
return renderingIcon;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import net.minecraft.tileentity.TileEntity;
|
||||
/**
|
||||
* Reference implementation of ILiquidTank. Use this or implement your own.
|
||||
*/
|
||||
@Deprecated //See new net.minecraftforge.fluids
|
||||
public class LiquidTank implements ILiquidTank {
|
||||
private LiquidStack liquid;
|
||||
private int capacity;
|
||||
|
||||
@@ -49,19 +49,38 @@ public class OreDictionary
|
||||
registerOre("stickWood", Item.stick);
|
||||
registerOre("treeSapling", new ItemStack(Block.sapling, 1, WILDCARD_VALUE));
|
||||
registerOre("treeLeaves", new ItemStack(Block.leaves, 1, WILDCARD_VALUE));
|
||||
registerOre("oreGold", Block.oreGold);
|
||||
registerOre("oreIron", Block.oreIron);
|
||||
registerOre("oreLapis", Block.oreLapis);
|
||||
registerOre("oreDiamond", Block.oreDiamond);
|
||||
registerOre("oreGold", Block.oreGold);
|
||||
registerOre("oreIron", Block.oreIron);
|
||||
registerOre("oreLapis", Block.oreLapis);
|
||||
registerOre("oreDiamond", Block.oreDiamond);
|
||||
registerOre("oreRedstone", Block.oreRedstone);
|
||||
registerOre("oreEmerald", Block.oreEmerald);
|
||||
registerOre("oreQuartz", Block.oreNetherQuartz);
|
||||
registerOre("oreEmerald", Block.oreEmerald);
|
||||
registerOre("oreQuartz", Block.oreNetherQuartz);
|
||||
registerOre("stone", Block.stone);
|
||||
registerOre("cobblestone", Block.cobblestone);
|
||||
registerOre("record", Item.record13);
|
||||
registerOre("record", Item.recordCat);
|
||||
registerOre("record", Item.recordBlocks);
|
||||
registerOre("record", Item.recordChirp);
|
||||
registerOre("record", Item.recordFar);
|
||||
registerOre("record", Item.recordMall);
|
||||
registerOre("record", Item.recordMellohi);
|
||||
registerOre("record", Item.recordStal);
|
||||
registerOre("record", Item.recordStrad);
|
||||
registerOre("record", Item.recordWard);
|
||||
registerOre("record", Item.record11);
|
||||
registerOre("record", Item.recordWait);
|
||||
}
|
||||
|
||||
// Build our list of items to replace with ore tags
|
||||
Map<ItemStack, String> replacements = new HashMap<ItemStack, String>();
|
||||
replacements.put(new ItemStack(Block.planks, 1, WILDCARD_VALUE), "plankWood");
|
||||
replacements.put(new ItemStack(Item.stick), "stickWood");
|
||||
replacements.put(new ItemStack(Block.planks), "plankWood");
|
||||
replacements.put(new ItemStack(Block.planks, 1, WILDCARD_VALUE), "plankWood");
|
||||
replacements.put(new ItemStack(Block.stone), "stone");
|
||||
replacements.put(new ItemStack(Block.stone, 1, WILDCARD_VALUE), "stone");
|
||||
replacements.put(new ItemStack(Block.cobblestone), "cobblestone");
|
||||
replacements.put(new ItemStack(Block.cobblestone, 1, WILDCARD_VALUE), "cobblestone");
|
||||
|
||||
// Register dyes
|
||||
String[] dyes =
|
||||
@@ -102,6 +121,14 @@ public class OreDictionary
|
||||
{
|
||||
new ItemStack(Block.blockLapis),
|
||||
new ItemStack(Item.cookie),
|
||||
new ItemStack(Block.stoneBrick),
|
||||
new ItemStack(Block.stoneSingleSlab),
|
||||
new ItemStack(Block.stairsCobblestone),
|
||||
new ItemStack(Block.cobblestoneWall),
|
||||
new ItemStack(Block.stairsWoodOak),
|
||||
new ItemStack(Block.stairsWoodBirch),
|
||||
new ItemStack(Block.stairsWoodJungle),
|
||||
new ItemStack(Block.stairsWoodSpruce)
|
||||
};
|
||||
|
||||
List recipes = CraftingManager.getInstance().getRecipeList();
|
||||
|
||||
@@ -0,0 +1,276 @@
|
||||
package net.minecraftforge.oredict;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import cpw.mods.fml.common.DummyModContainer;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.toposort.TopologicalSort;
|
||||
import cpw.mods.fml.common.toposort.TopologicalSort.DirectedGraph;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import net.minecraft.item.crafting.CraftingManager;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.item.crafting.RecipeFireworks;
|
||||
import net.minecraft.item.crafting.RecipesArmorDyes;
|
||||
import net.minecraft.item.crafting.RecipesMapCloning;
|
||||
import net.minecraft.item.crafting.RecipesMapExtending;
|
||||
import net.minecraft.item.crafting.ShapedRecipes;
|
||||
import net.minecraft.item.crafting.ShapelessRecipes;
|
||||
import static net.minecraftforge.oredict.RecipeSorter.Category.*;
|
||||
|
||||
public class RecipeSorter implements Comparator<IRecipe>
|
||||
{
|
||||
public enum Category
|
||||
{
|
||||
UNKNOWN,
|
||||
SHAPELESS,
|
||||
SHAPED
|
||||
};
|
||||
|
||||
private static class SortEntry
|
||||
{
|
||||
private String name;
|
||||
private Class cls;
|
||||
private Category cat;
|
||||
List<String> before = Lists.newArrayList();
|
||||
List<String> after = Lists.newArrayList();
|
||||
|
||||
private SortEntry(String name, Class cls, Category cat, String deps)
|
||||
{
|
||||
this.name = name;
|
||||
this.cls = cls;
|
||||
this.cat = cat;
|
||||
parseDepends(deps);
|
||||
}
|
||||
|
||||
private void parseDepends(String deps)
|
||||
{
|
||||
if (deps.isEmpty()) return;
|
||||
for (String dep : deps.split(" "))
|
||||
{
|
||||
if (dep.startsWith("before:"))
|
||||
{
|
||||
before.add(dep.substring(7));
|
||||
}
|
||||
else if (dep.startsWith("after:"))
|
||||
{
|
||||
after.add(dep.substring(6));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("Invalid dependancy: " + dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("RecipeEntry(\"").append(name).append("\", ");
|
||||
buf.append(cat.name()).append(", ");
|
||||
buf.append(cls == null ? "" : cls.getName()).append(")");
|
||||
|
||||
if (before.size() > 0)
|
||||
{
|
||||
buf.append(" Before: ").append(Joiner.on(", ").join(before));
|
||||
}
|
||||
|
||||
if (after.size() > 0)
|
||||
{
|
||||
buf.append(" After: ").append(Joiner.on(", ").join(after));
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return name.hashCode();
|
||||
}
|
||||
};
|
||||
|
||||
private static Map<Class, Category> categories = Maps.newHashMap();
|
||||
private static Map<String, Class> types = Maps.newHashMap();
|
||||
private static Map<String, SortEntry> entries = Maps.newHashMap();
|
||||
private static Map<Class, Integer> priorities = Maps.newHashMap();
|
||||
|
||||
public static RecipeSorter INSTANCE = new RecipeSorter();
|
||||
private static boolean isDirty = true;
|
||||
|
||||
private static SortEntry before = new SortEntry("Before", null, UNKNOWN, "");
|
||||
private static SortEntry after = new SortEntry("After", null, UNKNOWN, "");
|
||||
|
||||
private RecipeSorter()
|
||||
{
|
||||
register("minecraft:shaped", ShapedRecipes.class, SHAPED, "before:minecraft:shapeless");
|
||||
register("minecraft:mapextending", RecipesMapExtending.class, SHAPED, "after:minecraft:shaped before:minecraft:shapeless");
|
||||
register("minecraft:shapeless", ShapelessRecipes.class, SHAPELESS, "after:minecraft:shaped");
|
||||
register("minecraft:fireworks", RecipeFireworks.class, SHAPELESS, "after:minecraft:shapeless");
|
||||
register("minecraft:armordyes", RecipesArmorDyes.class, SHAPELESS, "after:minecraft:shapeless");
|
||||
register("minecraft:mapcloning", RecipesMapCloning.class, SHAPELESS, "after:minecraft:shapeless");
|
||||
|
||||
register("forge:shapedore", ShapedOreRecipe.class, SHAPED, "after:minecraft:shaped before:minecraft:shapeless");
|
||||
register("forge:shapelessore", ShapelessOreRecipe.class, SHAPELESS, "after:minecraft:shapeless");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(IRecipe r1, IRecipe r2)
|
||||
{
|
||||
Category c1 = getCategory(r1);
|
||||
Category c2 = getCategory(r2);
|
||||
if (c1 == SHAPELESS && c2 == SHAPED) return 1;
|
||||
if (c1 == SHAPED && c2 == SHAPELESS) return -1;
|
||||
if (r2.getRecipeSize() < r1.getRecipeSize()) return -1;
|
||||
if (r2.getRecipeSize() > r1.getRecipeSize()) return 1;
|
||||
return getPriority(r2) - getPriority(r1); // high priority value first!
|
||||
}
|
||||
|
||||
private static Set<Class> warned = Sets.newHashSet();
|
||||
public static void sortCraftManager()
|
||||
{
|
||||
bake();
|
||||
FMLLog.fine("Sorting recipies");
|
||||
warned.clear();
|
||||
Collections.sort(CraftingManager.getInstance().getRecipeList(), INSTANCE);
|
||||
}
|
||||
|
||||
public static void register(String name, Class recipe, Category category, String dependancies)
|
||||
{
|
||||
assert(category != UNKNOWN) : "Category must not be unknown!";
|
||||
isDirty = true;
|
||||
|
||||
SortEntry entry = new SortEntry(name, recipe, category, dependancies);
|
||||
entries.put(name, entry);
|
||||
setCategory(recipe, category);
|
||||
}
|
||||
|
||||
public static void setCategory(Class recipe, Category category)
|
||||
{
|
||||
assert(category != UNKNOWN) : "Category must not be unknown!";
|
||||
categories.put(recipe, category);
|
||||
}
|
||||
|
||||
public static Category getCategory(IRecipe recipe)
|
||||
{
|
||||
return getCategory(recipe.getClass());
|
||||
}
|
||||
|
||||
public static Category getCategory(Class recipe)
|
||||
{
|
||||
Class cls = recipe;
|
||||
Category ret = categories.get(cls);
|
||||
|
||||
if (ret == null)
|
||||
{
|
||||
cls = cls.getSuperclass();
|
||||
while (cls != Object.class)
|
||||
{
|
||||
ret = categories.get(cls);
|
||||
if (ret != null)
|
||||
{
|
||||
categories.put(recipe, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret == null ? UNKNOWN : ret;
|
||||
}
|
||||
|
||||
private static int getPriority(IRecipe recipe)
|
||||
{
|
||||
Class cls = recipe.getClass();
|
||||
Integer ret = priorities.get(cls);
|
||||
|
||||
if (ret == null)
|
||||
{
|
||||
if (!INSTANCE.warned.contains(cls))
|
||||
{
|
||||
FMLLog.fine(" Unknown recipe class! %s Modder please refer to %s", cls.getName(), RecipeSorter.class.getName());
|
||||
warned.add(cls);
|
||||
}
|
||||
cls = cls.getSuperclass();
|
||||
while (cls != Object.class)
|
||||
{
|
||||
ret = priorities.get(cls);
|
||||
if (ret != null)
|
||||
{
|
||||
priorities.put(recipe.getClass(), ret);
|
||||
FMLLog.fine(" Parent Found: %d - %s", ret.intValue(), cls.getName());
|
||||
return ret.intValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret == null ? 0 : ret.intValue();
|
||||
}
|
||||
|
||||
private static void bake()
|
||||
{
|
||||
if (!isDirty) return;
|
||||
FMLLog.fine("Forge RecipeSorter Baking:");
|
||||
DirectedGraph<SortEntry> sorter = new DirectedGraph<SortEntry>();
|
||||
sorter.addNode(before);
|
||||
sorter.addNode(after);
|
||||
sorter.addEdge(before, after);
|
||||
|
||||
for (Map.Entry<String, SortEntry> entry : entries.entrySet())
|
||||
{
|
||||
sorter.addNode(entry.getValue());
|
||||
}
|
||||
|
||||
for (Map.Entry<String, SortEntry> e : entries.entrySet())
|
||||
{
|
||||
SortEntry entry = e.getValue();
|
||||
boolean postAdded = false;
|
||||
|
||||
sorter.addEdge(before, entry);
|
||||
for (String dep : entry.after)
|
||||
{
|
||||
if (entries.containsKey(dep))
|
||||
{
|
||||
sorter.addEdge(entries.get(dep), entry);
|
||||
}
|
||||
}
|
||||
|
||||
for (String dep : entry.before)
|
||||
{
|
||||
postAdded = true;
|
||||
sorter.addEdge(entry, after);
|
||||
if (entries.containsKey(dep))
|
||||
{
|
||||
sorter.addEdge(entry, entries.get(dep));
|
||||
}
|
||||
}
|
||||
|
||||
if (!postAdded)
|
||||
{
|
||||
sorter.addEdge(entry, after);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
List<SortEntry> sorted = TopologicalSort.topologicalSort(sorter);
|
||||
int x = sorted.size();
|
||||
for (SortEntry entry : sorted)
|
||||
{
|
||||
FMLLog.fine(" %d: %s", x, entry);
|
||||
priorities.put(entry.cls, x--);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package net.minecraftforge.server;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.common.collect.MapMaker;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
public class ForgeTimeTracker {
|
||||
public static boolean tileEntityTracking;
|
||||
public static int tileEntityTrackingDuration;
|
||||
public static long tileEntityTrackingTime;
|
||||
|
||||
private Map<TileEntity,int[]> tileEntityTimings;
|
||||
private Map<Entity,int[]> entityTimings;
|
||||
|
||||
private static final ForgeTimeTracker INSTANCE = new ForgeTimeTracker();
|
||||
|
||||
private WeakReference<TileEntity> tile;
|
||||
private WeakReference<Entity> entity;
|
||||
|
||||
private long timing;
|
||||
|
||||
private ForgeTimeTracker()
|
||||
{
|
||||
MapMaker mm = new MapMaker();
|
||||
mm.weakKeys();
|
||||
tileEntityTimings = mm.makeMap();
|
||||
entityTimings = mm.makeMap();
|
||||
}
|
||||
|
||||
|
||||
private void trackTileStart(TileEntity tileEntity, long nanoTime)
|
||||
{
|
||||
if (tileEntityTrackingTime == 0)
|
||||
{
|
||||
tileEntityTrackingTime = nanoTime;
|
||||
}
|
||||
else if (tileEntityTrackingTime + tileEntityTrackingDuration < nanoTime)
|
||||
{
|
||||
tileEntityTracking = false;
|
||||
tileEntityTrackingTime = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
tile = new WeakReference<TileEntity>(tileEntity);
|
||||
timing = nanoTime;
|
||||
}
|
||||
|
||||
|
||||
private void trackTileEnd(TileEntity tileEntity, long nanoTime)
|
||||
{
|
||||
if (tile == null || tile.get() != tileEntity)
|
||||
{
|
||||
tile = null;
|
||||
// race, exit
|
||||
return;
|
||||
}
|
||||
int[] timings = tileEntityTimings.get(tileEntity);
|
||||
if (timings == null)
|
||||
{
|
||||
timings = new int[101];
|
||||
tileEntityTimings.put(tileEntity, timings);
|
||||
}
|
||||
int idx = timings[100] = (timings[100] + 1) % 100;
|
||||
timings[idx] = (int) (nanoTime - timing);
|
||||
}
|
||||
|
||||
public static ImmutableMap<TileEntity,int[]> getTileTimings()
|
||||
{
|
||||
return INSTANCE.buildImmutableTileEntityTimingMap();
|
||||
}
|
||||
|
||||
private ImmutableMap<TileEntity, int[]> buildImmutableTileEntityTimingMap()
|
||||
{
|
||||
Builder<TileEntity, int[]> builder = ImmutableMap.<TileEntity,int[]>builder();
|
||||
for (Entry<TileEntity, int[]> entry : tileEntityTimings.entrySet())
|
||||
{
|
||||
builder.put(entry.getKey(), Arrays.copyOfRange(entry.getValue(), 0, 100));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
public static void trackStart(TileEntity tileEntity)
|
||||
{
|
||||
if (!tileEntityTracking) return;
|
||||
INSTANCE.trackTileStart(tileEntity, System.nanoTime());
|
||||
}
|
||||
|
||||
public static void trackEnd(TileEntity tileEntity)
|
||||
{
|
||||
if (!tileEntityTracking) return;
|
||||
INSTANCE.trackTileEnd(tileEntity, System.nanoTime());
|
||||
}
|
||||
|
||||
public static void trackStart(Entity par1Entity)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static void trackEnd(Entity par1Entity)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package net.minecraftforge.server.command;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Multiset;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.ICommand;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.command.WrongUsageException;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.ChatMessageComponent;
|
||||
import net.minecraft.world.ChunkCoordIntPair;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import net.minecraftforge.common.ForgeChunkManager;
|
||||
import net.minecraftforge.server.ForgeTimeTracker;
|
||||
|
||||
public class ForgeCommand extends CommandBase {
|
||||
|
||||
private MinecraftServer server;
|
||||
|
||||
public ForgeCommand(MinecraftServer server)
|
||||
{
|
||||
this.server = server;
|
||||
}
|
||||
private static final DecimalFormat timeFormatter = new DecimalFormat("########0.000");
|
||||
|
||||
@Override
|
||||
public String getCommandName()
|
||||
{
|
||||
return "forge";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandUsage(ICommandSender icommandsender)
|
||||
{
|
||||
return "commands.forge.usage";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRequiredPermissionLevel()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args)
|
||||
{
|
||||
if (args.length == 0)
|
||||
{
|
||||
throw new WrongUsageException("commands.forge.usage");
|
||||
}
|
||||
else if ("help".equals(args[0]))
|
||||
{
|
||||
throw new WrongUsageException("commands.forge.usage");
|
||||
}
|
||||
else if ("tps".equals(args[0]))
|
||||
{
|
||||
displayTPS(sender,args);
|
||||
}
|
||||
else if ("tpslog".equals(args[0]))
|
||||
{
|
||||
doTPSLog(sender,args);
|
||||
}
|
||||
else if ("track".equals(args[0]))
|
||||
{
|
||||
handleTracking(sender, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new WrongUsageException("commands.forge.usage");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleTracking(ICommandSender sender, String[] args)
|
||||
{
|
||||
if (args.length != 3)
|
||||
{
|
||||
throw new WrongUsageException("commands.forge.usage.tracking");
|
||||
}
|
||||
String type = args[1];
|
||||
int duration = parseIntBounded(sender, args[2], 1, 60);
|
||||
|
||||
if ("te".equals(type))
|
||||
{
|
||||
doTurnOnTileEntityTracking(sender, duration);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new WrongUsageException("commands.forge.usage.tracking");
|
||||
}
|
||||
}
|
||||
|
||||
private void doTurnOnTileEntityTracking(ICommandSender sender, int duration)
|
||||
{
|
||||
ForgeTimeTracker.tileEntityTrackingDuration = duration;
|
||||
ForgeTimeTracker.tileEntityTracking = true;
|
||||
sender.sendChatToPlayer(ChatMessageComponent.createFromTranslationWithSubstitutions("commands.forge.tracking.te.enabled", duration));
|
||||
}
|
||||
|
||||
private void doTPSLog(ICommandSender sender, String[] args)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void displayTPS(ICommandSender sender, String[] args)
|
||||
{
|
||||
int dim = 0;
|
||||
boolean summary = true;
|
||||
if (args.length > 1)
|
||||
{
|
||||
dim = parseInt(sender, args[1]);
|
||||
summary = false;
|
||||
}
|
||||
if (summary)
|
||||
{
|
||||
for (Integer dimId : DimensionManager.getIDs())
|
||||
{
|
||||
double worldTickTime = ForgeCommand.mean(this.server.worldTickTimes.get(dimId)) * 1.0E-6D;
|
||||
double worldTPS = Math.min(1000.0/worldTickTime, 20);
|
||||
sender.sendChatToPlayer(ChatMessageComponent.createFromTranslationWithSubstitutions("commands.forge.tps.summary",String.format("Dim %d", dimId), timeFormatter.format(worldTickTime), timeFormatter.format(worldTPS)));
|
||||
}
|
||||
double meanTickTime = ForgeCommand.mean(this.server.tickTimeArray) * 1.0E-6D;
|
||||
double meanTPS = Math.min(1000.0/meanTickTime, 20);
|
||||
sender.sendChatToPlayer(ChatMessageComponent.createFromTranslationWithSubstitutions("commands.forge.tps.summary","Overall", timeFormatter.format(meanTickTime), timeFormatter.format(meanTPS)));
|
||||
}
|
||||
else
|
||||
{
|
||||
double worldTickTime = ForgeCommand.mean(this.server.worldTickTimes.get(dim)) * 1.0E-6D;
|
||||
double worldTPS = Math.min(1000.0/worldTickTime, 20);
|
||||
sender.sendChatToPlayer(ChatMessageComponent.createFromTranslationWithSubstitutions("commands.forge.tps.summary",String.format("Dim %d", dim), timeFormatter.format(worldTickTime), timeFormatter.format(worldTPS)));
|
||||
}
|
||||
}
|
||||
|
||||
private static long mean(long[] values)
|
||||
{
|
||||
long sum = 0l;
|
||||
for (long v : values)
|
||||
{
|
||||
sum+=v;
|
||||
}
|
||||
|
||||
return sum / values.length;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
+1
-1
Submodule fml updated: 902772ed0c...23baf3a8ce.
+1
-1
@@ -1,3 +1,3 @@
|
||||
@echo off
|
||||
.\fml\python\python_fml install.py
|
||||
.\fml\python\python_fml install.py %*
|
||||
pause
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
#!/bin/bash
|
||||
python install.py
|
||||
python install.py "$@"
|
||||
@@ -1,6 +1,6 @@
|
||||
--- ../src_base/minecraft/net/minecraft/block/Block.java
|
||||
+++ ../src_work/minecraft/net/minecraft/block/Block.java
|
||||
@@ -1,15 +1,20 @@
|
||||
@@ -1,15 +1,22 @@
|
||||
package net.minecraft.block;
|
||||
|
||||
-import cpw.mods.fml.relauncher.Side;
|
||||
@@ -20,10 +20,12 @@
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
+import net.minecraft.entity.EnumCreatureType;
|
||||
+import net.minecraft.entity.boss.EntityDragon;
|
||||
+import net.minecraft.entity.boss.EntityWither;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.item.EntityXPOrb;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -26,8 +31,10 @@
|
||||
@@ -26,8 +33,10 @@
|
||||
import net.minecraft.item.ItemSnow;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.stats.StatList;
|
||||
@@ -34,7 +36,7 @@
|
||||
import net.minecraft.util.Icon;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.util.StatCollector;
|
||||
@@ -35,9 +42,19 @@
|
||||
@@ -35,9 +44,20 @@
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
@@ -44,6 +46,7 @@
|
||||
+import net.minecraftforge.common.ForgeHooks;
|
||||
+import net.minecraftforge.common.IPlantable;
|
||||
+import net.minecraftforge.common.RotationHelper;
|
||||
+import net.minecraftforge.event.ForgeEventFactory;
|
||||
+import cpw.mods.fml.relauncher.Side;
|
||||
+import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
@@ -54,7 +57,7 @@
|
||||
/**
|
||||
* used as foreach item, if item.tab = current tab, display it on the screen
|
||||
*/
|
||||
@@ -460,9 +477,10 @@
|
||||
@@ -460,9 +480,10 @@
|
||||
return this.needsRandomTick;
|
||||
}
|
||||
|
||||
@@ -66,7 +69,7 @@
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -485,7 +503,7 @@
|
||||
@@ -485,7 +506,7 @@
|
||||
*/
|
||||
public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
|
||||
{
|
||||
@@ -75,7 +78,7 @@
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@@ -495,7 +513,7 @@
|
||||
@@ -495,7 +516,7 @@
|
||||
*/
|
||||
public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
|
||||
{
|
||||
@@ -84,9 +87,9 @@
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@@ -645,7 +663,13 @@
|
||||
/**
|
||||
* ejects contained items into the world, and notifies neighbours of an update, as appropriate
|
||||
@@ -648,7 +669,13 @@
|
||||
* different metadata value, but before the new metadata value is set. Args: World, x, y, z, old block ID, old
|
||||
* metadata
|
||||
*/
|
||||
- public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) {}
|
||||
+ public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
|
||||
@@ -99,7 +102,7 @@
|
||||
|
||||
/**
|
||||
* Returns the quantity of items to drop on block destruction.
|
||||
@@ -670,7 +694,7 @@
|
||||
@@ -673,7 +700,7 @@
|
||||
public float getPlayerRelativeBlockHardness(EntityPlayer par1EntityPlayer, World par2World, int par3, int par4, int par5)
|
||||
{
|
||||
float f = this.getBlockHardness(par2World, par3, par4, par5);
|
||||
@@ -108,7 +111,7 @@
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -688,18 +712,13 @@
|
||||
@@ -691,18 +718,14 @@
|
||||
{
|
||||
if (!par1World.isRemote)
|
||||
{
|
||||
@@ -116,7 +119,8 @@
|
||||
-
|
||||
- for (int k1 = 0; k1 < j1; ++k1)
|
||||
+ ArrayList<ItemStack> items = getBlockDropped(par1World, par2, par3, par4, par5, par7);
|
||||
+
|
||||
+ par6 = ForgeEventFactory.fireBlockHarvesting(items, par1World, this, par2, par3, par4, par5, par7, par6, false, harvesters.get());
|
||||
+
|
||||
+ for (ItemStack item : items)
|
||||
{
|
||||
if (par1World.rand.nextFloat() <= par6)
|
||||
@@ -131,7 +135,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -932,7 +951,8 @@
|
||||
@@ -935,7 +958,8 @@
|
||||
public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
|
||||
{
|
||||
int l = par1World.getBlockId(par2, par3, par4);
|
||||
@@ -141,19 +145,48 @@
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1092,7 +1112,7 @@
|
||||
@@ -1086,6 +1110,7 @@
|
||||
*/
|
||||
public void setBlockBoundsForItemRender() {}
|
||||
|
||||
+ private ThreadLocal<EntityPlayer> harvesters = new ThreadLocal();
|
||||
/**
|
||||
* 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.
|
||||
@@ -1095,28 +1120,37 @@
|
||||
par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1);
|
||||
par2EntityPlayer.addExhaustion(0.025F);
|
||||
|
||||
- if (this.canSilkHarvest() && EnchantmentHelper.getSilkTouchModifier(par2EntityPlayer))
|
||||
- {
|
||||
+ if (this.canSilkHarvest(par1World, par2EntityPlayer, par3, par4, par5, par6) && EnchantmentHelper.getSilkTouchModifier(par2EntityPlayer))
|
||||
{
|
||||
+ {
|
||||
+ ArrayList<ItemStack> items = new ArrayList<ItemStack>();
|
||||
ItemStack itemstack = this.createStackedBlock(par6);
|
||||
|
||||
@@ -1108,12 +1128,13 @@
|
||||
if (itemstack != null)
|
||||
{
|
||||
- this.dropBlockAsItem_do(par1World, par3, par4, par5, itemstack);
|
||||
+ items.add(itemstack);
|
||||
}
|
||||
+ ForgeEventFactory.fireBlockHarvesting(items, par1World, this, par3, par4, par5, par6, 0, 1.0f, true, par2EntityPlayer);
|
||||
+ for (ItemStack is : items)
|
||||
+ {
|
||||
+ this.dropBlockAsItem_do(par1World, par3, par4, par5, is);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
+ harvesters.set(par2EntityPlayer);
|
||||
int i1 = EnchantmentHelper.getFortuneModifier(par2EntityPlayer);
|
||||
this.dropBlockAsItem(par1World, par3, par4, par5, par6, i1);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
+ harvesters.set(null);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private int silk_check_meta = -1; //Dirty hack to stop us from needing to special case the silk check hook.
|
||||
/**
|
||||
* Return true if a player with Silk Touch can harvest this block directly, and not its normal drops.
|
||||
@@ -165,7 +198,7 @@
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1453,4 +1474,939 @@
|
||||
@@ -1457,4 +1491,1001 @@
|
||||
canBlockGrass[0] = true;
|
||||
StatList.initBreakableStats();
|
||||
}
|
||||
@@ -347,6 +380,7 @@
|
||||
+ *
|
||||
+ * @param itemList The list of items to display on the creative inventory.
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void addCreativeItems(ArrayList itemList)
|
||||
+ {
|
||||
+ }
|
||||
@@ -1006,8 +1040,7 @@
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Determines if this block is destroyed when a ender dragon tries to fly through it.
|
||||
+ * The block will be set to 0, nothing will drop.
|
||||
+ * Determines if this block is can be destroyed by the specified entities normal behavior.
|
||||
+ *
|
||||
+ * @param world The current world
|
||||
+ * @param x X Position
|
||||
@@ -1015,6 +1048,20 @@
|
||||
+ * @param z Z position
|
||||
+ * @return True to allow the ender dragon to destroy this block
|
||||
+ */
|
||||
+ public boolean canEntityDestroy(World world, int x, int y, int z, Entity entity)
|
||||
+ {
|
||||
+ if (entity instanceof EntityWither)
|
||||
+ {
|
||||
+ return blockID != Block.bedrock.blockID && blockID != Block.endPortal.blockID && blockID != Block.endPortalFrame.blockID;
|
||||
+ }
|
||||
+ else if (entity instanceof EntityDragon)
|
||||
+ {
|
||||
+ return canDragonDestroy(world, x, y, z);
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+ @Deprecated
|
||||
+ public boolean canDragonDestroy(World world, int x, int y, int z)
|
||||
+ {
|
||||
+ return blockID != obsidian.blockID && blockID != whiteStone.blockID && blockID != bedrock.blockID;
|
||||
@@ -1104,4 +1151,52 @@
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return the amount of XP that this block should drop when it is broken
|
||||
+ */
|
||||
+ public int getExpDrop(World world, int data, int enchantmentLevel)
|
||||
+ {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Called when a tile entity on a side of this block changes is created or is destroyed.
|
||||
+ * @param world The world
|
||||
+ * @param x The x position of this block instance
|
||||
+ * @param y The y position of this block instance
|
||||
+ * @param z The z position of this block instance
|
||||
+ * @param tileX The x position of the tile that changed
|
||||
+ * @param tileY The y position of the tile that changed
|
||||
+ * @param tileZ The z position of the tile that changed
|
||||
+ */
|
||||
+ public void onNeighborTileChange(World world, int x, int y, int z, int tileX, int tileY, int tileZ)
|
||||
+ {
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return true if this block is to be notified of TileEntity changes directly through one solid block like comparators
|
||||
+ */
|
||||
+ public boolean weakTileChanges()
|
||||
+ {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Called to determine whether to allow the a block to handle its own indirect power rather than using the default rules.
|
||||
+ * @param world The world
|
||||
+ * @param x The x position of this block instance
|
||||
+ * @param y The y position of this block instance
|
||||
+ * @param z The z position of this block instance
|
||||
+ * @param side The INPUT side of the block to be powered - ie the opposite of this block's output side
|
||||
+ * @return Whether Block#isProvidingWeakPower should be called when determining indirect power
|
||||
+ */
|
||||
+ public boolean shouldCheckWeakPower(World world, int x, int y, int z, int side)
|
||||
+ {
|
||||
+ return !this.isNormalCube(world.getBlockId(x, y, z));
|
||||
+ }
|
||||
+
|
||||
+ @Deprecated //Implemented here as we changed the IFluidBlock interface, and this allows us to do so without breaking exisitng mods.
|
||||
+ // To be removed next MC version {1.6.3+}
|
||||
+ public float getFilledPercentage(World world, int x, int y, int z){ return 1; }
|
||||
}
|
||||
@@ -23,8 +23,8 @@
|
||||
}
|
||||
|
||||
@@ -182,4 +186,22 @@
|
||||
this.cactusTopIcon = par1IconRegister.registerIcon(this.func_111023_E() + "_top");
|
||||
this.cactusBottomIcon = par1IconRegister.registerIcon(this.func_111023_E() + "_bottom");
|
||||
this.cactusTopIcon = par1IconRegister.registerIcon(this.getTextureName() + "_top");
|
||||
this.cactusBottomIcon = par1IconRegister.registerIcon(this.getTextureName() + "_bottom");
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
public class BlockChest extends BlockContainer
|
||||
{
|
||||
private final Random random = new Random();
|
||||
@@ -444,7 +446,7 @@
|
||||
@@ -446,7 +448,7 @@
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -452,19 +454,19 @@
|
||||
@@ -454,19 +456,19 @@
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@@ -248,4 +258,10 @@
|
||||
this.iconArray[i] = par1IconRegister.registerIcon(this.func_111023_E() + "_stage_" + i);
|
||||
this.iconArray[i] = par1IconRegister.registerIcon(this.getTextureName() + "_stage_" + i);
|
||||
}
|
||||
}
|
||||
+
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
--- ../src_base/minecraft/net/minecraft/block/BlockComparator.java
|
||||
+++ ../src_work/minecraft/net/minecraft/block/BlockComparator.java
|
||||
@@ -268,4 +268,17 @@
|
||||
{
|
||||
return new TileEntityComparator();
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public void onNeighborTileChange(World world, int x, int y, int z, int tileX, int tileY, int tileZ)
|
||||
+ {
|
||||
+ if(y == tileY)
|
||||
+ onNeighborBlockChange(world, x, y, z, world.getBlockId(tileX, tileY, tileZ));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean weakTileChanges()
|
||||
+ {
|
||||
+ return true;
|
||||
+ }
|
||||
}
|
||||
@@ -9,3 +9,17 @@
|
||||
l += (i2 & 16711680) >> 16;
|
||||
i1 += (i2 & 65280) >> 8;
|
||||
j1 += i2 & 255;
|
||||
@@ -81,6 +81,13 @@
|
||||
}
|
||||
|
||||
return (float)(par0 + 1) / 9.0F;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ @Deprecated //Implemented here for compatibility, need to change this when we make vanilla fluids use our fluid methods.
|
||||
+ public float getFilledPercentage(IBlockAccess world, int x, int y, int z)
|
||||
+ {
|
||||
+ return 1 - BlockFluid.getFluidHeightPercent(world.getBlockMetadata(x, y, z));
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@@ -20,7 +20,7 @@
|
||||
{
|
||||
public static final String[] LEAF_TYPES = new String[] {"oak", "spruce", "birch", "jungle"};
|
||||
public static final String[][] field_94396_b = new String[][] {{"leaves_oak", "leaves_spruce", "leaves_birch", "leaves_jungle"}, {"leaves_oak_opaque", "leaves_spruce_opaque", "leaves_birch_opaque", "leaves_jungle_opaque"}};
|
||||
@@ -107,10 +111,9 @@
|
||||
@@ -111,10 +115,9 @@
|
||||
{
|
||||
int j2 = par1World.getBlockId(par2 + k1, par3 + l1, par4 + i2);
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,11 +159,13 @@
|
||||
@@ -160,11 +163,13 @@
|
||||
{
|
||||
k2 = par1World.getBlockId(par2 + l1, par3 + i2, par4 + j2);
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
{
|
||||
this.adjacentTreeBlocks[(l1 + k1) * j1 + (i2 + k1) * b1 + j2 + k1] = -2;
|
||||
}
|
||||
@@ -325,15 +330,7 @@
|
||||
@@ -329,15 +334,7 @@
|
||||
*/
|
||||
public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6)
|
||||
{
|
||||
@@ -66,7 +66,7 @@
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -414,4 +411,30 @@
|
||||
@@ -418,4 +415,30 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- ../src_base/minecraft/net/minecraft/block/BlockLog.java
|
||||
+++ ../src_work/minecraft/net/minecraft/block/BlockLog.java
|
||||
@@ -60,14 +60,9 @@
|
||||
@@ -62,14 +62,9 @@
|
||||
{
|
||||
int j2 = par1World.getBlockId(par2 + k1, par3 + l1, par4 + i2);
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,4 +120,16 @@
|
||||
this.tree_top[i] = par1IconRegister.registerIcon(this.func_111023_E() + "_" + woodType[i] + "_top");
|
||||
@@ -135,4 +130,16 @@
|
||||
this.tree_top[i] = par1IconRegister.registerIcon(this.getTextureName() + "_" + woodType[i] + "_top");
|
||||
}
|
||||
}
|
||||
+
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
--- ../src_base/minecraft/net/minecraft/block/BlockMobSpawner.java
|
||||
+++ ../src_work/minecraft/net/minecraft/block/BlockMobSpawner.java
|
||||
@@ -45,8 +45,12 @@
|
||||
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 j1 = 15 + par1World.rand.nextInt(15) + par1World.rand.nextInt(15);
|
||||
- this.dropXpOnBlockBreak(par1World, par2, par3, par4, j1);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getExpDrop(World world, int data, int enchantmentLevel)
|
||||
+ {
|
||||
+ return 15 + world.rand.nextInt(15) + world.rand.nextInt(15);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
/**
|
||||
@@ -142,4 +128,23 @@
|
||||
this.iconArray[i] = par1IconRegister.registerIcon(this.func_111023_E() + "_stage_" + i);
|
||||
this.iconArray[i] = par1IconRegister.registerIcon(this.getTextureName() + "_stage_" + i);
|
||||
}
|
||||
}
|
||||
+
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
--- ../src_base/minecraft/net/minecraft/block/BlockOre.java
|
||||
+++ ../src_work/minecraft/net/minecraft/block/BlockOre.java
|
||||
@@ -60,6 +60,11 @@
|
||||
{
|
||||
super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7);
|
||||
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getExpDrop(World par1World, int par5, int par7)
|
||||
+ {
|
||||
if (this.idDropped(par5, par1World.rand, par7) != this.blockID)
|
||||
{
|
||||
int j1 = 0;
|
||||
@@ -84,9 +89,10 @@
|
||||
{
|
||||
j1 = MathHelper.getRandomIntegerInRange(par1World.rand, 2, 5);
|
||||
}
|
||||
+ return j1;
|
||||
+ }
|
||||
|
||||
- this.dropXpOnBlockBreak(par1World, par2, par3, par4, j1);
|
||||
- }
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -26,7 +26,7 @@
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,4 +243,107 @@
|
||||
@@ -244,4 +245,107 @@
|
||||
par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, par5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
--- ../src_base/minecraft/net/minecraft/block/BlockRedstoneOre.java
|
||||
+++ ../src_work/minecraft/net/minecraft/block/BlockRedstoneOre.java
|
||||
@@ -116,11 +116,17 @@
|
||||
{
|
||||
super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7);
|
||||
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getExpDrop(World par1World, int par5, int par7)
|
||||
+ {
|
||||
if (this.idDropped(par5, par1World.rand, par7) != this.blockID)
|
||||
{
|
||||
int j1 = 1 + par1World.rand.nextInt(5);
|
||||
- this.dropXpOnBlockBreak(par1World, par2, par3, par4, j1);
|
||||
- }
|
||||
+ return j1;
|
||||
+ }
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@@ -1,6 +1,6 @@
|
||||
--- ../src_base/minecraft/net/minecraft/block/BlockRedstoneWire.java
|
||||
+++ ../src_work/minecraft/net/minecraft/block/BlockRedstoneWire.java
|
||||
@@ -473,7 +473,7 @@
|
||||
@@ -475,7 +475,7 @@
|
||||
}
|
||||
else if (!Block.redstoneRepeaterIdle.func_94487_f(i1))
|
||||
{
|
||||
|
||||
@@ -21,16 +21,16 @@
|
||||
* Called when the block is attempted to be harvested
|
||||
*/
|
||||
public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer)
|
||||
@@ -150,6 +147,8 @@
|
||||
@@ -149,6 +146,8 @@
|
||||
par5 |= 8;
|
||||
par1World.setBlockMetadataWithNotify(par2, par3, par4, par5, 4);
|
||||
}
|
||||
|
||||
+ dropBlockAsItem(par1World, par2, par3, par4, par5, 0);
|
||||
+
|
||||
+ dropBlockAsItem(par1World, par2, par3, par4, par5, 0);
|
||||
|
||||
super.onBlockHarvested(par1World, par2, par3, par4, par5, par6EntityPlayer);
|
||||
}
|
||||
|
||||
@@ -158,24 +157,30 @@
|
||||
@@ -160,24 +159,30 @@
|
||||
*/
|
||||
public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
|
||||
{
|
||||
|
||||
Loaded 100 of 205 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user