mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 09:05:17 +00:00
Compare commits
1
Commits
rm
..
v164-pregradle
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f7ad51a02 |
No files matched your search
+2
-9
@@ -1,14 +1,7 @@
|
||||
* text eol=lf
|
||||
*.bat text eol=crlf
|
||||
*.patch text eol=lf
|
||||
*.java text eol=lf
|
||||
*.gradle text eol=crlf
|
||||
*.patch text
|
||||
*.png binary
|
||||
*.exe binary
|
||||
*.dll binary
|
||||
*.jar binary
|
||||
*.lzma binary
|
||||
*.zip binary
|
||||
*.pyd binary
|
||||
*.cfg text eol=lf
|
||||
*.py text eol=lf
|
||||
*.zip binary
|
||||
+8
-26
@@ -1,27 +1,9 @@
|
||||
#eclipse
|
||||
/bin
|
||||
/.settings
|
||||
/.classpath
|
||||
|
||||
#idea
|
||||
/.idea
|
||||
*.iml
|
||||
|
||||
#gradle
|
||||
/build
|
||||
/.gradle
|
||||
|
||||
#occupational hazards
|
||||
*.DS_Store
|
||||
/logs/
|
||||
/*.pyc
|
||||
/forge-*/
|
||||
/patches-old/
|
||||
/mcp/
|
||||
/eclipse/
|
||||
/repo/
|
||||
/buildSrc
|
||||
|
||||
#Patch rejects
|
||||
*.rej
|
||||
/patches-/
|
||||
# FML changelog
|
||||
changelog.txt
|
||||
/patches_old/
|
||||
/patches_old_bak/
|
||||
*.py
|
||||
*.7z
|
||||
/target/
|
||||
/temp/
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "fml"]
|
||||
path = fml
|
||||
url = https://github.com/MinecraftForge/FML.git
|
||||
@@ -1,10 +0,0 @@
|
||||
Contributing to Forge
|
||||
=====================
|
||||
|
||||
1) Keep patches to Minecraft classes minimal. If you need a lot of things done, you may either add to relevant forge classes or make a new class.
|
||||
|
||||
2) An example mod must be provided for all PRs adding events/hooks to Forge. Whether it's a full mod using your proposed hooks, or just a pastebin containing a simple example, an example mod is required. Please also explain in detail what your new hook does.
|
||||
|
||||
3) Follow Forge coding guidelines (braces on newlines, spaces instead of tabs, etc)
|
||||
|
||||
For more information, refer to [the wiki](https://github.com/MinecraftForge/MinecraftForge/wiki/If-you-want-to-contribute-to-Forge)
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
*** HOW TO INSTALL ***
|
||||
For Mod Users:
|
||||
|
||||
Download the latest installer from http://files.minecraftforge.net and follow instructions given by the installer.
|
||||
|
||||
|
||||
For Mod Devs:
|
||||
|
||||
Download the latest Forge source distribution from http://files.minecraftforge.net and unzip it to a folder.
|
||||
Open a command prompt, navigate to the directory where you unzipped the Forge sources, and run:
|
||||
If you have Gradle: gradle setupDevWorkspace
|
||||
If you DO NOT have Gradle installed:
|
||||
Windows: ./gradlew.bat setupDevWorkspace
|
||||
MacOS/Linux: ./gradlew setupDevWorkspace
|
||||
|
||||
If you wish to use the Eclipse IDE, run gradle eclipse instead of gradle setupDevWorkspace, or install the Gradle plugin for Eclipse and import the Forge source folder as a Gradle project.
|
||||
|
||||
To get the decompiled classes:
|
||||
If you have Gradle: gradle setupDecompWorkspace
|
||||
If you DO NOT have Gradle installed:
|
||||
Windows: ./gradlew.bat setupDecompWorkspace
|
||||
MacOS/Linux: ./gradlew setupDecompWorkspace
|
||||
|
||||
For Contributors: (Note: This assumes you have Gradle installed. If you don't, use ./gradlew(.bat) instead of gradle.
|
||||
|
||||
Clone this repository to a folder.
|
||||
Open a command prompt and navigate to the folder where you cloned this repo.
|
||||
Run gradle setupForge to setup your development environment.
|
||||
|
||||
To use Eclipse, point your Eclipse workspace at the eclipse folder inside the repo.
|
||||
|
||||
|
||||
Requirements (for both mod devs and contributors):
|
||||
You must have a JDK installed and accessible.
|
||||
If you do not wish to use the gradle wrapper, you can install Gradle from http://www.gradle.org/ .
|
||||
|
||||
@@ -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()
|
||||
-136
@@ -1,136 +0,0 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
maven {
|
||||
name = "central_mirrior"
|
||||
url = "http://uk.maven.org/maven2"
|
||||
}
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven {
|
||||
name = "forge"
|
||||
url = "http://files.minecraftforge.net/maven"
|
||||
}
|
||||
maven {
|
||||
name = "sonatype"
|
||||
url = "https://oss.sonatype.org/content/repositories/snapshots/"
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT'
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
deployJars
|
||||
}
|
||||
|
||||
import static net.minecraftforge.gradle.dev.ForgeDevPlugin.*
|
||||
|
||||
apply plugin: 'maven'
|
||||
apply plugin: 'forgedev'
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = "central_mirrior"
|
||||
url = "http://uk.maven.org/maven2"
|
||||
}
|
||||
mavenLocal()
|
||||
flatDir {
|
||||
name "fileRepo"
|
||||
dirs "repo"
|
||||
}
|
||||
}
|
||||
|
||||
minecraft {
|
||||
version = '1.8'
|
||||
mcpVersion = '9.10'
|
||||
mappings = 'snapshot_nodoc_20141130'
|
||||
fmlDir = projectDir.getAbsolutePath() + "/fml";
|
||||
mainClass = 'net.minecraftforge.fml.relauncher.ServerLaunchWrapper'
|
||||
tweakClass = 'net.minecraftforge.fml.common.launcher.FMLTweaker'
|
||||
installerVersion = "1.4"
|
||||
}
|
||||
|
||||
group = 'net.minecraftforge'
|
||||
version = getVersionFromJava(getProject(), 'src/main/java/net/minecraftforge/common/ForgeVersion.java')
|
||||
|
||||
jenkins {
|
||||
job = 'minecraftforge'
|
||||
}
|
||||
|
||||
// crowdin stuff
|
||||
if (project.hasProperty("crowdinKey"))
|
||||
tasks.getLocalizations.apiKey = project.crowdinKey
|
||||
|
||||
|
||||
launch4j {
|
||||
jreMinVersion = '1.6.0'
|
||||
}
|
||||
|
||||
uploadArchives {
|
||||
repositories {
|
||||
add getProject().repositories.mavenLocal()
|
||||
}
|
||||
repositories.mavenDeployer {
|
||||
configuration = configurations.deployJars
|
||||
|
||||
if (project.hasProperty("filesmaven")) {
|
||||
logger.info('Publishing to files server')
|
||||
repository(url: project.filesmaven.url) {
|
||||
authentication(userName: project.filesmaven.username, privateKey: project.filesmaven.key)
|
||||
}
|
||||
} else {
|
||||
logger.info('Publishing to repo folder')
|
||||
repository(url: 'file://localhost/' + project.file('repo').getAbsolutePath())
|
||||
}
|
||||
|
||||
pom {
|
||||
groupId = project.group
|
||||
version = project.version
|
||||
artifactId = project.archivesBaseName
|
||||
}
|
||||
pom.project {
|
||||
name project.archivesBaseName
|
||||
packaging 'jar'
|
||||
description 'Minecraft Forge API'
|
||||
url 'https://github.com/MinecraftForge/MinecraftForge'
|
||||
|
||||
scm {
|
||||
url 'https://github.com/MinecraftForge/MinecraftForge'
|
||||
connection 'scm:git:git://github.com/MinecraftForge/MinecraftForge.git'
|
||||
developerConnection 'scm:git:[email protected]:MinecraftForge/MinecraftForge.git'
|
||||
}
|
||||
|
||||
issueManagement {
|
||||
system 'github'
|
||||
url 'https://github.com/MinecraftForge/MinecraftForge/issues'
|
||||
}
|
||||
|
||||
licenses {
|
||||
license {
|
||||
name 'Forge Public License'
|
||||
url 'https://raw.github.com/MinecraftForge/MinecraftForge/master/MinecraftForge-License.txt'
|
||||
distribution 'repo'
|
||||
}
|
||||
}
|
||||
|
||||
developers {
|
||||
developer {
|
||||
id 'cpw'
|
||||
name 'cpw'
|
||||
roles { role 'developer' }
|
||||
}
|
||||
developer {
|
||||
id 'LexManos'
|
||||
name 'Lex Manos'
|
||||
roles { role 'developer' }
|
||||
}
|
||||
developer {
|
||||
id 'AbrarSyed'
|
||||
name 'Abrar Syed'
|
||||
roles { role 'contributor' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import os, os.path, sys
|
||||
from optparse import OptionParser
|
||||
|
||||
forge_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
mcp_dir = os.path.abspath('..')
|
||||
|
||||
from forge import build_forge_dev
|
||||
|
||||
def main():
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option('-m', '--mcp-dir', action='store', dest='mcp_dir', help='MCP Path', default=None)
|
||||
parser.add_option('-b', '--build', action='store', dest='build', help='Build number', default=None)
|
||||
options, _ = parser.parse_args()
|
||||
|
||||
build_num = 0
|
||||
if not options.build is None:
|
||||
try:
|
||||
build_num = int(options.build)
|
||||
except:
|
||||
pass
|
||||
|
||||
fml_dir = os.path.join(forge_dir, 'fml')
|
||||
mcp_dir = os.path.join(forge_dir, 'mcp')
|
||||
|
||||
if not options.mcp_dir is None:
|
||||
mcp_dir = os.path.abspath(options.mcp_dir)
|
||||
elif os.path.isfile(os.path.join('..', 'runtime', 'commands.py')):
|
||||
mcp_dir = os.path.abspath('..')
|
||||
|
||||
sys.exit(build_forge_dev(mcp_dir, forge_dir, fml_dir, build_num))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
import os, os.path, sys, re
|
||||
import json, urllib2
|
||||
from pprint import pprint
|
||||
from urlparse import urlparse
|
||||
import base64
|
||||
import optparse, ast
|
||||
|
||||
class PreemptiveBasicAuthHandler(urllib2.BaseHandler):
|
||||
def __init__(self, password_mgr=None):
|
||||
if password_mgr is None:
|
||||
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
|
||||
self.passwd = password_mgr
|
||||
self.add_password = self.passwd.add_password
|
||||
|
||||
def http_request(self,req):
|
||||
uri = req.get_full_url()
|
||||
user, pw = self.passwd.find_user_password(None,uri)
|
||||
if pw is None: return req
|
||||
raw = "%s:%s" % (user, pw)
|
||||
auth = 'Basic %s' % base64.b64encode(raw).strip()
|
||||
req.add_unredirected_header('Authorization', auth)
|
||||
return req
|
||||
|
||||
def https_request(self,req):
|
||||
return self.http_request(req)
|
||||
|
||||
def read_url(url):
|
||||
handler = PreemptiveBasicAuthHandler()
|
||||
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)
|
||||
|
||||
items = []
|
||||
output = []
|
||||
|
||||
for build in data:
|
||||
build['actions'] = filter(lambda act: act is not None, build['actions'])
|
||||
build['actions'] = filter(lambda act: 'text' in act, build['actions'])
|
||||
build['actions'] = filter(lambda act: not ' ' in act['text'], build['actions'])
|
||||
if len(build['actions']) == 0:
|
||||
build['version'] = current_version
|
||||
current_version = None
|
||||
else:
|
||||
build['version'] = build['actions'][0]['text']
|
||||
build['items'] = build['changeSet']['items']
|
||||
for item in build['items']:
|
||||
item['author'] = item['author']['fullName']
|
||||
if build['result'] != 'SUCCESS':
|
||||
items += build['items']
|
||||
else:
|
||||
build['items'] = items + build['items']
|
||||
items = []
|
||||
output += [build]
|
||||
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:" ]
|
||||
|
||||
for build in builds:
|
||||
if int(build['number']) > target_build: continue
|
||||
if len(build['items']) == 0: continue
|
||||
log.append('')
|
||||
if build['version'] is None:
|
||||
log.append('Build %s' % build['number'])
|
||||
else:
|
||||
log.append('Build %s' % build['version'])
|
||||
for change in build['items']:
|
||||
comments = filter(lambda cmt: len(cmt) > 0, change['comment'].split('\n'))
|
||||
if len(comments) > 1:
|
||||
log.append('\t' + change['author'])
|
||||
for comment in comments:
|
||||
log.append('\t\t' + comment)
|
||||
elif len(comments) == 1:
|
||||
log.append('\t%s: %s' % (change['author'], comments[0]))
|
||||
|
||||
file = open(change_file, 'wb')
|
||||
for line in log:
|
||||
file.write('%s\n' % line)
|
||||
file.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
make_changelog("http://ci.jenkins.minecraftforge.net/job/minecraftforge/", 70000, 'changelog.txt', 'pinecone')
|
||||
File renamed without changes.
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
@@ -10,7 +10,7 @@ public class Channel {
|
||||
private int[] global_volume, current_note;
|
||||
private boolean linear_periods, fast_volume_slides, key_on, silent;
|
||||
private int sample_idx, sample_frac, step, left_gain, right_gain;
|
||||
private int volume, panning, fine_tune, period, porta_period, key_add;
|
||||
private int volume, panning, fine_tune, period, porta_period, key_add;
|
||||
private int tremolo_speed, tremolo_depth, tremolo_tick, tremolo_wave, tremolo_add;
|
||||
private int vibrato_speed, vibrato_depth, vibrato_tick, vibrato_wave, vibrato_add;
|
||||
private int volume_slide_param, portamento_param, retrig_param;
|
||||
@@ -10,7 +10,7 @@ public class Envelope {
|
||||
set_num_points( 1 );
|
||||
}
|
||||
|
||||
public void set_num_points( int num_points ) {
|
||||
public void set_num_points( int num_points ) {
|
||||
int point;
|
||||
if( num_points <= 0 ) {
|
||||
num_points = 1;
|
||||
@@ -69,7 +69,7 @@ public class FastTracker2 {
|
||||
return module;
|
||||
}
|
||||
|
||||
private static Pattern read_xm_pattern( DataInput data_input, int num_channels ) throws IOException {
|
||||
private static Pattern read_xm_pattern( DataInput data_input, int num_channels ) throws IOException {
|
||||
int pattern_header_length, packing_type, num_rows, pattern_data_length;
|
||||
byte[] structure_header, pattern_header, pattern_data;
|
||||
Pattern pattern;
|
||||
@@ -85,7 +85,7 @@ public class IBXM {
|
||||
clear_vol_ramp_buffer();
|
||||
}
|
||||
|
||||
public void seek( int sample_position ) {
|
||||
public void seek( int sample_position ) {
|
||||
int idx;
|
||||
set_sequence_index( 0, 0 );
|
||||
next_tick();
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -104,8 +104,7 @@ public class Player {
|
||||
}
|
||||
|
||||
private class Driver implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
public void run() {
|
||||
if( running ) return;
|
||||
try {
|
||||
output_line.open();
|
||||
File renamed without changes.
File renamed without changes.
@@ -57,7 +57,7 @@ public class ScreamTracker3 {
|
||||
return s3m_identifier.equals( "SCRM" );
|
||||
}
|
||||
|
||||
public static Module load_s3m( byte[] header_96_bytes, DataInput data_input ) throws IOException {
|
||||
public static Module load_s3m( byte[] header_96_bytes, DataInput data_input ) throws IOException {
|
||||
int num_pattern_orders, num_instruments, num_patterns, num_channels;
|
||||
int flags, tracker_version, master_volume, panning, channel_config, sequence_length;
|
||||
int instrument_idx, pattern_idx, channel_idx, order_idx, panning_offset;
|
||||
+21
-20
@@ -9,20 +9,19 @@ import net.minecraft.command.CommandHandler;
|
||||
import net.minecraft.command.ICommand;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.command.WrongUsageException;
|
||||
import net.minecraft.util.ChatComponentTranslation;
|
||||
import net.minecraft.util.ChatMessageComponent;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.CommandEvent;
|
||||
import net.minecraftforge.fml.client.FMLClientHandler;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
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
|
||||
{
|
||||
@@ -31,8 +30,8 @@ public class ClientCommandHandler extends CommandHandler
|
||||
public String[] latestAutoComplete = null;
|
||||
|
||||
/**
|
||||
* @return 1 if successfully executed, -1 if no permission or wrong usage,
|
||||
* 0 if it doesn't exist or it was canceled (it's sent to the server)
|
||||
* @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)
|
||||
@@ -57,7 +56,7 @@ public class ClientCommandHandler extends CommandHandler
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (icommand.canCommandSenderUse(sender))
|
||||
if (icommand.canCommandSenderUseCommand(sender))
|
||||
{
|
||||
CommandEvent event = new CommandEvent(icommand, sender, args);
|
||||
if (MinecraftForge.EVENT_BUS.post(event))
|
||||
@@ -69,37 +68,40 @@ public class ClientCommandHandler extends CommandHandler
|
||||
return 0;
|
||||
}
|
||||
|
||||
icommand.execute(sender, args);
|
||||
icommand.processCommand(sender, args);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.addChatMessage(format(RED, "commands.generic.permission"));
|
||||
sender.sendChatToPlayer(format("commands.generic.permission").setColor(RED));
|
||||
}
|
||||
}
|
||||
catch (WrongUsageException wue)
|
||||
{
|
||||
sender.addChatMessage(format(RED, "commands.generic.usage", format(RED, wue.getMessage(), wue.getErrorObjects())));
|
||||
sender.sendChatToPlayer(format("commands.generic.usage", format(wue.getMessage(), wue.getErrorOjbects())).setColor(RED));
|
||||
}
|
||||
catch (CommandException ce)
|
||||
{
|
||||
sender.addChatMessage(format(RED, ce.getMessage(), ce.getErrorObjects()));
|
||||
sender.sendChatToPlayer(format(ce.getMessage(), ce.getErrorOjbects()).setColor(RED));
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
sender.addChatMessage(format(RED, "commands.generic.exception"));
|
||||
sender.sendChatToPlayer(format("commands.generic.exception").setColor(RED));
|
||||
t.printStackTrace();
|
||||
}
|
||||
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Couple of helpers because the mcp names are stupid and long...
|
||||
private ChatComponentTranslation format(EnumChatFormatting color, String str, Object... args)
|
||||
private ChatMessageComponent format(String str, Object... args)
|
||||
{
|
||||
ChatComponentTranslation ret = new ChatComponentTranslation(str, args);
|
||||
ret.getChatStyle().setColor(color);
|
||||
return ret;
|
||||
return ChatMessageComponent.createFromTranslationWithSubstitutions(str, args);
|
||||
}
|
||||
|
||||
private ChatMessageComponent format(String str)
|
||||
{
|
||||
return ChatMessageComponent.createFromTranslationKey(str);
|
||||
}
|
||||
|
||||
public void autoComplete(String leftOfCursor, String full)
|
||||
@@ -113,8 +115,7 @@ public class ClientCommandHandler extends CommandHandler
|
||||
Minecraft mc = FMLClientHandler.instance().getClient();
|
||||
if (mc.currentScreen instanceof GuiChat)
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> commands = getTabCompletionOptions(mc.thePlayer, leftOfCursor, mc.thePlayer.getPosition());
|
||||
List<String> commands = getPossibleCommands(mc.thePlayer, leftOfCursor);
|
||||
if (commands != null && !commands.isEmpty())
|
||||
{
|
||||
if (leftOfCursor.indexOf(' ') == -1)
|
||||
@@ -0,0 +1,44 @@
|
||||
package net.minecraftforge.client;
|
||||
|
||||
import net.minecraft.world.EnumGameType;
|
||||
import net.minecraft.util.EnumOS;
|
||||
import net.minecraft.client.settings.EnumOptions;
|
||||
import net.minecraft.item.EnumRarity;
|
||||
import net.minecraftforge.common.EnumHelper;
|
||||
|
||||
public class EnumHelperClient extends EnumHelper
|
||||
{
|
||||
|
||||
private static Class[][] clentTypes =
|
||||
{
|
||||
{EnumGameType.class, int.class, String.class},
|
||||
{EnumOptions.class, String.class, boolean.class, boolean.class},
|
||||
{EnumOS.class},
|
||||
{EnumRarity.class, int.class, String.class}
|
||||
};
|
||||
|
||||
public static EnumGameType addGameType(String name, int id, String displayName)
|
||||
{
|
||||
return addEnum(EnumGameType.class, name, id, displayName);
|
||||
}
|
||||
|
||||
public static EnumOptions addOptions(String name, String langName, boolean isSlider, boolean isToggle)
|
||||
{
|
||||
return addEnum(EnumOptions.class, name, langName, isSlider, isToggle);
|
||||
}
|
||||
|
||||
public static EnumOS addOS2(String name)
|
||||
{
|
||||
return addEnum(EnumOS.class, name);
|
||||
}
|
||||
|
||||
public static EnumRarity addRarity(String name, int color, String displayName)
|
||||
{
|
||||
return addEnum(EnumRarity.class, name, color, displayName);
|
||||
}
|
||||
|
||||
public static <T extends Enum<? >> T addEnum(Class<T> enumType, String enumName, Object... paramValues)
|
||||
{
|
||||
return addEnum(clentTypes, enumType, enumName, paramValues);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,393 @@
|
||||
package net.minecraftforge.client;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
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;
|
||||
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.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
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;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.entity.RenderItem;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
public static boolean renderEntityItem(EntityItem entity, ItemStack item, float bobing, float rotation, Random random, TextureManager engine, RenderBlocks renderBlocks)
|
||||
{
|
||||
IItemRenderer customRenderer = MinecraftForgeClient.getItemRenderer(item, ENTITY);
|
||||
if (customRenderer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (customRenderer.shouldUseRenderHelper(ENTITY, item, ENTITY_ROTATION))
|
||||
{
|
||||
GL11.glRotatef(rotation, 0.0F, 1.0F, 0.0F);
|
||||
}
|
||||
if (!customRenderer.shouldUseRenderHelper(ENTITY, item, ENTITY_BOBBING))
|
||||
{
|
||||
GL11.glTranslatef(0.0F, -bobing, 0.0F);
|
||||
}
|
||||
boolean is3D = customRenderer.shouldUseRenderHelper(ENTITY, item, BLOCK_3D);
|
||||
|
||||
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())))
|
||||
{
|
||||
int renderType = (block != null ? block.getRenderType() : 1);
|
||||
float scale = (renderType == 1 || renderType == 19 || renderType == 12 || renderType == 2 ? 0.5F : 0.25F);
|
||||
|
||||
if (RenderItem.renderInFrame)
|
||||
{
|
||||
GL11.glScalef(1.25F, 1.25F, 1.25F);
|
||||
GL11.glTranslatef(0.0F, 0.05F, 0.0F);
|
||||
GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F);
|
||||
}
|
||||
|
||||
GL11.glScalef(scale, scale, scale);
|
||||
|
||||
int size = item.stackSize;
|
||||
int count = (size > 40 ? 5 : (size > 20 ? 4 : (size > 5 ? 3 : (size > 1 ? 2 : 1))));
|
||||
|
||||
for(int j = 0; j < count; j++)
|
||||
{
|
||||
GL11.glPushMatrix();
|
||||
if (j > 0)
|
||||
{
|
||||
GL11.glTranslatef(
|
||||
((random.nextFloat() * 2.0F - 1.0F) * 0.2F) / scale,
|
||||
((random.nextFloat() * 2.0F - 1.0F) * 0.2F) / scale,
|
||||
((random.nextFloat() * 2.0F - 1.0F) * 0.2F) / scale);
|
||||
}
|
||||
customRenderer.renderItem(ENTITY, item, renderBlocks, entity);
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GL11.glScalef(0.5F, 0.5F, 0.5F);
|
||||
customRenderer.renderItem(ENTITY, item, renderBlocks, entity);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean renderInventoryItem(RenderBlocks renderBlocks, TextureManager engine, ItemStack item, boolean inColor, float zLevel, float x, float y)
|
||||
{
|
||||
IItemRenderer customRenderer = MinecraftForgeClient.getItemRenderer(item, INVENTORY);
|
||||
if (customRenderer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
engine.bindTexture(item.getItemSpriteNumber() == 0 ? TextureMap.locationBlocksTexture : TextureMap.locationItemsTexture);
|
||||
if (customRenderer.shouldUseRenderHelper(INVENTORY, item, INVENTORY_BLOCK))
|
||||
{
|
||||
GL11.glPushMatrix();
|
||||
GL11.glTranslatef(x - 2, y + 3, -3.0F + zLevel);
|
||||
GL11.glScalef(10F, 10F, 10F);
|
||||
GL11.glTranslatef(1.0F, 0.5F, 1.0F);
|
||||
GL11.glScalef(1.0F, 1.0F, -1F);
|
||||
GL11.glRotatef(210F, 1.0F, 0.0F, 0.0F);
|
||||
GL11.glRotatef(45F, 0.0F, 1.0F, 0.0F);
|
||||
|
||||
if(inColor)
|
||||
{
|
||||
int color = Item.itemsList[item.itemID].getColorFromItemStack(item, 0);
|
||||
float r = (float)(color >> 16 & 0xff) / 255F;
|
||||
float g = (float)(color >> 8 & 0xff) / 255F;
|
||||
float b = (float)(color & 0xff) / 255F;
|
||||
GL11.glColor4f(r, g, b, 1.0F);
|
||||
}
|
||||
|
||||
GL11.glRotatef(-90F, 0.0F, 1.0F, 0.0F);
|
||||
renderBlocks.useInventoryTint = inColor;
|
||||
customRenderer.renderItem(INVENTORY, item, renderBlocks);
|
||||
renderBlocks.useInventoryTint = true;
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
else
|
||||
{
|
||||
GL11.glDisable(GL11.GL_LIGHTING);
|
||||
GL11.glPushMatrix();
|
||||
GL11.glTranslatef(x, y, -3.0F + zLevel);
|
||||
|
||||
if (inColor)
|
||||
{
|
||||
int color = Item.itemsList[item.itemID].getColorFromItemStack(item, 0);
|
||||
float r = (float)(color >> 16 & 255) / 255.0F;
|
||||
float g = (float)(color >> 8 & 255) / 255.0F;
|
||||
float b = (float)(color & 255) / 255.0F;
|
||||
GL11.glColor4f(r, g, b, 1.0F);
|
||||
}
|
||||
|
||||
customRenderer.renderItem(INVENTORY, item, renderBlocks);
|
||||
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))
|
||||
{
|
||||
GL11.glPushMatrix();
|
||||
GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
|
||||
customRenderer.renderItem(type, item, renderBlocks, entity);
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
else
|
||||
{
|
||||
GL11.glPushMatrix();
|
||||
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
|
||||
GL11.glTranslatef(0.0F, -0.3F, 0.0F);
|
||||
GL11.glScalef(1.5F, 1.5F, 1.5F);
|
||||
GL11.glRotatef(50.0F, 0.0F, 1.0F, 0.0F);
|
||||
GL11.glRotatef(335.0F, 0.0F, 0.0F, 1.0F);
|
||||
GL11.glTranslatef(-0.9375F, -0.0625F, 0.0F);
|
||||
customRenderer.renderItem(type, item, renderBlocks, entity);
|
||||
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
//Optifine Helper Functions u.u, these are here specifically for Optifine
|
||||
//Note: When using Optfine, these methods are invoked using reflection, which
|
||||
//incurs a major performance penalty.
|
||||
public static void orientBedCamera(Minecraft mc, EntityLivingBase entity)
|
||||
{
|
||||
int x = MathHelper.floor_double(entity.posX);
|
||||
int y = MathHelper.floor_double(entity.posY);
|
||||
int z = MathHelper.floor_double(entity.posZ);
|
||||
Block block = Block.blocksList[mc.theWorld.getBlockId(x, y, z)];
|
||||
|
||||
if (block != null && block.isBed(mc.theWorld, x, y, z, entity))
|
||||
{
|
||||
int var12 = block.getBedDirection(mc.theWorld, x, y, z);
|
||||
GL11.glRotatef((float)(var12 * 90), 0.0F, 1.0F, 0.0F);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean onDrawBlockHighlight(RenderGlobal context, EntityPlayer player, MovingObjectPosition target, int subID, ItemStack currentItem, float partialTicks)
|
||||
{
|
||||
return MinecraftForge.EVENT_BUS.post(new DrawBlockHighlightEvent(context, player, target, subID, currentItem, partialTicks));
|
||||
}
|
||||
|
||||
public static void dispatchRenderLast(RenderGlobal context, float partialTicks)
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.post(new RenderWorldLastEvent(context, partialTicks));
|
||||
}
|
||||
|
||||
public static void onTextureStitchedPre(TextureMap map)
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.post(new TextureStitchEvent.Pre(map));
|
||||
}
|
||||
|
||||
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"));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is added for Optifine's convenience. And to explode if a ModMaker is developing.
|
||||
* @param texture
|
||||
*/
|
||||
public static void onTextureLoadPre(String texture)
|
||||
{
|
||||
if (Tessellator.renderingWorldRenderer)
|
||||
{
|
||||
String msg = String.format("Warning: Texture %s not preloaded, will cause render glitches!", texture);
|
||||
System.out.println(msg);
|
||||
if (Tessellator.class.getPackage() != null)
|
||||
{
|
||||
if (Tessellator.class.getPackage().getName().startsWith("net.minecraft."))
|
||||
{
|
||||
Minecraft mc = FMLClientHandler.instance().getClient();
|
||||
if (mc.ingameGUI != null)
|
||||
{
|
||||
mc.ingameGUI.getChatGUI().printChatMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int renderPass = -1;
|
||||
public static void setRenderPass(int pass)
|
||||
{
|
||||
renderPass = pass;
|
||||
}
|
||||
|
||||
public static ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int slotID, ModelBiped _default)
|
||||
{
|
||||
ModelBiped modelbiped = itemStack.getItem().getArmorModel(entityLiving, itemStack, slotID);
|
||||
return modelbiped == null ? _default : modelbiped;
|
||||
}
|
||||
|
||||
static int stencilBits = 0;
|
||||
public static void createDisplay() throws LWJGLException
|
||||
{
|
||||
ImageIO.setUseCache(false); //Disable on-disc stream cache should speed up texture pack reloading.
|
||||
PixelFormat format = new PixelFormat().withDepthBits(24);
|
||||
try
|
||||
{
|
||||
//TODO: Figure out how to determine the max bits.
|
||||
Display.create(format.withStencilBits(8));
|
||||
stencilBits = 8;
|
||||
}
|
||||
catch(LWJGLException e)
|
||||
{
|
||||
Display.create(format);
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package net.minecraftforge.client;
|
||||
|
||||
import org.lwjgl.input.Mouse;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
import net.minecraft.client.gui.GuiControls;
|
||||
import net.minecraft.client.gui.GuiSlot;
|
||||
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;
|
||||
private String[] message;
|
||||
private int _mouseX;
|
||||
private int _mouseY;
|
||||
private int selected = -1;
|
||||
|
||||
public GuiControlsScrollPanel(GuiControls controls, GameSettings options, Minecraft mc)
|
||||
{
|
||||
super(mc, controls.width, controls.height, 16, (controls.height - 32) + 4, 25);
|
||||
this.controls = controls;
|
||||
this.options = options;
|
||||
this.mc = mc;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSize()
|
||||
{
|
||||
return options.keyBindings.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void elementClicked(int i, boolean flag)
|
||||
{
|
||||
if (!flag)
|
||||
{
|
||||
if (selected == -1)
|
||||
{
|
||||
selected = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
options.setKeyBinding(selected, -100);
|
||||
selected = -1;
|
||||
KeyBinding.resetKeyBindingArrayAndHash();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSelected(int i)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawBackground() {}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int mX, int mY, float f)
|
||||
{
|
||||
_mouseX = mX;
|
||||
_mouseY = mY;
|
||||
|
||||
if (selected != -1 && !Mouse.isButtonDown(0) && Mouse.getDWheel() == 0)
|
||||
{
|
||||
if (Mouse.next() && Mouse.getEventButtonState())
|
||||
{
|
||||
options.setKeyBinding(selected, -100 + Mouse.getEventButton());
|
||||
selected = -1;
|
||||
KeyBinding.resetKeyBindingArrayAndHash();
|
||||
}
|
||||
}
|
||||
|
||||
super.drawScreen(mX, mY, f);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawSlot(int index, int xPosition, int yPosition, int l, Tessellator tessellator)
|
||||
{
|
||||
int width = 70;
|
||||
int height = 20;
|
||||
xPosition -= 20;
|
||||
boolean flag = _mouseX >= xPosition && _mouseY >= yPosition && _mouseX < xPosition + width && _mouseY < yPosition + height;
|
||||
int k = (flag ? 2 : 1);
|
||||
|
||||
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);
|
||||
controls.drawString(mc.fontRenderer, options.getKeyBindingDescription(index), xPosition + width + 4, yPosition + 6, 0xFFFFFFFF);
|
||||
|
||||
boolean conflict = false;
|
||||
for (int x = 0; x < options.keyBindings.length; x++)
|
||||
{
|
||||
if (x != index && options.keyBindings[x].keyCode == options.keyBindings[index].keyCode)
|
||||
{
|
||||
conflict = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
String str = (conflict ? EnumChatFormatting.RED : "") + options.getOptionDisplayString(index);
|
||||
str = (index == selected ? EnumChatFormatting.WHITE + "> " + EnumChatFormatting.YELLOW + "??? " + EnumChatFormatting.WHITE + "<" : str);
|
||||
controls.drawCenteredString(mc.fontRenderer, str, xPosition + (width / 2), yPosition + (height - 8) / 2, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
public boolean keyTyped(char c, int i)
|
||||
{
|
||||
if (selected != -1)
|
||||
{
|
||||
options.setKeyBinding(selected, i);
|
||||
selected = -1;
|
||||
KeyBinding.resetKeyBindingArrayAndHash();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+266
-259
@@ -6,36 +6,34 @@ import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.gui.GuiIngame;
|
||||
import net.minecraft.client.gui.GuiOverlayDebug;
|
||||
import net.minecraft.client.gui.GuiPlayerInfo;
|
||||
import net.minecraft.client.gui.ScaledResolution;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.multiplayer.NetClientHandler;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.crash.CallableMinecraftVersion;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.attributes.IAttributeInstance;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.ai.attributes.AttributeInstance;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.scoreboard.Score;
|
||||
import net.minecraft.scoreboard.ScoreObjective;
|
||||
import net.minecraft.scoreboard.ScorePlayerTeam;
|
||||
import net.minecraft.scoreboard.Scoreboard;
|
||||
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;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
@@ -47,15 +45,13 @@ import net.minecraftforge.common.MinecraftForge;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
|
||||
public class GuiIngameForge extends GuiIngame
|
||||
{
|
||||
//private static final ResourceLocation VIGNETTE = new ResourceLocation("textures/misc/vignette.png");
|
||||
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 ResourceLocation PUMPKIN_BLUR = new ResourceLocation("textures/misc/pumpkinblur.png");
|
||||
|
||||
private static final int WHITE = 0xFFFFFF;
|
||||
|
||||
@@ -82,20 +78,18 @@ public class GuiIngameForge extends GuiIngame
|
||||
private ScaledResolution res = null;
|
||||
private FontRenderer fontrenderer = null;
|
||||
private RenderGameOverlayEvent eventParent;
|
||||
private static final String MC_VERSION = MinecraftForge.MC_VERSION;
|
||||
private GuiOverlayDebugForge debugOverlay;
|
||||
private static final String MC_VERSION = (new CallableMinecraftVersion(null)).minecraftVersion();
|
||||
|
||||
public GuiIngameForge(Minecraft mc)
|
||||
{
|
||||
super(mc);
|
||||
debugOverlay = new GuiOverlayDebugForge(mc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderGameOverlay(float partialTicks)
|
||||
public void renderGameOverlay(float partialTicks, boolean hasScreen, int mouseX, int mouseY)
|
||||
{
|
||||
res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
|
||||
eventParent = new RenderGameOverlayEvent(partialTicks, res);
|
||||
res = new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight);
|
||||
eventParent = new RenderGameOverlayEvent(partialTicks, res, mouseX, mouseY);
|
||||
int width = res.getScaledWidth();
|
||||
int height = res.getScaledHeight();
|
||||
renderHealthMount = mc.thePlayer.ridingEntity instanceof EntityLivingBase;
|
||||
@@ -107,44 +101,45 @@ public class GuiIngameForge extends GuiIngame
|
||||
|
||||
if (pre(ALL)) return;
|
||||
|
||||
fontrenderer = mc.fontRendererObj;
|
||||
fontrenderer = mc.fontRenderer;
|
||||
mc.entityRenderer.setupOverlayRendering();
|
||||
GlStateManager.enableBlend();
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
|
||||
if (Minecraft.isFancyGraphicsEnabled())
|
||||
{
|
||||
func_180480_a(mc.thePlayer.getBrightness(partialTicks), res);
|
||||
renderVignette(mc.thePlayer.getBrightness(partialTicks), width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
if (renderHelmet) renderHelmet(res, partialTicks);
|
||||
if (renderHelmet) renderHelmet(res, partialTicks, hasScreen, mouseX, mouseY);
|
||||
|
||||
if (renderPortal && !mc.thePlayer.isPotionActive(Potion.confusion))
|
||||
{
|
||||
renderPortal(res, partialTicks);
|
||||
renderPortal(width, height, partialTicks);
|
||||
}
|
||||
|
||||
if (renderHotbar) renderTooltip(res, partialTicks);
|
||||
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
zLevel = -90.0F;
|
||||
rand.setSeed((long)(updateCounter * 312871));
|
||||
|
||||
if (renderCrosshairs) renderCrosshairs(width, height);
|
||||
if (renderBossHealth) renderBossHealth();
|
||||
|
||||
if (this.mc.playerController.shouldDrawHUD() && this.mc.getRenderViewEntity() instanceof EntityPlayer)
|
||||
if (!mc.playerController.enableEverythingIsScrewedUpMode())
|
||||
{
|
||||
if (renderHealth) renderHealth(width, height);
|
||||
if (renderArmor) renderArmor(width, height);
|
||||
if (renderFood) renderFood(width, height);
|
||||
if (renderHealthMount) renderHealthMount(width, height);
|
||||
if (renderAir) renderAir(width, height);
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
zLevel = -90.0F;
|
||||
rand.setSeed((long)(updateCounter * 312871));
|
||||
|
||||
if (renderCrosshairs) renderCrosshairs(width, height);
|
||||
if (renderBossHealth) renderBossHealth();
|
||||
|
||||
if (this.mc.playerController.shouldDrawHUD())
|
||||
{
|
||||
if (renderHealth) renderHealth(width, height);
|
||||
if (renderArmor) renderArmor(width, height);
|
||||
if (renderFood) renderFood(width, height);
|
||||
if (renderHealthMount) renderHealthMount(width, height);
|
||||
if (renderAir) renderAir(width, height);
|
||||
}
|
||||
if (renderHotbar) renderHotbar(width, height, partialTicks);
|
||||
}
|
||||
renderSleepFade(width, height);
|
||||
|
||||
if (renderJumpBar)
|
||||
{
|
||||
@@ -155,37 +150,28 @@ public class GuiIngameForge extends GuiIngame
|
||||
renderExperience(width, height);
|
||||
}
|
||||
|
||||
renderToolHightlight(res);
|
||||
renderSleepFade(width, height);
|
||||
renderToolHightlight(width, height);
|
||||
renderHUDText(width, height);
|
||||
renderRecordOverlay(width, height, partialTicks);
|
||||
renderTitle(width, height, partialTicks);
|
||||
|
||||
|
||||
Scoreboard scoreboard = this.mc.theWorld.getScoreboard();
|
||||
ScoreObjective objective = null;
|
||||
ScorePlayerTeam scoreplayerteam = scoreboard.getPlayersTeam(mc.thePlayer.getName());
|
||||
if (scoreplayerteam != null)
|
||||
ScoreObjective objective = mc.theWorld.getScoreboard().func_96539_a(1);
|
||||
if (renderObjective && objective != null)
|
||||
{
|
||||
int slot = scoreplayerteam.func_178775_l().getColorIndex();
|
||||
if (slot >= 0) objective = scoreboard.getObjectiveInDisplaySlot(3 + slot);
|
||||
}
|
||||
ScoreObjective scoreobjective1 = objective != null ? objective : scoreboard.getObjectiveInDisplaySlot(1);
|
||||
if (renderObjective && scoreobjective1 != null)
|
||||
{
|
||||
this.func_180475_a(scoreobjective1, res);
|
||||
this.func_96136_a(objective, height, width, fontrenderer);
|
||||
}
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0);
|
||||
GlStateManager.disableAlpha();
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GL11.glDisable(GL11.GL_ALPHA_TEST);
|
||||
|
||||
renderChat(width, height);
|
||||
|
||||
renderPlayerList(width, height);
|
||||
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GlStateManager.disableLighting();
|
||||
GlStateManager.enableAlpha();
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GL11.glDisable(GL11.GL_LIGHTING);
|
||||
GL11.glEnable(GL11.GL_ALPHA_TEST);
|
||||
|
||||
post(ALL);
|
||||
}
|
||||
@@ -195,19 +181,45 @@ public class GuiIngameForge extends GuiIngame
|
||||
return res;
|
||||
}
|
||||
|
||||
protected void renderHotbar(int width, int height, float partialTicks)
|
||||
{
|
||||
if (pre(HOTBAR)) return;
|
||||
mc.mcProfiler.startSection("actionBar");
|
||||
|
||||
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.bindTexture(WIDGITS);
|
||||
|
||||
InventoryPlayer inv = mc.thePlayer.inventory;
|
||||
drawTexturedModalRect(width / 2 - 91, height - 22, 0, 0, 182, 22);
|
||||
drawTexturedModalRect(width / 2 - 91 - 1 + inv.currentItem * 20, height - 22 - 1, 0, 22, 24, 22);
|
||||
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
|
||||
for (int i = 0; i < 9; ++i)
|
||||
{
|
||||
int x = width / 2 - 90 + i * 20 + 2;
|
||||
int z = height - 16 - 3;
|
||||
renderInventorySlot(i, x, z, partialTicks);
|
||||
}
|
||||
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
|
||||
mc.mcProfiler.endSection();
|
||||
post(HOTBAR);
|
||||
}
|
||||
|
||||
protected void renderCrosshairs(int width, int height)
|
||||
{
|
||||
if (pre(CROSSHAIRS)) return;
|
||||
if (this.showCrosshair())
|
||||
{
|
||||
bind(Gui.icons);
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.tryBlendFuncSeparate(GL11.GL_ONE_MINUS_DST_COLOR, GL11.GL_ONE_MINUS_SRC_COLOR, 1, 0);
|
||||
GlStateManager.enableAlpha();
|
||||
drawTexturedModalRect(width / 2 - 7, height / 2 - 7, 0, 0, 16, 16);
|
||||
GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0);
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
}
|
||||
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);
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
post(CROSSHAIRS);
|
||||
}
|
||||
|
||||
@@ -215,16 +227,13 @@ public class GuiIngameForge extends GuiIngame
|
||||
protected void renderBossHealth()
|
||||
{
|
||||
if (pre(BOSSHEALTH)) return;
|
||||
GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0);
|
||||
mc.mcProfiler.startSection("bossHealth");
|
||||
GlStateManager.enableBlend();
|
||||
super.renderBossHealth();
|
||||
GlStateManager.disableBlend();
|
||||
mc.mcProfiler.endSection();
|
||||
post(BOSSHEALTH);
|
||||
}
|
||||
|
||||
private void renderHelmet(ScaledResolution res, float partialTicks)
|
||||
private void renderHelmet(ScaledResolution res, float partialTicks, boolean hasScreen, int mouseX, int mouseY)
|
||||
{
|
||||
if (pre(HELMET)) return;
|
||||
|
||||
@@ -232,13 +241,13 @@ public class GuiIngameForge extends GuiIngame
|
||||
|
||||
if (this.mc.gameSettings.thirdPersonView == 0 && itemstack != null && itemstack.getItem() != null)
|
||||
{
|
||||
if (itemstack.getItem() == Item.getItemFromBlock(Blocks.pumpkin))
|
||||
if (itemstack.itemID == Block.pumpkin.blockID)
|
||||
{
|
||||
func_180476_e(res);
|
||||
renderPumpkinBlur(res.getScaledWidth(), res.getScaledHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
itemstack.getItem().renderHelmetOverlay(itemstack, mc.thePlayer, res, partialTicks);
|
||||
itemstack.getItem().renderHelmetOverlay(itemstack, mc.thePlayer, res, partialTicks, hasScreen, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,7 +259,6 @@ public class GuiIngameForge extends GuiIngame
|
||||
if (pre(ARMOR)) return;
|
||||
mc.mcProfiler.startSection("armor");
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
int left = width / 2 - 91;
|
||||
int top = height - left_height;
|
||||
|
||||
@@ -273,12 +281,11 @@ public class GuiIngameForge extends GuiIngame
|
||||
}
|
||||
left_height += 10;
|
||||
|
||||
GlStateManager.disableBlend();
|
||||
mc.mcProfiler.endSection();
|
||||
post(ARMOR);
|
||||
}
|
||||
|
||||
protected void renderPortal(ScaledResolution res, float partialTicks)
|
||||
protected void renderPortal(int width, int height, float partialTicks)
|
||||
{
|
||||
if (pre(PORTAL)) return;
|
||||
|
||||
@@ -286,41 +293,22 @@ public class GuiIngameForge extends GuiIngame
|
||||
|
||||
if (f1 > 0.0F)
|
||||
{
|
||||
func_180474_b(f1, res);
|
||||
func_130015_b(f1, width, height);
|
||||
}
|
||||
|
||||
post(PORTAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderTooltip(ScaledResolution res, float partialTicks)
|
||||
{
|
||||
if (pre(HOTBAR)) return;
|
||||
|
||||
if (mc.playerController.isSpectator())
|
||||
{
|
||||
this.spectatorGui.renderTooltip(res, partialTicks);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.renderTooltip(res, partialTicks);
|
||||
}
|
||||
|
||||
post(HOTBAR);
|
||||
}
|
||||
|
||||
protected void renderAir(int width, int height)
|
||||
{
|
||||
if (pre(AIR)) return;
|
||||
mc.mcProfiler.startSection("air");
|
||||
EntityPlayer player = (EntityPlayer)this.mc.getRenderViewEntity();
|
||||
GlStateManager.enableBlend();
|
||||
int left = width / 2 + 91;
|
||||
int top = height - right_height;
|
||||
|
||||
if (player.isInsideOfMaterial(Material.water))
|
||||
if (mc.thePlayer.isInsideOfMaterial(Material.water))
|
||||
{
|
||||
int air = player.getAir();
|
||||
int air = mc.thePlayer.getAir();
|
||||
int full = MathHelper.ceiling_double_int((double)(air - 2) * 10.0D / 300.0D);
|
||||
int partial = MathHelper.ceiling_double_int((double)air * 10.0D / 300.0D) - full;
|
||||
|
||||
@@ -331,7 +319,6 @@ public class GuiIngameForge extends GuiIngame
|
||||
right_height += 10;
|
||||
}
|
||||
|
||||
GlStateManager.disableBlend();
|
||||
mc.mcProfiler.endSection();
|
||||
post(AIR);
|
||||
}
|
||||
@@ -341,36 +328,19 @@ public class GuiIngameForge extends GuiIngame
|
||||
bind(icons);
|
||||
if (pre(HEALTH)) return;
|
||||
mc.mcProfiler.startSection("health");
|
||||
GlStateManager.enableBlend();
|
||||
|
||||
EntityPlayer player = (EntityPlayer)this.mc.getRenderViewEntity();
|
||||
int health = MathHelper.ceiling_float_int(player.getHealth());
|
||||
boolean highlight = field_175191_F > (long)updateCounter && (field_175191_F - (long)updateCounter) / 3L %2L == 1L;
|
||||
boolean highlight = mc.thePlayer.hurtResistantTime / 3 % 2 == 1;
|
||||
|
||||
if (health < this.field_175194_C && player.hurtResistantTime > 0)
|
||||
if (mc.thePlayer.hurtResistantTime < 10)
|
||||
{
|
||||
this.lastSystemTime = Minecraft.getSystemTime();
|
||||
this.field_175191_F = (long)(this.updateCounter + 20);
|
||||
}
|
||||
else if (health > this.field_175194_C && player.hurtResistantTime > 0)
|
||||
{
|
||||
this.lastSystemTime = Minecraft.getSystemTime();
|
||||
this.field_175191_F = (long)(this.updateCounter + 10);
|
||||
highlight = false;
|
||||
}
|
||||
|
||||
if (Minecraft.getSystemTime() - this.lastSystemTime > 1000L)
|
||||
{
|
||||
this.field_175194_C = health;
|
||||
this.field_175189_D = health;
|
||||
this.lastSystemTime = Minecraft.getSystemTime();
|
||||
}
|
||||
|
||||
this.field_175194_C = health;
|
||||
int healthLast = this.field_175189_D;
|
||||
|
||||
IAttributeInstance attrMaxHealth = player.getEntityAttribute(SharedMonsterAttributes.maxHealth);
|
||||
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.getAttributeValue();
|
||||
float absorb = player.getAbsorptionAmount();
|
||||
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);
|
||||
@@ -383,7 +353,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
if (rowHeight != 10) left_height += 10 - rowHeight;
|
||||
|
||||
int regen = -1;
|
||||
if (player.isPotionActive(Potion.regeneration))
|
||||
if (mc.thePlayer.isPotionActive(Potion.regeneration))
|
||||
{
|
||||
regen = updateCounter % 25;
|
||||
}
|
||||
@@ -391,13 +361,13 @@ public class GuiIngameForge extends GuiIngame
|
||||
final int TOP = 9 * (mc.theWorld.getWorldInfo().isHardcoreModeEnabled() ? 5 : 0);
|
||||
final int BACKGROUND = (highlight ? 25 : 16);
|
||||
int MARGIN = 16;
|
||||
if (player.isPotionActive(Potion.poison)) MARGIN += 36;
|
||||
else if (player.isPotionActive(Potion.wither)) MARGIN += 72;
|
||||
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);
|
||||
int b0 = (highlight ? 1 : 0);
|
||||
int row = MathHelper.ceiling_float_int((float)(i + 1) / 10.0F) - 1;
|
||||
int x = left + i % 10 * 8;
|
||||
int y = top - row * rowHeight;
|
||||
@@ -432,7 +402,6 @@ public class GuiIngameForge extends GuiIngame
|
||||
}
|
||||
}
|
||||
|
||||
GlStateManager.disableBlend();
|
||||
mc.mcProfiler.endSection();
|
||||
post(HEALTH);
|
||||
}
|
||||
@@ -442,8 +411,6 @@ public class GuiIngameForge extends GuiIngame
|
||||
if (pre(FOOD)) return;
|
||||
mc.mcProfiler.startSection("food");
|
||||
|
||||
EntityPlayer player = (EntityPlayer)this.mc.getRenderViewEntity();
|
||||
GlStateManager.enableBlend();
|
||||
int left = width / 2 + 91;
|
||||
int top = height - right_height;
|
||||
right_height += 10;
|
||||
@@ -468,7 +435,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
}
|
||||
if (unused) backgound = 1; //Probably should be a += 1 but vanilla never uses this
|
||||
|
||||
if (player.getFoodStats().getSaturationLevel() <= 0.0F && updateCounter % (level * 3 + 1) == 0)
|
||||
if (mc.thePlayer.getFoodStats().getSaturationLevel() <= 0.0F && updateCounter % (level * 3 + 1) == 0)
|
||||
{
|
||||
y = top + (rand.nextInt(3) - 1);
|
||||
}
|
||||
@@ -488,7 +455,6 @@ public class GuiIngameForge extends GuiIngame
|
||||
else if (idx == level)
|
||||
drawTexturedModalRect(x, y, icon + 45, 27, 9, 9);
|
||||
}
|
||||
GlStateManager.disableBlend();
|
||||
mc.mcProfiler.endSection();
|
||||
post(FOOD);
|
||||
}
|
||||
@@ -498,8 +464,8 @@ public class GuiIngameForge extends GuiIngame
|
||||
if (mc.thePlayer.getSleepTimer() > 0)
|
||||
{
|
||||
mc.mcProfiler.startSection("sleep");
|
||||
GlStateManager.disableDepth();
|
||||
GlStateManager.disableAlpha();
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
GL11.glDisable(GL11.GL_ALPHA_TEST);
|
||||
int sleepTime = mc.thePlayer.getSleepTimer();
|
||||
float opacity = (float)sleepTime / 100.0F;
|
||||
|
||||
@@ -510,8 +476,8 @@ public class GuiIngameForge extends GuiIngame
|
||||
|
||||
int color = (int)(220.0F * opacity) << 24 | 1052704;
|
||||
drawRect(0, 0, width, height, color);
|
||||
GlStateManager.enableAlpha();
|
||||
GlStateManager.enableDepth();
|
||||
GL11.glEnable(GL11.GL_ALPHA_TEST);
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
mc.mcProfiler.endSection();
|
||||
}
|
||||
}
|
||||
@@ -520,10 +486,9 @@ public class GuiIngameForge extends GuiIngame
|
||||
{
|
||||
bind(icons);
|
||||
if (pre(EXPERIENCE)) return;
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GlStateManager.disableBlend();
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
if (mc.playerController.gameIsSurvivalOrAdventure())
|
||||
if (mc.playerController.func_78763_f())
|
||||
{
|
||||
mc.mcProfiler.startSection("expBar");
|
||||
int cap = this.mc.thePlayer.xpBarCap();
|
||||
@@ -545,7 +510,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
this.mc.mcProfiler.endSection();
|
||||
|
||||
|
||||
if (mc.playerController.gameIsSurvivalOrAdventure() && mc.thePlayer.experienceLevel > 0)
|
||||
if (mc.playerController.func_78763_f() && mc.thePlayer.experienceLevel > 0)
|
||||
{
|
||||
mc.mcProfiler.startSection("expLevel");
|
||||
boolean flag1 = false;
|
||||
@@ -561,8 +526,7 @@ public class GuiIngameForge extends GuiIngame
|
||||
mc.mcProfiler.endSection();
|
||||
}
|
||||
}
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
post(EXPERIENCE);
|
||||
}
|
||||
@@ -572,7 +536,6 @@ public class GuiIngameForge extends GuiIngame
|
||||
bind(icons);
|
||||
if (pre(JUMPBAR)) return;
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GlStateManager.disableBlend();
|
||||
|
||||
mc.mcProfiler.startSection("jumpBar");
|
||||
float charge = mc.thePlayer.getHorseJumpPower();
|
||||
@@ -588,108 +551,144 @@ public class GuiIngameForge extends GuiIngame
|
||||
this.drawTexturedModalRect(x, top, 0, 89, filled, 5);
|
||||
}
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
mc.mcProfiler.endSection();
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
post(JUMPBAR);
|
||||
}
|
||||
|
||||
protected void renderToolHightlight(ScaledResolution res)
|
||||
protected void renderToolHightlight(int width, int height)
|
||||
{
|
||||
if (this.mc.gameSettings.heldItemTooltips && !this.mc.playerController.isSpectator())
|
||||
if (this.mc.gameSettings.heldItemTooltips)
|
||||
{
|
||||
mc.mcProfiler.startSection("toolHighlight");
|
||||
|
||||
if (this.remainingHighlightTicks > 0 && this.highlightingItemStack != null)
|
||||
{
|
||||
String name = this.highlightingItemStack.getDisplayName();
|
||||
if (this.highlightingItemStack.hasDisplayName())
|
||||
name = EnumChatFormatting.ITALIC + name;
|
||||
|
||||
int opacity = (int)((float)this.remainingHighlightTicks * 256.0F / 10.0F);
|
||||
if (opacity > 255) opacity = 255;
|
||||
|
||||
if (opacity > 0)
|
||||
{
|
||||
int y = res.getScaledHeight() - 59;
|
||||
int y = height - 59;
|
||||
if (!mc.playerController.shouldDrawHUD()) y += 14;
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0);
|
||||
GL11.glPushMatrix();
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
FontRenderer font = highlightingItemStack.getItem().getFontRenderer(highlightingItemStack);
|
||||
if (font != null)
|
||||
{
|
||||
int x = (res.getScaledWidth() - font.getStringWidth(name)) / 2;
|
||||
int x = (width - font.getStringWidth(name)) / 2;
|
||||
font.drawStringWithShadow(name, x, y, WHITE | (opacity << 24));
|
||||
}
|
||||
else
|
||||
{
|
||||
int x = (res.getScaledWidth() - fontrenderer.getStringWidth(name)) / 2;
|
||||
int x = (width - fontrenderer.getStringWidth(name)) / 2;
|
||||
fontrenderer.drawStringWithShadow(name, x, y, WHITE | (opacity << 24));
|
||||
}
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.popMatrix();
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
mc.mcProfiler.endSection();
|
||||
}
|
||||
else if (this.mc.thePlayer.isSpectator())
|
||||
{
|
||||
this.spectatorGui.func_175263_a(res);
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderHUDText(int width, int height)
|
||||
{
|
||||
mc.mcProfiler.startSection("forgeHudText");
|
||||
OpenGlHelper.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0);
|
||||
ArrayList<String> listL = new ArrayList<String>();
|
||||
ArrayList<String> listR = new ArrayList<String>();
|
||||
ArrayList<String> left = new ArrayList<String>();
|
||||
ArrayList<String> right = new ArrayList<String>();
|
||||
|
||||
if (mc.isDemo())
|
||||
{
|
||||
long time = mc.theWorld.getTotalWorldTime();
|
||||
if (time >= 120500L)
|
||||
{
|
||||
listR.add(I18n.format("demo.demoExpired"));
|
||||
right.add(StatCollector.translateToLocal("demo.demoExpired"));
|
||||
}
|
||||
else
|
||||
{
|
||||
listR.add(I18n.format("demo.remainingTime", StringUtils.ticksToElapsedTime((int)(120500L - time))));
|
||||
right.add(String.format(StatCollector.translateToLocal("demo.remainingTime"), StringUtils.ticksToElapsedTime((int)(120500L - time))));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.mc.gameSettings.showDebugInfo && !pre(DEBUG))
|
||||
|
||||
if (this.mc.gameSettings.showDebugInfo)
|
||||
{
|
||||
listL.addAll(debugOverlay.getLeft());
|
||||
listR.addAll(debugOverlay.getRight());
|
||||
post(DEBUG);
|
||||
mc.mcProfiler.startSection("debug");
|
||||
GL11.glPushMatrix();
|
||||
left.add("Minecraft " + MC_VERSION + " (" + this.mc.debug + ")");
|
||||
left.add(mc.debugInfoRenders());
|
||||
left.add(mc.getEntityDebug());
|
||||
left.add(mc.debugInfoEntities());
|
||||
left.add(mc.getWorldProviderName());
|
||||
left.add(null); //Spacer
|
||||
|
||||
long max = Runtime.getRuntime().maxMemory();
|
||||
long total = Runtime.getRuntime().totalMemory();
|
||||
long free = Runtime.getRuntime().freeMemory();
|
||||
long used = total - free;
|
||||
|
||||
right.add("Used memory: " + used * 100L / max + "% (" + used / 1024L / 1024L + "MB) of " + max / 1024L / 1024L + "MB");
|
||||
right.add("Allocated memory: " + total * 100L / max + "% (" + total / 1024L / 1024L + "MB)");
|
||||
|
||||
int x = MathHelper.floor_double(mc.thePlayer.posX);
|
||||
int y = MathHelper.floor_double(mc.thePlayer.posY);
|
||||
int z = MathHelper.floor_double(mc.thePlayer.posZ);
|
||||
float yaw = mc.thePlayer.rotationYaw;
|
||||
int heading = MathHelper.floor_double((double)(mc.thePlayer.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
|
||||
|
||||
left.add(String.format("x: %.5f (%d) // c: %d (%d)", mc.thePlayer.posX, x, x >> 4, x & 15));
|
||||
left.add(String.format("y: %.3f (feet pos, %.3f eyes pos)", mc.thePlayer.boundingBox.minY, mc.thePlayer.posY));
|
||||
left.add(String.format("z: %.5f (%d) // c: %d (%d)", mc.thePlayer.posZ, z, z >> 4, z & 15));
|
||||
left.add(String.format("f: %d (%s) / %f", heading, Direction.directions[heading], MathHelper.wrapAngleTo180_float(yaw)));
|
||||
|
||||
if (mc.theWorld != null && mc.theWorld.blockExists(x, y, z))
|
||||
{
|
||||
Chunk chunk = this.mc.theWorld.getChunkFromBlockCoords(x, z);
|
||||
left.add(String.format("lc: %d b: %s bl: %d sl: %d rl: %d",
|
||||
chunk.getTopFilledSegment() + 15,
|
||||
chunk.getBiomeGenForWorldCoords(x & 15, z & 15, mc.theWorld.getWorldChunkManager()).biomeName,
|
||||
chunk.getSavedLightValue(EnumSkyBlock.Block, x & 15, y, z & 15),
|
||||
chunk.getSavedLightValue(EnumSkyBlock.Sky, x & 15, y, z & 15),
|
||||
chunk.getBlockLightValue(x & 15, y, z & 15, 0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
left.add(null);
|
||||
}
|
||||
|
||||
left.add(String.format("ws: %.3f, fs: %.3f, g: %b, fl: %d", mc.thePlayer.capabilities.getWalkSpeed(), mc.thePlayer.capabilities.getFlySpeed(), mc.thePlayer.onGround, mc.theWorld.getHeightValue(x, z)));
|
||||
right.add(null);
|
||||
for (String s : FMLCommonHandler.instance().getBrandings().subList(1, FMLCommonHandler.instance().getBrandings().size()))
|
||||
{
|
||||
right.add(s);
|
||||
}
|
||||
GL11.glPopMatrix();
|
||||
mc.mcProfiler.endSection();
|
||||
}
|
||||
|
||||
RenderGameOverlayEvent.Text event = new RenderGameOverlayEvent.Text(eventParent, listL, listR);
|
||||
RenderGameOverlayEvent.Text event = new RenderGameOverlayEvent.Text(eventParent, left, right);
|
||||
if (!MinecraftForge.EVENT_BUS.post(event))
|
||||
{
|
||||
int top = 2;
|
||||
for (String msg : listL)
|
||||
for (int x = 0; x < left.size(); x++)
|
||||
{
|
||||
String msg = left.get(x);
|
||||
if (msg == null) continue;
|
||||
drawRect(1, top - 1, 2 + fontrenderer.getStringWidth(msg) + 1, top + fontrenderer.FONT_HEIGHT - 1, -1873784752);
|
||||
fontrenderer.drawString(msg, 2, top, 14737632);
|
||||
top += fontrenderer.FONT_HEIGHT;
|
||||
fontrenderer.drawStringWithShadow(msg, 2, 2 + x * 10, WHITE);
|
||||
}
|
||||
|
||||
top = 2;
|
||||
for (String msg : listR)
|
||||
for (int x = 0; x < right.size(); x++)
|
||||
{
|
||||
String msg = right.get(x);
|
||||
if (msg == null) continue;
|
||||
int w = fontrenderer.getStringWidth(msg);
|
||||
int left = width - 2 - w;
|
||||
drawRect(left - 1, top - 1, left + w + 1, top + fontrenderer.FONT_HEIGHT - 1, -1873784752);
|
||||
fontrenderer.drawString(msg, left, top, 14737632);
|
||||
top += fontrenderer.FONT_HEIGHT;
|
||||
fontrenderer.drawStringWithShadow(msg, width - w - 10, 2 + x * 10, WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -708,60 +707,20 @@ public class GuiIngameForge extends GuiIngame
|
||||
|
||||
if (opacity > 0)
|
||||
{
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate((float)(width / 2), (float)(height - 68), 0.0F);
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0);
|
||||
GL11.glPushMatrix();
|
||||
GL11.glTranslatef((float)(width / 2), (float)(height - 48), 0.0F);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
int color = (recordIsPlaying ? Color.HSBtoRGB(hue / 50.0F, 0.7F, 0.6F) & WHITE : WHITE);
|
||||
fontrenderer.drawString(recordPlaying, -fontrenderer.getStringWidth(recordPlaying) / 2, -4, color | (opacity << 24));
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.popMatrix();
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
|
||||
mc.mcProfiler.endSection();
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderTitle(int width, int height, float partialTicks)
|
||||
{
|
||||
if (field_175195_w > 0)
|
||||
{
|
||||
mc.mcProfiler.startSection("titleAndSubtitle");
|
||||
float age = (float)this.field_175195_w - partialTicks;
|
||||
int opacity = 255;
|
||||
|
||||
if (field_175195_w > field_175193_B + field_175192_A)
|
||||
{
|
||||
float f3 = (float)(field_175199_z + field_175192_A + field_175193_B) - age;
|
||||
opacity = (int)(f3 * 255.0F / (float)field_175199_z);
|
||||
}
|
||||
if (field_175195_w <= field_175193_B) opacity = (int)(age * 255.0F / (float)this.field_175193_B);
|
||||
|
||||
opacity = MathHelper.clamp_int(opacity, 0, 255);
|
||||
|
||||
if (opacity > 8)
|
||||
{
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate((float)(width / 2), (float)(height / 2), 0.0F);
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.scale(4.0F, 4.0F, 4.0F);
|
||||
int l = opacity << 24 & -16777216;
|
||||
this.func_175179_f().drawString(this.field_175201_x, (float)(-this.func_175179_f().getStringWidth(this.field_175201_x) / 2), -10.0F, 16777215 | l, true);
|
||||
GlStateManager.popMatrix();
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.scale(2.0F, 2.0F, 2.0F);
|
||||
this.func_175179_f().drawString(this.field_175200_y, (float)(-this.func_175179_f().getStringWidth(this.field_175200_y) / 2), 5.0F, 16777215 | l, true);
|
||||
GlStateManager.popMatrix();
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
this.mc.mcProfiler.endSection();
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderChat(int width, int height)
|
||||
{
|
||||
mc.mcProfiler.startSection("chat");
|
||||
@@ -769,10 +728,10 @@ public class GuiIngameForge extends GuiIngame
|
||||
RenderGameOverlayEvent.Chat event = new RenderGameOverlayEvent.Chat(eventParent, 0, height - 48);
|
||||
if (MinecraftForge.EVENT_BUS.post(event)) return;
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate((float)event.posX, (float)event.posY, 0.0F);
|
||||
GL11.glPushMatrix();
|
||||
GL11.glTranslatef((float)event.posX, (float)event.posY, 0.0F);
|
||||
persistantChatGUI.drawChat(updateCounter);
|
||||
GlStateManager.popMatrix();
|
||||
GL11.glPopMatrix();
|
||||
|
||||
post(CHAT);
|
||||
|
||||
@@ -781,26 +740,85 @@ public class GuiIngameForge extends GuiIngame
|
||||
|
||||
protected void renderPlayerList(int width, int height)
|
||||
{
|
||||
ScoreObjective scoreobjective = this.mc.theWorld.getScoreboard().getObjectiveInDisplaySlot(0);
|
||||
NetHandlerPlayClient handler = mc.thePlayer.sendQueue;
|
||||
ScoreObjective scoreobjective = this.mc.theWorld.getScoreboard().func_96539_a(0);
|
||||
NetClientHandler handler = mc.thePlayer.sendQueue;
|
||||
|
||||
if (mc.gameSettings.keyBindPlayerList.isKeyDown() && (!mc.isIntegratedServerRunning() || handler.func_175106_d().size() > 1 || scoreobjective != null))
|
||||
if (mc.gameSettings.keyBindPlayerList.pressed && (!mc.isIntegratedServerRunning() || handler.playerInfoList.size() > 1 || scoreobjective != null))
|
||||
{
|
||||
this.overlayPlayerList.func_175246_a(true);
|
||||
if (pre(PLAYER_LIST)) return;
|
||||
this.overlayPlayerList.func_175249_a(width, this.mc.theWorld.getScoreboard(), scoreobjective);
|
||||
this.mc.mcProfiler.startSection("playerList");
|
||||
List players = handler.playerInfoList;
|
||||
int maxPlayers = handler.currentServerMaxPlayers;
|
||||
int rows = maxPlayers;
|
||||
int columns = 1;
|
||||
|
||||
for (columns = 1; rows > 20; rows = (maxPlayers + columns - 1) / columns)
|
||||
{
|
||||
columns++;
|
||||
}
|
||||
|
||||
int columnWidth = 300 / columns;
|
||||
|
||||
if (columnWidth > 150)
|
||||
{
|
||||
columnWidth = 150;
|
||||
}
|
||||
|
||||
int left = (width - columns * columnWidth) / 2;
|
||||
byte border = 10;
|
||||
drawRect(left - 1, border - 1, left + columnWidth * columns, border + 9 * rows, Integer.MIN_VALUE);
|
||||
|
||||
for (int i = 0; i < maxPlayers; i++)
|
||||
{
|
||||
int xPos = left + i % columns * columnWidth;
|
||||
int yPos = border + i / columns * 9;
|
||||
drawRect(xPos, yPos, xPos + columnWidth - 1, yPos + 8, 553648127);
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GL11.glEnable(GL11.GL_ALPHA_TEST);
|
||||
|
||||
if (i < players.size())
|
||||
{
|
||||
GuiPlayerInfo player = (GuiPlayerInfo)players.get(i);
|
||||
ScorePlayerTeam team = mc.theWorld.getScoreboard().getPlayersTeam(player.name);
|
||||
String displayName = ScorePlayerTeam.formatPlayerName(team, player.name);
|
||||
fontrenderer.drawStringWithShadow(displayName, xPos, yPos, 16777215);
|
||||
|
||||
if (scoreobjective != null)
|
||||
{
|
||||
int endX = xPos + fontrenderer.getStringWidth(displayName) + 5;
|
||||
int maxX = xPos + columnWidth - 12 - 5;
|
||||
|
||||
if (maxX - endX > 5)
|
||||
{
|
||||
Score score = scoreobjective.getScoreboard().func_96529_a(player.name, scoreobjective);
|
||||
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.getTextureManager().bindTexture(Gui.icons);
|
||||
int pingIndex = 4;
|
||||
int ping = player.responseTime;
|
||||
if (ping < 0) pingIndex = 5;
|
||||
else if (ping < 150) pingIndex = 0;
|
||||
else if (ping < 300) pingIndex = 1;
|
||||
else if (ping < 600) pingIndex = 2;
|
||||
else if (ping < 1000) pingIndex = 3;
|
||||
|
||||
zLevel += 100.0F;
|
||||
drawTexturedModalRect(xPos + columnWidth - 12, yPos, 0, 176 + pingIndex * 8, 10, 8);
|
||||
zLevel -= 100.0F;
|
||||
}
|
||||
}
|
||||
post(PLAYER_LIST);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.overlayPlayerList.func_175246_a(false);
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderHealthMount(int width, int height)
|
||||
{
|
||||
EntityPlayer player = (EntityPlayer)mc.getRenderViewEntity();
|
||||
Entity tmp = player.ridingEntity;
|
||||
Entity tmp = mc.thePlayer.ridingEntity;
|
||||
if (!(tmp instanceof EntityLivingBase)) return;
|
||||
|
||||
bind(icons);
|
||||
@@ -811,7 +829,6 @@ public class GuiIngameForge extends GuiIngame
|
||||
int left_align = width / 2 + 91;
|
||||
|
||||
mc.mcProfiler.endStartSection("mountHealth");
|
||||
GlStateManager.enableBlend();
|
||||
EntityLivingBase mount = (EntityLivingBase)tmp;
|
||||
int health = (int)Math.ceil((double)mount.getHealth());
|
||||
float healthMax = mount.getMaxHealth();
|
||||
@@ -844,7 +861,6 @@ public class GuiIngameForge extends GuiIngame
|
||||
|
||||
right_height += 10;
|
||||
}
|
||||
GlStateManager.disableBlend();
|
||||
post(HEALTHMOUNT);
|
||||
}
|
||||
|
||||
@@ -861,13 +877,4 @@ public class GuiIngameForge extends GuiIngame
|
||||
{
|
||||
mc.getTextureManager().bindTexture(res);
|
||||
}
|
||||
|
||||
private class GuiOverlayDebugForge extends GuiOverlayDebug
|
||||
{
|
||||
private GuiOverlayDebugForge(Minecraft mc){ super(mc); }
|
||||
@Override protected void renderDebugInfoLeft(){}
|
||||
@Override protected void renderDebugInfoRight(ScaledResolution res){}
|
||||
private List<String> getLeft(){ return this.call(); }
|
||||
private List<String> getRight(){ return this.getDebugInfoRight(); }
|
||||
}
|
||||
}
|
||||
+36
-40
@@ -1,69 +1,69 @@
|
||||
package net.minecraftforge.client;
|
||||
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
|
||||
@Deprecated //Unused, for now. Rendering emensely changed in 1.8, Is this even needed at all anymore?
|
||||
//Modders should speak up if needed.
|
||||
public interface IItemRenderer
|
||||
{
|
||||
@Deprecated
|
||||
public enum ItemRenderType
|
||||
{
|
||||
/**
|
||||
/**
|
||||
* Called to render an in-world item, e.g. one that has been thrown or
|
||||
* dropped. The appropriate OpenGL transformations and scaling have already
|
||||
* been applied, so Tessellator location (0,0,0) is the center of the
|
||||
* EntityItem.
|
||||
*
|
||||
*
|
||||
* Data parameters:
|
||||
* RenderBlocks render - The RenderBlocks instance
|
||||
* EntityItem entity - The in-world item to be rendered
|
||||
*/
|
||||
ENTITY,
|
||||
|
||||
/**
|
||||
ENTITY,
|
||||
|
||||
/**
|
||||
* Called to render an item currently held in-hand by a living entity. If
|
||||
* rendering as a 3D block, the item will be rotated to a 45-degree angle.
|
||||
* To render a 2D texture with some thickness (like default items), see
|
||||
* net.minecraft.src.ItemRenderer. In either case, rendering should be done
|
||||
* in local coordinates from (0,0,0)-(1,1,1).
|
||||
*
|
||||
*
|
||||
* Data parameters:
|
||||
* RenderBlocks render - The RenderBlocks instance
|
||||
* EntityLiving entity - The entity holding this item
|
||||
*/
|
||||
EQUIPPED,
|
||||
|
||||
/**
|
||||
EQUIPPED,
|
||||
|
||||
/**
|
||||
* Called to render an item currently held in-hand by a living entity in
|
||||
* first person. If rendering as a 3D block, the item will be rotated to a
|
||||
* 45-degree angle. To render a 2D texture with some thickness, see
|
||||
* net.minecraft.src.ItemRenderer. In either case, rendering should be done
|
||||
* in local coordinates from (0,0,0)-(1,1,1).
|
||||
*
|
||||
*
|
||||
* Data parameters:
|
||||
* RenderBlocks render - The RenderBlocks instance
|
||||
* EntityLiving entity - The entity holding this item
|
||||
*/
|
||||
EQUIPPED_FIRST_PERSON,
|
||||
|
||||
/**
|
||||
EQUIPPED_FIRST_PERSON,
|
||||
|
||||
/**
|
||||
* Called to render an item in a GUI inventory slot. If rendering as a 3D
|
||||
* block, the appropriate OpenGL translations and scaling have already been
|
||||
* applied, and the rendering should be done in local coordinates from
|
||||
* (0,0,0)-(1,1,1). If rendering as a 2D texture, the rendering should be in
|
||||
* GUI pixel coordinates from (0, 0, 0)-(16, 16, 0).
|
||||
*
|
||||
*
|
||||
* Data parameters:
|
||||
* RenderBlocks render - The RenderBlocks instance
|
||||
*/
|
||||
INVENTORY,
|
||||
|
||||
|
||||
/**
|
||||
* The render type used for when a ItemMap is rendered in first person,
|
||||
* All appropriate rotations have been applied, and the player's hands,
|
||||
* The render type used for when a ItemMap is rendered in first person,
|
||||
* All appropriate rotations have been applied, and the player's hands,
|
||||
* and the map BG are already rendered.
|
||||
*
|
||||
*
|
||||
* Data Parameters:
|
||||
* EntityPlayer player - The player holding the map
|
||||
* RenderEngine engine - The RenderEngine instance
|
||||
@@ -71,71 +71,67 @@ public interface IItemRenderer
|
||||
*/
|
||||
FIRST_PERSON_MAP
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
||||
public enum ItemRendererHelper
|
||||
{
|
||||
/**
|
||||
/**
|
||||
* Determines if a rotation effect should be used when rendering an
|
||||
* EntityItem, like most default blocks do.
|
||||
*/
|
||||
ENTITY_ROTATION,
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Determines if an up-and-down bobbing effect should be used when
|
||||
* rendering an EntityItem, like most default items do.
|
||||
*/
|
||||
ENTITY_BOBBING,
|
||||
|
||||
/**
|
||||
/**
|
||||
* Determines if the currently equipped item should be rendered as a 3D
|
||||
* block or as a 2D texture.
|
||||
*/
|
||||
EQUIPPED_BLOCK,
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the item should equate to a block that has
|
||||
* Determines if the item should equate to a block that has
|
||||
* RenderBlocks.renderItemIn3d return true
|
||||
*/
|
||||
BLOCK_3D,
|
||||
|
||||
/**
|
||||
/**
|
||||
* Determines if the item should be rendered in GUI inventory slots as a 3D
|
||||
* block or as a 2D texture.
|
||||
*/
|
||||
INVENTORY_BLOCK
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Checks if this renderer should handle a specific item's render type
|
||||
* @param item The item we are trying to render
|
||||
* @param type A render type to check if this renderer handles
|
||||
* @return true if this renderer should handle the given render type,
|
||||
* otherwise false
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean handleRenderType(ItemStack item, ItemRenderType type);
|
||||
|
||||
|
||||
/**
|
||||
* Checks if certain helper functionality should be executed for this renderer.
|
||||
* See ItemRendererHelper for more info
|
||||
*
|
||||
*
|
||||
* @param type The render type
|
||||
* @param item The ItemStack being rendered
|
||||
* @param helper The type of helper functionality to be ran
|
||||
* @return True to run the helper functionality, false to not.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper);
|
||||
|
||||
|
||||
/**
|
||||
* Called to do the actual rendering, see ItemRenderType for details on when specific
|
||||
* Called to do the actual rendering, see ItemRenderType for details on when specific
|
||||
* types are run, and what extra data is passed into the data parameter.
|
||||
*
|
||||
*
|
||||
* @param type The render type
|
||||
* @param item The ItemStack being rendered
|
||||
* @param data Extra Type specific data
|
||||
*/
|
||||
@Deprecated
|
||||
public void renderItem(ItemRenderType type, ItemStack item, Object... data);
|
||||
}
|
||||
File renamed without changes.
+2
-2
@@ -1,7 +1,7 @@
|
||||
package net.minecraftforge.client;
|
||||
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
|
||||
+17
-16
@@ -6,18 +6,21 @@
|
||||
package net.minecraftforge.client;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.IdentityHashMap;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import org.lwjgl.opengl.Display;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumWorldBlockLayer;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.IItemRenderer.ItemRenderType;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
public class MinecraftForgeClient
|
||||
{
|
||||
private static IdentityHashMap<Item, IItemRenderer> customItemRenderers = Maps.newIdentityHashMap();
|
||||
private static IItemRenderer[] customItemRenderers = new IItemRenderer[Item.itemsList.length];
|
||||
|
||||
/**
|
||||
* Register a custom renderer for a specific item. This can be used to
|
||||
@@ -27,17 +30,17 @@ public class MinecraftForgeClient
|
||||
* @param renderer The IItemRenderer interface that handles rendering for
|
||||
* this item.
|
||||
*/
|
||||
public static void registerItemRenderer(Item item, IItemRenderer renderer)
|
||||
public static void registerItemRenderer(int itemID, IItemRenderer renderer)
|
||||
{
|
||||
customItemRenderers.put(item, renderer);
|
||||
customItemRenderers[itemID] = renderer;
|
||||
}
|
||||
|
||||
public static IItemRenderer getItemRenderer(ItemStack item, ItemRenderType type)
|
||||
{
|
||||
IItemRenderer renderer = customItemRenderers.get(item.getItem());
|
||||
IItemRenderer renderer = customItemRenderers[item.itemID];
|
||||
if (renderer != null && renderer.handleRenderType(item, type))
|
||||
{
|
||||
return renderer;
|
||||
return customItemRenderers[item.itemID];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -47,23 +50,21 @@ public class MinecraftForgeClient
|
||||
return ForgeHooksClient.renderPass;
|
||||
}
|
||||
|
||||
public static EnumWorldBlockLayer getRenderLayer()
|
||||
public static int getStencilBits()
|
||||
{
|
||||
return ForgeHooksClient.renderLayer.get();
|
||||
return ForgeHooksClient.stencilBits;
|
||||
}
|
||||
|
||||
private static BitSet stencilBits = new BitSet(8);
|
||||
|
||||
private static BitSet stencilBits = new BitSet(getStencilBits());
|
||||
static
|
||||
{
|
||||
stencilBits.set(0,8);
|
||||
stencilBits.set(0,getStencilBits());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reserve a stencil bit for use in rendering
|
||||
*
|
||||
* Note: you must check the Framebuffer you are working with to
|
||||
* determine if stencil bits are enabled on it before use.
|
||||
*
|
||||
* @return A bit or -1 if no further stencil bits are available
|
||||
*/
|
||||
public static int reserveStencilBit()
|
||||
@@ -83,7 +84,7 @@ public class MinecraftForgeClient
|
||||
*/
|
||||
public static void releaseStencilBit(int bit)
|
||||
{
|
||||
if (bit >= 0 && bit < stencilBits.length())
|
||||
if (bit >= 0 && bit < getStencilBits())
|
||||
{
|
||||
stencilBits.set(bit);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraftforge.event.Cancelable;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
@Cancelable
|
||||
public class ClientChatReceivedEvent extends Event
|
||||
{
|
||||
public String message;
|
||||
public ClientChatReceivedEvent(String message)
|
||||
{
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.client.renderer.RenderGlobal;
|
||||
import net.minecraftforge.event.Cancelable;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
@Cancelable
|
||||
public class DrawBlockHighlightEvent extends Event
|
||||
+5
-4
@@ -1,7 +1,8 @@
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.renderer.EntityRenderer;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
/**
|
||||
* Author: MachineMuse (Claire Semple)
|
||||
@@ -9,11 +10,11 @@ import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
*/
|
||||
public class FOVUpdateEvent extends Event
|
||||
{
|
||||
public final EntityPlayer entity;
|
||||
public final EntityPlayerSP entity;
|
||||
public final float fov;
|
||||
public float newfov;
|
||||
|
||||
public FOVUpdateEvent(EntityPlayer entity, float fov)
|
||||
public FOVUpdateEvent(EntityPlayerSP entity, float fov)
|
||||
{
|
||||
this.entity = entity;
|
||||
this.fov = fov;
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
import net.minecraftforge.fml.common.eventhandler.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.
|
||||
+2
-3
@@ -1,10 +1,9 @@
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraftforge.event.Cancelable;
|
||||
import net.minecraftforge.event.Event;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
|
||||
/**
|
||||
* Author: MachineMuse (Claire Semple)
|
||||
* Created: 2:46 PM, 9/4/13
|
||||
+10
-6
@@ -2,10 +2,9 @@ package net.minecraftforge.client.event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
|
||||
import net.minecraft.client.gui.ScaledResolution;
|
||||
import net.minecraftforge.event.Cancelable;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
@Cancelable
|
||||
public class RenderGameOverlayEvent extends Event
|
||||
@@ -27,18 +26,21 @@ public class RenderGameOverlayEvent extends Event
|
||||
HEALTHMOUNT,
|
||||
JUMPBAR,
|
||||
CHAT,
|
||||
PLAYER_LIST,
|
||||
DEBUG
|
||||
PLAYER_LIST
|
||||
}
|
||||
|
||||
public final float partialTicks;
|
||||
public final ScaledResolution resolution;
|
||||
public final int mouseX;
|
||||
public final int mouseY;
|
||||
public final ElementType type;
|
||||
|
||||
public RenderGameOverlayEvent(float partialTicks, ScaledResolution resolution)
|
||||
public RenderGameOverlayEvent(float partialTicks, ScaledResolution resolution, int mouseX, int mouseY)
|
||||
{
|
||||
this.partialTicks = partialTicks;
|
||||
this.resolution = resolution;
|
||||
this.mouseX = mouseX;
|
||||
this.mouseY = mouseY;
|
||||
this.type = null;
|
||||
}
|
||||
|
||||
@@ -46,6 +48,8 @@ public class RenderGameOverlayEvent extends Event
|
||||
{
|
||||
this.partialTicks = parent.partialTicks;
|
||||
this.resolution = parent.resolution;
|
||||
this.mouseX = parent.mouseX;
|
||||
this.mouseY = parent.mouseY;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
+8
-14
@@ -1,49 +1,43 @@
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
import net.minecraft.client.renderer.entity.RendererLivingEntity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraftforge.event.Cancelable;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
public abstract class RenderLivingEvent extends Event
|
||||
{
|
||||
public final EntityLivingBase entity;
|
||||
public final RendererLivingEntity renderer;
|
||||
public final double x;
|
||||
public final double y;
|
||||
public final double z;
|
||||
|
||||
public RenderLivingEvent(EntityLivingBase entity, RendererLivingEntity renderer, double x, double y, double z)
|
||||
public RenderLivingEvent(EntityLivingBase entity, RendererLivingEntity renderer)
|
||||
{
|
||||
this.entity = entity;
|
||||
this.renderer = renderer;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Cancelable
|
||||
public static class Pre extends RenderLivingEvent
|
||||
{
|
||||
public Pre(EntityLivingBase entity, RendererLivingEntity renderer, double x, double y, double z){ super(entity, renderer, x, y, z); }
|
||||
public Pre(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
|
||||
}
|
||||
public static class Post extends RenderLivingEvent
|
||||
{
|
||||
public Post(EntityLivingBase entity, RendererLivingEntity renderer, double x, double y, double z){ super(entity, renderer, x, y, z); }
|
||||
public Post(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
|
||||
}
|
||||
|
||||
public abstract static class Specials extends RenderLivingEvent
|
||||
{
|
||||
public Specials(EntityLivingBase entity, RendererLivingEntity renderer, double x, double y, double z){ super(entity, renderer, x, y, z); }
|
||||
public Specials(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
|
||||
|
||||
@Cancelable
|
||||
public static class Pre extends Specials
|
||||
{
|
||||
public Pre(EntityLivingBase entity, RendererLivingEntity renderer, double x, double y, double z){ super(entity, renderer, x, y, z); }
|
||||
public Pre(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
|
||||
}
|
||||
public static class Post extends Specials
|
||||
{
|
||||
public Post(EntityLivingBase entity, RendererLivingEntity renderer, double x, double y, double z){ super(entity, renderer, x, y, z); }
|
||||
public Post(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-18
@@ -1,50 +1,42 @@
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
import net.minecraft.client.renderer.entity.RenderPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.event.Cancelable;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
|
||||
public abstract class RenderPlayerEvent extends PlayerEvent
|
||||
{
|
||||
public final RenderPlayer renderer;
|
||||
public final float partialRenderTick;
|
||||
public final double x;
|
||||
public final double y;
|
||||
public final double z;
|
||||
|
||||
public RenderPlayerEvent(EntityPlayer player, RenderPlayer renderer, float partialRenderTick, double x, double y, double z)
|
||||
public RenderPlayerEvent(EntityPlayer player, RenderPlayer renderer, float partialRenderTick)
|
||||
{
|
||||
super(player);
|
||||
this.renderer = renderer;
|
||||
this.partialRenderTick = partialRenderTick;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Cancelable
|
||||
public static class Pre extends RenderPlayerEvent
|
||||
{
|
||||
public Pre(EntityPlayer player, RenderPlayer renderer, float tick, double x, double y, double z){ super(player, renderer, tick, x, y, z); }
|
||||
@Deprecated
|
||||
public Pre(EntityPlayer player, RenderPlayer renderer, float tick){ this(player, renderer, tick, 0D, 0D, 0D); }
|
||||
public Pre(EntityPlayer player, RenderPlayer renderer, float tick){ super(player, renderer, tick); }
|
||||
}
|
||||
|
||||
public static class Post extends RenderPlayerEvent
|
||||
{
|
||||
public Post(EntityPlayer player, RenderPlayer renderer, float tick, double x, double y, double z){ super(player, renderer, tick, x, y, z); }
|
||||
@Deprecated
|
||||
public Post(EntityPlayer player, RenderPlayer renderer, float tick){ this(player, renderer, tick, 0D, 0D, 0D); }
|
||||
public Post(EntityPlayer player, RenderPlayer renderer, float tick){ super(player, renderer, tick); }
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public abstract static class Specials extends RenderPlayerEvent
|
||||
{
|
||||
@Deprecated
|
||||
public final float partialTicks;
|
||||
public Specials(EntityPlayer player, RenderPlayer renderer, float partialTicks)
|
||||
{
|
||||
super(player, renderer, partialTicks, 0D, 0D, 0D);
|
||||
super(player, renderer, partialTicks);
|
||||
this.partialTicks = partialTicks;
|
||||
}
|
||||
|
||||
@Cancelable
|
||||
@@ -62,7 +54,6 @@ public abstract class RenderPlayerEvent extends PlayerEvent
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static class SetArmorModel extends RenderPlayerEvent
|
||||
{
|
||||
/**
|
||||
@@ -71,11 +62,14 @@ 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, partialTick, 0D, 0D, 0D);
|
||||
super(player, renderer, partialTick);
|
||||
this.slot = slot;
|
||||
this.partialTick = partialTick;
|
||||
this.stack = stack;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
import net.minecraft.client.renderer.RenderGlobal;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
public class RenderWorldLastEvent extends Event
|
||||
{
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
|
||||
public class TextureStitchEvent extends Event
|
||||
-1
@@ -8,7 +8,6 @@ import net.minecraft.client.audio.SoundPoolEntry;
|
||||
* If you return null from this function it will prevent the sound from being played,
|
||||
* you can return a different entry if you want to change the sound being played.
|
||||
*/
|
||||
@Deprecated // Remove in 1.8
|
||||
public class PlayBackgroundMusicEvent extends SoundResultEvent
|
||||
{
|
||||
public PlayBackgroundMusicEvent(SoundManager manager, SoundPoolEntry entry)
|
||||
-1
@@ -3,7 +3,6 @@ package net.minecraftforge.client.event.sound;
|
||||
import net.minecraft.client.audio.SoundManager;
|
||||
import net.minecraft.client.audio.SoundPoolEntry;
|
||||
|
||||
@Deprecated //Remove in 1.8
|
||||
public class PlaySoundEffectEvent extends SoundResultEvent
|
||||
{
|
||||
public PlaySoundEffectEvent(SoundManager manager, SoundPoolEntry source, String name, float volume, float pitch)
|
||||
-2
@@ -2,14 +2,12 @@ package net.minecraftforge.client.event.sound;
|
||||
|
||||
import net.minecraft.client.audio.SoundManager;
|
||||
|
||||
@Deprecated //Remove in 1.8
|
||||
public class PlaySoundEffectSourceEvent extends SoundEvent
|
||||
{
|
||||
public final SoundManager manager;
|
||||
public final String name;
|
||||
public PlaySoundEffectSourceEvent(SoundManager manager, String name)
|
||||
{
|
||||
super(manager);
|
||||
this.manager = manager;
|
||||
this.name = name;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package net.minecraftforge.client.event.sound;
|
||||
|
||||
import net.minecraft.client.audio.SoundManager;
|
||||
import net.minecraft.client.audio.SoundPoolEntry;
|
||||
|
||||
/***
|
||||
* Raised when the SoundManager tries to play a normal sound,
|
||||
* dogs barking, footsteps, etc. THe majority of all sounds during normal game play.
|
||||
*
|
||||
* If you return null from this function it will prevent the sound from being played,
|
||||
* you can return a different entry if you want to change the sound being played.
|
||||
*/
|
||||
public class PlaySoundEvent extends SoundResultEvent
|
||||
{
|
||||
public final float x;
|
||||
public final float y;
|
||||
public final float z;
|
||||
public PlaySoundEvent(SoundManager manager, SoundPoolEntry source, String name, float x, float y, float z, float volume, float pitch)
|
||||
{
|
||||
super(manager, source, name, volume, pitch);
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package net.minecraftforge.client.event.sound;
|
||||
|
||||
import net.minecraft.client.audio.SoundManager;
|
||||
|
||||
public class PlaySoundSourceEvent extends SoundEvent
|
||||
{
|
||||
public final SoundManager manager;
|
||||
public final String name;
|
||||
public final float x;
|
||||
public final float y;
|
||||
public final float z;
|
||||
public PlaySoundSourceEvent(SoundManager manager, String name, float x, float y, float z)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.name = name;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
-1
@@ -11,7 +11,6 @@ import net.minecraft.client.audio.SoundPoolEntry;
|
||||
* you can return a different entry if you want to change the sound being played.
|
||||
*
|
||||
*/
|
||||
@Deprecated
|
||||
public class PlayStreamingEvent extends SoundResultEvent
|
||||
{
|
||||
public final float x;
|
||||
@@ -0,0 +1,20 @@
|
||||
package net.minecraftforge.client.event.sound;
|
||||
|
||||
import net.minecraft.client.audio.SoundManager;
|
||||
|
||||
public class PlayStreamingSourceEvent extends SoundEvent
|
||||
{
|
||||
public final SoundManager manager;
|
||||
public final String name;
|
||||
public final float x;
|
||||
public final float y;
|
||||
public final float z;
|
||||
public PlayStreamingSourceEvent(SoundManager manager, String name, float x, float y, float z)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.name = name;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package net.minecraftforge.client.event.sound;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.client.audio.SoundManager;
|
||||
import net.minecraft.client.audio.SoundPoolEntry;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.Cancelable;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
public class SoundEvent extends Event
|
||||
{
|
||||
public SoundEvent(){}
|
||||
|
||||
public static SoundPoolEntry getResult(SoundResultEvent event)
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
return event.result;
|
||||
}
|
||||
}
|
||||
-2
@@ -8,11 +8,9 @@ import net.minecraft.client.audio.SoundManager;
|
||||
*/
|
||||
public class SoundLoadEvent extends SoundEvent
|
||||
{
|
||||
@Deprecated
|
||||
public final SoundManager manager;
|
||||
public SoundLoadEvent(SoundManager manager)
|
||||
{
|
||||
super(manager);
|
||||
this.manager = manager;
|
||||
}
|
||||
}
|
||||
-2
@@ -3,7 +3,6 @@ package net.minecraftforge.client.event.sound;
|
||||
import net.minecraft.client.audio.SoundManager;
|
||||
import net.minecraft.client.audio.SoundPoolEntry;
|
||||
|
||||
@Deprecated //Remove in 1.8
|
||||
public abstract class SoundResultEvent extends SoundEvent
|
||||
{
|
||||
public final SoundManager manager;
|
||||
@@ -15,7 +14,6 @@ public abstract class SoundResultEvent extends SoundEvent
|
||||
|
||||
public SoundResultEvent(SoundManager manager, SoundPoolEntry source, String name, float volume, float pitch)
|
||||
{
|
||||
super(manager);
|
||||
this.manager = manager;
|
||||
this.source = source;
|
||||
this.name = name;
|
||||
-2
@@ -8,11 +8,9 @@ import net.minecraft.client.audio.SoundManager;
|
||||
*/
|
||||
public class SoundSetupEvent extends SoundEvent
|
||||
{
|
||||
@Deprecated
|
||||
public final SoundManager manager;
|
||||
public SoundSetupEvent(SoundManager manager)
|
||||
{
|
||||
super(manager);
|
||||
this.manager = manager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package net.minecraftforge.client.model;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
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;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
/**
|
||||
* Common interface for advanced model loading from files, based on file suffix
|
||||
* Model support can be queried through the {@link #getSupportedSuffixes()} method.
|
||||
* Instances can be created by calling {@link #loadModel(String)} with a class-loadable-path
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class AdvancedModelLoader {
|
||||
private static Map<String, IModelCustomLoader> instances = Maps.newHashMap();
|
||||
|
||||
/**
|
||||
* Register a new model handler
|
||||
* @param modelHandler The model handler to register
|
||||
*/
|
||||
public static void registerModelHandler(IModelCustomLoader modelHandler)
|
||||
{
|
||||
for (String suffix : modelHandler.getSuffixes())
|
||||
{
|
||||
instances.put(suffix, modelHandler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the model from the supplied classpath resolvable resource name
|
||||
* @param resourceName The resource name
|
||||
* @return A model
|
||||
* @throws IllegalArgumentException if the resource name cannot be understood
|
||||
* @throws ModelFormatException if the underlying model handler cannot parse the model format
|
||||
*/
|
||||
public static IModelCustom loadModel(String resourceName) throws IllegalArgumentException, ModelFormatException
|
||||
{
|
||||
int i = resourceName.lastIndexOf('.');
|
||||
if (i == -1)
|
||||
{
|
||||
FMLLog.severe("The resource name %s is not valid", resourceName);
|
||||
throw new IllegalArgumentException("The resource name is not valid");
|
||||
}
|
||||
String suffix = resourceName.substring(i+1);
|
||||
IModelCustomLoader loader = instances.get(suffix);
|
||||
if (loader == null)
|
||||
{
|
||||
FMLLog.severe("The resource name %s is not supported", resourceName);
|
||||
throw new IllegalArgumentException("The resource name is not supported");
|
||||
}
|
||||
|
||||
URL resource = AdvancedModelLoader.class.getResource(resourceName);
|
||||
if (resource == null)
|
||||
{
|
||||
FMLLog.severe("The resource name %s could not be found", resourceName);
|
||||
throw new IllegalArgumentException("The resource name could not be found");
|
||||
}
|
||||
return loader.loadInstance(resourceName, resource);
|
||||
}
|
||||
|
||||
public static Collection<String> getSupportedSuffixes()
|
||||
{
|
||||
return instances.keySet();
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
{
|
||||
registerModelHandler(new ObjModelLoader());
|
||||
registerModelHandler(new TechneModelLoader());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package net.minecraftforge.client.model;
|
||||
|
||||
|
||||
|
||||
public interface IModelCustom {
|
||||
String getType();
|
||||
void renderAll();
|
||||
void renderOnly(String... groupNames);
|
||||
void renderPart(String partName);
|
||||
void renderAllExcept(String... excludedGroupNames);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package net.minecraftforge.client.model;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Instances of this class act as factories for their model type
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public interface IModelCustomLoader {
|
||||
/**
|
||||
* Get the main type name for this loader
|
||||
* @return the type name
|
||||
*/
|
||||
String getType();
|
||||
/**
|
||||
* Get resource suffixes this model loader recognizes
|
||||
* @return a list of suffixes
|
||||
*/
|
||||
String[] getSuffixes();
|
||||
/**
|
||||
* Load a model instance from the supplied path
|
||||
* @param resourceName The resource name to load
|
||||
* @param resource The URL associated with the classloader resource
|
||||
* @return A model instance
|
||||
* @throws ModelFormatException if the model format is not correct
|
||||
*/
|
||||
IModelCustom loadInstance(String resourceName, URL resource) throws ModelFormatException;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package net.minecraftforge.client.model;
|
||||
|
||||
/**
|
||||
* Thrown if there is a problem parsing the model
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class ModelFormatException extends RuntimeException {
|
||||
|
||||
public ModelFormatException()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public ModelFormatException(String message, Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ModelFormatException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ModelFormatException(Throwable cause)
|
||||
{
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package net.minecraftforge.client.model.obj;
|
||||
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.util.Vec3;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class Face
|
||||
{
|
||||
|
||||
public Vertex[] vertices;
|
||||
public Vertex[] vertexNormals;
|
||||
public Vertex faceNormal;
|
||||
public TextureCoordinate[] textureCoordinates;
|
||||
|
||||
public void addFaceForRender(Tessellator tessellator)
|
||||
{
|
||||
addFaceForRender(tessellator, 0.0005F);
|
||||
}
|
||||
|
||||
public void addFaceForRender(Tessellator tessellator, float textureOffset)
|
||||
{
|
||||
if (faceNormal == null)
|
||||
{
|
||||
faceNormal = this.calculateFaceNormal();
|
||||
}
|
||||
|
||||
tessellator.setNormal(faceNormal.x, faceNormal.y, faceNormal.z);
|
||||
|
||||
float averageU = 0F;
|
||||
float averageV = 0F;
|
||||
|
||||
if ((textureCoordinates != null) && (textureCoordinates.length > 0))
|
||||
{
|
||||
for (int i = 0; i < textureCoordinates.length; ++i)
|
||||
{
|
||||
averageU += textureCoordinates[i].u;
|
||||
averageV += textureCoordinates[i].v;
|
||||
}
|
||||
|
||||
averageU = averageU / textureCoordinates.length;
|
||||
averageV = averageV / textureCoordinates.length;
|
||||
}
|
||||
|
||||
float offsetU, offsetV;
|
||||
|
||||
for (int i = 0; i < vertices.length; ++i)
|
||||
{
|
||||
|
||||
if ((textureCoordinates != null) && (textureCoordinates.length > 0))
|
||||
{
|
||||
offsetU = textureOffset;
|
||||
offsetV = textureOffset;
|
||||
|
||||
if (textureCoordinates[i].u > averageU)
|
||||
{
|
||||
offsetU = -offsetU;
|
||||
}
|
||||
if (textureCoordinates[i].v > averageV)
|
||||
{
|
||||
offsetV = -offsetV;
|
||||
}
|
||||
|
||||
tessellator.addVertexWithUV(vertices[i].x, vertices[i].y, vertices[i].z, textureCoordinates[i].u + offsetU, textureCoordinates[i].v + offsetV);
|
||||
}
|
||||
else
|
||||
{
|
||||
tessellator.addVertex(vertices[i].x, vertices[i].y, vertices[i].z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vertex calculateFaceNormal()
|
||||
{
|
||||
Vec3 v1 = Vec3.createVectorHelper(vertices[1].x - vertices[0].x, vertices[1].y - vertices[0].y, vertices[1].z - vertices[0].z);
|
||||
Vec3 v2 = Vec3.createVectorHelper(vertices[2].x - vertices[0].x, vertices[2].y - vertices[0].y, vertices[2].z - vertices[0].z);
|
||||
Vec3 normalVector = null;
|
||||
|
||||
normalVector = v1.crossProduct(v2).normalize();
|
||||
|
||||
return new Vertex((float) normalVector.xCoord, (float) normalVector.yCoord, (float) normalVector.zCoord);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package net.minecraftforge.client.model.obj;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class GroupObject
|
||||
{
|
||||
|
||||
public String name;
|
||||
public ArrayList<Face> faces = new ArrayList<Face>();
|
||||
public int glDrawingMode;
|
||||
|
||||
public GroupObject()
|
||||
{
|
||||
this("");
|
||||
}
|
||||
|
||||
public GroupObject(String name)
|
||||
{
|
||||
this(name, -1);
|
||||
}
|
||||
|
||||
public GroupObject(String name, int glDrawingMode)
|
||||
{
|
||||
this.name = name;
|
||||
this.glDrawingMode = glDrawingMode;
|
||||
}
|
||||
|
||||
public void render()
|
||||
{
|
||||
if (faces.size() > 0)
|
||||
{
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
tessellator.startDrawing(glDrawingMode);
|
||||
render(tessellator);
|
||||
tessellator.draw();
|
||||
}
|
||||
}
|
||||
|
||||
public void render(Tessellator tessellator)
|
||||
{
|
||||
if (faces.size() > 0)
|
||||
{
|
||||
for (Face face : faces)
|
||||
{
|
||||
face.addFaceForRender(tessellator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package net.minecraftforge.client.model.obj;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
|
||||
import net.minecraftforge.client.model.IModelCustom;
|
||||
import net.minecraftforge.client.model.IModelCustomLoader;
|
||||
import net.minecraftforge.client.model.ModelFormatException;
|
||||
|
||||
public class ObjModelLoader implements IModelCustomLoader {
|
||||
|
||||
@Override
|
||||
public String getType()
|
||||
{
|
||||
return "OBJ model";
|
||||
}
|
||||
|
||||
private static final String[] types = { "obj" };
|
||||
@Override
|
||||
public String[] getSuffixes()
|
||||
{
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IModelCustom loadInstance(String resourceName, URL resource) throws ModelFormatException
|
||||
{
|
||||
return new WavefrontObject(resourceName, resource);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.minecraftforge.client.model.obj;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class TextureCoordinate
|
||||
{
|
||||
|
||||
public float u, v, w;
|
||||
|
||||
public TextureCoordinate(float u, float v)
|
||||
{
|
||||
this(u, v, 0F);
|
||||
}
|
||||
|
||||
public TextureCoordinate(float u, float v, float w)
|
||||
{
|
||||
this.u = u;
|
||||
this.v = v;
|
||||
this.w = w;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.minecraftforge.client.model.obj;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class Vertex
|
||||
{
|
||||
|
||||
public float x, y, z;
|
||||
|
||||
public Vertex(float x, float y)
|
||||
{
|
||||
this(x, y, 0F);
|
||||
}
|
||||
|
||||
public Vertex(float x, float y, float z)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,650 @@
|
||||
package net.minecraftforge.client.model.obj;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraftforge.client.model.IModelCustom;
|
||||
import net.minecraftforge.client.model.ModelFormatException;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
/**
|
||||
* Wavefront Object importer
|
||||
* Based heavily off of the specifications found at http://en.wikipedia.org/wiki/Wavefront_.obj_file
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class WavefrontObject implements IModelCustom
|
||||
{
|
||||
|
||||
private static Pattern vertexPattern = Pattern.compile("(v( (\\-){0,1}\\d+\\.\\d+){3,4} *\\n)|(v( (\\-){0,1}\\d+\\.\\d+){3,4} *$)");
|
||||
private static Pattern vertexNormalPattern = Pattern.compile("(vn( (\\-){0,1}\\d+\\.\\d+){3,4} *\\n)|(vn( (\\-){0,1}\\d+\\.\\d+){3,4} *$)");
|
||||
private static Pattern textureCoordinatePattern = Pattern.compile("(vt( (\\-){0,1}\\d+\\.\\d+){2,3} *\\n)|(vt( (\\-){0,1}\\d+\\.\\d+){2,3} *$)");
|
||||
private static Pattern face_V_VT_VN_Pattern = Pattern.compile("(f( \\d+/\\d+/\\d+){3,4} *\\n)|(f( \\d+/\\d+/\\d+){3,4} *$)");
|
||||
private static Pattern face_V_VT_Pattern = Pattern.compile("(f( \\d+/\\d+){3,4} *\\n)|(f( \\d+/\\d+){3,4} *$)");
|
||||
private static Pattern face_V_VN_Pattern = Pattern.compile("(f( \\d+//\\d+){3,4} *\\n)|(f( \\d+//\\d+){3,4} *$)");
|
||||
private static Pattern face_V_Pattern = Pattern.compile("(f( \\d+){3,4} *\\n)|(f( \\d+){3,4} *$)");
|
||||
private static Pattern groupObjectPattern = Pattern.compile("([go]( [\\w\\d]+) *\\n)|([go]( [\\w\\d]+) *$)");
|
||||
|
||||
private static Matcher vertexMatcher, vertexNormalMatcher, textureCoordinateMatcher;
|
||||
private static Matcher face_V_VT_VN_Matcher, face_V_VT_Matcher, face_V_VN_Matcher, face_V_Matcher;
|
||||
private static Matcher groupObjectMatcher;
|
||||
|
||||
public ArrayList<Vertex> vertices = new ArrayList<Vertex>();
|
||||
public ArrayList<Vertex> vertexNormals = new ArrayList<Vertex>();
|
||||
public ArrayList<TextureCoordinate> textureCoordinates = new ArrayList<TextureCoordinate>();
|
||||
public ArrayList<GroupObject> groupObjects = new ArrayList<GroupObject>();
|
||||
private GroupObject currentGroupObject;
|
||||
private String fileName;
|
||||
|
||||
public WavefrontObject(String fileName, URL resource) throws ModelFormatException
|
||||
{
|
||||
this.fileName = fileName;
|
||||
|
||||
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(InputStream inputStream) throws ModelFormatException
|
||||
{
|
||||
BufferedReader reader = null;
|
||||
|
||||
String currentLine = null;
|
||||
int lineCount = 0;
|
||||
|
||||
try
|
||||
{
|
||||
reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
|
||||
while ((currentLine = reader.readLine()) != null)
|
||||
{
|
||||
lineCount++;
|
||||
currentLine = currentLine.replaceAll("\\s+", " ").trim();
|
||||
|
||||
if (currentLine.startsWith("#") || currentLine.length() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (currentLine.startsWith("v "))
|
||||
{
|
||||
Vertex vertex = parseVertex(currentLine, lineCount);
|
||||
if (vertex != null)
|
||||
{
|
||||
vertices.add(vertex);
|
||||
}
|
||||
}
|
||||
else if (currentLine.startsWith("vn "))
|
||||
{
|
||||
Vertex vertex = parseVertexNormal(currentLine, lineCount);
|
||||
if (vertex != null)
|
||||
{
|
||||
vertexNormals.add(vertex);
|
||||
}
|
||||
}
|
||||
else if (currentLine.startsWith("vt "))
|
||||
{
|
||||
TextureCoordinate textureCoordinate = parseTextureCoordinate(currentLine, lineCount);
|
||||
if (textureCoordinate != null)
|
||||
{
|
||||
textureCoordinates.add(textureCoordinate);
|
||||
}
|
||||
}
|
||||
else if (currentLine.startsWith("f "))
|
||||
{
|
||||
|
||||
if (currentGroupObject == null)
|
||||
{
|
||||
currentGroupObject = new GroupObject("Default");
|
||||
}
|
||||
|
||||
Face face = parseFace(currentLine, lineCount);
|
||||
|
||||
if (face != null)
|
||||
{
|
||||
currentGroupObject.faces.add(face);
|
||||
}
|
||||
}
|
||||
else if (currentLine.startsWith("g ") | currentLine.startsWith("o "))
|
||||
{
|
||||
GroupObject group = parseGroupObject(currentLine, lineCount);
|
||||
|
||||
if (group != null)
|
||||
{
|
||||
if (currentGroupObject != null)
|
||||
{
|
||||
groupObjects.add(currentGroupObject);
|
||||
}
|
||||
}
|
||||
|
||||
currentGroupObject = group;
|
||||
}
|
||||
}
|
||||
|
||||
groupObjects.add(currentGroupObject);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ModelFormatException("IO Exception reading model format", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
reader.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// hush
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
inputStream.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// hush
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAll()
|
||||
{
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
|
||||
if (currentGroupObject != null)
|
||||
{
|
||||
tessellator.startDrawing(currentGroupObject.glDrawingMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
tessellator.startDrawing(GL11.GL_TRIANGLES);
|
||||
}
|
||||
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)
|
||||
{
|
||||
for (String groupName : groupNames)
|
||||
{
|
||||
if (groupName.equalsIgnoreCase(groupObject.name))
|
||||
{
|
||||
groupObject.render();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (partName.equalsIgnoreCase(groupObject.name))
|
||||
{
|
||||
groupObject.render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Vertex parseVertex(String line, int lineCount) throws ModelFormatException
|
||||
{
|
||||
Vertex vertex = null;
|
||||
|
||||
if (isValidVertexLine(line))
|
||||
{
|
||||
line = line.substring(line.indexOf(" ") + 1);
|
||||
String[] tokens = line.split(" ");
|
||||
|
||||
try
|
||||
{
|
||||
if (tokens.length == 2)
|
||||
{
|
||||
return new Vertex(Float.parseFloat(tokens[0]), Float.parseFloat(tokens[1]));
|
||||
}
|
||||
else if (tokens.length == 3)
|
||||
{
|
||||
return new Vertex(Float.parseFloat(tokens[0]), Float.parseFloat(tokens[1]), Float.parseFloat(tokens[2]));
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new ModelFormatException(String.format("Number formatting error at line %d",lineCount), e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
|
||||
}
|
||||
|
||||
return vertex;
|
||||
}
|
||||
|
||||
private Vertex parseVertexNormal(String line, int lineCount) throws ModelFormatException
|
||||
{
|
||||
Vertex vertexNormal = null;
|
||||
|
||||
if (isValidVertexNormalLine(line))
|
||||
{
|
||||
line = line.substring(line.indexOf(" ") + 1);
|
||||
String[] tokens = line.split(" ");
|
||||
|
||||
try
|
||||
{
|
||||
if (tokens.length == 3)
|
||||
return new Vertex(Float.parseFloat(tokens[0]), Float.parseFloat(tokens[1]), Float.parseFloat(tokens[2]));
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new ModelFormatException(String.format("Number formatting error at line %d",lineCount), e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
|
||||
}
|
||||
|
||||
return vertexNormal;
|
||||
}
|
||||
|
||||
private TextureCoordinate parseTextureCoordinate(String line, int lineCount) throws ModelFormatException
|
||||
{
|
||||
TextureCoordinate textureCoordinate = null;
|
||||
|
||||
if (isValidTextureCoordinateLine(line))
|
||||
{
|
||||
line = line.substring(line.indexOf(" ") + 1);
|
||||
String[] tokens = line.split(" ");
|
||||
|
||||
try
|
||||
{
|
||||
if (tokens.length == 2)
|
||||
return new TextureCoordinate(Float.parseFloat(tokens[0]), 1 - Float.parseFloat(tokens[1]));
|
||||
else if (tokens.length == 3)
|
||||
return new TextureCoordinate(Float.parseFloat(tokens[0]), 1 - Float.parseFloat(tokens[1]), Float.parseFloat(tokens[2]));
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new ModelFormatException(String.format("Number formatting error at line %d",lineCount), e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
|
||||
}
|
||||
|
||||
return textureCoordinate;
|
||||
}
|
||||
|
||||
private Face parseFace(String line, int lineCount) throws ModelFormatException
|
||||
{
|
||||
Face face = null;
|
||||
|
||||
if (isValidFaceLine(line))
|
||||
{
|
||||
face = new Face();
|
||||
|
||||
String trimmedLine = line.substring(line.indexOf(" ") + 1);
|
||||
String[] tokens = trimmedLine.split(" ");
|
||||
String[] subTokens = null;
|
||||
|
||||
if (tokens.length == 3)
|
||||
{
|
||||
if (currentGroupObject.glDrawingMode == -1)
|
||||
{
|
||||
currentGroupObject.glDrawingMode = GL11.GL_TRIANGLES;
|
||||
}
|
||||
else if (currentGroupObject.glDrawingMode != GL11.GL_TRIANGLES)
|
||||
{
|
||||
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Invalid number of points for face (expected 4, found " + tokens.length + ")");
|
||||
}
|
||||
}
|
||||
else if (tokens.length == 4)
|
||||
{
|
||||
if (currentGroupObject.glDrawingMode == -1)
|
||||
{
|
||||
currentGroupObject.glDrawingMode = GL11.GL_QUADS;
|
||||
}
|
||||
else if (currentGroupObject.glDrawingMode != GL11.GL_QUADS)
|
||||
{
|
||||
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Invalid number of points for face (expected 3, found " + tokens.length + ")");
|
||||
}
|
||||
}
|
||||
|
||||
// f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ...
|
||||
if (isValidFace_V_VT_VN_Line(line))
|
||||
{
|
||||
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("/");
|
||||
|
||||
face.vertices[i] = vertices.get(Integer.parseInt(subTokens[0]) - 1);
|
||||
face.textureCoordinates[i] = textureCoordinates.get(Integer.parseInt(subTokens[1]) - 1);
|
||||
face.vertexNormals[i] = vertexNormals.get(Integer.parseInt(subTokens[2]) - 1);
|
||||
}
|
||||
|
||||
face.faceNormal = face.calculateFaceNormal();
|
||||
}
|
||||
// f v1/vt1 v2/vt2 v3/vt3 ...
|
||||
else if (isValidFace_V_VT_Line(line))
|
||||
{
|
||||
face.vertices = new Vertex[tokens.length];
|
||||
face.textureCoordinates = new TextureCoordinate[tokens.length];
|
||||
|
||||
for (int i = 0; i < tokens.length; ++i)
|
||||
{
|
||||
subTokens = tokens[i].split("/");
|
||||
|
||||
face.vertices[i] = vertices.get(Integer.parseInt(subTokens[0]) - 1);
|
||||
face.textureCoordinates[i] = textureCoordinates.get(Integer.parseInt(subTokens[1]) - 1);
|
||||
}
|
||||
|
||||
face.faceNormal = face.calculateFaceNormal();
|
||||
}
|
||||
// f v1//vn1 v2//vn2 v3//vn3 ...
|
||||
else if (isValidFace_V_VN_Line(line))
|
||||
{
|
||||
face.vertices = new Vertex[tokens.length];
|
||||
face.vertexNormals = new Vertex[tokens.length];
|
||||
|
||||
for (int i = 0; i < tokens.length; ++i)
|
||||
{
|
||||
subTokens = tokens[i].split("//");
|
||||
|
||||
face.vertices[i] = vertices.get(Integer.parseInt(subTokens[0]) - 1);
|
||||
face.vertexNormals[i] = vertexNormals.get(Integer.parseInt(subTokens[1]) - 1);
|
||||
}
|
||||
|
||||
face.faceNormal = face.calculateFaceNormal();
|
||||
}
|
||||
// f v1 v2 v3 ...
|
||||
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);
|
||||
}
|
||||
|
||||
face.faceNormal = face.calculateFaceNormal();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
|
||||
}
|
||||
|
||||
return face;
|
||||
}
|
||||
|
||||
private GroupObject parseGroupObject(String line, int lineCount) throws ModelFormatException
|
||||
{
|
||||
GroupObject group = null;
|
||||
|
||||
if (isValidGroupObjectLine(line))
|
||||
{
|
||||
String trimmedLine = line.substring(line.indexOf(" ") + 1);
|
||||
|
||||
if (trimmedLine.length() > 0)
|
||||
{
|
||||
group = new GroupObject(trimmedLine);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
/***
|
||||
* Verifies that the given line from the model file is a valid vertex
|
||||
* @param line the line being validated
|
||||
* @return true if the line is a valid vertex, false otherwise
|
||||
*/
|
||||
private static boolean isValidVertexLine(String line)
|
||||
{
|
||||
if (vertexMatcher != null)
|
||||
{
|
||||
vertexMatcher.reset();
|
||||
}
|
||||
|
||||
vertexMatcher = vertexPattern.matcher(line);
|
||||
return vertexMatcher.matches();
|
||||
}
|
||||
|
||||
/***
|
||||
* Verifies that the given line from the model file is a valid vertex normal
|
||||
* @param line the line being validated
|
||||
* @return true if the line is a valid vertex normal, false otherwise
|
||||
*/
|
||||
private static boolean isValidVertexNormalLine(String line)
|
||||
{
|
||||
if (vertexNormalMatcher != null)
|
||||
{
|
||||
vertexNormalMatcher.reset();
|
||||
}
|
||||
|
||||
vertexNormalMatcher = vertexNormalPattern.matcher(line);
|
||||
return vertexNormalMatcher.matches();
|
||||
}
|
||||
|
||||
/***
|
||||
* Verifies that the given line from the model file is a valid texture coordinate
|
||||
* @param line the line being validated
|
||||
* @return true if the line is a valid texture coordinate, false otherwise
|
||||
*/
|
||||
private static boolean isValidTextureCoordinateLine(String line)
|
||||
{
|
||||
if (textureCoordinateMatcher != null)
|
||||
{
|
||||
textureCoordinateMatcher.reset();
|
||||
}
|
||||
|
||||
textureCoordinateMatcher = textureCoordinatePattern.matcher(line);
|
||||
return textureCoordinateMatcher.matches();
|
||||
}
|
||||
|
||||
/***
|
||||
* Verifies that the given line from the model file is a valid face that is described by vertices, texture coordinates, and vertex normals
|
||||
* @param line the line being validated
|
||||
* @return true if the line is a valid face that matches the format "f v1/vt1/vn1 ..." (with a minimum of 3 points in the face, and a maximum of 4), false otherwise
|
||||
*/
|
||||
private static boolean isValidFace_V_VT_VN_Line(String line)
|
||||
{
|
||||
if (face_V_VT_VN_Matcher != null)
|
||||
{
|
||||
face_V_VT_VN_Matcher.reset();
|
||||
}
|
||||
|
||||
face_V_VT_VN_Matcher = face_V_VT_VN_Pattern.matcher(line);
|
||||
return face_V_VT_VN_Matcher.matches();
|
||||
}
|
||||
|
||||
/***
|
||||
* Verifies that the given line from the model file is a valid face that is described by vertices and texture coordinates
|
||||
* @param line the line being validated
|
||||
* @return true if the line is a valid face that matches the format "f v1/vt1 ..." (with a minimum of 3 points in the face, and a maximum of 4), false otherwise
|
||||
*/
|
||||
private static boolean isValidFace_V_VT_Line(String line)
|
||||
{
|
||||
if (face_V_VT_Matcher != null)
|
||||
{
|
||||
face_V_VT_Matcher.reset();
|
||||
}
|
||||
|
||||
face_V_VT_Matcher = face_V_VT_Pattern.matcher(line);
|
||||
return face_V_VT_Matcher.matches();
|
||||
}
|
||||
|
||||
/***
|
||||
* Verifies that the given line from the model file is a valid face that is described by vertices and vertex normals
|
||||
* @param line the line being validated
|
||||
* @return true if the line is a valid face that matches the format "f v1//vn1 ..." (with a minimum of 3 points in the face, and a maximum of 4), false otherwise
|
||||
*/
|
||||
private static boolean isValidFace_V_VN_Line(String line)
|
||||
{
|
||||
if (face_V_VN_Matcher != null)
|
||||
{
|
||||
face_V_VN_Matcher.reset();
|
||||
}
|
||||
|
||||
face_V_VN_Matcher = face_V_VN_Pattern.matcher(line);
|
||||
return face_V_VN_Matcher.matches();
|
||||
}
|
||||
|
||||
/***
|
||||
* Verifies that the given line from the model file is a valid face that is described by only vertices
|
||||
* @param line the line being validated
|
||||
* @return true if the line is a valid face that matches the format "f v1 ..." (with a minimum of 3 points in the face, and a maximum of 4), false otherwise
|
||||
*/
|
||||
private static boolean isValidFace_V_Line(String line)
|
||||
{
|
||||
if (face_V_Matcher != null)
|
||||
{
|
||||
face_V_Matcher.reset();
|
||||
}
|
||||
|
||||
face_V_Matcher = face_V_Pattern.matcher(line);
|
||||
return face_V_Matcher.matches();
|
||||
}
|
||||
|
||||
/***
|
||||
* Verifies that the given line from the model file is a valid face of any of the possible face formats
|
||||
* @param line the line being validated
|
||||
* @return true if the line is a valid face that matches any of the valid face formats, false otherwise
|
||||
*/
|
||||
private static boolean isValidFaceLine(String line)
|
||||
{
|
||||
return isValidFace_V_VT_VN_Line(line) || isValidFace_V_VT_Line(line) || isValidFace_V_VN_Line(line) || isValidFace_V_Line(line);
|
||||
}
|
||||
|
||||
/***
|
||||
* Verifies that the given line from the model file is a valid group (or object)
|
||||
* @param line the line being validated
|
||||
* @return true if the line is a valid group (or object), false otherwise
|
||||
*/
|
||||
private static boolean isValidGroupObjectLine(String line)
|
||||
{
|
||||
if (groupObjectMatcher != null)
|
||||
{
|
||||
groupObjectMatcher.reset();
|
||||
}
|
||||
|
||||
groupObjectMatcher = groupObjectPattern.matcher(line);
|
||||
return groupObjectMatcher.matches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType()
|
||||
{
|
||||
return "obj";
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+1
-9
@@ -7,13 +7,13 @@ import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
|
||||
import paulscode.sound.ICodec;
|
||||
import paulscode.sound.SoundBuffer;
|
||||
import paulscode.sound.SoundSystemConfig;
|
||||
import paulscode.sound.SoundSystemLogger;
|
||||
|
||||
import ibxm.FastTracker2;
|
||||
import ibxm.IBXM;
|
||||
import ibxm.Module;
|
||||
@@ -170,7 +170,6 @@ public class CodecIBXM implements ICodec
|
||||
* will call the reverseByteOrder() method.
|
||||
* @param b True if the calling audio library requires byte-reversal.
|
||||
*/
|
||||
@Override
|
||||
public void reverseByteOrder( boolean b )
|
||||
{
|
||||
reverseBytes = b;
|
||||
@@ -182,7 +181,6 @@ public class CodecIBXM implements ICodec
|
||||
* @param url URL to an audio file to stream from.
|
||||
* @return False if an error occurred or if end of stream was reached.
|
||||
*/
|
||||
@Override
|
||||
public boolean initialize( URL url )
|
||||
{
|
||||
initialized( SET, false );
|
||||
@@ -267,7 +265,6 @@ public class CodecIBXM implements ICodec
|
||||
* Returns false if the stream is busy initializing.
|
||||
* @return True if steam is initialized.
|
||||
*/
|
||||
@Override
|
||||
public boolean initialized()
|
||||
{
|
||||
return initialized( GET, XXX );
|
||||
@@ -279,7 +276,6 @@ public class CodecIBXM implements ICodec
|
||||
* information about accessing and changing default settings.
|
||||
* @return The audio data wrapped into a SoundBuffer context.
|
||||
*/
|
||||
@Override
|
||||
public SoundBuffer read()
|
||||
{
|
||||
if( endOfStream( GET, XXX ) )
|
||||
@@ -337,7 +333,6 @@ public class CodecIBXM implements ICodec
|
||||
* information about accessing and changing default settings.
|
||||
* @return the audio data wrapped into a SoundBuffer context.
|
||||
*/
|
||||
@Override
|
||||
public SoundBuffer readAll()
|
||||
{
|
||||
if( module == null )
|
||||
@@ -398,7 +393,6 @@ public class CodecIBXM implements ICodec
|
||||
* Returns false if there is still more data available to be read in.
|
||||
* @return True if end of stream was reached.
|
||||
*/
|
||||
@Override
|
||||
public boolean endOfStream()
|
||||
{
|
||||
return endOfStream( GET, XXX );
|
||||
@@ -407,7 +401,6 @@ public class CodecIBXM implements ICodec
|
||||
/**
|
||||
* Closes the audio stream and remove references to all instantiated objects.
|
||||
*/
|
||||
@Override
|
||||
public void cleanup()
|
||||
{
|
||||
// if( ibxm != null )
|
||||
@@ -420,7 +413,6 @@ public class CodecIBXM implements ICodec
|
||||
* readAll() methods.
|
||||
* @return Information wrapped into an AudioFormat context.
|
||||
*/
|
||||
@Override
|
||||
public AudioFormat getAudioFormat()
|
||||
{
|
||||
return myAudioFormat;
|
||||
@@ -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.
|
||||
@@ -0,0 +1,160 @@
|
||||
#Main Forge Access Transformer configuration file
|
||||
# Tessellator
|
||||
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 yn.<init>(ILyd;)V #MD:ItemPickaxe/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
|
||||
public+f yn.c #FD:ItemPickaxe/field_77867_c #blocksEffectiveAgainst
|
||||
# ItemAxe
|
||||
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 yy.<init>(ILyd;)V #MD:ItemSpade/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
|
||||
public+f yy.c #FD:ItemSpade/field_77866_c #blocksEffectiveAgainst
|
||||
# ItemTool
|
||||
public xj.a #FD:ItemTool/field_77864_a #efficiencyOnProperMaterial
|
||||
public xj.d #FD:ItemTool/field_77865_bY #damageVsEntity
|
||||
# EntityEnderman
|
||||
public tg.br #FD:EntityEnderman/field_70827_d #carriableBlocks
|
||||
# RenderGlobal
|
||||
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 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 st.* #FD:EntityMinecart/* # All private -> protected
|
||||
# Block
|
||||
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 ka.f #FD:NetServerHandler/field_72572_g #playerInAirTime
|
||||
# TileEntity
|
||||
public asp.k #FD:TileEntity/field_70331_k #worldObj
|
||||
# BlockLeavesBase
|
||||
public arh.d #FD:BlockLeavesBase/field_72131_c #graphicsLevel
|
||||
# Item
|
||||
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 amz #CL:BlockBaseRailLogic
|
||||
public amz.a()I #MD:BlockBaseRailLogic/func_94505_a #getNAdjacentTiles
|
||||
# EntityPlayer
|
||||
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 bdi.a(Lss;)V #MD:EntityClientPlayerMP/func_71012_a #joinEntityItemWithWorld
|
||||
# World Gen Chests Related
|
||||
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 aee.d #FD:AnvilChunkLoader/field_75825_d
|
||||
# ChunkProviderServer.currentChunkLoader
|
||||
public jr.e #FD:ChunkProviderServer/field_73247_e
|
||||
# PlayerManager
|
||||
public jp.a(IIZ)Ljq; #MD:PlayerManager/func_72690_a #getOrCreateChunkWatcher
|
||||
# PlayerInstance
|
||||
public jq #CL:PlayerInstance
|
||||
# World
|
||||
public-f abw.A #FD:World/field_72982_D #villageCollectionObj
|
||||
public abw.G #FD:World/field_72993_I #activeChunkSet
|
||||
# EntityLiving
|
||||
public og.b #FD:EntityLiving/field_70728_aV #experienceValue
|
||||
public og.d #FD:EntityLiving/field_70715_bh #targetTasks
|
||||
# GuiFlatPresets
|
||||
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 acq.*() #MD:BiomeGenBase/* #Everything protected->public
|
||||
# MapGenVillage
|
||||
public-f aiw.e #FD:MapGenVillage/field_75055_e #villageSpawnBiomes
|
||||
# ShapedRecipes
|
||||
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 aaj.b #FD:ShapelessRecipes/field_77579_b #recipeItems
|
||||
# GuiContainer
|
||||
protected awy.a(Lwe;)V #MD:GuiContainer/func_74192_a #drawSlotInventory
|
||||
# ContainerPlayer
|
||||
protected vv.h #FD:ContainerPlayer/field_82862_h #player
|
||||
# BlockButton
|
||||
protected anf.n(Labw;III)V #MD:BlockButton/func_82535_o #checkActivation
|
||||
protected-f anf.a #FD:BlockButton/field_82537_a #sensible
|
||||
# BiomeDecorator
|
||||
public acu.* #FD:BiomeDecorator/* # All private -> protected
|
||||
# CreativeTabs
|
||||
public-f ww.a #FD:CreativeTabs/field_78032_a # creativeTabArray non-final
|
||||
# Packet
|
||||
public ey.a(IZZLjava/lang/Class;)V #MD:Packet/func_73285_a #addIdClassMapping
|
||||
# SaveHandler
|
||||
public alq.b()Ljava/io/File; #MD:SaveHandler/func_75765_b
|
||||
# World stuff
|
||||
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 bdd.b(Lnn;)V #MD:WorldClient/func_72847_b #releaseEntitySkin
|
||||
#WorldServer
|
||||
public js.b(Lnn;)V #MD:WorldServer/func_72847_b #releaseEntitySkin
|
||||
public js.N #FD:WorldServer/field_73068_P #allPlayersSleeping
|
||||
#TextureMap
|
||||
public bik.g #FD:TextureMap/field_94255_a
|
||||
public bik.h #FD:TextureMap/field_94254_c
|
||||
#Potion
|
||||
public ni.b(II)Lni; #MD:Potion/func_76399_b #setIconIndex
|
||||
#PotionHelper
|
||||
public zp.m #FD:PotionHelper/field_77927_l #potionRequirements
|
||||
public zp.n #FD:PotionHelper/field_77928_m #potionAmplifiers
|
||||
#PotionEffect
|
||||
public nj.b #FD:PotionEffect/field_76460_b #duration
|
||||
#BlockFluid
|
||||
protected apc.a #FD:BlockFluid/field_94425_a #theIcon
|
||||
#GuiIngame
|
||||
protected avj.* #FD:GuiIngame/* # All private -> protected
|
||||
protected avj.*() #MD:GuiIngame/* # All private -> protected
|
||||
#ItemStack
|
||||
default ye.f #FD:ItemStack/field_77991_e # make default access for itemDamage
|
||||
#GuiSlot
|
||||
protected awg.b(IIII)V #MD:GuiSlot/func_77206_b #overlayBackground
|
||||
#EntityPlayer
|
||||
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
|
||||
+12
-9
@@ -3,23 +3,32 @@ package net.minecraftforge.classloading;
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
|
||||
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()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getASMTransformerClass()
|
||||
{
|
||||
return new String[0];
|
||||
return new String[]{
|
||||
"net.minecraftforge.transformers.ForgeAccessTransformer",
|
||||
"net.minecraftforge.transformers.EventTransformer"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModContainerClass()
|
||||
{
|
||||
return "net.minecraftforge.common.ForgeModContainer";
|
||||
return "net.minecraftforge.common.ForgeDummyContainer";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -34,10 +43,4 @@ public class FMLForgePlugin implements IFMLLoadingPlugin
|
||||
RUNTIME_DEOBF = (Boolean)data.get("runtimeDeobfuscationEnabled");
|
||||
forgeLocation = (File)data.get("coremodLocation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAccessTransformerClass()
|
||||
{
|
||||
return "net.minecraftforge.transformers.ForgeAccessTransformer";
|
||||
}
|
||||
}
|
||||
File renamed without changes.
@@ -0,0 +1,319 @@
|
||||
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.*;
|
||||
|
||||
public class BiomeDictionary
|
||||
{
|
||||
public enum Type
|
||||
{
|
||||
FOREST,
|
||||
PLAINS,
|
||||
MOUNTAIN,
|
||||
HILLS,
|
||||
SWAMP,
|
||||
WATER,
|
||||
DESERT,
|
||||
FROZEN,
|
||||
JUNGLE,
|
||||
WASTELAND,
|
||||
BEACH,
|
||||
NETHER,
|
||||
END,
|
||||
MUSHROOM,
|
||||
MAGICAL;
|
||||
}
|
||||
|
||||
private static final int BIOME_LIST_SIZE = 256;
|
||||
private static BiomeInfo[] biomeList = new BiomeInfo[BIOME_LIST_SIZE];
|
||||
private static ArrayList<BiomeGenBase>[] typeInfoList = new ArrayList[Type.values().length];
|
||||
|
||||
private static class BiomeInfo
|
||||
{
|
||||
public EnumSet<Type> typeList;
|
||||
|
||||
public BiomeInfo(Type[] types)
|
||||
{
|
||||
typeList = EnumSet.noneOf(Type.class);
|
||||
for(Type t : types)
|
||||
{
|
||||
typeList.add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
registerVanillaBiomes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a biome with a specific biome type
|
||||
*
|
||||
* @param biome the biome to be registered
|
||||
* @param type the type to register the biome as
|
||||
* @return returns true if the biome was registered successfully
|
||||
*/
|
||||
public static boolean registerBiomeType(BiomeGenBase biome, Type ... types)
|
||||
{
|
||||
if(BiomeGenBase.biomeList[biome.biomeID] != null)
|
||||
{
|
||||
for(Type type : types)
|
||||
{
|
||||
if(typeInfoList[type.ordinal()] == null)
|
||||
{
|
||||
typeInfoList[type.ordinal()] = new ArrayList<BiomeGenBase>();
|
||||
}
|
||||
|
||||
typeInfoList[type.ordinal()].add(biome);
|
||||
}
|
||||
|
||||
if(biomeList[biome.biomeID] == null)
|
||||
{
|
||||
biomeList[biome.biomeID] = new BiomeInfo(types);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(Type type : types)
|
||||
{
|
||||
biomeList[biome.biomeID].typeList.add(type);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of biomes registered with a specific type
|
||||
*
|
||||
* @param type the Type to look for
|
||||
* @return a list of biomes of the specified type, null if there are none
|
||||
*/
|
||||
public static BiomeGenBase[] getBiomesForType(Type type)
|
||||
{
|
||||
if(typeInfoList[type.ordinal()] != null)
|
||||
{
|
||||
return (BiomeGenBase[])typeInfoList[type.ordinal()].toArray(new BiomeGenBase[0]);
|
||||
}
|
||||
|
||||
return new BiomeGenBase[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of Types that a specific biome is registered with
|
||||
*
|
||||
* @param biome the biome to check
|
||||
* @return the list of types, null if there are none
|
||||
*/
|
||||
public static Type[] getTypesForBiome(BiomeGenBase biome)
|
||||
{
|
||||
checkRegistration(biome);
|
||||
|
||||
if(biomeList[biome.biomeID] != null)
|
||||
{
|
||||
return (Type[])biomeList[biome.biomeID].typeList.toArray(new Type[0]);
|
||||
}
|
||||
|
||||
return new Type[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if two biomes are registered as having the same type
|
||||
*
|
||||
* @param biomeA
|
||||
* @param biomeB
|
||||
* @return returns true if a common type is found, false otherwise
|
||||
*/
|
||||
public static boolean areBiomesEquivalent(BiomeGenBase biomeA, BiomeGenBase biomeB)
|
||||
{
|
||||
int a = biomeA.biomeID;
|
||||
int b = biomeB.biomeID;
|
||||
|
||||
checkRegistration(biomeA);
|
||||
checkRegistration(biomeB);
|
||||
|
||||
if(biomeList[a] != null && biomeList[b] != null)
|
||||
{
|
||||
for(Type type : biomeList[a].typeList)
|
||||
{
|
||||
if(containsType(biomeList[b], type))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the given biome is registered as being a specific type
|
||||
*
|
||||
* @param biome the biome to be considered
|
||||
* @param type the type to check for
|
||||
* @return returns true if the biome is registered as being of type type, false otherwise
|
||||
*/
|
||||
public static boolean isBiomeOfType(BiomeGenBase biome, Type type)
|
||||
{
|
||||
checkRegistration(biome);
|
||||
|
||||
if(biomeList[biome.biomeID] != null)
|
||||
{
|
||||
return containsType(biomeList[biome.biomeID], type);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the given biome has been registered as being of any type
|
||||
* @param biome the biome to consider
|
||||
* @return returns true if the biome has been registered, false otherwise
|
||||
*/
|
||||
public static boolean isBiomeRegistered(BiomeGenBase biome)
|
||||
{
|
||||
return biomeList[biome.biomeID] != null;
|
||||
}
|
||||
|
||||
public static boolean isBiomeRegistered(int biomeID)
|
||||
{
|
||||
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 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 registerAllBiomesAndGenerateEvents()
|
||||
{
|
||||
for(int i = 0; i < BiomeGenBase.biomeList.length; i++)
|
||||
{
|
||||
BiomeGenBase biome = BiomeGenBase.biomeList[i];
|
||||
|
||||
if(biome == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (biome.theBiomeDecorator instanceof DeferredBiomeDecorator)
|
||||
{
|
||||
DeferredBiomeDecorator decorator = (DeferredBiomeDecorator) biome.theBiomeDecorator;
|
||||
decorator.fireCreateEventAndReplace();
|
||||
}
|
||||
|
||||
checkRegistration(biome);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically looks for and registers a given biome with appropriate tags
|
||||
* This method is called automatically if a biome has not been registered with any tags,
|
||||
* And another method requests information about it
|
||||
*
|
||||
* NOTE: You can opt out of having your biome registered by registering it as type NULL
|
||||
*
|
||||
* @param biome the biome to be considered
|
||||
*/
|
||||
public static void makeBestGuess(BiomeGenBase biome)
|
||||
{
|
||||
if(biome.theBiomeDecorator.treesPerChunk >= 3)
|
||||
{
|
||||
if(biome.isHighHumidity() && biome.temperature >= 1.0F)
|
||||
{
|
||||
BiomeDictionary.registerBiomeType(biome, JUNGLE);
|
||||
}
|
||||
else if(!biome.isHighHumidity())
|
||||
{
|
||||
BiomeDictionary.registerBiomeType(biome, FOREST);
|
||||
}
|
||||
}
|
||||
else if(biome.maxHeight <= 0.3F && biome.maxHeight >= 0.0F)
|
||||
{
|
||||
if(!biome.isHighHumidity() || biome.minHeight >= 0.0F)
|
||||
{
|
||||
BiomeDictionary.registerBiomeType(biome, PLAINS);
|
||||
}
|
||||
}
|
||||
|
||||
if(biome.isHighHumidity() && biome.minHeight < 0.0F && (biome.maxHeight <= 0.3F && biome.maxHeight >= 0.0F))
|
||||
{
|
||||
BiomeDictionary.registerBiomeType(biome, SWAMP);
|
||||
}
|
||||
|
||||
if(biome.minHeight <= -0.5F)
|
||||
{
|
||||
BiomeDictionary.registerBiomeType(biome, WATER);
|
||||
}
|
||||
|
||||
if(biome.maxHeight >= 1.5F)
|
||||
{
|
||||
BiomeDictionary.registerBiomeType(biome, MOUNTAIN);
|
||||
}
|
||||
|
||||
if(biome.getEnableSnow() || biome.temperature < 0.2F)
|
||||
{
|
||||
BiomeDictionary.registerBiomeType(biome, FROZEN);
|
||||
}
|
||||
|
||||
if(!biome.isHighHumidity() && biome.temperature >= 1.0F)
|
||||
{
|
||||
BiomeDictionary.registerBiomeType(biome, DESERT);
|
||||
}
|
||||
}
|
||||
|
||||
//Internal implementation
|
||||
private static void checkRegistration(BiomeGenBase biome)
|
||||
{
|
||||
if(!isBiomeRegistered(biome))
|
||||
{
|
||||
makeBestGuess(biome);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean containsType(BiomeInfo info, Type type)
|
||||
{
|
||||
return info.typeList.contains(type);
|
||||
}
|
||||
|
||||
private static void registerVanillaBiomes()
|
||||
{
|
||||
registerBiomeType(ocean, WATER );
|
||||
registerBiomeType(plains, PLAINS );
|
||||
registerBiomeType(desert, DESERT );
|
||||
registerBiomeType(extremeHills, MOUNTAIN );
|
||||
registerBiomeType(forest, FOREST );
|
||||
registerBiomeType(taiga, FOREST, FROZEN);
|
||||
registerBiomeType(taigaHills, FOREST, FROZEN);
|
||||
registerBiomeType(swampland, SWAMP );
|
||||
registerBiomeType(river, WATER );
|
||||
registerBiomeType(frozenOcean, WATER, FROZEN);
|
||||
registerBiomeType(frozenRiver, WATER, FROZEN);
|
||||
registerBiomeType(icePlains, FROZEN );
|
||||
registerBiomeType(iceMountains, FROZEN );
|
||||
registerBiomeType(beach, BEACH );
|
||||
registerBiomeType(desertHills, DESERT );
|
||||
registerBiomeType(jungle, JUNGLE );
|
||||
registerBiomeType(jungleHills, JUNGLE );
|
||||
registerBiomeType(forestHills, FOREST );
|
||||
registerBiomeType(sky, END );
|
||||
registerBiomeType(hell, NETHER );
|
||||
registerBiomeType(mushroomIsland, MUSHROOM );
|
||||
registerBiomeType(extremeHillsEdge, MOUNTAIN );
|
||||
registerBiomeType(mushroomIslandShore, MUSHROOM, BEACH);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.world.biome.BiomeGenBase;
|
||||
import net.minecraft.world.gen.ChunkProviderGenerate;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
import net.minecraft.world.gen.structure.MapGenStronghold;
|
||||
import net.minecraft.world.gen.structure.MapGenVillage;
|
||||
import net.minecraft.world.biome.WorldChunkManager;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class BiomeManager
|
||||
{
|
||||
public static void addVillageBiome(BiomeGenBase biome, boolean canSpawn)
|
||||
{
|
||||
if (!MapGenVillage.villageSpawnBiomes.contains(biome))
|
||||
{
|
||||
ArrayList<BiomeGenBase> biomes = new ArrayList<BiomeGenBase>(MapGenVillage.villageSpawnBiomes);
|
||||
biomes.add(biome);
|
||||
MapGenVillage.villageSpawnBiomes = biomes;
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeVillageBiome(BiomeGenBase biome)
|
||||
{
|
||||
if (MapGenVillage.villageSpawnBiomes.contains(biome))
|
||||
{
|
||||
ArrayList<BiomeGenBase> biomes = new ArrayList<BiomeGenBase>(MapGenVillage.villageSpawnBiomes);
|
||||
biomes.remove(biome);
|
||||
MapGenVillage.villageSpawnBiomes = biomes;
|
||||
}
|
||||
}
|
||||
|
||||
public static void addStrongholdBiome(BiomeGenBase biome)
|
||||
{
|
||||
if (!MapGenStronghold.allowedBiomes.contains(biome))
|
||||
{
|
||||
MapGenStronghold.allowedBiomes.add(biome);
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeStrongholdBiome(BiomeGenBase biome)
|
||||
{
|
||||
if (MapGenStronghold.allowedBiomes.contains(biome))
|
||||
{
|
||||
MapGenStronghold.allowedBiomes.remove(biome);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addSpawnBiome(BiomeGenBase biome)
|
||||
{
|
||||
if (!WorldChunkManager.allowedBiomes.contains(biome))
|
||||
{
|
||||
WorldChunkManager.allowedBiomes.add(biome);
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeSpawnBiome(BiomeGenBase biome)
|
||||
{
|
||||
if (WorldChunkManager.allowedBiomes.contains(biome))
|
||||
{
|
||||
WorldChunkManager.allowedBiomes.remove(biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
+35
-34
@@ -1,8 +1,7 @@
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import java.util.*;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.init.Items;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.WeightedRandom;
|
||||
@@ -10,13 +9,6 @@ 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.minecraft.world.gen.structure.ComponentScatteredFeaturePieces.DesertPyramid;
|
||||
import net.minecraft.world.gen.structure.ComponentScatteredFeaturePieces.JunglePyramid;
|
||||
import net.minecraft.world.gen.structure.StructureStrongholdPieces.ChestCorridor;
|
||||
import net.minecraft.world.gen.structure.StructureStrongholdPieces.Library;
|
||||
import net.minecraft.world.gen.structure.StructureStrongholdPieces.RoomCrossing;
|
||||
import net.minecraft.world.gen.structure.StructureVillagePieces.House2;
|
||||
import net.minecraft.world.gen.structure.StructureNetherBridgePieces.Corridor;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
public class ChestGenHooks
|
||||
@@ -32,7 +24,6 @@ public class ChestGenHooks
|
||||
public static final String VILLAGE_BLACKSMITH = "villageBlacksmith";
|
||||
public static final String BONUS_CHEST = "bonusChest";
|
||||
public static final String DUNGEON_CHEST = "dungeonChest";
|
||||
public static final String NETHER_FORTRESS = "netherFortress";
|
||||
|
||||
private static final HashMap<String, ChestGenHooks> chestInfo = new HashMap<String, ChestGenHooks>();
|
||||
private static boolean hasInit = false;
|
||||
@@ -49,24 +40,27 @@ public class ChestGenHooks
|
||||
}
|
||||
|
||||
hasInit = true;
|
||||
// This causes the classes static initializers to run
|
||||
new WorldGenDungeons();
|
||||
new DesertPyramid();
|
||||
new JunglePyramid();
|
||||
new StructureMineshaftPieces();
|
||||
new StructureOceanMonument();
|
||||
new StructureStrongholdPieces.ChestCorridor();
|
||||
new StructureStrongholdPieces.Library();
|
||||
new StructureStrongholdPieces.RoomCrossing();
|
||||
new StructureVillagePieces.House2();
|
||||
new StructureNetherBridgePieces.Corridor();
|
||||
WorldServer.fillChestHook();
|
||||
}
|
||||
|
||||
// INTERNAL DO NO USE
|
||||
public static void init(String category, List items, int min, int max)
|
||||
{
|
||||
chestInfo.put(category, new ChestGenHooks(category, (List<WeightedRandomChestContent>)items, min, max));
|
||||
addInfo(MINESHAFT_CORRIDOR, StructureMineshaftPieces.mineshaftChestContents, 3, 7);
|
||||
addInfo(PYRAMID_DESERT_CHEST, ComponentScatteredFeatureDesertPyramid.itemsToGenerateInTemple, 2, 7);
|
||||
addInfo(PYRAMID_JUNGLE_CHEST, ComponentScatteredFeatureJunglePyramid.junglePyramidsChestContents, 2, 7);
|
||||
addInfo(PYRAMID_JUNGLE_DISPENSER, ComponentScatteredFeatureJunglePyramid.junglePyramidsDispenserContents, 2, 2);
|
||||
addInfo(STRONGHOLD_CORRIDOR, ComponentStrongholdChestCorridor.strongholdChestContents, 2, 4);
|
||||
addInfo(STRONGHOLD_LIBRARY, ComponentStrongholdLibrary.strongholdLibraryChestContents, 1, 5);
|
||||
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);
|
||||
getInfo(MINESHAFT_CORRIDOR ).addItem(tmp);
|
||||
getInfo(PYRAMID_DESERT_CHEST).addItem(tmp);
|
||||
getInfo(PYRAMID_JUNGLE_CHEST).addItem(tmp);
|
||||
getInfo(STRONGHOLD_CORRIDOR ).addItem(tmp);
|
||||
getInfo(STRONGHOLD_LIBRARY ).addItem(new WeightedRandomChestContent(book, 1, 5, 2));
|
||||
getInfo(STRONGHOLD_CROSSING ).addItem(tmp);
|
||||
getInfo(DUNGEON_CHEST ).addItem(tmp);
|
||||
}
|
||||
|
||||
static void addDungeonLoot(ChestGenHooks dungeon, ItemStack item, int weight, int min, int max)
|
||||
@@ -74,6 +68,11 @@ public class ChestGenHooks
|
||||
dungeon.addItem(new WeightedRandomChestContent(item, min, max, weight));
|
||||
}
|
||||
|
||||
private static void addInfo(String category, WeightedRandomChestContent[] items, int min, int max)
|
||||
{
|
||||
chestInfo.put(category, new ChestGenHooks(category, items, min, max));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves, or creates the info class for the specified category.
|
||||
*
|
||||
@@ -128,7 +127,7 @@ public class ChestGenHooks
|
||||
}
|
||||
|
||||
//shortcut functions, See the non-static versions below
|
||||
public static List<WeightedRandomChestContent> getItems(String category, Random rnd){ return getInfo(category).getItems(rnd); }
|
||||
public static WeightedRandomChestContent[] getItems(String category, Random rnd){ return getInfo(category).getItems(rnd); }
|
||||
public static int getCount(String category, Random rand){ return getInfo(category).getCount(rand); }
|
||||
public static void addItem(String category, WeightedRandomChestContent item){ getInfo(category).addItem(item); }
|
||||
public static void removeItem(String category, ItemStack item){ getInfo(category).removeItem(item); }
|
||||
@@ -137,14 +136,15 @@ public class ChestGenHooks
|
||||
private String category;
|
||||
private int countMin = 0;
|
||||
private int countMax = 0;
|
||||
private ArrayList<WeightedRandomChestContent> contents = new ArrayList<WeightedRandomChestContent>();
|
||||
//TO-DO: Privatize this once again when we remove the Deprecated stuff in DungeonHooks
|
||||
ArrayList<WeightedRandomChestContent> contents = new ArrayList<WeightedRandomChestContent>();
|
||||
|
||||
public ChestGenHooks(String category)
|
||||
{
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public ChestGenHooks(String category, List<WeightedRandomChestContent> items, int min, int max)
|
||||
public ChestGenHooks(String category, WeightedRandomChestContent[] items, int min, int max)
|
||||
{
|
||||
this(category);
|
||||
for (WeightedRandomChestContent item : items)
|
||||
@@ -177,7 +177,7 @@ public class ChestGenHooks
|
||||
while(itr.hasNext())
|
||||
{
|
||||
WeightedRandomChestContent cont = itr.next();
|
||||
if (item.isItemEqual(cont.theItemId) || (item.getItemDamage() == OreDictionary.WILDCARD_VALUE && item.getItem() == cont.theItemId.getItem()))
|
||||
if (item.isItemEqual(cont.theItemId) || (item.getItemDamage() == OreDictionary.WILDCARD_VALUE && item.itemID == cont.theItemId.itemID))
|
||||
{
|
||||
itr.remove();
|
||||
}
|
||||
@@ -189,7 +189,7 @@ public class ChestGenHooks
|
||||
*
|
||||
* @return The random objects
|
||||
*/
|
||||
public List<WeightedRandomChestContent> getItems(Random rnd)
|
||||
public WeightedRandomChestContent[] getItems(Random rnd)
|
||||
{
|
||||
ArrayList<WeightedRandomChestContent> ret = new ArrayList<WeightedRandomChestContent>();
|
||||
|
||||
@@ -207,7 +207,7 @@ public class ChestGenHooks
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret.toArray(new WeightedRandomChestContent[ret.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,7 +230,8 @@ public class ChestGenHooks
|
||||
*/
|
||||
public ItemStack getOneItem(Random rand)
|
||||
{
|
||||
WeightedRandomChestContent item = (WeightedRandomChestContent)WeightedRandom.getRandomItem(rand, getItems(rand));
|
||||
WeightedRandomChestContent[] items = getItems(rand);
|
||||
WeightedRandomChestContent item = (WeightedRandomChestContent)WeightedRandom.getRandomItem(rand, items);
|
||||
ItemStack[] stacks = ChestGenHooks.generateStacks(rand, item.theItemId, item.theMinimumChanceToGenerateItem, item.theMaximumChanceToGenerateItem);
|
||||
return (stacks.length > 0 ? stacks[0] : null);
|
||||
}
|
||||
+18
-175
@@ -1,46 +1,27 @@
|
||||
/**
|
||||
* This software is provided under the terms of the Minecraft Forge Public
|
||||
* License v1.0.
|
||||
*/
|
||||
package net.minecraftforge.common;
|
||||
|
||||
package net.minecraftforge.common.config;
|
||||
|
||||
import static net.minecraftforge.common.config.Configuration.COMMENT_SEPARATOR;
|
||||
import static net.minecraftforge.common.config.Configuration.NEW_LINE;
|
||||
import static net.minecraftforge.common.config.Configuration.allowedProperties;
|
||||
import static net.minecraftforge.common.Configuration.NEW_LINE;
|
||||
import static net.minecraftforge.common.Configuration.allowedProperties;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import net.minecraftforge.fml.client.config.GuiConfigEntries.IConfigEntry;
|
||||
import com.google.common.base.Splitter;
|
||||
|
||||
public class ConfigCategory implements Map<String, Property>
|
||||
{
|
||||
private String name;
|
||||
private String comment;
|
||||
private String languagekey;
|
||||
private ArrayList<ConfigCategory> children = new ArrayList<ConfigCategory>();
|
||||
private Map<String, Property> properties = new TreeMap<String, Property>();
|
||||
private int propNumber = 0;
|
||||
public final ConfigCategory parent;
|
||||
private boolean changed = false;
|
||||
private boolean requiresWorldRestart = false;
|
||||
private boolean showInGui = true;
|
||||
private boolean requiresMcRestart = false;
|
||||
private Class<? extends IConfigEntry> customEntryClass = null;
|
||||
private List<String> propertyOrder = null;
|
||||
|
||||
public ConfigCategory(String name)
|
||||
{
|
||||
@@ -57,23 +38,17 @@ public class ConfigCategory implements Map<String, Property>
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj instanceof ConfigCategory)
|
||||
{
|
||||
ConfigCategory cat = (ConfigCategory)obj;
|
||||
return name.equals(cat.name) && children.equals(cat.children);
|
||||
return name.equals(cat.name) && children.equals(cat.children);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getQualifiedName()
|
||||
{
|
||||
return getQualifiedName(name, parent);
|
||||
@@ -99,133 +74,11 @@ public class ConfigCategory implements Map<String, Property>
|
||||
return ImmutableMap.copyOf(properties);
|
||||
}
|
||||
|
||||
public List<Property> getOrderedValues()
|
||||
{
|
||||
if (this.propertyOrder != null)
|
||||
{
|
||||
ArrayList<Property> set = new ArrayList<Property>();
|
||||
for (String key : this.propertyOrder)
|
||||
if (properties.containsKey(key))
|
||||
set.add(properties.get(key));
|
||||
|
||||
return ImmutableList.copyOf(set);
|
||||
}
|
||||
else
|
||||
return ImmutableList.copyOf(properties.values());
|
||||
}
|
||||
|
||||
public ConfigCategory setConfigEntryClass(Class<? extends IConfigEntry> clazz)
|
||||
{
|
||||
this.customEntryClass = clazz;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Class<? extends IConfigEntry> getConfigEntryClass()
|
||||
{
|
||||
return this.customEntryClass;
|
||||
}
|
||||
|
||||
public ConfigCategory setLanguageKey(String languagekey)
|
||||
{
|
||||
this.languagekey = languagekey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getLanguagekey()
|
||||
{
|
||||
if (this.languagekey != null)
|
||||
return this.languagekey;
|
||||
else
|
||||
return getQualifiedName();
|
||||
}
|
||||
|
||||
public void setComment(String comment)
|
||||
{
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public String getComment()
|
||||
{
|
||||
return this.comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flag for whether or not this category can be edited while a world is running. Care should be taken to ensure
|
||||
* that only properties that are truly dynamic can be changed from the in-game options menu. Only set this flag to
|
||||
* true if all child properties/categories are unable to be modified while a world is running.
|
||||
*/
|
||||
public ConfigCategory setRequiresWorldRestart(boolean requiresWorldRestart)
|
||||
{
|
||||
this.requiresWorldRestart = requiresWorldRestart;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not this category is able to be edited while a world is running using the in-game Mod Options screen
|
||||
* as well as the Mods list screen, or only from the Mods list screen.
|
||||
*/
|
||||
public boolean requiresWorldRestart()
|
||||
{
|
||||
return this.requiresWorldRestart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not this ConfigCategory should be allowed to show on config GUIs.
|
||||
* Defaults to true.
|
||||
*/
|
||||
public ConfigCategory setShowInGui(boolean showInGui)
|
||||
{
|
||||
this.showInGui = showInGui;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether or not this ConfigCategory should be allowed to show on config GUIs.
|
||||
* Defaults to true unless set to false.
|
||||
*/
|
||||
public boolean showInGui()
|
||||
{
|
||||
return showInGui;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not this ConfigCategory requires Minecraft to be restarted when changed.
|
||||
* Defaults to false. Only set this flag to true if ALL child properties/categories require
|
||||
* Minecraft to be restarted when changed. Setting this flag will also prevent modification
|
||||
* of the child properties/categories while a world is running.
|
||||
*/
|
||||
public ConfigCategory setRequiresMcRestart(boolean requiresMcRestart)
|
||||
{
|
||||
this.requiresMcRestart = this.requiresWorldRestart = requiresMcRestart;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether or not this ConfigCategory requires Minecraft to be restarted when changed.
|
||||
* Defaults to false unless set to true.
|
||||
*/
|
||||
public boolean requiresMcRestart()
|
||||
{
|
||||
return this.requiresMcRestart;
|
||||
}
|
||||
|
||||
public ConfigCategory setPropertyOrder(List<String> propertyOrder)
|
||||
{
|
||||
this.propertyOrder = propertyOrder;
|
||||
for (String s : properties.keySet())
|
||||
if (!propertyOrder.contains(s))
|
||||
propertyOrder.add(s);
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<String> getPropertyOrder()
|
||||
{
|
||||
if (this.propertyOrder != null)
|
||||
return ImmutableList.copyOf(this.propertyOrder);
|
||||
else
|
||||
return ImmutableList.copyOf(properties.keySet());
|
||||
}
|
||||
|
||||
public boolean containsKey(String key)
|
||||
{
|
||||
return properties.containsKey(key);
|
||||
@@ -256,37 +109,36 @@ public class ConfigCategory implements Map<String, Property>
|
||||
String pad1 = getIndent(indent + 1);
|
||||
String pad2 = getIndent(indent + 2);
|
||||
|
||||
if (comment != null && !comment.isEmpty())
|
||||
write(out, pad0, "####################");
|
||||
write(out, pad0, "# ", name);
|
||||
|
||||
if (comment != null)
|
||||
{
|
||||
write(out, pad0, COMMENT_SEPARATOR);
|
||||
write(out, pad0, "# ", name);
|
||||
write(out, pad0, "#--------------------------------------------------------------------------------------------------------#");
|
||||
write(out, pad0, "#===================");
|
||||
Splitter splitter = Splitter.onPattern("\r?\n");
|
||||
|
||||
for (String line : splitter.split(comment))
|
||||
{
|
||||
write(out, pad0, "# ", line);
|
||||
}
|
||||
|
||||
write(out, pad0, COMMENT_SEPARATOR, NEW_LINE);
|
||||
}
|
||||
|
||||
String displayName = name;
|
||||
write(out, pad0, "####################", NEW_LINE);
|
||||
|
||||
if (!allowedProperties.matchesAllOf(name))
|
||||
{
|
||||
displayName = '"' + name + '"';
|
||||
name = '"' + name + '"';
|
||||
}
|
||||
|
||||
write(out, pad0, displayName, " {");
|
||||
write(out, pad0, name, " {");
|
||||
|
||||
Property[] props = getOrderedValues().toArray(new Property[] {});
|
||||
Property[] props = properties.values().toArray(new Property[properties.size()]);
|
||||
|
||||
for (int x = 0; x < props.length; x++)
|
||||
{
|
||||
Property prop = props[x];
|
||||
|
||||
if (prop.comment != null && !prop.comment.isEmpty())
|
||||
if (prop.comment != null)
|
||||
{
|
||||
if (x != 0)
|
||||
{
|
||||
@@ -310,7 +162,7 @@ public class ConfigCategory implements Map<String, Property>
|
||||
if (prop.isList())
|
||||
{
|
||||
char type = prop.getType().getID();
|
||||
|
||||
|
||||
write(out, pad1, String.valueOf(type), ":", propName, " <");
|
||||
|
||||
for (String line : prop.getStringList())
|
||||
@@ -331,9 +183,6 @@ public class ConfigCategory implements Map<String, Property>
|
||||
}
|
||||
}
|
||||
|
||||
if (children.size() > 0)
|
||||
out.newLine();
|
||||
|
||||
for (ConfigCategory child : children)
|
||||
{
|
||||
child.write(out, indent + 1);
|
||||
@@ -381,8 +230,6 @@ public class ConfigCategory implements Map<String, Property>
|
||||
@Override public Property put(String key, Property value)
|
||||
{
|
||||
changed = true;
|
||||
if (this.propertyOrder != null && !this.propertyOrder.contains(key))
|
||||
this.propertyOrder.add(key);
|
||||
return properties.put(key, value);
|
||||
}
|
||||
@Override public Property remove(Object key)
|
||||
@@ -393,10 +240,6 @@ public class ConfigCategory implements Map<String, Property>
|
||||
@Override public void putAll(Map<? extends String, ? extends Property> m)
|
||||
{
|
||||
changed = true;
|
||||
if (this.propertyOrder != null)
|
||||
for (String key : m.keySet())
|
||||
if (!this.propertyOrder.contains(key))
|
||||
this.propertyOrder.add(key);
|
||||
properties.putAll(m);
|
||||
}
|
||||
@Override public void clear()
|
||||
@@ -414,7 +257,7 @@ public class ConfigCategory implements Map<String, Property>
|
||||
}
|
||||
|
||||
public Set<ConfigCategory> getChildren(){ return ImmutableSet.copyOf(children); }
|
||||
|
||||
|
||||
public void removeChild(ConfigCategory child)
|
||||
{
|
||||
if (children.contains(child))
|
||||
@@ -0,0 +1,927 @@
|
||||
/**
|
||||
* This software is provided under the terms of the Minecraft Forge Public
|
||||
* License v1.0.
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import static net.minecraftforge.common.Property.Type.BOOLEAN;
|
||||
import static net.minecraftforge.common.Property.Type.DOUBLE;
|
||||
import static net.minecraftforge.common.Property.Type.INTEGER;
|
||||
import static net.minecraftforge.common.Property.Type.STRING;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PushbackInputStream;
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.Item;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.relauncher.FMLInjectionData;
|
||||
|
||||
/**
|
||||
* This class offers advanced configurations capabilities, allowing to provide
|
||||
* various categories for configuration variables.
|
||||
*/
|
||||
public class Configuration
|
||||
{
|
||||
private static boolean[] configMarkers = new boolean[Item.itemsList.length];
|
||||
private static final int ITEM_SHIFT = 256;
|
||||
private static final int MAX_BLOCKS = 4096;
|
||||
|
||||
public static final String CATEGORY_GENERAL = "general";
|
||||
public static final String CATEGORY_BLOCK = "block";
|
||||
public static final String CATEGORY_ITEM = "item";
|
||||
public static final String ALLOWED_CHARS = "._-";
|
||||
public static final String DEFAULT_ENCODING = "UTF-8";
|
||||
public static final String CATEGORY_SPLITTER = ".";
|
||||
public static final String NEW_LINE;
|
||||
private static final Pattern CONFIG_START = Pattern.compile("START: \"([^\\\"]+)\"");
|
||||
private static final Pattern CONFIG_END = Pattern.compile("END: \"([^\\\"]+)\"");
|
||||
public static final CharMatcher allowedProperties = CharMatcher.JAVA_LETTER_OR_DIGIT.or(CharMatcher.anyOf(ALLOWED_CHARS));
|
||||
private static Configuration PARENT = null;
|
||||
|
||||
File file;
|
||||
|
||||
private Map<String, ConfigCategory> categories = new TreeMap<String, ConfigCategory>();
|
||||
private Map<String, Configuration> children = new TreeMap<String, Configuration>();
|
||||
|
||||
private boolean caseSensitiveCustomCategories;
|
||||
public String defaultEncoding = DEFAULT_ENCODING;
|
||||
private String fileName = null;
|
||||
public boolean isChild = false;
|
||||
private boolean changed = false;
|
||||
|
||||
static
|
||||
{
|
||||
Arrays.fill(configMarkers, false);
|
||||
NEW_LINE = System.getProperty("line.separator");
|
||||
}
|
||||
|
||||
public Configuration(){}
|
||||
|
||||
/**
|
||||
* Create a configuration file for the file given in parameter.
|
||||
*/
|
||||
public Configuration(File file)
|
||||
{
|
||||
this.file = file;
|
||||
String basePath = ((File)(FMLInjectionData.data()[6])).getAbsolutePath().replace(File.separatorChar, '/').replace("/.", "");
|
||||
String path = file.getAbsolutePath().replace(File.separatorChar, '/').replace("/./", "/").replace(basePath, "");
|
||||
if (PARENT != null)
|
||||
{
|
||||
PARENT.setChild(path, this);
|
||||
isChild = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fileName = path;
|
||||
load();
|
||||
}
|
||||
}
|
||||
|
||||
public Configuration(File file, boolean caseSensitiveCustomCategories)
|
||||
{
|
||||
this(file);
|
||||
this.caseSensitiveCustomCategories = caseSensitiveCustomCategories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets or create a block id property. If the block id property key is
|
||||
* already in the configuration, then it will be used. Otherwise,
|
||||
* defaultId will be used, except if already taken, in which case this
|
||||
* will try to determine a free default id.
|
||||
*/
|
||||
public Property getBlock(String key, int defaultID) { return getBlock(CATEGORY_BLOCK, key, defaultID, null); }
|
||||
public Property getBlock(String key, int defaultID, String comment) { return getBlock(CATEGORY_BLOCK, key, defaultID, comment); }
|
||||
public Property getBlock(String category, String key, int defaultID) { return getBlockInternal(category, key, defaultID, null, 256, Block.blocksList.length); }
|
||||
public Property getBlock(String category, String key, int defaultID, String comment) { return getBlockInternal(category, key, defaultID, comment, 256, Block.blocksList.length); }
|
||||
|
||||
/**
|
||||
* Special version of getBlock to be used when you want to garentee the ID you get is below 256
|
||||
* This should ONLY be used by mods who do low level terrain generation, or ones that add new
|
||||
* biomes.
|
||||
* EXA: ExtraBiomesXL
|
||||
*
|
||||
* Specifically, if your block is used BEFORE the Chunk is created, and placed in the terrain byte array directly.
|
||||
* If you add a new biome and you set the top/filler block, they need to be <256, nothing else.
|
||||
*
|
||||
* If you're adding a new ore, DON'T call this function.
|
||||
*
|
||||
* Normal mods such as '50 new ores' do not need to be below 256 so should use the normal getBlock
|
||||
*/
|
||||
public Property getTerrainBlock(String category, String key, int defaultID, String comment)
|
||||
{
|
||||
return getBlockInternal(category, key, defaultID, comment, 0, 256);
|
||||
}
|
||||
|
||||
private Property getBlockInternal(String category, String key, int defaultID, String comment, int lower, int upper)
|
||||
{
|
||||
Property prop = get(category, key, -1, comment);
|
||||
|
||||
if (prop.getInt() != -1)
|
||||
{
|
||||
configMarkers[prop.getInt()] = true;
|
||||
return prop;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (defaultID < lower)
|
||||
{
|
||||
FMLLog.warning(
|
||||
"Mod attempted to get a block ID with a default in the Terrain Generation section, " +
|
||||
"mod authors should make sure there defaults are above 256 unless explicitly needed " +
|
||||
"for terrain generation. Most ores do not need to be below 256.");
|
||||
FMLLog.warning("Config \"%s\" Category: \"%s\" Key: \"%s\" Default: %d", fileName, category, key, defaultID);
|
||||
defaultID = upper - 1;
|
||||
}
|
||||
|
||||
if (Block.blocksList[defaultID] == null && !configMarkers[defaultID])
|
||||
{
|
||||
prop.set(defaultID);
|
||||
configMarkers[defaultID] = true;
|
||||
return prop;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = upper - 1; j > 0; j--)
|
||||
{
|
||||
if (Block.blocksList[j] == null && !configMarkers[j])
|
||||
{
|
||||
prop.set(j);
|
||||
configMarkers[j] = true;
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("No more block ids available for " + key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Property getItem(String key, int defaultID) { return getItem(CATEGORY_ITEM, key, defaultID, null); }
|
||||
public Property getItem(String key, int defaultID, String comment) { return getItem(CATEGORY_ITEM, key, defaultID, comment); }
|
||||
public Property getItem(String category, String key, int defaultID) { return getItem(category, key, defaultID, null); }
|
||||
|
||||
public Property getItem(String category, String key, int defaultID, String comment)
|
||||
{
|
||||
Property prop = get(category, key, -1, comment);
|
||||
int defaultShift = defaultID + ITEM_SHIFT;
|
||||
|
||||
if (prop.getInt() != -1)
|
||||
{
|
||||
configMarkers[prop.getInt() + ITEM_SHIFT] = true;
|
||||
return prop;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (defaultID < MAX_BLOCKS - ITEM_SHIFT)
|
||||
{
|
||||
FMLLog.warning(
|
||||
"Mod attempted to get a item ID with a default value in the block ID section, " +
|
||||
"mod authors should make sure there defaults are above %d unless explicitly needed " +
|
||||
"so that all block ids are free to store blocks.", MAX_BLOCKS - ITEM_SHIFT);
|
||||
FMLLog.warning("Config \"%s\" Category: \"%s\" Key: \"%s\" Default: %d", fileName, category, key, defaultID);
|
||||
}
|
||||
|
||||
if (Item.itemsList[defaultShift] == null && !configMarkers[defaultShift] && defaultShift >= Block.blocksList.length)
|
||||
{
|
||||
prop.set(defaultID);
|
||||
configMarkers[defaultShift] = true;
|
||||
return prop;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int x = Item.itemsList.length - 1; x >= ITEM_SHIFT; x--)
|
||||
{
|
||||
if (Item.itemsList[x] == null && !configMarkers[x])
|
||||
{
|
||||
prop.set(x - ITEM_SHIFT);
|
||||
configMarkers[x] = true;
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("No more item ids available for " + key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Property get(String category, String key, int defaultValue)
|
||||
{
|
||||
return get(category, key, defaultValue, null);
|
||||
}
|
||||
|
||||
public Property get(String category, String key, int defaultValue, String comment)
|
||||
{
|
||||
Property prop = get(category, key, Integer.toString(defaultValue), comment, INTEGER);
|
||||
if (!prop.isIntValue())
|
||||
{
|
||||
prop.set(defaultValue);
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
|
||||
public Property get(String category, String key, boolean defaultValue)
|
||||
{
|
||||
return get(category, key, defaultValue, null);
|
||||
}
|
||||
|
||||
public Property get(String category, String key, boolean defaultValue, String comment)
|
||||
{
|
||||
Property prop = get(category, key, Boolean.toString(defaultValue), comment, BOOLEAN);
|
||||
if (!prop.isBooleanValue())
|
||||
{
|
||||
prop.set(defaultValue);
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
|
||||
public Property get(String category, String key, double defaultValue)
|
||||
{
|
||||
return get(category, key, defaultValue, null);
|
||||
}
|
||||
|
||||
public Property get(String category, String key, double defaultValue, String comment)
|
||||
{
|
||||
Property prop = get(category, key, Double.toString(defaultValue), comment, DOUBLE);
|
||||
if (!prop.isDoubleValue())
|
||||
{
|
||||
prop.set(defaultValue);
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
|
||||
public Property get(String category, String key, String defaultValue)
|
||||
{
|
||||
return get(category, key, defaultValue, null);
|
||||
}
|
||||
|
||||
public Property get(String category, String key, String defaultValue, String comment)
|
||||
{
|
||||
return get(category, key, defaultValue, comment, STRING);
|
||||
}
|
||||
|
||||
public Property get(String category, String key, String[] defaultValue)
|
||||
{
|
||||
return get(category, key, defaultValue, null);
|
||||
}
|
||||
|
||||
public Property get(String category, String key, String[] defaultValue, String comment)
|
||||
{
|
||||
return get(category, key, defaultValue, comment, STRING);
|
||||
}
|
||||
|
||||
public Property get(String category, String key, int[] defaultValue)
|
||||
{
|
||||
return get(category, key, defaultValue, null);
|
||||
}
|
||||
|
||||
public Property get(String category, String key, int[] defaultValue, String comment)
|
||||
{
|
||||
String[] values = new String[defaultValue.length];
|
||||
for (int i = 0; i < defaultValue.length; i++)
|
||||
{
|
||||
values[i] = Integer.toString(defaultValue[i]);
|
||||
}
|
||||
|
||||
Property prop = get(category, key, values, comment, INTEGER);
|
||||
if (!prop.isIntList())
|
||||
{
|
||||
prop.set(values);
|
||||
}
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
public Property get(String category, String key, double[] defaultValue)
|
||||
{
|
||||
return get(category, key, defaultValue, null);
|
||||
}
|
||||
|
||||
public Property get(String category, String key, double[] defaultValue, String comment)
|
||||
{
|
||||
String[] values = new String[defaultValue.length];
|
||||
for (int i = 0; i < defaultValue.length; i++)
|
||||
{
|
||||
values[i] = Double.toString(defaultValue[i]);
|
||||
}
|
||||
|
||||
Property prop = get(category, key, values, comment, DOUBLE);
|
||||
|
||||
if (!prop.isDoubleList())
|
||||
{
|
||||
prop.set(values);
|
||||
}
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
public Property get(String category, String key, boolean[] defaultValue)
|
||||
{
|
||||
return get(category, key, defaultValue, null);
|
||||
}
|
||||
|
||||
public Property get(String category, String key, boolean[] defaultValue, String comment)
|
||||
{
|
||||
String[] values = new String[defaultValue.length];
|
||||
for (int i = 0; i < defaultValue.length; i++)
|
||||
{
|
||||
values[i] = Boolean.toString(defaultValue[i]);
|
||||
}
|
||||
|
||||
Property prop = get(category, key, values, comment, BOOLEAN);
|
||||
|
||||
if (!prop.isBooleanList())
|
||||
{
|
||||
prop.set(values);
|
||||
}
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
public Property get(String category, String key, String defaultValue, String comment, Property.Type type)
|
||||
{
|
||||
if (!caseSensitiveCustomCategories)
|
||||
{
|
||||
category = category.toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
ConfigCategory cat = getCategory(category);
|
||||
|
||||
if (cat.containsKey(key))
|
||||
{
|
||||
Property prop = cat.get(key);
|
||||
|
||||
if (prop.getType() == null)
|
||||
{
|
||||
prop = new Property(prop.getName(), prop.getString(), type);
|
||||
cat.put(key, prop);
|
||||
}
|
||||
|
||||
prop.comment = comment;
|
||||
return prop;
|
||||
}
|
||||
else if (defaultValue != null)
|
||||
{
|
||||
Property prop = new Property(key, defaultValue, type);
|
||||
prop.set(defaultValue); //Set and mark as dirty to signify it should save
|
||||
cat.put(key, prop);
|
||||
prop.comment = comment;
|
||||
return prop;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Property get(String category, String key, String[] defaultValue, String comment, Property.Type type)
|
||||
{
|
||||
if (!caseSensitiveCustomCategories)
|
||||
{
|
||||
category = category.toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
ConfigCategory cat = getCategory(category);
|
||||
|
||||
if (cat.containsKey(key))
|
||||
{
|
||||
Property prop = cat.get(key);
|
||||
|
||||
if (prop.getType() == null)
|
||||
{
|
||||
prop = new Property(prop.getName(), prop.getString(), type);
|
||||
cat.put(key, prop);
|
||||
}
|
||||
|
||||
prop.comment = comment;
|
||||
|
||||
return prop;
|
||||
}
|
||||
else if (defaultValue != null)
|
||||
{
|
||||
Property prop = new Property(key, defaultValue, type);
|
||||
prop.comment = comment;
|
||||
cat.put(key, prop);
|
||||
return prop;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasCategory(String category)
|
||||
{
|
||||
return categories.get(category) != null;
|
||||
}
|
||||
|
||||
public boolean hasKey(String category, String key)
|
||||
{
|
||||
ConfigCategory cat = categories.get(category);
|
||||
return cat != null && cat.containsKey(key);
|
||||
}
|
||||
|
||||
public void load()
|
||||
{
|
||||
if (PARENT != null && PARENT != this)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BufferedReader buffer = null;
|
||||
UnicodeInputStreamReader input = null;
|
||||
try
|
||||
{
|
||||
if (file.getParentFile() != null)
|
||||
{
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
|
||||
if (!file.exists() && !file.createNewFile())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (file.canRead())
|
||||
{
|
||||
input = new UnicodeInputStreamReader(new FileInputStream(file), defaultEncoding);
|
||||
defaultEncoding = input.getEncoding();
|
||||
buffer = new BufferedReader(input);
|
||||
|
||||
String line;
|
||||
ConfigCategory currentCat = null;
|
||||
Property.Type type = null;
|
||||
ArrayList<String> tmpList = null;
|
||||
int lineNum = 0;
|
||||
String name = null;
|
||||
|
||||
while (true)
|
||||
{
|
||||
lineNum++;
|
||||
line = buffer.readLine();
|
||||
|
||||
if (line == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Matcher start = CONFIG_START.matcher(line);
|
||||
Matcher end = CONFIG_END.matcher(line);
|
||||
|
||||
if (start.matches())
|
||||
{
|
||||
fileName = start.group(1);
|
||||
categories = new TreeMap<String, ConfigCategory>();
|
||||
continue;
|
||||
}
|
||||
else if (end.matches())
|
||||
{
|
||||
fileName = end.group(1);
|
||||
Configuration child = new Configuration();
|
||||
child.categories = categories;
|
||||
this.children.put(fileName, child);
|
||||
continue;
|
||||
}
|
||||
|
||||
int nameStart = -1, nameEnd = -1;
|
||||
boolean skip = false;
|
||||
boolean quoted = false;
|
||||
|
||||
for (int i = 0; i < line.length() && !skip; ++i)
|
||||
{
|
||||
if (Character.isLetterOrDigit(line.charAt(i)) || ALLOWED_CHARS.indexOf(line.charAt(i)) != -1 || (quoted && line.charAt(i) != '"'))
|
||||
{
|
||||
if (nameStart == -1)
|
||||
{
|
||||
nameStart = i;
|
||||
}
|
||||
|
||||
nameEnd = i;
|
||||
}
|
||||
else if (Character.isWhitespace(line.charAt(i)))
|
||||
{
|
||||
// ignore space charaters
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (line.charAt(i))
|
||||
{
|
||||
case '#':
|
||||
skip = true;
|
||||
continue;
|
||||
|
||||
case '"':
|
||||
if (quoted)
|
||||
{
|
||||
quoted = false;
|
||||
}
|
||||
if (!quoted && nameStart == -1)
|
||||
{
|
||||
quoted = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case '{':
|
||||
name = line.substring(nameStart, nameEnd + 1);
|
||||
String qualifiedName = ConfigCategory.getQualifiedName(name, currentCat);
|
||||
|
||||
ConfigCategory cat = categories.get(qualifiedName);
|
||||
if (cat == null)
|
||||
{
|
||||
currentCat = new ConfigCategory(name, currentCat);
|
||||
categories.put(qualifiedName, currentCat);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentCat = cat;
|
||||
}
|
||||
name = null;
|
||||
|
||||
break;
|
||||
|
||||
case '}':
|
||||
if (currentCat == null)
|
||||
{
|
||||
throw new RuntimeException(String.format("Config file corrupt, attepted to close to many categories '%s:%d'", fileName, lineNum));
|
||||
}
|
||||
currentCat = currentCat.parent;
|
||||
break;
|
||||
|
||||
case '=':
|
||||
name = line.substring(nameStart, nameEnd + 1);
|
||||
|
||||
if (currentCat == null)
|
||||
{
|
||||
throw new RuntimeException(String.format("'%s' has no scope in '%s:%d'", name, fileName, lineNum));
|
||||
}
|
||||
|
||||
Property prop = new Property(name, line.substring(i + 1), type, true);
|
||||
i = line.length();
|
||||
|
||||
currentCat.put(name, prop);
|
||||
|
||||
break;
|
||||
|
||||
case ':':
|
||||
type = Property.Type.tryParse(line.substring(nameStart, nameEnd + 1).charAt(0));
|
||||
nameStart = nameEnd = -1;
|
||||
break;
|
||||
|
||||
case '<':
|
||||
if (tmpList != null)
|
||||
{
|
||||
throw new RuntimeException(String.format("Malformed list property \"%s:%d\"", fileName, lineNum));
|
||||
}
|
||||
|
||||
name = line.substring(nameStart, nameEnd + 1);
|
||||
|
||||
if (currentCat == null)
|
||||
{
|
||||
throw new RuntimeException(String.format("'%s' has no scope in '%s:%d'", name, fileName, lineNum));
|
||||
}
|
||||
|
||||
tmpList = new ArrayList<String>();
|
||||
|
||||
skip = true;
|
||||
|
||||
break;
|
||||
|
||||
case '>':
|
||||
if (tmpList == null)
|
||||
{
|
||||
throw new RuntimeException(String.format("Malformed list property \"%s:%d\"", fileName, lineNum));
|
||||
}
|
||||
|
||||
currentCat.put(name, new Property(name, tmpList.toArray(new String[tmpList.size()]), type));
|
||||
name = null;
|
||||
tmpList = null;
|
||||
type = null;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RuntimeException(String.format("Unknown character '%s' in '%s:%d'", line.charAt(i), fileName, lineNum));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (quoted)
|
||||
{
|
||||
throw new RuntimeException(String.format("Unmatched quote in '%s:%d'", fileName, lineNum));
|
||||
}
|
||||
else if (tmpList != null && !skip)
|
||||
{
|
||||
tmpList.add(line.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (buffer != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
buffer.close();
|
||||
} catch (IOException e){}
|
||||
}
|
||||
if (input != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
input.close();
|
||||
} catch (IOException e){}
|
||||
}
|
||||
}
|
||||
|
||||
resetChangedState();
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
if (PARENT != null && PARENT != this)
|
||||
{
|
||||
PARENT.save();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (file.getParentFile() != null)
|
||||
{
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
|
||||
if (!file.exists() && !file.createNewFile())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (file.canWrite())
|
||||
{
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
BufferedWriter buffer = new BufferedWriter(new OutputStreamWriter(fos, defaultEncoding));
|
||||
|
||||
buffer.write("# Configuration file" + NEW_LINE + NEW_LINE);
|
||||
|
||||
if (children.isEmpty())
|
||||
{
|
||||
save(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Map.Entry<String, Configuration> entry : children.entrySet())
|
||||
{
|
||||
buffer.write("START: \"" + entry.getKey() + "\"" + NEW_LINE);
|
||||
entry.getValue().save(buffer);
|
||||
buffer.write("END: \"" + entry.getKey() + "\"" + NEW_LINE + NEW_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.close();
|
||||
fos.close();
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void save(BufferedWriter out) throws IOException
|
||||
{
|
||||
for (ConfigCategory cat : categories.values())
|
||||
{
|
||||
if (!cat.isChild())
|
||||
{
|
||||
cat.write(out, 0);
|
||||
out.newLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ConfigCategory getCategory(String category)
|
||||
{
|
||||
ConfigCategory ret = categories.get(category);
|
||||
|
||||
if (ret == null)
|
||||
{
|
||||
if (category.contains(CATEGORY_SPLITTER))
|
||||
{
|
||||
String[] hierarchy = category.split("\\"+CATEGORY_SPLITTER);
|
||||
ConfigCategory parent = categories.get(hierarchy[0]);
|
||||
|
||||
if (parent == null)
|
||||
{
|
||||
parent = new ConfigCategory(hierarchy[0]);
|
||||
categories.put(parent.getQualifiedName(), parent);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
for (int i = 1; i < hierarchy.length; i++)
|
||||
{
|
||||
String name = ConfigCategory.getQualifiedName(hierarchy[i], parent);
|
||||
ConfigCategory child = categories.get(name);
|
||||
|
||||
if (child == null)
|
||||
{
|
||||
child = new ConfigCategory(hierarchy[i], parent);
|
||||
categories.put(name, child);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
ret = child;
|
||||
parent = child;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = new ConfigCategory(category);
|
||||
categories.put(category, ret);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void removeCategory(ConfigCategory category)
|
||||
{
|
||||
for (ConfigCategory child : category.getChildren())
|
||||
{
|
||||
removeCategory(child);
|
||||
}
|
||||
|
||||
if (categories.containsKey(category.getQualifiedName()))
|
||||
{
|
||||
categories.remove(category.getQualifiedName());
|
||||
if (category.parent != null)
|
||||
{
|
||||
category.parent.removeChild(category);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void addCustomCategoryComment(String category, String comment)
|
||||
{
|
||||
if (!caseSensitiveCustomCategories)
|
||||
category = category.toLowerCase(Locale.ENGLISH);
|
||||
getCategory(category).setComment(comment);
|
||||
}
|
||||
|
||||
private void setChild(String name, Configuration child)
|
||||
{
|
||||
if (!children.containsKey(name))
|
||||
{
|
||||
children.put(name, child);
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Configuration old = children.get(name);
|
||||
child.categories = old.categories;
|
||||
child.fileName = old.fileName;
|
||||
old.changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void enableGlobalConfig()
|
||||
{
|
||||
PARENT = new Configuration(new File(Loader.instance().getConfigDir(), "global.cfg"));
|
||||
PARENT.load();
|
||||
}
|
||||
|
||||
public static class UnicodeInputStreamReader extends Reader
|
||||
{
|
||||
private final InputStreamReader input;
|
||||
private final String defaultEnc;
|
||||
|
||||
public UnicodeInputStreamReader(InputStream source, String encoding) throws IOException
|
||||
{
|
||||
defaultEnc = encoding;
|
||||
String enc = encoding;
|
||||
byte[] data = new byte[4];
|
||||
|
||||
PushbackInputStream pbStream = new PushbackInputStream(source, data.length);
|
||||
int read = pbStream.read(data, 0, data.length);
|
||||
int size = 0;
|
||||
|
||||
int bom16 = (data[0] & 0xFF) << 8 | (data[1] & 0xFF);
|
||||
int bom24 = bom16 << 8 | (data[2] & 0xFF);
|
||||
int bom32 = bom24 << 8 | (data[3] & 0xFF);
|
||||
|
||||
if (bom24 == 0xEFBBBF)
|
||||
{
|
||||
enc = "UTF-8";
|
||||
size = 3;
|
||||
}
|
||||
else if (bom16 == 0xFEFF)
|
||||
{
|
||||
enc = "UTF-16BE";
|
||||
size = 2;
|
||||
}
|
||||
else if (bom16 == 0xFFFE)
|
||||
{
|
||||
enc = "UTF-16LE";
|
||||
size = 2;
|
||||
}
|
||||
else if (bom32 == 0x0000FEFF)
|
||||
{
|
||||
enc = "UTF-32BE";
|
||||
size = 4;
|
||||
}
|
||||
else if (bom32 == 0xFFFE0000) //This will never happen as it'll be caught by UTF-16LE,
|
||||
{ //but if anyone ever runs across a 32LE file, i'd like to disect it.
|
||||
enc = "UTF-32LE";
|
||||
size = 4;
|
||||
}
|
||||
|
||||
if (size < read)
|
||||
{
|
||||
pbStream.unread(data, size, read - size);
|
||||
}
|
||||
|
||||
this.input = new InputStreamReader(pbStream, enc);
|
||||
}
|
||||
|
||||
public String getEncoding()
|
||||
{
|
||||
return input.getEncoding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(char[] cbuf, int off, int len) throws IOException
|
||||
{
|
||||
return input.read(cbuf, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
input.close();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasChanged()
|
||||
{
|
||||
if (changed) return true;
|
||||
|
||||
for (ConfigCategory cat : categories.values())
|
||||
{
|
||||
if (cat.hasChanged()) return true;
|
||||
}
|
||||
|
||||
for (Configuration child : children.values())
|
||||
{
|
||||
if (child.hasChanged()) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void resetChangedState()
|
||||
{
|
||||
changed = false;
|
||||
for (ConfigCategory cat : categories.values())
|
||||
{
|
||||
cat.resetChangedState();
|
||||
}
|
||||
|
||||
for (Configuration child : children.values())
|
||||
{
|
||||
child.resetChangedState();
|
||||
}
|
||||
}
|
||||
|
||||
public Set<String> getCategoryNames()
|
||||
{
|
||||
return ImmutableSet.copyOf(categories.keySet());
|
||||
}
|
||||
}
|
||||
+18
-10
@@ -4,23 +4,32 @@ import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.apache.logging.log4j.Level;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.HashMultiset;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.MapMaker;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multiset;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.ChunkCoordIntPair;
|
||||
import net.minecraft.world.MinecraftException;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldManager;
|
||||
@@ -223,8 +232,7 @@ public class DimensionManager
|
||||
MinecraftServer.getServer().worldServers = tmp.toArray(new WorldServer[tmp.size()]);
|
||||
}
|
||||
|
||||
public static void initDimension(int dim)
|
||||
{
|
||||
public static void initDimension(int dim) {
|
||||
WorldServer overworld = getWorld(0);
|
||||
if (overworld == null)
|
||||
{
|
||||
@@ -243,7 +251,7 @@ public class DimensionManager
|
||||
ISaveHandler savehandler = overworld.getSaveHandler();
|
||||
WorldSettings worldSettings = new WorldSettings(overworld.getWorldInfo());
|
||||
|
||||
WorldServer world = (dim == 0 ? overworld : (WorldServer)(new WorldServerMulti(mcServer, savehandler, dim, overworld, mcServer.theProfiler).init()));
|
||||
WorldServer world = (dim == 0 ? overworld : new WorldServerMulti(mcServer, savehandler, overworld.getWorldInfo().getWorldName(), dim, worldSettings, overworld, mcServer.theProfiler, overworld.getWorldLogAgent()));
|
||||
world.addWorldAccess(new WorldManager(mcServer, world));
|
||||
MinecraftForge.EVENT_BUS.post(new WorldEvent.Load(world));
|
||||
if (!mcServer.isSinglePlayer())
|
||||
@@ -300,7 +308,7 @@ public class DimensionManager
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLCommonHandler.instance().getFMLLogger().log(Level.ERROR, String.format("An error occured trying to create an instance of WorldProvider %d (%s)",
|
||||
FMLCommonHandler.instance().getFMLLogger().log(Level.SEVERE,String.format("An error occured trying to create an instance of WorldProvider %d (%s)",
|
||||
dim, providers.get(getProviderType(dim)).getSimpleName()),e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -381,9 +389,9 @@ public class DimensionManager
|
||||
|
||||
public static void loadDimensionDataMap(NBTTagCompound compoundTag)
|
||||
{
|
||||
dimensionMap.clear();
|
||||
if (compoundTag == null)
|
||||
{
|
||||
dimensionMap.clear();
|
||||
for (Integer id : dimensions.keySet())
|
||||
{
|
||||
if (id >= 0)
|
||||
@@ -426,4 +434,4 @@ public class DimensionManager
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-1
@@ -3,7 +3,16 @@ package net.minecraftforge.common;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.WeightedRandom;
|
||||
import net.minecraft.util.WeightedRandomChestContent;
|
||||
import net.minecraft.util.WeightedRandomItem;
|
||||
|
||||
import static net.minecraftforge.common.ChestGenHooks.DUNGEON_CHEST;
|
||||
|
||||
public class DungeonHooks
|
||||
{
|
||||
@@ -77,7 +86,7 @@ public class DungeonHooks
|
||||
}
|
||||
|
||||
|
||||
public static class DungeonMob extends WeightedRandom.Item
|
||||
public static class DungeonMob extends WeightedRandomItem
|
||||
{
|
||||
public String type;
|
||||
public DungeonMob(int weight, String type)
|
||||
+44
-42
@@ -1,24 +1,25 @@
|
||||
package net.minecraftforge.common.util;
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraft.block.BlockPressurePlate.Sensitivity;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
import net.minecraft.block.EnumMobType;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.enchantment.EnumEnchantmentType;
|
||||
import net.minecraft.entity.EnumCreatureAttribute;
|
||||
import net.minecraft.entity.EnumCreatureType;
|
||||
import net.minecraft.entity.item.EntityPainting.EnumArt;
|
||||
import net.minecraft.entity.player.EntityPlayer.EnumStatus;
|
||||
import net.minecraft.entity.EnumEntitySize;
|
||||
import net.minecraft.entity.player.EnumStatus;
|
||||
import net.minecraft.item.EnumAction;
|
||||
import net.minecraft.item.EnumRarity;
|
||||
import net.minecraft.item.Item.ToolMaterial;
|
||||
import net.minecraft.item.ItemArmor.ArmorMaterial;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.util.MovingObjectPosition.MovingObjectType;
|
||||
import net.minecraft.item.EnumArmorMaterial;
|
||||
import net.minecraft.item.EnumToolMaterial;
|
||||
import net.minecraft.util.EnumArt;
|
||||
import net.minecraft.util.EnumMovingObjectType;
|
||||
import net.minecraft.world.EnumSkyBlock;
|
||||
import net.minecraft.world.gen.structure.StructureStrongholdPieces.Stronghold.Door;
|
||||
import net.minecraft.world.gen.structure.EnumDoor;
|
||||
import net.minecraftforge.classloading.FMLForgePlugin;
|
||||
|
||||
public class EnumHelper
|
||||
@@ -31,31 +32,30 @@ public class EnumHelper
|
||||
private static boolean isSetup = false;
|
||||
|
||||
//Some enums are decompiled with extra arguments, so lets check for that
|
||||
@SuppressWarnings("rawtypes")
|
||||
private static Class[][] commonTypes =
|
||||
{
|
||||
{EnumAction.class},
|
||||
{ArmorMaterial.class, String.class, int.class, int[].class, int.class},
|
||||
{EnumArmorMaterial.class, int.class, int[].class, int.class},
|
||||
{EnumArt.class, String.class, int.class, int.class, int.class, int.class},
|
||||
{EnumCreatureAttribute.class},
|
||||
{EnumCreatureType.class, Class.class, int.class, Material.class, boolean.class, boolean.class},
|
||||
{Door.class},
|
||||
{EnumCreatureType.class, Class.class, int.class, Material.class, boolean.class},
|
||||
{EnumDoor.class},
|
||||
{EnumEnchantmentType.class},
|
||||
{Sensitivity.class},
|
||||
{MovingObjectType.class},
|
||||
{EnumEntitySize.class},
|
||||
{EnumMobType.class},
|
||||
{EnumMovingObjectType.class},
|
||||
{EnumSkyBlock.class, int.class},
|
||||
{EnumStatus.class},
|
||||
{ToolMaterial.class, int.class, int.class, float.class, float.class, int.class},
|
||||
{EnumRarity.class, EnumChatFormatting.class, String.class}
|
||||
};
|
||||
{EnumToolMaterial.class, int.class, int.class, float.class, float.class, int.class}
|
||||
};
|
||||
|
||||
public static EnumAction addAction(String name)
|
||||
{
|
||||
return addEnum(EnumAction.class, name);
|
||||
}
|
||||
public static ArmorMaterial addArmorMaterial(String name, String textureName, int durability, int[] reductionAmounts, int enchantability)
|
||||
public static EnumArmorMaterial addArmorMaterial(String name, int durability, int[] reductionAmounts, int enchantability)
|
||||
{
|
||||
return addEnum(ArmorMaterial.class, name, textureName, durability, reductionAmounts, enchantability);
|
||||
return addEnum(EnumArmorMaterial.class, name, durability, reductionAmounts, enchantability);
|
||||
}
|
||||
public static EnumArt addArt(String name, String tile, int sizeX, int sizeY, int offsetX, int offsetY)
|
||||
{
|
||||
@@ -65,26 +65,34 @@ public class EnumHelper
|
||||
{
|
||||
return addEnum(EnumCreatureAttribute.class, name);
|
||||
}
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static EnumCreatureType addCreatureType(String name, Class typeClass, int maxNumber, Material material, boolean peaceful, boolean animal)
|
||||
public static EnumCreatureType addCreatureType(String name, Class typeClass, int maxNumber, Material material, boolean peaceful)
|
||||
{
|
||||
return addEnum(EnumCreatureType.class, name, typeClass, maxNumber, material, peaceful, animal);
|
||||
return addEnum(EnumCreatureType.class, name, typeClass, maxNumber, material, peaceful);
|
||||
}
|
||||
public static Door addDoor(String name)
|
||||
public static EnumDoor addDoor(String name)
|
||||
{
|
||||
return addEnum(Door.class, name);
|
||||
return addEnum(EnumDoor.class, name);
|
||||
}
|
||||
public static EnumEnchantmentType addEnchantmentType(String name)
|
||||
{
|
||||
return addEnum(EnumEnchantmentType.class, name);
|
||||
}
|
||||
public static Sensitivity addSensitivity(String name)
|
||||
public static EnumEntitySize addEntitySize(String name)
|
||||
{
|
||||
return addEnum(Sensitivity.class, name);
|
||||
return addEnum(EnumEntitySize.class, name);
|
||||
}
|
||||
public static MovingObjectType addMovingObjectType(String name)
|
||||
public static EnumMobType addMobType(String name)
|
||||
{
|
||||
return addEnum(MovingObjectType.class, name);
|
||||
return addEnum(EnumMobType.class, name);
|
||||
}
|
||||
public static EnumMovingObjectType addMovingObjectType(String name)
|
||||
{
|
||||
if (!isSetup)
|
||||
{
|
||||
setup();
|
||||
}
|
||||
|
||||
return addEnum(EnumMovingObjectType.class, name);
|
||||
}
|
||||
public static EnumSkyBlock addSkyBlock(String name, int lightValue)
|
||||
{
|
||||
@@ -94,13 +102,9 @@ public class EnumHelper
|
||||
{
|
||||
return addEnum(EnumStatus.class, name);
|
||||
}
|
||||
public static ToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, float damage, int enchantability)
|
||||
public static EnumToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, float damage, int enchantability)
|
||||
{
|
||||
return addEnum(ToolMaterial.class, name, harvestLevel, maxUses, efficiency, damage, enchantability);
|
||||
}
|
||||
public static EnumRarity addRarity(String name, EnumChatFormatting color, String displayName)
|
||||
{
|
||||
return addEnum(EnumRarity.class, name, color, displayName);
|
||||
return addEnum(EnumToolMaterial.class, name, harvestLevel, maxUses, efficiency, damage, enchantability);
|
||||
}
|
||||
|
||||
private static void setup()
|
||||
@@ -181,11 +185,9 @@ public class EnumHelper
|
||||
|
||||
public static <T extends Enum<? >> T addEnum(Class<T> enumType, String enumName, Object... paramValues)
|
||||
{
|
||||
setup();
|
||||
return addEnum(commonTypes, enumType, enumName, paramValues);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
|
||||
public static <T extends Enum<? >> T addEnum(Class[][] map, Class<T> enumType, String enumName, Object... paramValues)
|
||||
{
|
||||
for (Class[] lookup : map)
|
||||
@@ -213,7 +215,7 @@ public class EnumHelper
|
||||
|
||||
Field valuesField = null;
|
||||
Field[] fields = enumType.getDeclaredFields();
|
||||
|
||||
|
||||
for (Field field : fields)
|
||||
{
|
||||
String name = field.getName();
|
||||
@@ -228,7 +230,7 @@ public class EnumHelper
|
||||
if (valuesField == null)
|
||||
{
|
||||
String valueType = String.format("[L%s;", enumType.getName().replace('.', '/'));
|
||||
|
||||
|
||||
for (Field field : fields)
|
||||
{
|
||||
if ((field.getModifiers() & flags) == flags &&
|
||||
File renamed without changes.
@@ -0,0 +1,48 @@
|
||||
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 EntityPlayerMP
|
||||
{
|
||||
public FakePlayer(World world, String name)
|
||||
{
|
||||
super(FMLCommonHandler.instance().getMinecraftServerInstance(), world, name, new ItemInWorldManager(world));
|
||||
}
|
||||
|
||||
public void sendChatToPlayer(String s){}
|
||||
public boolean canCommandSenderUseCommand(int i, String s){ return false; }
|
||||
public ChunkCoordinates getPlayerCoordinates()
|
||||
{
|
||||
return new ChunkCoordinates(0,0,0);
|
||||
}
|
||||
|
||||
@Override
|
||||
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; }
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package net.minecraftforge.common;
|
||||
|
||||
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 = 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);
|
||||
}
|
||||
}
|
||||
+70
-139
@@ -1,56 +1,64 @@
|
||||
/**
|
||||
* This software is provided under the terms of the Minecraft Forge Public
|
||||
* License v1.0.
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
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;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.MapMaker;
|
||||
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 net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.ModContainer;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
import com.google.common.collect.TreeMultiset;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.ChunkCoordIntPair;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.ClassInheritanceMultiMap;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.common.config.ConfigCategory;
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
import net.minecraftforge.common.config.Property;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.common.ForgeChunkManager.Ticket;
|
||||
import net.minecraftforge.event.Event;
|
||||
|
||||
/**
|
||||
* Manages chunkloading for mods.
|
||||
@@ -93,16 +101,7 @@ public class ForgeChunkManager
|
||||
private static int playerTicketLength;
|
||||
private static int dormantChunkCacheSize;
|
||||
|
||||
public static final List<String> MOD_PROP_ORDER = new ArrayList<String>(2);
|
||||
|
||||
private static Set<String> warnedMods = Sets.newHashSet();
|
||||
|
||||
static
|
||||
{
|
||||
MOD_PROP_ORDER.add("maximumTicketCount");
|
||||
MOD_PROP_ORDER.add("maximumChunksPerTicket");
|
||||
}
|
||||
|
||||
/**
|
||||
* All mods requiring chunkloading need to implement this to handle the
|
||||
* re-registration of chunk tickets at world loading time
|
||||
@@ -194,7 +193,7 @@ public class ForgeChunkManager
|
||||
private NBTTagCompound modData;
|
||||
public final World world;
|
||||
private int maxDepth;
|
||||
//private String entityClazz;
|
||||
private String entityClazz;
|
||||
private int entityChunkX;
|
||||
private int entityChunkZ;
|
||||
private Entity entity;
|
||||
@@ -218,7 +217,7 @@ public class ForgeChunkManager
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.log(Level.ERROR, "Attempt to create a player ticket without a valid player");
|
||||
FMLLog.log(Level.SEVERE, "Attempt to create a player ticket without a valid player");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
@@ -337,7 +336,7 @@ public class ForgeChunkManager
|
||||
/**
|
||||
* Gets a list of requested chunks for this ticket.
|
||||
*/
|
||||
public ImmutableSet<ChunkCoordIntPair> getChunkList()
|
||||
public ImmutableSet getChunkList()
|
||||
{
|
||||
return ImmutableSet.copyOf(requestedChunks);
|
||||
}
|
||||
@@ -384,7 +383,7 @@ public class ForgeChunkManager
|
||||
try
|
||||
{
|
||||
NBTTagCompound forcedChunkData = CompressedStreamTools.read(chunkLoaderData);
|
||||
return forcedChunkData.getTagList("TicketList", Constants.NBT.TAG_COMPOUND).tagCount() > 0;
|
||||
return forcedChunkData.getTagList("TicketList").tagCount() > 0;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
@@ -421,13 +420,13 @@ public class ForgeChunkManager
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
FMLLog.log(Level.WARN, e, "Unable to read forced chunk data at %s - it will be ignored", chunkLoaderData.getAbsolutePath());
|
||||
FMLLog.log(Level.WARNING, e, "Unable to read forced chunk data at %s - it will be ignored", chunkLoaderData.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
NBTTagList ticketList = forcedChunkData.getTagList("TicketList", Constants.NBT.TAG_COMPOUND);
|
||||
NBTTagList ticketList = forcedChunkData.getTagList("TicketList");
|
||||
for (int i = 0; i < ticketList.tagCount(); i++)
|
||||
{
|
||||
NBTTagCompound ticketHolder = (NBTTagCompound)ticketList.getCompoundTagAt(i);
|
||||
NBTTagCompound ticketHolder = (NBTTagCompound) ticketList.tagAt(i);
|
||||
String modId = ticketHolder.getString("Owner");
|
||||
boolean isPlayer = "Forge".equals(modId);
|
||||
|
||||
@@ -443,13 +442,13 @@ public class ForgeChunkManager
|
||||
continue;
|
||||
}
|
||||
|
||||
NBTTagList tickets = ticketHolder.getTagList("Tickets", Constants.NBT.TAG_COMPOUND);
|
||||
NBTTagList tickets = ticketHolder.getTagList("Tickets");
|
||||
for (int j = 0; j < tickets.tagCount(); j++)
|
||||
{
|
||||
NBTTagCompound ticket = (NBTTagCompound) tickets.getCompoundTagAt(j);
|
||||
NBTTagCompound ticket = (NBTTagCompound) tickets.tagAt(j);
|
||||
modId = ticket.hasKey("ModId") ? ticket.getString("ModId") : modId;
|
||||
Type type = Type.values()[ticket.getByte("Type")];
|
||||
//byte ticketChunkDepth = ticket.getByte("ChunkListDepth");
|
||||
byte ticketChunkDepth = ticket.getByte("ChunkListDepth");
|
||||
Ticket tick = new Ticket(modId, type, world);
|
||||
if (ticket.hasKey("ModData"))
|
||||
{
|
||||
@@ -627,7 +626,7 @@ public class ForgeChunkManager
|
||||
ModContainer mc = getContainer(mod);
|
||||
if (mc == null)
|
||||
{
|
||||
FMLLog.log(Level.ERROR, "Failed to locate the container for mod instance %s (%s : %x)", mod, mod.getClass().getName(), System.identityHashCode(mod));
|
||||
FMLLog.log(Level.SEVERE, "Failed to locate the container for mod instance %s (%s : %x)", mod, mod.getClass().getName(), System.identityHashCode(mod));
|
||||
return null;
|
||||
}
|
||||
if (playerTickets.get(player).size()>playerTicketLength)
|
||||
@@ -653,7 +652,7 @@ public class ForgeChunkManager
|
||||
ModContainer container = getContainer(mod);
|
||||
if (container == null)
|
||||
{
|
||||
FMLLog.log(Level.ERROR, "Failed to locate the container for mod instance %s (%s : %x)", mod, mod.getClass().getName(), System.identityHashCode(mod));
|
||||
FMLLog.log(Level.SEVERE, "Failed to locate the container for mod instance %s (%s : %x)", mod, mod.getClass().getName(), System.identityHashCode(mod));
|
||||
return null;
|
||||
}
|
||||
String modId = container.getModId();
|
||||
@@ -787,8 +786,6 @@ public class ForgeChunkManager
|
||||
|
||||
static void loadConfiguration()
|
||||
{
|
||||
ticketConstraints.clear();
|
||||
chunkConstraints.clear();
|
||||
for (String mod : config.getCategoryNames())
|
||||
{
|
||||
if (mod.equals("Forge") || mod.equals("defaults"))
|
||||
@@ -832,7 +829,6 @@ public class ForgeChunkManager
|
||||
forcedChunkData.setTag("TicketList", ticketList);
|
||||
|
||||
Multimap<String, Ticket> ticketSet = tickets.get(worldServer);
|
||||
if (ticketSet == null) return;
|
||||
for (String modId : ticketSet.keySet())
|
||||
{
|
||||
NBTTagCompound ticketHolder = new NBTTagCompound();
|
||||
@@ -854,7 +850,7 @@ public class ForgeChunkManager
|
||||
}
|
||||
if (tick.modData != null)
|
||||
{
|
||||
ticket.setTag("ModData", tick.modData);
|
||||
ticket.setCompoundTag("ModData", tick.modData);
|
||||
}
|
||||
if (tick.ticketType == Type.ENTITY && tick.entity != null && tick.entity.writeToNBTOptional(new NBTTagCompound()))
|
||||
{
|
||||
@@ -876,7 +872,7 @@ public class ForgeChunkManager
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
FMLLog.log(Level.WARN, e, "Unable to write forced chunk data to %s - chunkloading won't work", chunkLoaderData.getAbsolutePath());
|
||||
FMLLog.log(Level.WARNING, e, "Unable to write forced chunk data to %s - chunkloading won't work", chunkLoaderData.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -894,14 +890,13 @@ public class ForgeChunkManager
|
||||
|
||||
public static void putDormantChunk(long coords, Chunk chunk)
|
||||
{
|
||||
Cache<Long, Chunk> cache = dormantChunkCache.get(chunk.getWorld());
|
||||
Cache<Long, Chunk> cache = dormantChunkCache.get(chunk.worldObj);
|
||||
if (cache != null)
|
||||
{
|
||||
cache.put(coords, chunk);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Chunk fetchDormantChunk(long coords, World world)
|
||||
{
|
||||
Cache<Long, Chunk> cache = dormantChunkCache.get(world);
|
||||
@@ -912,12 +907,11 @@ public class ForgeChunkManager
|
||||
Chunk chunk = cache.getIfPresent(coords);
|
||||
if (chunk != null)
|
||||
{
|
||||
for (ClassInheritanceMultiMap eList : chunk.getEntityLists())
|
||||
for (List<Entity> eList : chunk.entityLists)
|
||||
{
|
||||
Iterator<Entity> itr = (Iterator<Entity>)eList.iterator();
|
||||
while (itr.hasNext())
|
||||
for (Entity e: eList)
|
||||
{
|
||||
(itr.next()).resetEntityId();
|
||||
e.resetEntityId();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -940,111 +934,53 @@ public class ForgeChunkManager
|
||||
dest.delete();
|
||||
}
|
||||
cfgFile.renameTo(dest);
|
||||
FMLLog.log(Level.ERROR, e, "A critical error occured reading the forgeChunkLoading.cfg file, defaults will be used - the invalid file is backed up at forgeChunkLoading.cfg.bak");
|
||||
FMLLog.log(Level.SEVERE, e, "A critical error occured reading the forgeChunkLoading.cfg file, defaults will be used - the invalid file is backed up at forgeChunkLoading.cfg.bak");
|
||||
}
|
||||
syncConfigDefaults();
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronizes the local fields with the values in the Configuration object.
|
||||
*/
|
||||
public static void syncConfigDefaults()
|
||||
{
|
||||
// By adding a property order list we are defining the order that the properties will appear both in the config file and on the GUIs.
|
||||
// Property order lists are defined per-ConfigCategory.
|
||||
List<String> propOrder = new ArrayList<String>();
|
||||
|
||||
config.setCategoryComment("defaults", "Default configuration for forge chunk loading control")
|
||||
.setCategoryRequiresWorldRestart("defaults", true);
|
||||
|
||||
Property temp = config.get("defaults", "enabled", true);
|
||||
temp.comment = "Are mod overrides enabled?";
|
||||
temp.setLanguageKey("forge.configgui.enableModOverrides");
|
||||
overridesEnabled = temp.getBoolean(true);
|
||||
propOrder.add("enabled");
|
||||
|
||||
temp = config.get("defaults", "maximumChunksPerTicket", 25);
|
||||
temp.comment = "The default maximum number of chunks a mod can force, per ticket, \n" +
|
||||
"for a mod without an override. This is the maximum number of chunks a single ticket can force.";
|
||||
temp.setLanguageKey("forge.configgui.maximumChunksPerTicket");
|
||||
temp.setMinValue(0);
|
||||
defaultMaxChunks = temp.getInt(25);
|
||||
propOrder.add("maximumChunksPerTicket");
|
||||
|
||||
temp = config.get("defaults", "maximumTicketCount", 200);
|
||||
temp.comment = "The default maximum ticket count for a mod which does not have an override\n" +
|
||||
config.addCustomCategoryComment("defaults", "Default configuration for forge chunk loading control");
|
||||
Property maxTicketCount = config.get("defaults", "maximumTicketCount", 200);
|
||||
maxTicketCount.comment = "The default maximum ticket count for a mod which does not have an override\n" +
|
||||
"in this file. This is the number of chunk loading requests a mod is allowed to make.";
|
||||
temp.setLanguageKey("forge.configgui.maximumTicketCount");
|
||||
temp.setMinValue(0);
|
||||
defaultMaxCount = temp.getInt(200);
|
||||
propOrder.add("maximumTicketCount");
|
||||
defaultMaxCount = maxTicketCount.getInt(200);
|
||||
|
||||
temp = config.get("defaults", "playerTicketCount", 500);
|
||||
temp.comment = "The number of tickets a player can be assigned instead of a mod. This is shared across all mods and it is up to the mods to use it.";
|
||||
temp.setLanguageKey("forge.configgui.playerTicketCount");
|
||||
temp.setMinValue(0);
|
||||
playerTicketLength = temp.getInt(500);
|
||||
propOrder.add("playerTicketCount");
|
||||
Property maxChunks = config.get("defaults", "maximumChunksPerTicket", 25);
|
||||
maxChunks.comment = "The default maximum number of chunks a mod can force, per ticket, \n" +
|
||||
"for a mod without an override. This is the maximum number of chunks a single ticket can force.";
|
||||
defaultMaxChunks = maxChunks.getInt(25);
|
||||
|
||||
temp = config.get("defaults", "dormantChunkCacheSize", 0);
|
||||
temp.comment = "Unloaded chunks can first be kept in a dormant cache for quicker\n" +
|
||||
Property playerTicketCount = config.get("defaults", "playerTicketCount", 500);
|
||||
playerTicketCount.comment = "The number of tickets a player can be assigned instead of a mod. This is shared across all mods and it is up to the mods to use it.";
|
||||
playerTicketLength = playerTicketCount.getInt(500);
|
||||
|
||||
Property dormantChunkCacheSizeProperty = config.get("defaults", "dormantChunkCacheSize", 0);
|
||||
dormantChunkCacheSizeProperty.comment = "Unloaded chunks can first be kept in a dormant cache for quicker\n" +
|
||||
"loading times. Specify the size (in chunks) of that cache here";
|
||||
temp.setLanguageKey("forge.configgui.dormantChunkCacheSize");
|
||||
temp.setMinValue(0);
|
||||
dormantChunkCacheSize = temp.getInt(0);
|
||||
propOrder.add("dormantChunkCacheSize");
|
||||
FMLLog.info("Configured a dormant chunk cache size of %d", temp.getInt(0));
|
||||
dormantChunkCacheSize = dormantChunkCacheSizeProperty.getInt(0);
|
||||
FMLLog.info("Configured a dormant chunk cache size of %d", dormantChunkCacheSizeProperty.getInt(0));
|
||||
|
||||
config.setCategoryPropertyOrder("defaults", propOrder);
|
||||
Property modOverridesEnabled = config.get("defaults", "enabled", true);
|
||||
modOverridesEnabled.comment = "Are mod overrides enabled?";
|
||||
overridesEnabled = modOverridesEnabled.getBoolean(true);
|
||||
|
||||
config.addCustomCategoryComment("Forge", "Sample mod specific control section.\n" +
|
||||
"Copy this section and rename the with the modid for the mod you wish to override.\n" +
|
||||
"A value of zero in either entry effectively disables any chunkloading capabilities\n" +
|
||||
"for that mod");
|
||||
|
||||
temp = config.get("Forge", "maximumTicketCount", 200);
|
||||
temp.comment = "Maximum ticket count for the mod. Zero disables chunkloading capabilities.";
|
||||
temp = config.get("Forge", "maximumChunksPerTicket", 25);
|
||||
temp.comment = "Maximum chunks per ticket for the mod.";
|
||||
Property sampleTC = config.get("Forge", "maximumTicketCount", 200);
|
||||
sampleTC.comment = "Maximum ticket count for the mod. Zero disables chunkloading capabilities.";
|
||||
sampleTC = config.get("Forge", "maximumChunksPerTicket", 25);
|
||||
sampleTC.comment = "Maximum chunks per ticket for the mod.";
|
||||
for (String mod : config.getCategoryNames())
|
||||
{
|
||||
if (mod.equals("Forge") || mod.equals("defaults"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
config.get(mod, "maximumTicketCount", 200).setLanguageKey("forge.configgui.maximumTicketCount").setMinValue(0);
|
||||
config.get(mod, "maximumChunksPerTicket", 25).setLanguageKey("forge.configgui.maximumChunksPerTicket").setMinValue(0);
|
||||
}
|
||||
|
||||
if (config.hasChanged())
|
||||
{
|
||||
config.save();
|
||||
Property modTC = config.get(mod, "maximumTicketCount", 200);
|
||||
Property modCPT = config.get(mod, "maximumChunksPerTicket", 25);
|
||||
}
|
||||
}
|
||||
|
||||
public static Configuration getConfig()
|
||||
{
|
||||
return config;
|
||||
}
|
||||
|
||||
public static ConfigCategory getDefaultsCategory()
|
||||
{
|
||||
return config.getCategory("defaults");
|
||||
}
|
||||
|
||||
public static List<ConfigCategory> getModCategories()
|
||||
{
|
||||
List<ConfigCategory> list = new ArrayList<ConfigCategory>();
|
||||
for (String mod : config.getCategoryNames())
|
||||
{
|
||||
if (mod.equals("Forge") || mod.equals("defaults"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
list.add(config.getCategory(mod));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static ConfigCategory getConfigFor(Object mod)
|
||||
{
|
||||
@@ -1063,12 +999,7 @@ public class ForgeChunkManager
|
||||
if (container != null)
|
||||
{
|
||||
ConfigCategory cat = config.getCategory(container.getModId());
|
||||
Property prop = new Property(propertyName, value, type).setLanguageKey("forge.configgui." + propertyName);
|
||||
if (type == Property.Type.INTEGER)
|
||||
{
|
||||
prop.setMinValue(0);
|
||||
}
|
||||
cat.put(propertyName, prop);
|
||||
cat.put(propertyName, new Property(propertyName, value, type));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package net.minecraftforge.common;
|
||||
|
||||
public enum ForgeDirection
|
||||
{
|
||||
/** -Y */
|
||||
DOWN(0, -1, 0),
|
||||
|
||||
/** +Y */
|
||||
UP(0, 1, 0),
|
||||
|
||||
/** -Z */
|
||||
NORTH(0, 0, -1),
|
||||
|
||||
/** +Z */
|
||||
SOUTH(0, 0, 1),
|
||||
|
||||
/** -X */
|
||||
WEST(-1, 0, 0),
|
||||
|
||||
/** +X */
|
||||
EAST(1, 0, 0),
|
||||
|
||||
/**
|
||||
* Used only by getOrientation, for invalid inputs
|
||||
*/
|
||||
UNKNOWN(0, 0, 0);
|
||||
|
||||
public final int offsetX;
|
||||
public final int offsetY;
|
||||
public final int offsetZ;
|
||||
public final int flag;
|
||||
public static final ForgeDirection[] VALID_DIRECTIONS = {DOWN, UP, NORTH, SOUTH, WEST, EAST};
|
||||
public static final int[] OPPOSITES = {1, 0, 3, 2, 5, 4, 6};
|
||||
// Left hand rule rotation matrix for all possible axes of rotation
|
||||
public static final int[][] ROTATION_MATRIX = {
|
||||
{0, 1, 4, 5, 3, 2, 6},
|
||||
{0, 1, 5, 4, 2, 3, 6},
|
||||
{5, 4, 2, 3, 0, 1, 6},
|
||||
{4, 5, 2, 3, 1, 0, 6},
|
||||
{2, 3, 1, 0, 4, 5, 6},
|
||||
{3, 2, 0, 1, 4, 5, 6},
|
||||
{0, 1, 2, 3, 4, 5, 6},
|
||||
};
|
||||
|
||||
private ForgeDirection(int x, int y, int z)
|
||||
{
|
||||
offsetX = x;
|
||||
offsetY = y;
|
||||
offsetZ = z;
|
||||
flag = 1 << ordinal();
|
||||
}
|
||||
|
||||
public static ForgeDirection getOrientation(int id)
|
||||
{
|
||||
if (id >= 0 && id < VALID_DIRECTIONS.length)
|
||||
{
|
||||
return VALID_DIRECTIONS[id];
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
public ForgeDirection getOpposite()
|
||||
{
|
||||
return getOrientation(OPPOSITES[ordinal()]);
|
||||
}
|
||||
|
||||
public ForgeDirection getRotation(ForgeDirection axis)
|
||||
{
|
||||
return getOrientation(ROTATION_MATRIX[axis.ordinal()][ordinal()]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
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;
|
||||
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",
|
||||
connectionHandler = ForgeConnectionHandler.class,
|
||||
packetHandler = ForgePacketHandler.class,
|
||||
tinyPacketHandler = ForgeTinyPacketHandler.class
|
||||
)
|
||||
public class ForgeDummyContainer extends DummyModContainer implements WorldAccessContainer
|
||||
{
|
||||
public static int clumpingThreshold = 64;
|
||||
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()
|
||||
{
|
||||
super(new ModMetadata());
|
||||
ModMetadata meta = getMetadata();
|
||||
meta.modId = "Forge";
|
||||
meta.name = "Minecraft Forge";
|
||||
meta.version = String.format("%d.%d.%d.%d", majorVersion, minorVersion, revisionVersion, buildVersion);
|
||||
meta.credits = "Made possible with help from many people";
|
||||
meta.authorList = Arrays.asList("LexManos", "Eloraam", "Spacetoad");
|
||||
meta.description = "Minecraft Forge is a common open source API allowing a broad range of mods " +
|
||||
"to work cooperatively together. It allows many mods to be created without " +
|
||||
"them editing the main Minecraft code.";
|
||||
meta.url = "http://MinecraftForge.net";
|
||||
meta.updateUrl = "http://MinecraftForge.net/forum/index.php/topic,5.0.html";
|
||||
meta.screenshots = new String[0];
|
||||
meta.logoFile = "/forge_logo.png";
|
||||
|
||||
Configuration config = null;
|
||||
File cfgFile = new File(Loader.instance().getConfigDir(), "forge.cfg");
|
||||
try
|
||||
{
|
||||
config = new Configuration(cfgFile);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.out.println("Error loading forge.cfg, deleting file and resetting: ");
|
||||
e.printStackTrace();
|
||||
|
||||
if (cfgFile.exists())
|
||||
cfgFile.delete();
|
||||
|
||||
config = new Configuration(cfgFile);
|
||||
}
|
||||
if (!config.isChild)
|
||||
{
|
||||
config.load();
|
||||
Property enableGlobalCfg = config.get(Configuration.CATEGORY_GENERAL, "enableGlobalConfig", false);
|
||||
if (enableGlobalCfg.getBoolean(false))
|
||||
{
|
||||
Configuration.enableGlobalConfig();
|
||||
}
|
||||
}
|
||||
Property prop;
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "clumpingThreshold", 64);
|
||||
prop.comment = "Controls the number threshold at which Packet51 is preferred over Packet52, default and minimum 64, maximum 1024";
|
||||
clumpingThreshold = prop.getInt(64);
|
||||
if (clumpingThreshold > 1024 || clumpingThreshold < 64)
|
||||
{
|
||||
clumpingThreshold = 64;
|
||||
prop.set(64);
|
||||
}
|
||||
|
||||
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("Enabling removal of erroring Entities - USE AT YOUR OWN RISK");
|
||||
}
|
||||
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "removeErroringTileEntities", 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.";
|
||||
removeErroringTileEntities = prop.getBoolean(false);
|
||||
|
||||
if (removeErroringTileEntities)
|
||||
{
|
||||
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, "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())
|
||||
{
|
||||
config.save();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerBus(EventBus bus, LoadController controller)
|
||||
{
|
||||
bus.register(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void modConstruction(FMLConstructionEvent evt)
|
||||
{
|
||||
FMLLog.info("Registering Forge Packet Handler");
|
||||
try
|
||||
{
|
||||
FMLNetworkHandler.instance().registerNetworkMod(new ForgeNetworkHandler(this));
|
||||
FMLLog.info("Succeeded registering Forge Packet Handler");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "Failed to register packet handler for Forge");
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void preInit(FMLPreInitializationEvent evt)
|
||||
{
|
||||
ForgeChunkManager.captureConfig(evt.getModConfigurationDirectory());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void postInit(FMLPostInitializationEvent evt)
|
||||
{
|
||||
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)
|
||||
{
|
||||
NBTTagCompound forgeData = new NBTTagCompound();
|
||||
NBTTagCompound dimData = DimensionManager.saveDimensionDataMap();
|
||||
forgeData.setCompoundTag("DimensionData", dimData);
|
||||
return forgeData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readData(SaveHandler handler, WorldInfo info, Map<String, NBTBase> propertyMap, NBTTagCompound tag)
|
||||
{
|
||||
if (tag.hasKey("DimensionData"))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,500 @@
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
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;
|
||||
import net.minecraftforge.event.entity.living.LivingAttackEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingDeathEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingDropsEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingEvent.LivingJumpEvent;
|
||||
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
|
||||
{
|
||||
static class GrassEntry extends WeightedRandomItem
|
||||
{
|
||||
public final Block block;
|
||||
public final int metadata;
|
||||
public GrassEntry(Block block, int meta, int weight)
|
||||
{
|
||||
super(weight);
|
||||
this.block = block;
|
||||
this.metadata = meta;
|
||||
}
|
||||
}
|
||||
|
||||
static class SeedEntry extends WeightedRandomItem
|
||||
{
|
||||
public final ItemStack seed;
|
||||
public SeedEntry(ItemStack seed, int weight)
|
||||
{
|
||||
super(weight);
|
||||
this.seed = seed;
|
||||
}
|
||||
}
|
||||
static final List<GrassEntry> grassList = new ArrayList<GrassEntry>();
|
||||
static final List<SeedEntry> seedList = new ArrayList<SeedEntry>();
|
||||
|
||||
public static void plantGrass(World world, int x, int y, int z)
|
||||
{
|
||||
GrassEntry grass = (GrassEntry)WeightedRandom.getRandomItem(world.rand, grassList);
|
||||
if (grass == null || grass.block == null || !grass.block.canBlockStay(world, x, y, z))
|
||||
{
|
||||
return;
|
||||
}
|
||||
world.setBlock(x, y, z, grass.block.blockID, grass.metadata, 3);
|
||||
}
|
||||
|
||||
public static ItemStack getGrassSeed(World world)
|
||||
{
|
||||
SeedEntry entry = (SeedEntry)WeightedRandom.getRandomItem(world.rand, seedList);
|
||||
if (entry == null || entry.seed == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return entry.seed.copy();
|
||||
}
|
||||
|
||||
private static boolean toolInit = false;
|
||||
static HashMap<Item, List> toolClasses = new HashMap<Item, List>();
|
||||
static HashMap<List, Integer> toolHarvestLevels = new HashMap<List, Integer>();
|
||||
static HashSet<List> toolEffectiveness = new HashSet<List>();
|
||||
|
||||
public static boolean canHarvestBlock(Block block, EntityPlayer player, int metadata)
|
||||
{
|
||||
if (block.blockMaterial.isToolNotRequired())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ItemStack stack = player.inventory.getCurrentItem();
|
||||
if (stack == null)
|
||||
{
|
||||
return player.canHarvestBlock(block);
|
||||
}
|
||||
|
||||
List info = toolClasses.get(stack.getItem());
|
||||
if (info == null)
|
||||
{
|
||||
return player.canHarvestBlock(block);
|
||||
}
|
||||
|
||||
Object[] tmp = info.toArray();
|
||||
String toolClass = (String)tmp[0];
|
||||
int harvestLevel = (Integer)tmp[1];
|
||||
|
||||
Integer blockHarvestLevel = toolHarvestLevels.get(Arrays.asList(block, metadata, toolClass));
|
||||
if (blockHarvestLevel == null)
|
||||
{
|
||||
return player.canHarvestBlock(block);
|
||||
}
|
||||
|
||||
if (blockHarvestLevel > harvestLevel)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean canToolHarvestBlock(Block block, int metadata, ItemStack stack)
|
||||
{
|
||||
if (stack == null) return false;
|
||||
List info = toolClasses.get(stack.getItem());
|
||||
if (info == null) return false;
|
||||
|
||||
Object[] tmp = info.toArray();
|
||||
String toolClass = (String)tmp[0];
|
||||
int harvestLevel = (Integer)tmp[1];
|
||||
|
||||
Integer blockHarvestLevel = toolHarvestLevels.get(Arrays.asList(block, metadata, toolClass));
|
||||
return !(blockHarvestLevel == null || blockHarvestLevel > harvestLevel);
|
||||
}
|
||||
|
||||
public static float blockStrength(Block block, EntityPlayer player, World world, int x, int y, int z)
|
||||
{
|
||||
int metadata = world.getBlockMetadata(x, y, z);
|
||||
float hardness = block.getBlockHardness(world, x, y, z);
|
||||
if (hardness < 0.0F)
|
||||
{
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
if (!canHarvestBlock(block, player, metadata))
|
||||
{
|
||||
float speed = ForgeEventFactory.getBreakSpeed(player, block, metadata, 1.0f);
|
||||
return (speed < 0 ? 0 : speed) / hardness / 100F;
|
||||
}
|
||||
else
|
||||
{
|
||||
return player.getCurrentPlayerStrVsBlock(block, false, metadata) / hardness / 30F;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isToolEffective(ItemStack stack, Block block, int metadata)
|
||||
{
|
||||
List toolClass = toolClasses.get(stack.getItem());
|
||||
return toolClass != null && toolEffectiveness.contains(Arrays.asList(block, metadata, toolClass.get(0)));
|
||||
}
|
||||
|
||||
static void initTools()
|
||||
{
|
||||
if (toolInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
toolInit = true;
|
||||
|
||||
MinecraftForge.setToolClass(Item.pickaxeWood, "pickaxe", 0);
|
||||
MinecraftForge.setToolClass(Item.pickaxeStone, "pickaxe", 1);
|
||||
MinecraftForge.setToolClass(Item.pickaxeIron, "pickaxe", 2);
|
||||
MinecraftForge.setToolClass(Item.pickaxeGold, "pickaxe", 0);
|
||||
MinecraftForge.setToolClass(Item.pickaxeDiamond, "pickaxe", 3);
|
||||
|
||||
MinecraftForge.setToolClass(Item.axeWood, "axe", 0);
|
||||
MinecraftForge.setToolClass(Item.axeStone, "axe", 1);
|
||||
MinecraftForge.setToolClass(Item.axeIron, "axe", 2);
|
||||
MinecraftForge.setToolClass(Item.axeGold, "axe", 0);
|
||||
MinecraftForge.setToolClass(Item.axeDiamond, "axe", 3);
|
||||
|
||||
MinecraftForge.setToolClass(Item.shovelWood, "shovel", 0);
|
||||
MinecraftForge.setToolClass(Item.shovelStone, "shovel", 1);
|
||||
MinecraftForge.setToolClass(Item.shovelIron, "shovel", 2);
|
||||
MinecraftForge.setToolClass(Item.shovelGold, "shovel", 0);
|
||||
MinecraftForge.setToolClass(Item.shovelDiamond, "shovel", 3);
|
||||
|
||||
for (Block block : ItemPickaxe.blocksEffectiveAgainst)
|
||||
{
|
||||
MinecraftForge.setBlockHarvestLevel(block, "pickaxe", 0);
|
||||
}
|
||||
|
||||
for (Block block : ItemSpade.blocksEffectiveAgainst)
|
||||
{
|
||||
MinecraftForge.setBlockHarvestLevel(block, "shovel", 0);
|
||||
}
|
||||
|
||||
for (Block block : ItemAxe.blocksEffectiveAgainst)
|
||||
{
|
||||
MinecraftForge.setBlockHarvestLevel(block, "axe", 0);
|
||||
}
|
||||
|
||||
MinecraftForge.setBlockHarvestLevel(Block.obsidian, "pickaxe", 3);
|
||||
MinecraftForge.setBlockHarvestLevel(Block.oreEmerald, "pickaxe", 2);
|
||||
MinecraftForge.setBlockHarvestLevel(Block.oreDiamond, "pickaxe", 2);
|
||||
MinecraftForge.setBlockHarvestLevel(Block.blockDiamond, "pickaxe", 2);
|
||||
MinecraftForge.setBlockHarvestLevel(Block.oreGold, "pickaxe", 2);
|
||||
MinecraftForge.setBlockHarvestLevel(Block.blockGold, "pickaxe", 2);
|
||||
MinecraftForge.setBlockHarvestLevel(Block.oreIron, "pickaxe", 1);
|
||||
MinecraftForge.setBlockHarvestLevel(Block.blockIron, "pickaxe", 1);
|
||||
MinecraftForge.setBlockHarvestLevel(Block.oreLapis, "pickaxe", 1);
|
||||
MinecraftForge.setBlockHarvestLevel(Block.blockLapis, "pickaxe", 1);
|
||||
MinecraftForge.setBlockHarvestLevel(Block.oreRedstone, "pickaxe", 2);
|
||||
MinecraftForge.setBlockHarvestLevel(Block.oreRedstoneGlowing, "pickaxe", 2);
|
||||
MinecraftForge.removeBlockEffectiveness(Block.oreRedstone, "pickaxe");
|
||||
MinecraftForge.removeBlockEffectiveness(Block.obsidian, "pickaxe");
|
||||
MinecraftForge.removeBlockEffectiveness(Block.oreRedstoneGlowing, "pickaxe");
|
||||
}
|
||||
|
||||
public static int getTotalArmorValue(EntityPlayer player)
|
||||
{
|
||||
int ret = 0;
|
||||
for (int x = 0; x < player.inventory.armorInventory.length; x++)
|
||||
{
|
||||
ItemStack stack = player.inventory.armorInventory[x];
|
||||
if (stack != null && stack.getItem() instanceof ISpecialArmor)
|
||||
{
|
||||
ret += ((ISpecialArmor)stack.getItem()).getArmorDisplay(player, stack, x);
|
||||
}
|
||||
else if (stack != null && stack.getItem() instanceof ItemArmor)
|
||||
{
|
||||
ret += ((ItemArmor)stack.getItem()).damageReduceAmount;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
grassList.add(new GrassEntry(Block.plantYellow, 0, 20));
|
||||
grassList.add(new GrassEntry(Block.plantRed, 0, 10));
|
||||
seedList.add(new SeedEntry(new ItemStack(Item.seeds), 10));
|
||||
initTools();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player uses 'pick block', calls new Entity and Block hooks.
|
||||
*/
|
||||
public static boolean onPickBlock(MovingObjectPosition target, EntityPlayer player, World world)
|
||||
{
|
||||
ItemStack result = null;
|
||||
boolean isCreative = player.capabilities.isCreativeMode;
|
||||
|
||||
if (target.typeOfHit == EnumMovingObjectType.TILE)
|
||||
{
|
||||
int x = target.blockX;
|
||||
int y = target.blockY;
|
||||
int z = target.blockZ;
|
||||
Block var8 = Block.blocksList[world.getBlockId(x, y, z)];
|
||||
|
||||
if (var8 == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
result = var8.getPickBlock(target, world, x, y, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target.typeOfHit != EnumMovingObjectType.ENTITY || target.entityHit == null || !isCreative)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
result = target.entityHit.getPickedResult(target);
|
||||
}
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int x = 0; x < 9; x++)
|
||||
{
|
||||
ItemStack stack = player.inventory.getStackInSlot(x);
|
||||
if (stack != null && stack.isItemEqual(result) && ItemStack.areItemStackTagsEqual(stack, result))
|
||||
{
|
||||
player.inventory.currentItem = x;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isCreative)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int slot = player.inventory.getFirstEmptyStack();
|
||||
if (slot < 0 || slot >= 9)
|
||||
{
|
||||
slot = player.inventory.currentItem;
|
||||
}
|
||||
|
||||
player.inventory.setInventorySlotContents(slot, result);
|
||||
player.inventory.currentItem = slot;
|
||||
return true;
|
||||
}
|
||||
|
||||
//Optifine Helper Functions u.u, these are here specifically for Optifine
|
||||
//Note: When using Optfine, these methods are invoked using reflection, which
|
||||
//incurs a major performance penalty.
|
||||
public static void onLivingSetAttackTarget(EntityLivingBase entity, EntityLivingBase target)
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.post(new LivingSetAttackTargetEvent(entity, target));
|
||||
}
|
||||
|
||||
public static boolean onLivingUpdate(EntityLivingBase entity)
|
||||
{
|
||||
return MinecraftForge.EVENT_BUS.post(new LivingUpdateEvent(entity));
|
||||
}
|
||||
|
||||
public static boolean onLivingAttack(EntityLivingBase entity, DamageSource src, float amount)
|
||||
{
|
||||
return MinecraftForge.EVENT_BUS.post(new LivingAttackEvent(entity, src, amount));
|
||||
}
|
||||
|
||||
public static float onLivingHurt(EntityLivingBase entity, DamageSource src, float amount)
|
||||
{
|
||||
LivingHurtEvent event = new LivingHurtEvent(entity, src, amount);
|
||||
return (MinecraftForge.EVENT_BUS.post(event) ? 0 : event.ammount);
|
||||
}
|
||||
|
||||
public static boolean onLivingDeath(EntityLivingBase entity, DamageSource src)
|
||||
{
|
||||
return MinecraftForge.EVENT_BUS.post(new LivingDeathEvent(entity, src));
|
||||
}
|
||||
|
||||
public static boolean onLivingDrops(EntityLivingBase entity, DamageSource source, ArrayList<EntityItem> drops, int lootingLevel, boolean recentlyHit, int specialDropValue)
|
||||
{
|
||||
return MinecraftForge.EVENT_BUS.post(new LivingDropsEvent(entity, source, drops, lootingLevel, recentlyHit, specialDropValue));
|
||||
}
|
||||
|
||||
public static float onLivingFall(EntityLivingBase entity, float distance)
|
||||
{
|
||||
LivingFallEvent event = new LivingFallEvent(entity, distance);
|
||||
return (MinecraftForge.EVENT_BUS.post(event) ? 0.0f : event.distance);
|
||||
}
|
||||
|
||||
public static boolean isLivingOnLadder(Block block, World world, int x, int y, int z, EntityLivingBase 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)
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.post(new LivingJumpEvent(entity));
|
||||
}
|
||||
|
||||
public static EntityItem onPlayerTossEvent(EntityPlayer player, ItemStack item)
|
||||
{
|
||||
player.captureDrops = true;
|
||||
EntityItem ret = player.dropPlayerItemWithRandomChoice(item, false);
|
||||
player.capturedDrops.clear();
|
||||
player.captureDrops = false;
|
||||
|
||||
if (ret == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ItemTossEvent event = new ItemTossEvent(ret, player);
|
||||
if (MinecraftForge.EVENT_BUS.post(event))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
player.joinEntityItemWithWorld(event.entityItem);
|
||||
return event.entityItem;
|
||||
}
|
||||
|
||||
public static float getEnchantPower(World world, int x, int y, int z)
|
||||
{
|
||||
if (world.isAirBlock(x, y, z))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Block block = Block.blocksList[world.getBlockId(x, y, z)];
|
||||
return (block == null ? 0 : block.getEnchantPowerBonus(world, x, y, z));
|
||||
}
|
||||
|
||||
public static ChatMessageComponent onServerChatEvent(NetServerHandler net, String raw, ChatMessageComponent comp)
|
||||
{
|
||||
ServerChatEvent event = new ServerChatEvent(net.playerEntity, raw, comp);
|
||||
if (MinecraftForge.EVENT_BUS.post(event))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
+11
-13
@@ -1,20 +1,20 @@
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.eventhandler.EventPriority;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import java.util.UUID;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.common.util.FakePlayerFactory;
|
||||
import net.minecraftforge.event.*;
|
||||
import net.minecraftforge.event.entity.*;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
|
||||
public class ForgeInternalHandler
|
||||
{
|
||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||
@ForgeSubscribe(priority = EventPriority.HIGHEST)
|
||||
public void onEntityJoinWorld(EntityJoinWorldEvent event)
|
||||
{
|
||||
if (!event.world.isRemote)
|
||||
@@ -37,9 +37,9 @@ public class ForgeInternalHandler
|
||||
Item item = stack.getItem();
|
||||
if (item == null)
|
||||
{
|
||||
FMLLog.warning("Attempted to add a EntityItem to the world with a invalid item at " +
|
||||
FMLLog.warning("Attempted to add a EntityItem to the world with a invalid item: ID %d at " +
|
||||
"(%2.2f, %2.2f, %2.2f), this is most likely a config issue between you and the server. Please double check your configs",
|
||||
entity.posX, entity.posY, entity.posZ);
|
||||
stack.itemID, entity.posX, entity.posY, entity.posZ);
|
||||
entity.setDead();
|
||||
event.setCanceled(true);
|
||||
return;
|
||||
@@ -58,23 +58,21 @@ public class ForgeInternalHandler
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||
@ForgeSubscribe(priority = EventPriority.HIGHEST)
|
||||
public void onDimensionLoad(WorldEvent.Load event)
|
||||
{
|
||||
ForgeChunkManager.loadWorld(event.world);
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||
@ForgeSubscribe(priority = EventPriority.HIGHEST)
|
||||
public void onDimensionSave(WorldEvent.Save event)
|
||||
{
|
||||
ForgeChunkManager.saveWorld(event.world);
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||
@ForgeSubscribe(priority = EventPriority.HIGHEST)
|
||||
public void onDimensionUnload(WorldEvent.Unload event)
|
||||
{
|
||||
ForgeChunkManager.unloadWorld(event.world);
|
||||
if (event.world instanceof WorldServer)
|
||||
FakePlayerFactory.unloadWorld((WorldServer)event.world);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* This software is provided under the terms of the Minecraft Forge Public
|
||||
* License v1.0.
|
||||
*/
|
||||
|
||||
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 = 9;
|
||||
//This number is incremented every minecraft release, never reset
|
||||
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 = 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;
|
||||
|
||||
public static int getMajorVersion()
|
||||
{
|
||||
return majorVersion;
|
||||
}
|
||||
|
||||
public static int getMinorVersion()
|
||||
{
|
||||
return minorVersion;
|
||||
}
|
||||
|
||||
public static int getRevisionVersion()
|
||||
{
|
||||
return revisionVersion;
|
||||
}
|
||||
|
||||
public static int getBuildVersion()
|
||||
{
|
||||
return buildVersion;
|
||||
}
|
||||
|
||||
public static String getVersion()
|
||||
{
|
||||
return String.format("%d.%d.%d.%d", majorVersion, minorVersion, revisionVersion, buildVersion);
|
||||
}
|
||||
}
|
||||
|
||||
-2
@@ -30,8 +30,6 @@ public interface IExtendedEntityProperties {
|
||||
* Used to initialize the extended properties with the entity that this is attached to, as well
|
||||
* as the world object.
|
||||
* Called automatically if you register with the EntityConstructing event.
|
||||
* May be called multiple times if the extended properties is moved over to a new entity.
|
||||
* Such as when a player switches dimension {Minecraft re-creates the player entity}
|
||||
* @param entity The entity that this extended properties is attached to
|
||||
* @param world The world in which the entity exists
|
||||
*/
|
||||
File renamed without changes.
@@ -0,0 +1,10 @@
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface IPlantable
|
||||
{
|
||||
public EnumPlantType getPlantType(World world, int x, int y, int z);
|
||||
public int getPlantID(World world, int x, int y, int z);
|
||||
public int getPlantMetadata(World world, int x, int y, int z);
|
||||
}
|
||||
+13
-9
@@ -1,10 +1,11 @@
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -22,17 +23,18 @@ public interface IShearable
|
||||
*
|
||||
* @param item The itemstack that is being used, Possible to be null
|
||||
* @param world The current world
|
||||
* @param pos Block's position in world.
|
||||
* @param x The X Position
|
||||
* @param y The Y Position
|
||||
* @param z The Z Position
|
||||
* @return If this is shearable, and onSheared should be called.
|
||||
*/
|
||||
public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos);
|
||||
public boolean isShearable(ItemStack item, World world, int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Performs the shear function on this object.
|
||||
* This is called for both client, and server.
|
||||
* The object should perform all actions related to being sheared,
|
||||
* except for dropping of the items, and removal of the block.
|
||||
* As those are handled by ItemShears itself.
|
||||
* except for dropping of the items.
|
||||
*
|
||||
* Returns a list of items that resulted from the shearing process.
|
||||
*
|
||||
@@ -41,9 +43,11 @@ public interface IShearable
|
||||
*
|
||||
* @param item The itemstack that is being used, Possible to be null
|
||||
* @param world The current world
|
||||
* @param pos If this is a block, the block's position in world.
|
||||
* @param x The X Position
|
||||
* @param y The Y Position
|
||||
* @param z The Z Position
|
||||
* @param fortune The fortune level of the shears being used
|
||||
* @return A ArrayList containing all items from this shearing. Possible to be null.
|
||||
*/
|
||||
public List<ItemStack> onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune);
|
||||
public ArrayList<ItemStack> onSheared(ItemStack item, World world, int x, int y, int z, int fortune);
|
||||
}
|
||||
+2
-4
@@ -64,7 +64,7 @@ public interface ISpecialArmor
|
||||
* @param slot The armor slot the item is in.
|
||||
*/
|
||||
public abstract void damageArmor(EntityLivingBase entity, ItemStack stack, DamageSource source, int damage, int slot);
|
||||
|
||||
|
||||
public static class ArmorProperties implements Comparable<ArmorProperties>
|
||||
{
|
||||
public int Priority = 0;
|
||||
@@ -90,7 +90,7 @@ public interface ISpecialArmor
|
||||
* @param damage The total damage being done
|
||||
* @return The left over damage that has not been absorbed by the armor
|
||||
*/
|
||||
public static float applyArmor(EntityLivingBase entity, ItemStack[] inventory, DamageSource source, double damage)
|
||||
public static float ApplyArmor(EntityLivingBase entity, ItemStack[] inventory, DamageSource source, double damage)
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
@@ -293,7 +293,6 @@ public interface ISpecialArmor
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ArmorProperties o)
|
||||
{
|
||||
if (o.Priority != Priority)
|
||||
@@ -305,7 +304,6 @@ public interface ISpecialArmor
|
||||
return (int)(left - right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%d, %d, %f, %d", Priority, AbsorbMax, AbsorbRatio, (AbsorbRatio == 0 ? 0 : (int)(AbsorbMax * 100.0D / AbsorbRatio)));
|
||||
@@ -0,0 +1,222 @@
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.*;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Mod;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.renderer.texture.IconRegister;
|
||||
import net.minecraft.crash.CrashReport;
|
||||
import net.minecraft.entity.monster.EntityEnderman;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.common.ForgeHooks.GrassEntry;
|
||||
import net.minecraftforge.common.ForgeHooks.SeedEntry;
|
||||
import net.minecraftforge.event.EventBus;
|
||||
import net.minecraftforge.event.ForgeSubscribe;
|
||||
import net.minecraftforge.event.entity.EntityEvent;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
public class MinecraftForge
|
||||
{
|
||||
/**
|
||||
* The core Forge EventBusses, all events for Forge will be fired on these,
|
||||
* you should use this to register all your listeners.
|
||||
* This replaces every register*Handler() function in the old version of Forge.
|
||||
* TERRAIN_GEN_BUS for terrain gen events
|
||||
* ORE_GEN_BUS for ore gen events
|
||||
* EVENT_BUS for everything else
|
||||
*/
|
||||
public static final EventBus EVENT_BUS = new EventBus();
|
||||
public static final EventBus TERRAIN_GEN_BUS = new EventBus();
|
||||
public static final EventBus ORE_GEN_BUS = new EventBus();
|
||||
|
||||
private static final ForgeInternalHandler INTERNAL_HANDLER = new ForgeInternalHandler();
|
||||
|
||||
|
||||
/** Register a new plant to be planted when bonemeal is used on grass.
|
||||
* @param block The block to place.
|
||||
* @param metadata The metadata to set for the block when being placed.
|
||||
* @param weight The weight of the plant, where red flowers are
|
||||
* 10 and yellow flowers are 20.
|
||||
*/
|
||||
public static void addGrassPlant(Block block, int metadata, int weight)
|
||||
{
|
||||
ForgeHooks.grassList.add(new GrassEntry(block, metadata, weight));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new seed to be dropped when breaking tall grass.
|
||||
*
|
||||
* @param seed The item to drop as a seed.
|
||||
* @param weight The relative probability of the seeds,
|
||||
* where wheat seeds are 10.
|
||||
*/
|
||||
public static void addGrassSeed(ItemStack seed, int weight)
|
||||
{
|
||||
ForgeHooks.seedList.add(new SeedEntry(seed, weight));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Register a tool as a tool class with a given harvest level.
|
||||
*
|
||||
* @param tool The custom tool to register.
|
||||
* @param toolClass The tool class to register as. The predefined tool
|
||||
* clases are "pickaxe", "shovel", "axe". You can add
|
||||
* others for custom tools.
|
||||
* @param harvestLevel The harvest level of the tool.
|
||||
*/
|
||||
public static void setToolClass(Item tool, String toolClass, int harvestLevel)
|
||||
{
|
||||
ForgeHooks.toolClasses.put(tool, Arrays.asList(toolClass, harvestLevel));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a block to be harvested by a tool class. This is the metadata
|
||||
* sensitive version, use it if your blocks are using metadata variants.
|
||||
* By default, this sets the block class as effective against that type.
|
||||
*
|
||||
* @param block The block to register.
|
||||
* @param metadata The metadata for the block subtype.
|
||||
* @param toolClass The tool class to register as able to remove this block.
|
||||
* You may register the same block multiple times with different tool
|
||||
* classes, if multiple tool types can be used to harvest this block.
|
||||
* @param harvestLevel The minimum tool harvest level required to successfully
|
||||
* harvest the block.
|
||||
* @see MinecraftForge#setToolClass for details on tool classes.
|
||||
*/
|
||||
public static void setBlockHarvestLevel(Block block, int metadata, String toolClass, int harvestLevel)
|
||||
{
|
||||
List key = Arrays.asList(block, metadata, toolClass);
|
||||
ForgeHooks.toolHarvestLevels.put(key, harvestLevel);
|
||||
ForgeHooks.toolEffectiveness.add(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a block effectiveness mapping. Since setBlockHarvestLevel
|
||||
* makes the tool class effective against the block by default, this can be
|
||||
* used to remove that mapping. This will force a block to be harvested at
|
||||
* the same speed regardless of tool quality, while still requiring a given
|
||||
* harvesting level.
|
||||
*
|
||||
* @param block The block to remove effectiveness from.
|
||||
* @param metadata The metadata for the block subtype.
|
||||
* @param toolClass The tool class to remove the effectiveness mapping from.
|
||||
* @see MinecraftForge#setToolClass for details on tool classes.
|
||||
*/
|
||||
public static void removeBlockEffectiveness(Block block, int metadata, String toolClass)
|
||||
{
|
||||
List key = Arrays.asList(block, metadata, toolClass);
|
||||
ForgeHooks.toolEffectiveness.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a block to be harvested by a tool class.
|
||||
* By default, this sets the block class as effective against that type.
|
||||
*
|
||||
* @param block The block to register.
|
||||
* @param toolClass The tool class to register as able to remove this block.
|
||||
* You may register the same block multiple times with different tool
|
||||
* classes, if multiple tool types can be used to harvest this block.
|
||||
* @param harvestLevel The minimum tool harvest level required to successfully
|
||||
* harvest the block.
|
||||
* @see MinecraftForge#setToolClass for details on tool classes.
|
||||
*/
|
||||
public static void setBlockHarvestLevel(Block block, String toolClass, int harvestLevel)
|
||||
{
|
||||
for (int metadata = 0; metadata < 16; metadata++)
|
||||
{
|
||||
List key = Arrays.asList(block, metadata, toolClass);
|
||||
ForgeHooks.toolHarvestLevels.put(key, harvestLevel);
|
||||
ForgeHooks.toolEffectiveness.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the block harvest level for a particular tool class.
|
||||
*
|
||||
* @param block The block to check.
|
||||
* @param metadata The metadata for the block subtype.
|
||||
* @param toolClass The tool class to check as able to remove this block.
|
||||
* @see MinecraftForge#setToolClass for details on tool classes.
|
||||
* @return The harvest level or -1 if no mapping exists.
|
||||
*/
|
||||
public static int getBlockHarvestLevel(Block block, int metadata, String toolClass)
|
||||
{
|
||||
ForgeHooks.initTools();
|
||||
List key = Arrays.asList(block, metadata, toolClass);
|
||||
Integer harvestLevel = ForgeHooks.toolHarvestLevels.get(key);
|
||||
return (harvestLevel == null ? -1 : harvestLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a block effectiveness mapping. Since setBlockHarvestLevel
|
||||
* makes the tool class effective against the block by default, this can be
|
||||
* used to remove that mapping. This will force a block to be harvested at
|
||||
* the same speed regardless of tool quality, while still requiring a given
|
||||
* harvesting level.
|
||||
*
|
||||
* @param block The block to remove effectiveness from.
|
||||
* @param toolClass The tool class to remove the effectiveness mapping from.
|
||||
* @see MinecraftForge#setToolClass for details on tool classes.
|
||||
*/
|
||||
public static void removeBlockEffectiveness(Block block, String toolClass)
|
||||
{
|
||||
for (int metadata = 0; metadata < 16; metadata++)
|
||||
{
|
||||
List key = Arrays.asList(block, metadata, toolClass);
|
||||
ForgeHooks.toolEffectiveness.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method invoked by FML before any other mods are loaded.
|
||||
*/
|
||||
public static void initialize()
|
||||
{
|
||||
System.out.printf("MinecraftForge v%s Initialized\n", ForgeVersion.getVersion());
|
||||
FMLLog.info("MinecraftForge v%s Initialized", ForgeVersion.getVersion());
|
||||
|
||||
Block filler = new Block(0, Material.air)
|
||||
{
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void registerIcons(IconRegister register){}
|
||||
};
|
||||
Block.blocksList[0] = null;
|
||||
Block.opaqueCubeLookup[0] = false;
|
||||
Block.lightOpacity[0] = 0;
|
||||
filler.setUnlocalizedName("ForgeFiller");
|
||||
|
||||
for (int x = 256; x < 4096; x++)
|
||||
{
|
||||
if (Item.itemsList[x] != null)
|
||||
{
|
||||
Block.blocksList[x] = filler;
|
||||
}
|
||||
}
|
||||
|
||||
boolean[] temp = new boolean[4096];
|
||||
System.arraycopy(EntityEnderman.carriableBlocks, 0, temp, 0, EntityEnderman.carriableBlocks.length);
|
||||
EntityEnderman.carriableBlocks = temp;
|
||||
|
||||
EVENT_BUS.register(INTERNAL_HANDLER);
|
||||
OreDictionary.getOreName(0);
|
||||
|
||||
//Force these classes to be defined, Should prevent derp error hiding.
|
||||
new CrashReport("ThisIsFake", new Exception("Not real"));
|
||||
}
|
||||
|
||||
public static String getBrandingVersion()
|
||||
{
|
||||
return "Minecraft Forge "+ ForgeVersion.getVersion();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,409 @@
|
||||
/**
|
||||
* This software is provided under the terms of the Minecraft Forge Public
|
||||
* License v1.0.
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import net.minecraftforge.common.Property.Type;
|
||||
|
||||
public class Property
|
||||
{
|
||||
public enum Type
|
||||
{
|
||||
STRING,
|
||||
INTEGER,
|
||||
BOOLEAN,
|
||||
DOUBLE;
|
||||
|
||||
private static Type[] values = {STRING, INTEGER, BOOLEAN, DOUBLE};
|
||||
|
||||
public static Type tryParse(char id)
|
||||
{
|
||||
for (int x = 0; x < values.length; x++)
|
||||
{
|
||||
if (values[x].getID() == id)
|
||||
{
|
||||
return values[x];
|
||||
}
|
||||
}
|
||||
|
||||
return STRING;
|
||||
}
|
||||
|
||||
public char getID()
|
||||
{
|
||||
return name().charAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
private String name;
|
||||
private String value;
|
||||
public String comment;
|
||||
private String[] values;
|
||||
|
||||
private final boolean wasRead;
|
||||
private final boolean isList;
|
||||
private final Type type;
|
||||
private boolean changed = false;
|
||||
|
||||
public Property()
|
||||
{
|
||||
wasRead = false;
|
||||
type = null;
|
||||
isList = false;
|
||||
}
|
||||
|
||||
public Property(String name, String value, Type type)
|
||||
{
|
||||
this(name, value, type, false);
|
||||
}
|
||||
|
||||
Property(String name, String value, Type type, boolean read)
|
||||
{
|
||||
setName(name);
|
||||
this.value = value;
|
||||
this.type = type;
|
||||
wasRead = read;
|
||||
isList = false;
|
||||
}
|
||||
|
||||
public Property(String name, String[] values, Type type)
|
||||
{
|
||||
this(name, values, type, false);
|
||||
}
|
||||
|
||||
Property(String name, String[] values, Type type, boolean read)
|
||||
{
|
||||
setName(name);
|
||||
this.type = type;
|
||||
this.values = values;
|
||||
wasRead = read;
|
||||
isList = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value in this property as it's raw string.
|
||||
*
|
||||
* @return current value
|
||||
*/
|
||||
public String getString()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value in this property as an integer,
|
||||
* if the value is not a valid integer, it will return -1.
|
||||
*
|
||||
* @return The value
|
||||
*/
|
||||
public int getInt()
|
||||
{
|
||||
return getInt(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value in this property as an integer,
|
||||
* if the value is not a valid integer, it will return the
|
||||
* provided default.
|
||||
*
|
||||
* @param _default The default to provide if the current value is not a valid integer
|
||||
* @return The value
|
||||
*/
|
||||
public int getInt(int _default)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Integer.parseInt(value);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return _default;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current value stored in this property can be converted to an integer.
|
||||
* @return True if the type of the Property is an Integer
|
||||
*/
|
||||
public boolean isIntValue()
|
||||
{
|
||||
try
|
||||
{
|
||||
Integer.parseInt(value);
|
||||
return true;
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value in this property as a boolean,
|
||||
* if the value is not a valid boolean, it will return the
|
||||
* provided default.
|
||||
*
|
||||
* @param _default The default to provide
|
||||
* @return The value as a boolean, or the default
|
||||
*/
|
||||
public boolean getBoolean(boolean _default)
|
||||
{
|
||||
if (isBooleanValue())
|
||||
{
|
||||
return Boolean.parseBoolean(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _default;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current value held by this property is a valid boolean value.
|
||||
* @return True if it is a boolean value
|
||||
*/
|
||||
public boolean isBooleanValue()
|
||||
{
|
||||
return ("true".equals(value.toLowerCase()) || "false".equals(value.toLowerCase()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current value held by this property is a valid double value.
|
||||
* @return True if the value can be converted to an double
|
||||
*/
|
||||
public boolean isDoubleValue()
|
||||
{
|
||||
try
|
||||
{
|
||||
Double.parseDouble(value);
|
||||
return true;
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value in this property as a double,
|
||||
* if the value is not a valid double, it will return the
|
||||
* provided default.
|
||||
*
|
||||
* @param _default The default to provide if the current value is not a valid double
|
||||
* @return The value
|
||||
*/
|
||||
public double getDouble(double _default)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Double.parseDouble(value);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return _default;
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getStringList()
|
||||
{
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the integer value of all values that can
|
||||
* be parsed in the list.
|
||||
*
|
||||
* @return Array of length 0 if none of the values could be parsed.
|
||||
*/
|
||||
public int[] getIntList()
|
||||
{
|
||||
ArrayList<Integer> nums = new ArrayList<Integer>();
|
||||
|
||||
for (String value : values)
|
||||
{
|
||||
try
|
||||
{
|
||||
nums.add(Integer.parseInt(value));
|
||||
}
|
||||
catch (NumberFormatException e){}
|
||||
}
|
||||
|
||||
int[] primitives = new int[nums.size()];
|
||||
|
||||
for (int i = 0; i < nums.size(); i++)
|
||||
{
|
||||
primitives[i] = nums.get(i);
|
||||
}
|
||||
|
||||
return primitives;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if all of the current values stored in this property can be converted to an integer.
|
||||
* @return True if the type of the Property is an Integer List
|
||||
*/
|
||||
public boolean isIntList()
|
||||
{
|
||||
for (String value : values)
|
||||
{
|
||||
try
|
||||
{
|
||||
Integer.parseInt(value);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boolean value of all values that can
|
||||
* be parsed in the list.
|
||||
*
|
||||
* @return Array of length 0 if none of the values could be parsed.
|
||||
*/
|
||||
public boolean[] getBooleanList()
|
||||
{
|
||||
ArrayList<Boolean> tmp = new ArrayList<Boolean>();
|
||||
for (String value : values)
|
||||
{
|
||||
try
|
||||
{
|
||||
tmp.add(Boolean.parseBoolean(value));
|
||||
}
|
||||
catch (NumberFormatException e){}
|
||||
}
|
||||
|
||||
boolean[] primitives = new boolean[tmp.size()];
|
||||
|
||||
for (int i = 0; i < tmp.size(); i++)
|
||||
{
|
||||
primitives[i] = tmp.get(i);
|
||||
}
|
||||
|
||||
return primitives;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if all of current values stored in this property can be converted to a boolean.
|
||||
* @return True if it is a boolean value
|
||||
*/
|
||||
public boolean isBooleanList()
|
||||
{
|
||||
for (String value : values)
|
||||
{
|
||||
if (!"true".equalsIgnoreCase(value) && !"false".equalsIgnoreCase(value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the double value of all values that can
|
||||
* be parsed in the list.
|
||||
*
|
||||
* @return Array of length 0 if none of the values could be parsed.
|
||||
*/
|
||||
public double[] getDoubleList()
|
||||
{
|
||||
ArrayList<Double> tmp = new ArrayList<Double>();
|
||||
for (String value : values)
|
||||
{
|
||||
try
|
||||
{
|
||||
tmp.add(Double.parseDouble(value));
|
||||
}
|
||||
catch (NumberFormatException e) {}
|
||||
}
|
||||
|
||||
double[] primitives = new double[tmp.size()];
|
||||
|
||||
for (int i = 0; i < tmp.size(); i++)
|
||||
{
|
||||
primitives[i] = tmp.get(i);
|
||||
}
|
||||
|
||||
return primitives;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if all of the current values stored in this property can be converted to a double.
|
||||
* @return True if the type of the Property is a double List
|
||||
*/
|
||||
public boolean isDoubleList()
|
||||
{
|
||||
for (String value : values)
|
||||
{
|
||||
try
|
||||
{
|
||||
Double.parseDouble(value);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this config value was just created, or if it was read from the config file.
|
||||
* This is useful for mods who auto-assign there blocks to determine if the ID returned is
|
||||
* a configured one, or a automatically generated one.
|
||||
*
|
||||
* @return True if this property was loaded from the config file with a value
|
||||
*/
|
||||
public boolean wasRead()
|
||||
{
|
||||
return wasRead;
|
||||
}
|
||||
|
||||
public Type getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public boolean isList()
|
||||
{
|
||||
return isList;
|
||||
}
|
||||
|
||||
public boolean hasChanged(){ return changed; }
|
||||
void resetChangedState(){ changed = false; }
|
||||
|
||||
public void set(String value)
|
||||
{
|
||||
this.value = value;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
public void set(String[] values)
|
||||
{
|
||||
this.values = values;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
public void set(int value){ set(Integer.toString(value)); }
|
||||
public void set(boolean value){ set(Boolean.toString(value)); }
|
||||
public void set(double value){ set(Double.toString(value)); }
|
||||
}
|
||||
@@ -0,0 +1,408 @@
|
||||
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.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 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)
|
||||
{
|
||||
if (worldObj.isRemote)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (axis == UP || axis == DOWN)
|
||||
{
|
||||
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 BlockLog)
|
||||
{
|
||||
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, BlockType blockType)
|
||||
{
|
||||
int rotMeta = worldObj.getBlockMetadata(x, y, z);
|
||||
if (blockType == BlockType.DOOR && (rotMeta & 0x8) == 0x8)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int masked = rotMeta & ~mask;
|
||||
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);
|
||||
}
|
||||
}
|
||||
+3
-8
@@ -23,6 +23,8 @@ public class WorldSpecificSaveHandler implements ISaveHandler
|
||||
{
|
||||
this.world = world;
|
||||
this.parent = parent;
|
||||
dataDir = new File(world.getChunkSaveLocation(), "data");
|
||||
dataDir.mkdirs();
|
||||
}
|
||||
|
||||
@Override public WorldInfo loadWorldInfo() { return parent.loadWorldInfo(); }
|
||||
@@ -30,20 +32,13 @@ public class WorldSpecificSaveHandler implements ISaveHandler
|
||||
@Override public IChunkLoader getChunkLoader(WorldProvider var1) { return parent.getChunkLoader(var1); }
|
||||
@Override public void saveWorldInfoWithPlayer(WorldInfo var1, NBTTagCompound var2) { parent.saveWorldInfoWithPlayer(var1, var2); }
|
||||
@Override public void saveWorldInfo(WorldInfo var1){ parent.saveWorldInfo(var1); }
|
||||
@Override public IPlayerFileData getPlayerNBTManager() { return parent.getPlayerNBTManager(); }
|
||||
@Override public IPlayerFileData getSaveHandler() { return parent.getSaveHandler(); }
|
||||
@Override public void flush() { parent.flush(); }
|
||||
@Override public String getWorldDirectoryName() { return parent.getWorldDirectoryName(); }
|
||||
@Override public File getWorldDirectory() { return parent.getWorldDirectory(); }
|
||||
|
||||
@Override
|
||||
public File getMapFileFromName(String name)
|
||||
{
|
||||
if (dataDir == null) //Delayed down here do that world has time to be initalized first.
|
||||
{
|
||||
dataDir = new File(world.getChunkSaveLocation(), "data");
|
||||
dataDir.mkdirs();
|
||||
}
|
||||
return new File(dataDir, name + ".dat");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package net.minecraftforge.common.network;
|
||||
|
||||
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 {
|
||||
|
||||
@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
|
||||
public String connectionReceived(NetLoginHandler netHandler, INetworkManager manager)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionOpened(NetHandler netClientHandler, String server, int port, INetworkManager manager)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionOpened(NetHandler netClientHandler, MinecraftServer server, INetworkManager manager)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionClosed(INetworkManager manager)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clientLoggedIn(NetHandler clientHandler, INetworkManager manager, Packet1Login login)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package net.minecraftforge.common.network;
|
||||
|
||||
import net.minecraftforge.common.ForgeDummyContainer;
|
||||
import cpw.mods.fml.common.network.NetworkMod;
|
||||
import cpw.mods.fml.common.network.NetworkModHandler;
|
||||
|
||||
public class ForgeNetworkHandler extends NetworkModHandler
|
||||
{
|
||||
public ForgeNetworkHandler(ForgeDummyContainer container)
|
||||
{
|
||||
super(container,container.getClass().getAnnotation(NetworkMod.class));
|
||||
configureNetworkMod(container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptVersion(String version)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
package net.minecraftforge.common.network;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
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;
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.primitives.Bytes;
|
||||
import com.google.common.primitives.Ints;
|
||||
import com.google.common.primitives.UnsignedBytes;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.network.FMLNetworkException;
|
||||
|
||||
public abstract class ForgePacket
|
||||
{
|
||||
public static final String CHANNEL_ID = "FORGE";
|
||||
enum Type
|
||||
{
|
||||
/**
|
||||
* Registers a dimension for a provider on client
|
||||
*/
|
||||
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;
|
||||
|
||||
private Type(Class<? extends ForgePacket> clazz)
|
||||
{
|
||||
this.packetType = clazz;
|
||||
}
|
||||
|
||||
ForgePacket make()
|
||||
{
|
||||
try
|
||||
{
|
||||
return this.packetType.newInstance();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Throwables.propagateIfPossible(e);
|
||||
FMLLog.log(Level.SEVERE, e, "A bizarre critical error occured during packet encoding");
|
||||
throw new FMLNetworkException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ForgePacket consumePart(INetworkManager network, byte[] data)
|
||||
{
|
||||
if (partTracker == null)
|
||||
{
|
||||
partTracker = new MapMaker().weakKeys().weakValues().makeMap();
|
||||
}
|
||||
if (!partTracker.containsKey(network))
|
||||
{
|
||||
partTracker.put(network, make());
|
||||
}
|
||||
|
||||
ForgePacket pkt = partTracker.get(network);
|
||||
|
||||
ByteArrayDataInput bdi = ByteStreams.newDataInput(data);
|
||||
int chunkIdx = UnsignedBytes.toInt(bdi.readByte());
|
||||
int chunkTotal = UnsignedBytes.toInt(bdi.readByte());
|
||||
int chunkLength = bdi.readInt();
|
||||
|
||||
if (pkt.partials == null)
|
||||
{
|
||||
pkt.partials = new byte[chunkTotal][];
|
||||
}
|
||||
|
||||
pkt.partials[chunkIdx] = new byte[chunkLength];
|
||||
bdi.readFully(pkt.partials[chunkIdx]);
|
||||
for (int i = 0; i < pkt.partials.length; i++)
|
||||
{
|
||||
if (pkt.partials[i] == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return pkt;
|
||||
}
|
||||
}
|
||||
|
||||
private Type type;
|
||||
private byte[][] partials;
|
||||
|
||||
public static Packet250CustomPayload[] makePacketSet(ForgePacket packet)
|
||||
{
|
||||
byte[] packetData = packet.generatePacket();
|
||||
|
||||
if (packetData.length < 32000)
|
||||
{
|
||||
return new Packet250CustomPayload[]
|
||||
{
|
||||
new Packet250CustomPayload(CHANNEL_ID,
|
||||
Bytes.concat(new byte[]
|
||||
{
|
||||
UnsignedBytes.checkedCast(0), //IsMultipart: False
|
||||
UnsignedBytes.checkedCast(packet.getID())
|
||||
},
|
||||
packetData))
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[][] chunks = new byte[packetData.length / 32000 + 1][];
|
||||
for (int i = 0; i < packetData.length / 32000 + 1; i++)
|
||||
{
|
||||
int len = Math.min(32000, packetData.length - i* 32000);
|
||||
chunks[i] = Bytes.concat(new byte[]
|
||||
{
|
||||
UnsignedBytes.checkedCast(1), //IsMultipart: True
|
||||
UnsignedBytes.checkedCast(packet.getID()), //Packet ID
|
||||
UnsignedBytes.checkedCast(i), //Part Number
|
||||
UnsignedBytes.checkedCast(chunks.length), //Total Parts
|
||||
},
|
||||
Ints.toByteArray(len), //Length
|
||||
Arrays.copyOfRange(packetData, i * 32000, len + i * 32000));
|
||||
}
|
||||
|
||||
Packet250CustomPayload[] ret = new Packet250CustomPayload[chunks.length];
|
||||
for (int i = 0; i < chunks.length; i++)
|
||||
{
|
||||
ret[i] = new Packet250CustomPayload(CHANNEL_ID, chunks[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public static ForgePacket readPacket(INetworkManager network, byte[] payload)
|
||||
{
|
||||
boolean multipart = UnsignedBytes.toInt(payload[0]) == 1;
|
||||
int type = UnsignedBytes.toInt(payload[1]);
|
||||
Type eType = Type.values()[type];
|
||||
byte[] data = Arrays.copyOfRange(payload, 2, payload.length);
|
||||
|
||||
if (multipart)
|
||||
{
|
||||
ForgePacket pkt = eType.consumePart(network, data);
|
||||
if (pkt != null)
|
||||
{
|
||||
return pkt.consumePacket(Bytes.concat(pkt.partials));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return eType.make().consumePacket(data);
|
||||
}
|
||||
}
|
||||
|
||||
public ForgePacket()
|
||||
{
|
||||
for (Type t : Type.values())
|
||||
{
|
||||
if (t.packetType == getClass())
|
||||
{
|
||||
type = t;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (type == null)
|
||||
{
|
||||
throw new RuntimeException("ForgePacket constructor called on ungregistered type.");
|
||||
}
|
||||
}
|
||||
|
||||
public byte getID()
|
||||
{
|
||||
return UnsignedBytes.checkedCast(type.ordinal());
|
||||
}
|
||||
|
||||
public abstract byte[] generatePacket();
|
||||
|
||||
public abstract ForgePacket consumePacket(byte[] data);
|
||||
|
||||
public abstract void execute(INetworkManager network, EntityPlayer player);
|
||||
}
|
||||
Loaded 100 of 1083 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user